News

view:  full / summary

C++ Framework for Linux/Unix

Posted by Daniel V. Gomes on September 5, 2015 at 6:25 PM Comments comments (0)

I have been working with a small development framework for LINUX/UNIX.

I have added classes for threads, sockets, string manipulation, sqlite api. You may find makefiles already prepared to work.

I have not enough time to go through explaining how it works, but I plan to shared. I must add I make use of C++11 th and STL.


You can download the package at:


https://goo.gl/kVRQD6


The latest feature I added there was a factory class which you could expand. Basically you can load all kinds of object on stack and execute something using them based on the key you want to pass to it.

 

 


 


// Objects created by factory
// Object 1
class Derived1: public BasePtr
{
public:
    Derived1():BasePtr(){};
    virtual ~Derived1(){ cout << "Destructor Derived 1" << endl;};
    virtual int DoSomething()
    { 
        cout << "Do Something derived 1" << endl ; 
        return 0;
    };
};
// Object 2
class Derived2: public BasePtr
{
public:
    Derived2():BasePtr(){};
    virtual ~Derived2(){ cout << "Destructor Derived 2" << endl;};
    virtual int DoSomething()
    { 
        cout << "Do Something derived 2" << endl ;
        return 0;
    };
};

// Object 3
class Derived3: public BasePtr
{
public:
    Derived3():BasePtr(){};
    virtual ~Derived3(){ cout << "Destructor Derived 3" << endl;};
    virtual int DoSomething()
    { 
        cout << "Do Something derived 3" << endl ; 
        return 0;
    };
};


// Class factory
class MyClassFactory
{
public:
    BasePtr* getObjc(int option, BasePtr* ptr ) const;
};

// Queue used to store task
class MyQueue
{
public:
    MyQueue()
    {
    }
    ~MyQueue();
    void Register( BasePtr* ptr, int o );
    void Run(int myitem)const;
private:
    map< BasePtr*, int > myQueue;
    MyClassFactory fact{};
};

#endif

#include "factory.h"

BasePtr* MyClassFactory::getObjc(int option, BasePtr* ptr ) const
{
    switch ( option )
    {
        case 1:
            ptr =  new Derived1;
            break;
        case 2:
            ptr =  new Derived2;
            break;
        case 3:
            ptr =  new Derived3;
            break;
        default:
            ptr = nullptr;
    }
    return ptr;
}

void MyQueue::Register(BasePtr* ptr, int o )
{
   ptr = fact.getObjc( o , ptr );
   if ( ptr != nullptr )
   {
        myQueue.insert( std::pair< BasePtr*, int >(ptr, o) );
   }
   else
   {
        cout << "Object-" << o <<  " cannot be created, does not exist declaration" << endl;
   }
}

MyQueue::~MyQueue()
{
    for( auto mptr = myQueue.cbegin(); mptr != myQueue.cend(); mptr++ )
    {
       BasePtr* p = mptr->first;
       if ( p != NULL )
       {
            delete p;
            p = NULL;
       }
    }
}

void MyQueue::Run( int myitem ) const
{
    for( auto mptr = myQueue.cbegin(); mptr != myQueue.cend(); mptr++ )
    {
       if ( myitem == mptr->second )
       {
            BasePtr* p = mptr->first;
            p->DoSomething();
       }
    }
}

//int main()
//{
//    BasePtr* ptr1 = NULL;
//    BasePtr* ptr2 = NULL;
//    BasePtr* ptr3 = NULL;
//    MyQueue q{};

//    q.Register( ptr1, 1 );
//    q.Register( ptr2, 2 );
//    q.Register( ptr3, 3 );
//    q.Register( ptr3, 325 );

//    q.Run(1);
//    q.Run(325);


//    return 0;
//}


C++ Linux Thread

Posted by Daniel V. Gomes on May 31, 2014 at 8:50 AM Comments comments (0)
/*
*	-----------------------------------------------------------------
*	Modulo de threads
*	Daniel V. Gomes [email protected]
*	http://danielvgomes.webs.com/
*       ------------------------------------------------------------------
*/
#ifndef _THREADS_
#define _THREADS_

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <pthread.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <string>
#include <unistd.h>


// you actually won't need all these headers above, but they might come at hand...

using namespace std;

