#pragma once
#include <windows.h>
#include <limits>
union FLEXDATA{ // buftype
void*v; // als erstes zur allgemeinen Initialisierung
const float*cf; // 8
const bool*ca; // 0
const BYTE*cb; // 0
const WORD*ch; // 1
const DWORD*cw; // 2
const unsigned __int64*cq;//3
const char*cc; // 4
const short*cs; // 5
const long*ci; // 6
const __int64*cl; // 7
const double*cd; // 9
const void*cv;
float*f;
bool*a;
BYTE*b;
WORD*h;
DWORD*w;
unsigned __int64*q;
char*c;
short*s;
long*i;
__int64*l;
double*d;
};
template<typename T> class Datareader{
virtual T get() const =0;
virtual T operator()() =0;
};
template<typename T> class DatareaderN:public Datareader<T>{ // <T> ist "float" oder "double"
static T takeint(__int64 val,__int64 infbase) {
__int64 infnan=val-infbase;
if ((unsigned __int64)infnan>=3) return static_cast<T>(val);
switch (static_cast<char>(infnan)) {
case 0: return +std::numeric_limits<T>::infinity();
case 2: return -std::numeric_limits<T>::infinity();
default: return std::numeric_limits<T>::quiet_NaN();
}
}
public:
static T takeu8(FLEXDATA p) {return *p.cb;}
static T takeu16(FLEXDATA p) {return *p.ch;}
static T takeu32(FLEXDATA p) {return static_cast<T>(*p.cw);}
static T takeu64(FLEXDATA p) {return static_cast<T>(*p.cq);}
static T takei8(FLEXDATA p) {return takeint(*p.cc,0x7F);}
static T takei16(FLEXDATA p) {return takeint(*p.cs,0x7FFF);}
static T takei32(FLEXDATA p) {return takeint(*p.ci,0x7FFFFFFF);}
static T takei64(FLEXDATA p) {return takeint(*p.cl,0x7FFFFFFFFFFFFFFF);}
static T takefloat(FLEXDATA p) {return *p.cf;}
static T takedbl(FLEXDATA p) {return static_cast<T>(*p.cd);}
typedef T (*getfcn)(FLEXDATA);
enum typ{
U8,U16,U32,U64,I8,I16,I32,I64,F32,F64
};
static getfcn getters[]; // Liste der 10 Entnahmefunktionen
private:
FLEXDATA data; // Laufender Datenzeiger
getfcn getter; // Aktuelle Entnahmefunktion (statt einem Rudel abgeleiteter Klassen)
UINT increment; // Sprungweite des Datenzeigers in Bytes
public:
T operator[](UINT);
T get() const {return getter(data);}
static UINT getarrayinc(typ _typ) {return _typ&8?4<<(_typ&1):1<<(_typ&3);}
// Parameterliste: Datenzeiger, Werttyp, Sprungweite des Zeigers zum nächsten Wert in Bytes
DatareaderN(const void*_data,typ _typ,int _increment=0) {
data.cv=_data;
getter=getters[_typ]; // Funktionszeiger setzen
increment=_increment;
if (!increment) increment=getarrayinc(_typ);
}
T operator()() {
T r=get();
data.cb+=increment;
return r;
}
};
template<typename T> class DatareaderFcn:public Datareader<T>{
public:
typedef T (*fcn_t)(T);
DatareaderFcn(fcn_t _fcn,T _start, T _increment){
fcn=_fcn;
start=_start;
increment=_increment;
}
T get() const {return fcn(start);}
T operator()() {
T r=get(); start+=increment; return r;
}
private:
fcn_t fcn;
T start, increment;
};
template<typename T> class DatareaderBits:public Datareader<T>{
public:
DatareaderBits(const void*_mem, int _numbits=1, int increment=0, int index=0){
mem.cv=_mem;
numbits=_numbits;
if (!_increment) _increment=_numbits;
increment=_increment;
index=_index;
}
T get() const {return *(DWORD*)(mem.cb+index>>3)>>(index&7)&(1<<numbits)-1;}
T operator()() {
T r=fcn(start); index+=increment; return r;
}
private:
FLEXDATA mem;
int index,numbits,increment;
};
Detected encoding: ANSI (CP1252) | 4
|
|