converted by lore's source converter
//////////////////////////////////////////////////////////////////////////////
//
// MDataX.cpp: Implementation of the MDataX class
//
//////////////////////////////////////////////////////////////////////////////
//
// author: Eckhard Kantz
// website: http://wegalink.eu
//
//////////////////////////////////////////////////////////////////////////////
/*
This is FREE software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
There are no conditions imposed on the use of this software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "MDataX.h"
#define RADIX_216 216
// Initialize time period hierarchy
static struct stTimePeriodHierarchy TimePeriodHierarchy[] = {
{ MAX_INT32, "%u", "%u" },
{ MAX_INT32, "-%u", "-%02u" },
{ 24*60*60, "%uth", "-%02u" }, // one file per day
{ 60*60, "utc%02uh", "_utc%02uh" }, // one file per hour
{ 60, "%02um", "%02um" }, // one file per minute
{ 1, "%02us", "%02us" }, // one file per second
{ 0, "", "(%u)" }, // one file for each data chunk
};
// Initialize months table
char* Months[] = {"0","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
//////////////////////////////////////////////////////////////////////
// MDataX class.
//////////////////////////////////////////////////////////////////////
MDataX::MDataX(int8* szIdentifier,int8* szFileName,int8* szDataXroot)
{
// External interface initialization
#ifdef WIN32
DataXroot = "X:";
Delimiter = "\\";
InitialDir = "";
#else //Unix
DataXroot = "/home/DataX";
Delimiter = "/";
#endif
DeviceDir = DataXroot;
DeviceDir += Delimiter;
DeviceDir += szIdentifier;
Identifier = szIdentifier;
FileName = szFileName;
FilePeriod = 60*60; // data of one hour goes into one file
Parameters = "parameters.txt"; // the content of this file will be included after the header line of the DataX file
LogFile = "DataXlog.txt"; // default log file for a DataX server
// Internal initialization
data_fd = 0; // indicate that no data file is open
TimeIndex = 0;
FileIndex = 0;
// Initial dir
char curdir[MAXPATHLEN];
GETCWD(curdir,MAXPATHLEN);
InitialDir += curdir;
// Generate and fill conversion table
BinXconvert = new uint16[32768];
for (int i=0;i<32768;i++){
*(BinXconvert+i)=256*bcode(i/216)+bcode(i%216);
}
}
MDataX::~MDataX()
{
// Close data file if still open
if (0!=data_fd){
close(data_fd);
}
}
void MDataX::unitTest()
{
#define BIN_LEN 1421507
#define STR_LEN 30
uint8* pField = new uint8[BIN_LEN+1];
uint8* pField1 = new uint8[BIN_LEN+1];
uint16* pBinMCL = new uint16[16*BIN_LEN/15];
MString mBinX;
MString mBinX1(STR_LEN);
MString mBinX2(STR_LEN);
printf("Testing BinX conversion\n");
for (int i=0;i<BIN_LEN;i++){
pField[i] = (uint8)(i*43);
}
// Convert binary to a BinX string
bin2BinX(&mBinX,pField,BIN_LEN);
strncpy(mBinX1.getBuffer(),mBinX.getBuffer(),STR_LEN);
strncpy(mBinX2.getBuffer(),mBinX.getBuffer()+mBinX.getLength()-STR_LEN,STR_LEN);
printf("\nBinX (%3d): \"%s.....%s\"\n",mBinX.getLength(),mBinX1.getBuffer(),mBinX2.getBuffer());
// Convert a BinX string to binary
BinX2bin(pField1,BIN_LEN,mBinX);
// Compare
if (0==memcmp(pField,pField1,BIN_LEN)){
printf("\nBinX conversion successful for %u bytes.\n\n",BIN_LEN);
}else{
printf("BinX conversion ---FAILED---\n\n");
}
// Convert binary to a BinMCL string
bin2BinMCL(BIN_LEN/30,(uint16*)pField,pBinMCL);
strncpy(mBinX1.getBuffer(),(char*)pBinMCL,STR_LEN);
printf("\nBinMCL: \"%s\"\n",mBinX1.getBuffer());
// Convert a BinMCL string to binary
BinMCL2bin(BIN_LEN/30,pBinMCL,(uint16*)pField1);
// Compare
if (0==memcmp(pField,pField1,BIN_LEN-BIN_LEN%2)){
printf("\nBinMCL conversion successful for %u bytes.\n\n",BIN_LEN);
}else{
printf("BinMCL conversion ---FAILED---\n\n");
}
// Convert numeric value
uint64 u64Num = 85;
uint64 u64Num1;
uint64 u64Factor =1;
srand((unsigned)time(NULL));
for (int i=0;i<9;i++){
if (i<8){
u64Num = u64Factor + (rand()*rand())%(u64Factor*RADIX_216);
}else{
u64Num += 0xC000000000000000;
}
num2BinX(&mBinX,&u64Num);
u64Num1 = BinX2num(mBinX);
if (i==7){
// Extended search for failure
for (int k=0;k<100000&&u64Num==u64Num1;k++){
u64Num = u64Factor + (rand()*rand())%(u64Factor*RADIX_216);
num2BinX(&mBinX,&u64Num);
u64Num1 = BinX2num(mBinX);
}
}
#ifndef WIN32
printf("Numeric conversion (%20u): %9s len=%u (%20u) %s\n",
(uint32)u64Num,mBinX.getBuffer(),mBinX.getLength(),(uint32)u64Num1,u64Num==u64Num1?"OK":"failed");
#else
printf("Numeric conversion (%20I64u): %9s len=%u (%20I64u) %s\n",
u64Num,mBinX.getBuffer(),mBinX.getLength(),u64Num1,u64Num==u64Num1?"OK":"failed");
#endif
u64Factor *= RADIX_216;
}
MBenchmark mBenchmark(3);
try{
while(mBenchmark.run()){
bin2BinX(&mBinX,pField,BIN_LEN);
}
printf("\n bin2BinX / Byte: %s\n",mBenchmark.info(850,BIN_LEN).getText());
}catch(MException E){
throw MException(E.getMessage(),"Dump");
}
try{
while(mBenchmark.run()){
bin2BinMCL(BIN_LEN/30,(uint16*)pField,pBinMCL);
}
printf("\n bin2BinMCL / Byte: %s\n",mBenchmark.info(850,BIN_LEN).getText());
}catch(MException E){
throw MException(E.getMessage(),"Dump");
}
return;
}
//--------------------------------------------------
// DataX bin code, byt<=215
unsigned char MDataX::bcode(unsigned char byt)
{
unsigned char b;
switch (byt)
{
case 12: b=248;break; // avoid ,
case 13: b=249;break; // avoid -
case 26: b=250;break; // avoid :
case 27: b=251;break; // avoid ;
case 29: b=252;break; // avoid =
case 32: b=253;break; // avoid @
case 64: b=254;break; // avoid `
case 95: b=255;break; // avoid del
default: b=byt+32;
}
return b;
}
//--------------------------------------------------
// DataX bin decode
unsigned char MDataX::bdecode(unsigned char byt)
{
unsigned char b;
switch (byt)
{
case 248: b=12;break; // avoid ,
case 249: b=13;break; // avoid -
case 250: b=26;break; // avoid :
case 251: b=27;break; // avoid ;
case 252: b=29;break; // avoid =
case 253: b=32;break; // avoid @
case 254: b=64;break; // avoid `
case 255: b=95;break; // avoid del
default: b=byt-32;
}
return b;
}
//--------------------------------------------------
// uuu_packer_w converts n groups of 15 words into 32n DataX legal chars
void MDataX::bin2BinMCL(int n, uint16 *inp, uint16 *out)
{
union shifter {
uint16 wrd[2]; //[0]=lsw [1]=msw
unsigned long lwr;
} shf;
int i;
for (i=0;i<n;i++){ //30270 = 32768*15/16
shf.lwr = 0;
shf.wrd[0]=*inp++; //get input word
shf.lwr=shf.lwr<<1; //save msb
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1)); //table lookup and store two chars
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
shf.wrd[0]=*inp++;
shf.lwr=shf.lwr<<1;
*out++=*(uint16*)(BinXconvert+(shf.wrd[0]>>1));
*out++=*(uint16*)(BinXconvert+shf.wrd[1]); //store the word made of msb's
}
}
//------------------------------------------
//unpacks n 32 byte groups into n 15 word groups
void MDataX::BinMCL2bin(int n, uint16 *inp, uint16 *out)
{
uint16 w,wb[15];
for (int i=0;i<n;i++)
{
for (int j=0;j<15;j++)
{
w=*inp++;
wb[j]=216*bdecode(w/256)+bdecode(w%256);
}
w=*inp++;
w=216*bdecode(w/256)+bdecode(w%256);
w=w<<1;
for (int j=0;j<15;j++)
{
*out++=(wb[j])+(w&32768);
w=w<<1;
}
}
}
MString* MDataX::num2BinX(MString* pBinX,uint64 u64Num)
{
return num2BinX(pBinX,&u64Num);
}
MString* MDataX::num2BinX(MString* pBinX,uint64* p64Num)
{
uint64 u64Num = *p64Num;
int32 nDigits;
if (0 == (u64Num & 0xFFFFFFFF80000000)){
for (nDigits=1;u64Num >= RADIX_216;nDigits++){
u64Num /= RADIX_216;
}
}else if (0 == (u64Num & 0xC000000000000000)){
u64Num >>= 31;
for (nDigits=5;u64Num >= RADIX_216;nDigits++){
u64Num /= RADIX_216;
}
}else{
nDigits = 9;
}
return bin2BinX(pBinX,(uint8*)p64Num,8,nDigits);
}
uint64 MDataX::BinX2num(MString& mBinX)
{
uint64 u64Num;
BinX2bin((uint8*)&u64Num,8,mBinX,true);
return u64Num;
}
MString* MDataX::bin2BinX(MString* pBinX,uint8* pBuf,int32 nBinLen,int32 nDigits)
{
int64 n64Bits = 8*nBinLen;
int32 nBinXLen = nDigits>0?nDigits:(int32)(4*((n64Bits)/31)+((n64Bits)%31)/8+((n64Bits)%31>0?1:0));
int64 n64Used;
int32 nShift;
int32 nPos = 0;
int64 n64Factor;
uint8 uchCode;
uint32 uQuadrupel;
uint64 u64Register;
// Determine length of the resulting BinX string
pBinX->setLength(nBinXLen);
// Split input bit field into 31-bit chunks
for (n64Used=0;n64Used<n64Bits;n64Used+=31){
//Load register
if (n64Used/8+8<=nBinLen){
u64Register = *((uint64*)(pBuf+(int32)(n64Used/8)));
}else{
u64Register = 0;
n64Factor = 1;
for (int i=(int32)(n64Used/8);i<nBinLen;i++){
u64Register += *(pBuf+i) * n64Factor;
n64Factor *= 256;
}
}
// Bit shift
nShift = (int32)(n64Used%8);
if (0==nShift){
uQuadrupel = (uint32)u64Register;
}else{
u64Register >>= nShift;
uQuadrupel = (uint32)u64Register;
}
uQuadrupel &= 0x7FFFFFFF;
// Code generation
for (int i=0;i<4 && nPos<nBinXLen;i++){
uchCode = uQuadrupel%RADIX_216;
uQuadrupel /= RADIX_216;
uchCode = *(uint8*)(BinXconvert+uchCode);
pBinX->setAt(nPos++,uchCode);
}
}
return pBinX;
}
int32 MDataX::BinX2bin(uint8* pBuf,int32 nBufSize,MString& mBinX,bool fTail)
{
int32 nBinXLen = mBinX.getLength();
int32 nBinXbits = 31*(nBinXLen/4)+((nBinXLen%4)==0?0:8*(nBinXLen%4)-1);
int32 nBinLen = nBinXbits/8 + ((fTail==true) && (nBinXbits<64) && (nBinXbits%8>0) ? 1 : 0);
int32 nPos;
uint8 uchMerge;
int64 n64Used = 0;
int32 nShift;
int32 nFactor;
uint8 uchCode;
bool fMerge;
uint64 uQuadrupel;
// Check if buffer size is sufficient
if (nBufSize<nBinLen){
throw MException("Unsufficient binary buffer size",nBufSize);
}
memset(pBuf,0,nBufSize);
for (nPos=0;nPos<nBinXLen;nPos+=4){
//Decode BinX characters
uQuadrupel = 0;
nFactor = 1;
for (int i=nPos;i<nPos+4 && i<nBinXLen;i++){
uchCode = *(mBinX.getBuffer()+i);
switch (uchCode){
case 248: uchCode = 12; break; //avoid 44 - comma
case 249: uchCode = 13; break; //avoid 45 - minus sign
case 250: uchCode = 26; break; //avoid 58 - colon
case 251: uchCode = 27; break; //avoid 59 - semicolon
case 252: uchCode = 29; break; //avoid 61 - equal sign
case 253: uchCode = 32; break; //avoid 64 - @ sign
case 254: uchCode = 64; break; //avoid 96 - back apostroph
case 255: uchCode = 95; break; //avoid 127- del
default: uchCode -= 32;
}
uQuadrupel += uchCode * nFactor;
nFactor *= RADIX_216;
}
// Generate bit sequence
nShift = (int32)(n64Used%8);
fMerge = true;
if (0==nShift){
fMerge = false;
}else{
uQuadrupel <<= nShift;
}
if (true==fMerge){
uchMerge = *(pBuf+(n64Used/8));
uQuadrupel += uchMerge;
}
// Fill buffer
if (n64Used/8+4 < nBinLen){
*(int32*)(pBuf+(n64Used/8)) = (int32)uQuadrupel;
if (nShift > 1){
*(pBuf+(n64Used/8)+4) = (int8)(uQuadrupel>>32);
}
}else{
for (int32 i=(int32)(n64Used/8);i<nBinLen;i++){
*(pBuf+i) = (int8)(uQuadrupel);
uQuadrupel >>= 8;
}
}
n64Used += 31;
}
return nBinLen;
}
void MDataX::enterSubDirectory(struct stTimePeriodHierarchy* pTimePeriodHierarchy,
unsigned int* pTimeVal,MString& Prefix,bool fCreate)
{
#define S_MASK S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH
// Escape period==0
if (0==pTimePeriodHierarchy->period){
char Index[100];
sprintf(Index,pTimePeriodHierarchy->file_format,FileIndex++);
Prefix += Index;
return;
}
// Generate subsequent names
char dir[100];
char prefix[100];
sprintf(dir,pTimePeriodHierarchy->dir_format,*pTimeVal);
// Convert month to string
if (dir[0]=='-'){
strcpy(dir,Months[*pTimeVal]);
}
// Adjust day numeral
if (!strcmp(dir,"1th")){
strcpy(dir,"1st");
}
if (!strcmp(dir,"2th")){
strcpy(dir,"2nd");
}
if (!strcmp(dir,"3th")){
strcpy(dir,"3rd");
}
if (!strcmp(dir,"21th")){
strcpy(dir,"21st");
}
if (!strcmp(dir,"22th")){
strcpy(dir,"22nd");
}
if (!strcmp(dir,"23th")){
strcpy(dir,"23rd");
}
if (!strcmp(dir,"31th")){
strcpy(dir,"31st");
}
sprintf(prefix,pTimePeriodHierarchy->file_format,*pTimeVal);
Prefix += prefix;
// Enter (create) subsequent directory level
if (-1==chdir(dir)){
if (true==fCreate){
if (-1==MKDIR(dir,S_MASK)){
throw (MException(strerror(errno)));
}
if (-1==chdir(dir)){
throw (MException(strerror(errno)));
}
}else{
throw MException("Folder does not exist",Prefix);
}
}
// Check if another directory level is needed
if (FilePeriod<pTimePeriodHierarchy->period){
enterSubDirectory(pTimePeriodHierarchy+1,pTimeVal+1,Prefix,fCreate);
}
}
void MDataX::openTimePeriodFile(time_t SampleTime,bool fCreate)
{
struct tm* pDateTime = gmtime(&SampleTime);
unsigned int TimeVal[] = {
pDateTime->tm_year + 1900,
pDateTime->tm_mon + 1,
pDateTime->tm_mday,
pDateTime->tm_hour,
pDateTime->tm_min,
pDateTime->tm_sec,
0
};
MString Prefix("");
// Enter (create) root directory in data storage
if (-1==chdir(DeviceDir.getText())){
if (true==fCreate){
if (-1==MKDIR(DeviceDir.getText(),S_MASK)){
throw (MException(strerror(errno)));
}
if (-1==chdir(DeviceDir.getText())){
throw (MException(strerror(errno)));
}
}else{
throw MException("Folder does not exist",DeviceDir.getText());
}
}
// Enter (create) subsequent directories in data storage
enterSubDirectory(TimePeriodHierarchy,TimeVal,Prefix,fCreate);
// Complete file name
Prefix += "_";
Prefix += FileName;
if (true==fCreate){
// Open data file for writing
if (-1==(data_fd = OPEN(Prefix.getText(),O_RDWR|O_APPEND,S_IREAD|S_IWRITE))){
// Maybe file does not exist so creat it
if (-1==(data_fd = OPEN(Prefix.getText(),O_RDWR| // read/write access
O_CREAT, // create file
S_IREAD| // user can read
S_IWRITE| // user can write
S_IRGRP| // group can read
S_IWGRP))){ // group can write
throw (MException(strerror(errno)));
}
// Generate identification line
char achTime[20];
sprintf(achTime,"%u,duration:%u",(uint32)SampleTime,FilePeriod);
MString mData(Identifier);
mData += ",";
mData += achTime;
mData += "\n";
// Write identification line to file
if (-1==write(data_fd,mData.getBuffer(),mData.getLength())){
throw (MException(strerror(errno)));
}
// Append parameter file content
MString mParameter(DeviceDir);
mParameter += Delimiter;
mParameter += Parameters;
try{
mData.read(mParameter.getBuffer());
// Write parameters section to file
if (-1==write(data_fd,mData.getBuffer(),mData.getLength())){
throw (MException(strerror(errno)));
}
}catch(...){
}
}
}else{
// Open data file for reading
if (-1==(data_fd = OPEN(Prefix.getText(),O_RDONLY,0))){
throw (MException("File does not exist"));
}
}
// Remember opened file period
if (FilePeriod>0){
TimeIndex = SampleTime/FilePeriod;
}else{
TimeIndex = 0;
}
// Change back to initial dir
if (-1==chdir(InitialDir.getText())){
throw (MException(strerror(errno)));
}
}
void MDataX::writeData(time_t SampleTime, MString& mData)
{
writeData(SampleTime, mData.getBuffer(), mData.getLength());
}
void MDataX::writeData(time_t SampleTime, char* Data, int DataLen)
{
// Check time period index
if (FilePeriod!=0 && TimeIndex==SampleTime/FilePeriod){
// Check if the data file needs to be opened
if (0==data_fd){
openTimePeriodFile(SampleTime,true);
}
}else{
if (0!=data_fd){
close(data_fd);
}
openTimePeriodFile(SampleTime,true);
}
// Append data to file
if (-1==write(data_fd,Data,DataLen)){
throw (MException(strerror(errno)));
}
}
void MDataX::readData(time_t SampleTime,MString* pData)
{
openTimePeriodFile(SampleTime);
//Determine file size
struct stat stat_buf;
uint32 uFileSize;
if (0==fstat(data_fd,&stat_buf)){
uFileSize = stat_buf.st_size;
pData->setLength(uFileSize+1);
*(pData->getBuffer()+uFileSize) = 0;
}else{
throw MException("File status not accessible:");
}
// Get data from file into memory
read(data_fd,pData->getBuffer(),uFileSize);
close(data_fd);
}
void MDataX::dumpData(time_t SampleTime,MString* pData,MString& mStyle)
{
uint32 uCount;
uint64 u64MilliTimeStamp;
MString mTimeStamp;
MString mFile;
MString mPrefix;
MString mNum;
MString mBin;
MString mDataVector;
MMString mLine(mFile,"\r\n");
MMString mCollection(mLine,":=");
MMString mItem(mCollection,",;");
// Obtain file content
readData(SampleTime-SampleTime%FilePeriod,&mFile);
// Generate header
if (mStyle=="meta"){
(*pData) += "\nMeta data:\n----------\n";
}
// Split file into lines
mLine.resetPosition();
while (NULL!=mLine.getNextDelimitedString()){
// Check for BinXtime
if (true==isDataTypeIdentifier(mLine,BINX_TIME)){
// Proceed to desired timestamp
for(;;){
// Obtain next measurement line
if (NULL!=mLine.getNextDelimitedString()){
mCollection.resetPosition();
// Read complete measurement line
if (NULL!=mCollection.getNextDelimitedString()){
mItem.resetPosition();
// Read timestamp
if (NULL!=mItem.getNextDelimitedString()){
// Check for desired timestamp
if ((uint32)SampleTime > (uint32)((u64MilliTimeStamp = BinX2num(mItem))/1000)){
continue;
}
// Read data vector
if (NULL!=mItem.getNextDelimitedString()){
if (mStyle=="binx"){
(*pData) += "\nBinX data:\n-----------\n";
(*pData) += mItem;
}
mBin.setLength(mItem.getLength());
uCount = BinX2bin((uint8*)mBin.getBuffer(),mBin.getLength(),mItem);
if (mStyle=="table"){
(*pData) += "\nTable data:\n------------\n";
}else if (mStyle=="data"){
(*pData) += "\nData:\n-----\n";
}
for (uint32 i=0;i<uCount;i++){
mNum = i;
if (mStyle=="table"){
mDataVector += mNum;
mDataVector += ",";
mNum = (uint32)(*((uint8*)(mBin.getBuffer()+i)));
mDataVector += mNum;
mDataVector += "\n";
}else if (mStyle=="data"){
mNum = (uint32)(*((uint8*)(mBin.getBuffer()+i)));
mDataVector += mNum;
mDataVector += ",";
}
}
(*pData) += mDataVector;
(*pData) += "\nTimestamp: ";
mTimeStamp = u64MilliTimeStamp/1000;
(*pData) += mTimeStamp;
(*pData) += ".";
mTimeStamp = u64MilliTimeStamp%1000;
(*pData) += mTimeStamp;
break;
}
}
}
}
break;
}
return;
}
// Meta data
if (mStyle=="meta"){
// Adjust path
mCollection.resetPosition();
if (NULL!=mCollection.getNextDelimitedString()){
// Split path into folders
mPrefix = "";
mItem.resetPosition();
while (NULL!=mItem.getNextDelimitedString()){
(*pData) += mPrefix;
(*pData) += mItem;
(*pData) += "\n";
mPrefix += " ";
}
}
// Adjust collection
if (NULL!=mCollection.getNextDelimitedString()){
// Split collection into items
(*pData) += mPrefix;
mItem.resetPosition();
while (NULL!=mItem.getNextDelimitedString()){
(*pData) += " ";
(*pData) += mItem;
}
(*pData) += "\n";
}
}
}
(*pData) += "\n";
}
bool MDataX::isDataTypeIdentifier(MString& mData,DATAX_DATA_TYPE_IDENTIFIER eDataType)
{
uint32 uNum = 0;
// Evaluate first 4 bytes
if (mData.getLength()>=4){
for (int i=3;i>=0;i--){
uNum *= 216;
uNum += *((uint8*)(mData.getBuffer()+i)) - 32;
}
if ((uint32)eDataType==uNum){
return true;
}
}
return false;
}
void MDataX::logMessage(int8* szHeader,uint32 uNum,int8* szTrailer)
{
MString mNum;
mNum = uNum;
logMessage(szHeader,mNum,szTrailer);
}
void MDataX::logMessage(int8* szHeader,MString& mMsg,int8* szTrailer)
{
FILE* pLog;
MString mLog;
mLog = MDateTime::getTimeUTC();
mLog += " ";
mLog += szHeader;
mLog += mMsg;
mLog += szTrailer;
if (NULL!=(pLog=fopen(LogFile.getText(),"a"))){
fwrite(mLog.getText(),mLog.getLength(),1,pLog);
fclose(pLog);
}
}