#define MAX_THREADS 10
/*--------------------------------------------------------------------------------------------
*		Threads
---------------------------------------------------------------------------------------------*/
typedef struct Data
{
    int NoThread;
} ThreadData;


class ThreadWrapper
{
public:
    ThreadWrapper();
    void AddRun(void* (*f)(void*) );
    int GetThreadID()const{ return tid ;};
    void Join(int id );
    bool getFullStack()const{ return FullStack ;};
private:
    pthread_t pthreadObj[ MAX_THREADS ];
    bool FullStack;
    int tid;
};
 
#endif


#include "th.h"

ThreadWrapper::ThreadWrapper(  )
{
     // contador das threads usadas no pool
     tid = 0;
     FullStack = false;
}

void ThreadWrapper::AddRun( void* (*f)(void*) )
{
    // executa a thread atraves da funcao passada para f
    if ( tid < MAX_THREADS )
    {
	    pthread_create( &pthreadObj[tid], NULL, f, NULL);
	    tid++;
    }
    else
    {
	   FullStack = true;
    }
}

void ThreadWrapper::Join(int id )
{
    // join da thread
    pthread_join(pthreadObj[id],NULL);
}

Mp3s tags

Posted by Daniel V. Gomes on January 27, 2014 at 6:55 PM Comments comments (0)

Call me dumb or something but I did not know a simple fact: mp3s TAGs are put in the last 128 bytes of the mp3 file. Well I had found about it here:

http://www.dreamincode.net/forums/topic/47881-reading-id3-tags-from-mp3/

So, I went to HxD editor and open a song ( by the way Accept "Balls To The Walls", which I own the legal mp3s from it )


It is easily seen it. As dealing with binary files, grabbing information from them, and doing something with them, has been my job for 5 years, I thought to my self : why not create a tool to read my mp3s collection and create a decent list out of it ? Ok, I am on the very start of this, but I have already came up with code to parse the data input:


// Headers ommited for a while...

 

#define Print( x ) std::cout << x << std::endl

 

class GetProgInput

{

public:

GetProgInput( int argc, char* argv[] );

std::string& getPathFile( ){ return PathFile; };

std::string& getPathDir( ){ return PathDir; };

std::string& getPathOut( ) { return PathOut; };

private:

GetProgInput( );// No need for these

GetProgInput(GetProgInput const&;);

void operator=(GetProgInput const&;);

std::string PathFile;

std::string PathDir;

std::string PathOut;

};

 

#include "inc.h"

 

GetProgInput::GetProgInput( int argc, char* argv[] )

{

PathFile = argv[ 0 ];

if ( argc == 1 )

{

Print( "Default parameters" );

PathDir = PathFile;

PathOut = PathFile;

}

else

{

if ( argc > 3 )

{

Print( "Number of parameters too high and were ignored" );

}

PathDir = argv[ 1 ] ;

PathOut = argv[ 2 ] ;

}

Print( PathFile );

Print( PathDir );

Print( PathOut );

}

 

int main( int argc, char* argv[] )

{

GetProgInput prog( argc, argv );

return 0;

}

I will obviously come back to this later...





Convert integer to hex ( string ) and vice versa

Posted by Daniel V. Gomes on January 7, 2014 at 6:55 PM Comments comments (0)

First ( Look at these containers and streams ):

Now if you need to convert an integer to hex representation and convert a hex number to int, you can use the following functions:

 

#include  <string>

#include  <iostream>

#include  <sstream>

#include  <cstdlib>

#include <iomanip>


 

#define Print( x ) std::cout << x << std::endl;

std::string ConvertToStringHex( int& d );

int ConvertHexToInt( int& d );

 

int main ( )

{

int a = 19999;

int bh = 0x4e1f;

std::string ahex = ConvertToStringHex(a);

Print(ahex);

Print( ConvertHexToInt( bh ) );

}

 

std::string ConvertToStringHex( int& d )

{

std::stringstream ss;

ss << std::hex << (int)d;

return ss.str();

}

 

int ConvertHexToInt( int& d )

{

std::stringstream ss;

ss << std::dec << d;

return std::stoi(ss.str().c_str());

//return atoi( ss.str().c_str() ); // C solution

}



C++ Makefile

