Source file: /~heha/hsn/esptool.zip/intrin.h

#pragma once
#include <assert.h>

#if _MSC_VER < 1400	// Visual C++ 6
extern "C" unsigned long _cdecl _byteswap_ulong(unsigned long);
extern "C" unsigned __int64 _cdecl _byteswap_uint64(unsigned __int64);

namespace std{
__forceinline uint32 rotl(uint32 x, byte n) {	// rotate x left by n bits
 _asm	mov	cl,n
 _asm	rol	x,cl
 return x;
}

__forceinline uint32 rotr(uint32 x, byte n) {	// rotate x right by n bits
 _asm	mov	cl,n
 _asm	ror	x,cl
 return x;
}

__forceinline uint64 rotl(uint64 x, byte n) {return x<<n | x>>(64-n);}
__forceinline uint64 rotr(uint64 x, byte n) {return x>>n | x<<(64-n);}

#else
# include <stdlib.h>
#pragma intrinsic(_byteswap_ulong,_byteswap_uint64,_rotl,_rotr,_rotl64,_rotr64)
namespace std{
__forceinline uint32 rotl(uint32 x,byte cl) {return _rotl(x,cl);}
__forceinline uint32 rotr(uint32 x,byte cl) {return _rotr(x,cl);}
__forceinline uint64 rotl(uint64 x,byte cl) {return _rotl64(x,cl);}
__forceinline uint64 rotr(uint64 x,byte cl) {return _rotr64(x,cl);}

#endif

__forceinline uint32 byteswap(uint32 x) {
 return _byteswap_ulong(x);
// _asm	bswap	x // geht nicht, Compilerfehler!
}

__forceinline uint64 byteswap(uint64 x) {
 return _byteswap_uint64(x);
}
}

// Ein unique_ptr für die Rückgabe von Funktionen
// (die im Innern realloc() aurufen müssen)
template<class T>class autofreeptr{
 T*h;
public:
 autofreeptr(autofreeptr<T>&o) {h=o.h; o.h=0;}	// Raubkopier-Konstruktor
 autofreeptr(T*o):h(o) {}			// Konstruktor mit Pointer-Übernahme (muss von alloc/realloc kommen)
 ~autofreeptr() {free(h);}			// Destruktor = Dreierregel
 void operator=(autofreeptr<T>&o) {free(h); h=o.h; o.h=0;}	// Raubkopier-Zuweisung
 void operator=(T*o) {free(h); h=o;}		// Pointer-Übernahme (darf auch nullptr sein)
 operator const T*() const {return h;}
 const T*operator->() const {return h;}
};

template<class T>class fix_array{	// wie oben aber ohne operator-> für non-struct/union/class-Typen
 T*h;
public:
 fix_array(size_t n):h(new T[n]) {}
 ~fix_array() {delete[]h;}
 fix_array(const fix_array&o) {h=o.h; o.h=0;}
 void operator=(fix_array&o) {delete[]h; h=o.h; o.h=0;}
 operator T*() {return h;}
};

// Mini-Implementierung von Strings variabler(!) Länge als Returnwert von Funktionen.
// std::string generiert umständlichen Kode.
// Auch dieser String wird (leider) per __$ReturnUdt durchgewurstelt,
// auch wenn's in 32 Bit passt, leider.
class autostring{
 mutable char*s;	// Nur ein Pointer!
public:
 const char*c_str() const {return s;}		// (Einziger) Typecast, nach Möglichkeit auch für ... verwenden
 autostring(size_t n):s(new char[n]) {*s=0;}	// Genereller Konstruktor
 autostring(const autostring&a):s(a.s) {a.s=0;}	// kommt bei return() auf den Plan
 autostring(char*_s):s(_s) {}			// _s muss mit new[] alloziert sein!
 ~autostring() {delete[]s;}			// mit s==0 tut delete[] nichts, zum Glück
};

inline byte digit(char c) {
 if (c<0) return c;	// Fehler
 if (c<='9') return c-'0';
 c&=' ';	// klein->groß, aber auch '@' (40) -> ' ' (20)
 c-='A';
 if (c<0) return c;	// Fehler
 return c+10;
}

// Wenn schon __$ReturnUdt dann für Strings von einigermaßen bekannter Länge!
// Das erspart new und delete komplett: Kein Heap erforderlich.
// gcc und MSVC2008+ optimieren den Kopierkonstruktor bei return weg,
// d.h. rettype buf benutzt __$ReturnUdt statt neuen Platz auf dem Stack.
// MSVC6 hingegen optimiert den Kopierkonstruktor nur bei gleichen Pointern weg.
template<unsigned N,class T=char>class String{
 T s[(N+sizeof(void*)-1)&~(sizeof(void*)-1)];	// in 4-Byte- oder 8-Byte-Stückelung allokieren
public:
 enum{capacity=N};
 operator T*() {return s;}		// so Zugriff mittels *__$ReturnUdt
 const T*c_str() const {return s;}	// Erforderlich für ...-Argument
};

// Lästiges Aneinanderreihen von Strings in einen Puffer per sprintf
// inklusive Überlaufschutz erleichtert diese Hilfsklasse
class Printbuf{
protected:
 char*s;
 unsigned n,k;	// muss nicht size_t sein
public:
 Printbuf(char*o,unsigned os):s(o),n(os) {reset();}	// gleich nullterminieren
 void reset() {s[k=0]=0;}
 unsigned size() const {return k;}
 unsigned capacity() const {return n;}
 void _cdecl operator() (const char*,...);
};

#ifdef _MSC_VER
# define MAKEBUF(size) String<size>&buf=*__$ReturnUdt	// Alias für __$ReturnUdt
#else
# define MAKEBUF(size) String<size>buf	// gcc, allgemein: neuer Platz, return Kopie (wird alles wegoptimiert)
#endif


#define MAKEPRINTBUF(size)	\
 MAKEBUF(size);			\
 Printbuf print(buf,buf.capacity);
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded