輸出格式化工具

輸出格式化工具

typedef void (*pfn_outputchar)( void *, int );

typedef void (*pfn_outputtext)( void *, const char *, size_t );


typedef struct _output_target

{

pfn_outputchar pFnOutputChar;

pfn_outputtext pFnOutputText;

void * pData;

void putChar( int ch )

{

pFnOutputChar( pData, ch );

}

void putText( const char * pText, size_t len )

{

pFnOutputText( pData, pText, len );

}

}st_output_target;


typedef void (*pfn_output_value)( st_output_target * pTarget, const void*, const char * );



template <typename T>

struct tout

{

static void _output(st_output_target * pTarget)

{

pTarget->putText( __FUNCTION__, strlen( __FUNCTION__ ) );

}

};



struct st_output_unknown_converter

{

st_output_unknown_converter( const char * pszText )

{

_T = pszText;

_Len = strlen( pszText );

}

const char * _T;

size_t _Len;

};



template <typename T>

void t_output_value( st_output_target * pTarget, const void * pV, const char * pStyle )

{

st_output_unknown_converter ocvt( *(T*) pV );

pTarget->putText( ocvt._T, ocvt._Len );

}




template <>

void t_output_value<int>( st_output_target * pTarget, const void * pV, const char * pStyle )

{

char szIntText[20];

size_t len = sprintf( szIntText, "%d", *(int*)pV );

pTarget->putText( szIntText, len );

}


template <>

void t_output_value<char *>( st_output_target * pTarget, const void * pV, const char * pStyle )

{

char * p = *(char**)pV;

size_t len = strlen( p );

pTarget->putText( p, len );

}


template <>

void t_output_value<const char *>( st_output_target * pTarget, const void * pV, const char * pStyle )

{

size_t len = strlen( *(char**)pV );

pTarget->putText( *(char**)pV, len );

}

template <>

void t_output_value<char[]>( st_output_target * pTarget, const void * pV, const char * pStyle )

{

size_t len = strlen( *(char**)pV );

pTarget->putText( *(char**)pV, len );

}




typedef struct _output_param

{

pfn_output_value pFn;

const void * pValue;

}st_output_param;


// compile-time type transformation

template<typename T>

struct ptr_decay {

typedef T type;

};

template<typename T>

struct ptr_decay<T[]> {

typedef T* type;

};

template<typename T, std::size_t N>

struct ptr_decay<T[N]> {

typedef T* type;

};


template <typename T1>

void t_output( st_output_target * pTarget, const char * pszText, const T1 & v1 )

{

const int paramCount = 1;

typename ptr_decay<T1>::type _v1 = (typename ptr_decay<T1>::type)v1;

st_output_param params[paramCount] = {

{ t_output_value<typename ptr_decay<T1>::type>, &_v1 },

};

const char * p = pszText;

int iState = 0;

const char * pParamBegin = NULL;

const char * pParamStyleBegin = NULL;

const char * pTextBegin = pszText;

while( *p )

{

if( iState == 0 )

{

if( *p == '{' )

{

size_t textLen = (size_t)(p-pTextBegin);

if( textLen > 0 )

{

pTarget->putText( pTextBegin, textLen );

}

pParamBegin = p;

pParamStyleBegin = NULL;

iState = 1;

}

}

else if( iState == 1 )

{

if( *p == ':' )

{

pParamStyleBegin = p;

}

else if( *p == '}' )

{

char szIndex[20];

char szStyle[20];

int iIndexLen = pParamStyleBegin == NULL ? (int)(p-pParamBegin)-1 : (int)(pParamStyleBegin - pParamBegin) - 1;

int iStyleLen = pParamStyleBegin == NULL ? 0 : (int)(p-pParamStyleBegin)-1;

if( iIndexLen > 0 && iIndexLen <= 3 )

{

strncpy( szIndex, pParamBegin + 1, iIndexLen );

szIndex[iIndexLen] = 0;

if( iStyleLen > 0 && iStyleLen <= 10 )

{

strncpy(szStyle, pParamStyleBegin, iStyleLen);

szStyle[iStyleLen] = 0;

}

else

szStyle[0] = 0;

int iParamIndex = atoi( szIndex );

if( iParamIndex >= 0 &&

  iParamIndex < paramCount )

{

params[iParamIndex].pFn( pTarget, params[iParamIndex].pValue, szStyle );

}

}

iState = 0;

pTextBegin = p + 1;

}

}

++p;

}

size_t textLen = (size_t)( p - pTextBegin );

if( textLen > 0 )

{

pTarget->putText( pTextBegin, textLen );

}

}


void _output_char( void *, int ch )

{

putchar( ch );

}

void _output_text( void *, const char * pszText, size_t len )

{

for( int i = 0;i < (int)len; ++i )

{

putchar( pszText[i] );

}

}




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

{


st_output_target ot = 

{

_output_char,

_output_text,

NULL

};

char * astr = "abc";

t_output(&ot, "test {0}\n", "abc");

你可能感兴趣的:(輸出格式化工具)