Posted by Daniel V. Gomes on December 15, 2013 at 9:55 PM Comments comments (0)

I was trying to come up with a decent ( nearly generic ) C++ makefile for GCC. Then I found this, excellent tutorial

http://aulasdec.wordpress.com/2011/07/28/utilitarios-make-makefiles-e-sua-importancia/

This was initially a Makedfile for C and I have modified the example given above to work with C++, including using C++11.

 

cc=g++

 

INCLUDE = ../include

INCLUDELIB = ../include/CImg-1.5.6

CTAGS = -g -std=c++11 -Wall -pedantic -O2 -lgdi32

OUT = main

LDIR = ../lib

VPATH = ../src

 

FONTES= imp.cpp\

main.cpp\

util.cpp

 

 

all:$(OUT)

 

$(OUT): $(FONTES:.cpp=.o)

$(cc) -o [email protected] $^

 

%.o: %.cpp

$(cc) -c $(CTAGS) -I$(INCLUDE) -I$(INCLUDELIB) $< -o [email protected]

 

clean:

rm -f $(OUT).exe *.

I also recommend these tutorials that teach how to write Windows Code using gcc using makefiles rather than an IDE to link after DLLs, and create them:

http://www.transmissionzero.co.uk/computing/win32-apps-with-mingw/

Before using it, you have to install a few software ( they will work either for 32 or 62 bits windows versions )

http://gnuwin32.sourceforge.net/packages/make.htm ( Make For Windows )

http://www.mingw.org/wiki/MSYS ( MSys is a bash - slightly reduced version - shell port to Windows )

http://www.mingw.org/  ( MingW, or gcc for windows )

These are actually less space demanding than Cygwin. All you have to do is to add the bin directory created by these sowftware installation on the Windows path.

MSys comes with a small interface that also mimics Unix like shell. Look here:


 

C Data Structures

Posted by Daniel V. Gomes on December 15, 2013 at 9:45 PM Comments comments (0)

A few months ago I had to write the urgent need of writting a small data structure facility for C. At that time I came up with a more simpler approach, while here I try to write something more complete.

The Makefile:

OBJS = hello.o data.o

CC = gcc

DEBUG = -g

CFLAGS = -Wall -c $(DEBUG)

LFLAGS = -Wall $(DEBUG)

INCLUDE = ../inc

 

all: Hello

 

Hello: $(OBJS)

$(CC) $(LFLAGS) -I$(INCLUDE) $(OBJS) -o Hello

 

clean:

rm *.o *.exe

 


main.c

#include "../inc/include.h"

#include "../inc/data.h"

 

int main( void )

{

Node Node1;

Node1.Id = 0;

Node1.data = NULL;

initData();

AllocateSegment( 1 );

InsertNode( &Node1 );

return 0;

}


Include.h

#include "stdio.h"

#include "string.h"

#include "stdlib.h"


data.h

#include "include.h"

 

#define MAX_SEG_SZE 250000

#define MAX_SEG 5

 

typedef struct {

int Id;

void* data;

} Node;

 

typedef struct {

unsigned char seg;

int location;

Node* CurrentNode;

} Cursor;

 

/*

It will hold pointers to every segment, we need to allocate every one of them

Segment1 =

Segment2 =

Segment3 =

:

Segmentn =

*/

typedef Node* Segment;

Segment* Segments[ MAX_SEG ];

Cursor Navigator;

 

inline void SV( int seg, int pos, Node* ptr );

void initData( void );

void dealallocateseg( int n );

 

int InsertNode( Node* ptr );

int AllocateSegment( int n );

int isSegmentFull( int n );

int getNumberOfSegmentsAllocated( void );

 

Node* GetCurrentNode( void );

 

 


Data.c

 

#include "../inc/data.h"

 

inline void SV( int seg, int pos, Node* ptr )

{

Navigator.seg = seg;

Navigator.location = pos;

Navigator.CurrentNode = ptr;

}

void initData( void )

{

memset( Segments, 0x00, sizeof( Segments ));

SV( 0, 0, NULL );

}

 

int AllocateSegment( int n )

{

if (( n < 0 )||( n > MAX_SEG ) )

return -1;

/*

we allocate memory for MAX_SEG_SZE nodes

*/

Segments[n] = malloc( sizeof( Node* )* MAX_SEG_SZE );

if ( Segments[0] == NULL )

return -1;

SV( n, 1, NULL );

return 0;

}

 

void dealallocateseg( int n )

{

if ( Segments[n] != NULL )

free( Segments[n] );

}

 

int isSegmentFull( int n )

{

if ( n < 0 )

return 0;

/* See if it matches the current segment*/

if ( Navigator.seg == n )

{

if ( Navigator.location > MAX_SEG_SZE )

return 1;

}

return 0;

}

 

int getNumberOfSegmentsAllocated( void )

{

 

return Navigator.seg;

}

 

int InsertNode( Node* ptr )

{

if ( ptr == NULL )

return -1;

if ( isSegmentFull( Navigator.seg ) == 1 )

{

/*Current segment is full we need to get to next*/

AllocateSegment( Navigator.seg );

}

Segments[ Navigator.seg ][ Navigator.location++ ] = ptr;

return 0;

}

 

Node* GetCurrentNode( void )

{

return Segments[ Navigator.seg ][ Navigator.location ];

}

 


C++ 11

Posted by Daniel V. Gomes on April 30, 2013 at 8:05 PM Comments comments (0)

 

There is a new C++ standard, namely C++11.. There are lots of improvements over the last C++ standards. I can tell you that Bjarne Stroustrup has an excellent FAQ at his web site http://www.stroustrup.com/C++11FAQ.html.

Stroustrup has a new C++11 book coming out on May 20th and I certainly will acquire it. In the meantime I ordered Sams Teach Your Self C++ in 24 hours http://www.amazon.com/Sams-Teach-Yourself-One-Hour/dp/0672335670. Why did you buy it ?

1. It is updated with the new C++11 standard

 2. It is a very complete desktop reference.

 3. It is clear, concize and quite well written.

 4. It has around 300 pages of STL!

 5. It estimulates programmers to write modern C++11 - and proper- code.

6. It addresses C++ with reference to modern processors and how it works under the hood.

I am not a beginner, I am actually nearly an expert. Of course I need to tear down some old C programming habits though.

I will buy the Stroustrup next, but this book seems wildly good.

At Windows I recommend that you use MingW  or Visual Studio 201x, both support C++11. I was actually having some troubles to use VS 2012 express on my 64bits machine, not sure why yet, but I found out a MingW port for 32/64 bits that works fine on Windows 7 64 bits and also supports C++11. And a plus, you can use Code Blocks with it easily. Get both, Code Blocks and TDM at:

TDM-GCC Compiler For Windows




C++ std::string facilities

Posted by Daniel V. Gomes on February 14, 2013 at 10:35 AM Comments comments (0)

The std::string is a much better approach for  C++ than char values, but std::string can come at hand when handling char buffers as well...


Source file

 1 /**
 2 *  I aim to demonstrate certain std::string facilities that will make you avoiding
 3 *  much of usage of ANSI C strings
 4 */
 5 
 6 #include <string>
 7 #include <iostream>
 8 
 9 using namespace std;
10 
11 int getChar_OldC( const char*, int, std::string& );
12 
13 int main(void)
14 {
15 	char _tmp_[] = { 0x34, 0x76  };
16 	int n = 2;
17 	string _s_;
18 	_s_.clear();
19 	char c = 0;
20 
21 	getChar_OldC( _tmp_, n, _s_ );
22 
23 	// we can check now what _s_ holds, it should be a cool "4v"
24 	cout << _s_ << "\n" ;
25 
26 	// if you want to individually access the members of _s_
27 	for( int i = 0; i < n ; i++ )
28 	{
29 		//ok we use the at method
30 		cout << "ASCII: " << _s_.at( i ) << "\n" ;
31 		// or
32 		c = _s_.at( i );// c will hold 34 then 76
33 	}
34 
35 	return 0;
36 }
37 
38 int getChar_OldC( const char* _b, int _n, std::string& _s )
39 {
40 	// suppose someone sent you a   0x34, 0x76 
41 	// or 34 76 if you wish to see on a hex editor this translates
42 	// to a hex string "4v" which does not mean anything in ASCII
43 	// but it is a valid hex value
44 
45 	if ( _b == NULL )
46 		return 1;
47 
48 	if ( _s.length() != 0 )
49 		return 1;
50 
51 	// ok you knew that you can randomly access members of _s 
52 	// or simply pushing it into the container right ?
53 	for( int INDEX = 0; INDEX < _n; INDEX++ )
54 	{
55 		_s.push_back( _b[ INDEX ] );// cool stuff right ?
56 	}
57 	
58 	//check for errors
59 	if ( _s.length() == 0 )
60 		return 1;
61 	
62 	// _s now holds "4v" or 0x34 0x76
63 	return 0;
64 }
65 
66 

index: 9999;" id="ugdv_jqContextMenu">

Useful classes for logging

Posted by Daniel V. Gomes on February 13, 2013 at 8:20 AM Comments comments (0)

Have you ever been faced with the needs of debbuging code and the debugger would not help much ? I have written this class/ C interface to help you out...

Source file

#ifndef _UTILCLSDEBUG
#define _UTILCLSDEBUG


#ifdef _ANSI_C_

#include "time.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

Open__( char* __file_name );
Close__( void );

void vLogBinData( char* BinData, int s );
void vLogBinAscii( char* BinData, int s );
void vPrintRegs( int* regs, int n );
void vPrintReg( int regs, int n, const char* msg );
char* vSetCurrentTimeStamp( char* szTimeStamp )const;
char* vSetCurrentTimeStamp( char* szTimeStamp, const char* szFormat, int isize );
int calculateCRC( char* buffer, int size );
char* szConvertStringToData( char* stringbuffer, char* hexbuffer, int size);
void vprintMsg( char* msg );
int ConvertHexStringToDecimalString( const char* HexInputString, char* Output );

int iConvertBin2Ascii(		 char* bBindata, 
							 int iDataSize, 
							 char* szDataAscii );
int iConvertBinArray2String( char* bBindata, 
							 int iDataSize,
							 char* szDataString );
unsigned char* sConvertHexBin2String( unsigned char ch, 
									  unsigned char* buffer);
									
FILE* ___f;	
		

#else

#include <string>
using namespace std;

#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>

class CDebugUtil
{
public:
	CDebugUtil( char* __file_name );
	~CDebugUtil( void );

	void vLogBinData( char* BinData, int s );
	void vLogBinAscii( char* BinData, int s );
	void vPrintRegs( int* regs, int n );
	void vPrintReg( int regs, int n, const char* msg );

	int ConvertHexStringToDecimalString( const char* HexInputString, std::string& Output ) const;
	char* vSetCurrentTimeStamp( char* szTimeStamp )const;
	char* vSetCurrentTimeStamp( char* szTimeStamp, const char* szFormat, int isize )const;
	int calculateCRC( char* buffer, int size )const;
	char* szConvertStringToData( char* stringbuffer, char* hexbuffer, int size)const;
	void vprintMsg( char* msg );
	
private:

	int iConvertBin2Ascii(		 char* bBindata, 
								 int iDataSize, 
								 char* szDataAscii ) const;
	int iConvertBinArray2String( char* bBindata, 
								 int iDataSize,
								 char* szDataString ) const;
	unsigned char* sConvertHexBin2String( unsigned char ch, 
										  unsigned char* buffer) const;
									 	
	FILE* ___f;	
		
};

#endif



#endif


Source file

#include "debug_util.h"

#ifdef _ANSI_C_
Open__( char* __file_name )
#else
CDebugUtil::CDebugUtil( char* __file_name )
#endif
{	
	time_t rawtime;
	struct tm * timeinfo;
	char buffer [1024];
	memset( buffer, 0x00, sizeof( buffer ) );
	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	strncat( buffer, __file_name, strlen( __file_name ) );
	strftime (buffer + strlen( __file_name ) ,1024,"_%I_%M%p.txt",timeinfo);
	___f = fopen(buffer, "at" );	
}

#ifdef _ANSI_C_
Close__( void )
#else
CDebugUtil::~CDebugUtil( void )
#endif
{
	if ( ___f != NULL )
		fclose( ___f );
}

#ifdef _ANSI_C_
void vPrintRegs( int* regs, int n )
#else
void CDebugUtil::vPrintRegs( int* regs, int n )
#endif
{
	for( int i = 0; i < n ; i++ )
	{
		fprintf( ___f,	
				 "V%d : %d ",
				i,
				regs[ i ] );
	}	
	fprintf( ___f, "\n" );
	
}

#ifdef _ANSI_C_
void vPrintReg( int regs, int n, const char* msg )
#else
void CDebugUtil::vPrintReg( int regs, int n, const char* msg )
#endif
{
	if ( msg == NULL )
	{
		fprintf( ___f,	"-- %d -- ", regs );
	}
	else
	{
		fprintf( ___f,	"--%s-- %d", msg, regs );
	}

	if ( n == 0 )
	{
		fprintf( ___f,"\n");
	}
}

#ifdef _ANSI_C_
void vLogBinData( char* BinData, int s )
#else
void CDebugUtil::vLogBinData( char* BinData, int s )
#endif
{
	char buffer [1024];
	memset( buffer, 0x00, sizeof( buffer ) );
    iConvertBinArray2String( BinData, s, buffer);
    fprintf(___f, "Data: %s \n", buffer );	
}

#ifdef _ANSI_C_
void vLogBinAscii( char* BinData, int s )
#else
void CDebugUtil::vLogBinAscii( char* BinData, int s )
#endif
{
	char buffer [1024];
	memset( buffer, 0x00, sizeof( buffer ) );
	iConvertBin2Ascii( BinData, s, buffer );
	fprintf(___f, "Data: %s \n", buffer );
}

#ifdef _ANSI_C_
void vprintMsg( char* msg )
#else
void CDebugUtil::vprintMsg( char* msg )
#endif
{
	fprintf(___f, "%s \n", msg );
}

#ifdef _ANSI_C_
int iConvertBin2Ascii(char* bBindata, int iDataSize, char* szDataAscii )
#else
int CDebugUtil::iConvertBin2Ascii(char* bBindata, int iDataSize, char* szDataAscii ) const
#endif
{
	// ex: 0x55 = U
	//     0x21 = !
	//     0x00 gets converted to . to avoid problems with NULL terminators
	//     control chars get converted to .

	if (( bBindata == NULL )||(szDataAscii) == NULL )
		return 1;

	for(int i = 0; i < iDataSize; i++ )
	{
		if ( bBindata[i] < 0x20 )
			szDataAscii[i] = '.';
		else
			szDataAscii[i] =  bBindata[i] ;
	}

	return 0;
}

/************************************************************************************
* int CMFRegisterLogger::iConvertBinArray2String( char* bBindata, 
*												 int iDataSize,
*												 char* szDataString )
* description: Originally the data  is binary, thus to print it in a file we must convert
*			   it to an ASCII representation of this array of bytes. This convertion is not literal,
*			   because each nibble of the bin values is converted to an ASCII byte. The output is
*			   twice as big as the input
* INPUT:		Original data buffer and its size
* OUTPUT:	 	New buffer	
* RETURNS:	    returns 0 OK else 1
*************************************************************************************/
#ifdef _ANSI_C_
int iConvertBinArray2String(				char* bBindata, 
											int iDataSize,
											char* szDataString )
#else
int CDebugUtil::iConvertBinArray2String(	char* bBindata, 
											int iDataSize,
											char* szDataString ) const
#endif
{	

	if (( bBindata == NULL )||(szDataString) == NULL )
		return 1;

	for(int i = 0; i < iDataSize ; i++)
	{
		char tmp[3];
		memset(tmp,0,3);
		sConvertHexBin2String((unsigned char)bBindata[i],(unsigned char*)tmp);
		memcpy((szDataString+2*i),tmp,2);
	}

	return 0;
}
/************************************************************************************
*unsigned char* CMFRegisterLogger::sConvertHexBin2String(unsigned char ch, unsigned char* buffer)
* description: Originally the data  is binary, thus to print it in a file we must convert
*			   it to an ASCII representation of this array of bytes. This convertion is not literal,
*			   because each nibble of the bin values is converted to an ASCII byte. The output is
*			   twice as big as the input. This method actually converts each nibble of a byte to
*			   its ascii representation.
* INPUT:		A char
* OUTPUT:	 	2 byte ASCII array representation
* RETURNS:	    Pointer of the first byte of this array ( includes NULL terminator )
*************************************************************************************/
#ifdef _ANSI_C_
unsigned char* CDebugUtil::sConvertHexBin2String(unsigned char ch, unsigned char* buffer)
#else
unsigned char* CDebugUtil::sConvertHexBin2String(unsigned char ch, unsigned char* buffer) const
#endif
{
  char tmp[3];
  memset(tmp,0,3);
  if ( (ch&0x0F) == 0 )
  {
		if ( ch == 0x00 )
		{
				tmp[0] = 0x30;
				tmp[1] = 0x30;
				tmp[2] = 0x00;
		}
		else
		{
				sprintf(tmp,"%x",ch);
				if ( tmp[1] == 0 )
					tmp[1] = 0x30;
		}
  }
  else
  if ( ((ch&0xF0)<<4) == 0 )
  {
	    char cfix = 0x00;
		sprintf(tmp,"%x",ch);
		cfix = tmp[0];
		tmp[0] = 0x30;
		tmp[1] = cfix;
  }
  else
		sprintf(tmp,"%x",ch);
  memcpy(buffer,tmp,3);	
  return buffer;  
}

#ifdef _ANSI_C_
int ConvertHexStringToDecimalString( const char* HexInputString, char* Output )
#else
int CDebugUtil::ConvertHexStringToDecimalString( const char* HexInputString, std::string& Output ) const
#endif
{
        // Given an input like "0E0AFF1245EE99"
        // convert it to "14 10 255 18 69 238 153"
        char Out[ 528 ];

        if ( HexInputString == NULL )
                return -1;

        memset( Out, 0x00, sizeof( Out ) );

#ifdef _ANSI_C_
		// TODO implement C version
#else
        std::string tmp( HexInputString );
        Output.clear();
        int len = ( ( tmp.length() - 2 )/2 );

        for( int i = 0; i < len + 1 ; i ++ )
        {
            string tmp2 = tmp.substr( 2*i , 2 );
            int tmpInteger =  strtol( tmp2.c_str(), NULL, 16 );
			sprintf( Out + strlen( Out ), "%d", tmpInteger );
            if( i == len )
            {                   
                break;
            }
        }

        Output.append( Out );

        if ( Output.length() <= 0 )
           return -1;
#endif
        return 0;
}

#ifdef _ANSI_C_

#else
char* CDebugUtil::vSetCurrentTimeStamp( char* szTimeStamp )const
#endif
{
        time_t rawtime;
        struct tm * timeinfo;

        char buffer[32];
        memset(buffer,0,sizeof( buffer));

        if ( szTimeStamp == NULL )
          return NULL;

        time ( &rawtime );
        timeinfo = localtime ( &rawtime );

        // 01012000_HHMMSS
        strftime (buffer,16,"%d%m%Y_%H%M%S",timeinfo);
        memcpy(szTimeStamp,buffer,15);
        *(szTimeStamp+15)= 0x00;

		return szTimeStamp;

}

#ifdef _ANSI_C_

#else
char* CDebugUtil::vSetCurrentTimeStamp( char* szTimeStamp, const char* szFormat, int isize )const
#endif
{
    time_t rawtime;
    struct tm * timeinfo;

    char buffer[32];
    memset(buffer,0,sizeof( buffer));

    if ( szTimeStamp == NULL )
            return NULL;

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );

    strftime (buffer, isize, szFormat ,timeinfo);
    memcpy(szTimeStamp,buffer,isize);
    *(szTimeStamp+isize)= 0x00;

    return szTimeStamp;
}

#ifdef _ANSI_C_

#else
int CDebugUtil::calculateCRC( char* buffer, int size )const
#endif
{
        int CRC = 0;
        int Index = 0;
        for( Index = 0; Index < size ; Index++ )
                CRC = CRC + buffer[ Index ];
        return CRC;
}


#ifdef _ANSI_C_

#else
char* CDebugUtil::szConvertStringToData( char* stringbuffer, char* hexbuffer, int size)const
#endif
{
        int i = 0;
        for( i = 0 ; i < size/2 ; i++  )
        {
            char buf[3];
            memset(buf,0,3);
            memcpy(buf,&stringbuffer[2*i],2);
            buf[2] = 0;
            hexbuffer[ i ] = strtol( buf, NULL, 16 );
        }
        return hexbuffer;
}

Rss_feed