From bf91e4c243459fea2a5d4d3f6601a35f98d45c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Wed, 15 Nov 2017 11:32:19 +0100 Subject: [PATCH] 2017-11-15 11:32 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbjson.h * src/rtl/hbjson.c * changed 3-rd parameter 'HB_BOOL fHuman' in hb_jsonEncode() and hb_jsonEncodeCP() C functions to 'int iIndent' char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent ); char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent, PHB_CODEPAGE cdp ); Positive iIndent value defines number of spaces used for indenting, 0 disables indenting and -1 means TAB ( ASCII:9 ) indenting. This modification is binary compatible though in C code using HB_TRUE as 3-rd parameter it changes indenting from 2 spaces to 1 so please update the code if it's significant. + added optional support for numeric value in 2-nd parameter of hb_jsonEncode() PRG function. Current syntax is: hb_jsonEncode( , [ | ], [ ] ) -> * contrib/rddads/ads1.c * minor simplification * include/hbapigt.h * formatting --- ChangeLog.txt | 26 +++++++++++++++++++ contrib/rddads/ads1.c | 8 +++--- include/hbapigt.h | 2 +- include/hbjson.h | 4 +-- src/rtl/hbjson.c | 60 ++++++++++++++++++++++--------------------- 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 0be1b23a7f..eb2f47c955 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,32 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2017-11-15 11:32 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbjson.h + * src/rtl/hbjson.c + * changed 3-rd parameter 'HB_BOOL fHuman' in hb_jsonEncode() and + hb_jsonEncodeCP() C functions to 'int iIndent' + char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, + int iIndent ); + char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, + int iIndent, PHB_CODEPAGE cdp ); + Positive iIndent value defines number of spaces used for indenting, + 0 disables indenting and -1 means TAB ( ASCII:9 ) indenting. + This modification is binary compatible though in C code using HB_TRUE + as 3-rd parameter it changes indenting from 2 spaces to 1 so please + update the code if it's significant. + + + added optional support for numeric value in 2-nd parameter of + hb_jsonEncode() PRG function. Current syntax is: + hb_jsonEncode( , [ | ], [ ] ) + -> + + * contrib/rddads/ads1.c + * minor simplification + + * include/hbapigt.h + * formatting + 2017-11-14 20:44 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/hbwin/hbwin.hbx * contrib/hbwin/wapi_winbase_2.c diff --git a/contrib/rddads/ads1.c b/contrib/rddads/ads1.c index 3bb6edfedc..de8edece83 100644 --- a/contrib/rddads/ads1.c +++ b/contrib/rddads/ads1.c @@ -2468,12 +2468,11 @@ static HB_ERRCODE adsGetValue( ADSAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem else if( u16Type == ADS_BINARY || u16Type == ADS_IMAGE ) { u32RetVal = AdsGetBinaryLength( pArea->hTable, ADSFIELD( uiIndex ), &u32Length ); - if( u32RetVal != AE_SUCCESS ) + if( u32RetVal != AE_SUCCESS || u32Length == 0 ) hb_itemPutC( pItem, NULL ); else { - u32Length++; /* make room for NULL */ - pucBuf = ( UNSIGNED8 * ) hb_xgrab( u32Length ); + pucBuf = ( UNSIGNED8 * ) hb_xgrab( ++u32Length ); /* ++ to make room for NULL */ u32RetVal = AdsGetBinary( pArea->hTable, ADSFIELD( uiIndex ), 0, pucBuf, &u32Length ); if( u32RetVal != AE_SUCCESS ) { @@ -2503,8 +2502,7 @@ static HB_ERRCODE adsGetValue( ADSAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem #endif else { - u32Length++; /* make room for NULL */ - pucBuf = ( UNSIGNED8 * ) hb_xgrab( u32Length ); + pucBuf = ( UNSIGNED8 * ) hb_xgrab( ++u32Length ); /* ++ to make room for NULL */ u32RetVal = AdsGetString( pArea->hTable, ADSFIELD( uiIndex ), pucBuf, &u32Length, ADS_NONE ); if( u32RetVal != AE_SUCCESS ) hb_itemPutC( pItem, NULL ); diff --git a/include/hbapigt.h b/include/hbapigt.h index 240ce105e1..2258fdcf37 100644 --- a/include/hbapigt.h +++ b/include/hbapigt.h @@ -337,7 +337,7 @@ extern HB_EXPORT int hb_inkeyKeyVal( int iKey ); /* extract key/chara #define HB_INKEY_NEW_MPOS( x, y ) ( ( ( ( y ) & HB_INKEY_EXT_POSMASK ) << HB_INKEY_EXT_POSBITS ) | \ ( ( x ) & HB_INKEY_EXT_POSMASK ) | \ ( HB_INKEY_EXT_BIT | HB_INKEY_EXT_MOUSEPOS ) ) -#define HB_INKEY_NEW_EVENT( e ) ( ( e ) | ( HB_INKEY_EXT_BIT | HB_INKEY_EXT_EVENT ) ) +#define HB_INKEY_NEW_EVENT( e ) ( ( e ) | ( HB_INKEY_EXT_BIT | HB_INKEY_EXT_EVENT ) ) #define HB_INKEY_MOUSEPOSX( n ) ( ( n ) & HB_INKEY_EXT_POSMASK ) #define HB_INKEY_MOUSEPOSY( n ) ( ( ( n ) >> HB_INKEY_EXT_POSBITS ) & HB_INKEY_EXT_POSMASK ) diff --git a/include/hbjson.h b/include/hbjson.h index 31d01c4a12..2d98107243 100644 --- a/include/hbjson.h +++ b/include/hbjson.h @@ -52,8 +52,8 @@ HB_EXTERN_BEGIN -extern HB_EXPORT char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman ); -extern HB_EXPORT char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman, PHB_CODEPAGE cdp ); +extern HB_EXPORT char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent ); +extern HB_EXPORT char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent, PHB_CODEPAGE cdp ); extern HB_EXPORT HB_SIZE hb_jsonDecode( const char * szSource, PHB_ITEM pValue ); extern HB_EXPORT HB_SIZE hb_jsonDecodeCP( const char * szSource, PHB_ITEM pValue, PHB_CODEPAGE cdp ); diff --git a/src/rtl/hbjson.c b/src/rtl/hbjson.c index 2155fe5773..2624d9df1c 100644 --- a/src/rtl/hbjson.c +++ b/src/rtl/hbjson.c @@ -55,11 +55,11 @@ https://tools.ietf.org/html/rfc4627 C level functions: - char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman ); + char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent ); pValue - value to encode; pnLen - if pnLen is not NULL, length of returned buffer is stored to *pnLen; - fHuman - format to be human readable; + iIndent - indenting to be human readable; returns pointer to encoded JSON buffer. buffer must be fried by the caller. @@ -72,7 +72,7 @@ purposes. Returns 0 on error. Harbour level functions: - hb_jsonEncode( xValue [, lHuman = .F. ] ) --> cJSON + hb_jsonEncode( xValue [, lHuman = .F. | nIndent = 0 ] ) --> cJSON hb_jsonDecode( cJSON ) --> xValue hb_jsonDecode( cJSON, @xValue ) --> nLengthDecoded @@ -98,7 +98,7 @@ typedef struct HB_SIZE nAlloc; void ** pId; HB_SIZE nAllocId; - HB_BOOL fHuman; + int iIndent; int iEolLen; const char * szEol; } HB_JSON_ENCODE_CTX, * PHB_JSON_ENCODE_CTX; @@ -123,10 +123,11 @@ static void _hb_jsonCtxAdd( PHB_JSON_ENCODE_CTX pCtx, const char * szString, HB_ } } -static void _hb_jsonCtxAddIndent( PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nCount ) +static void _hb_jsonCtxAddIndent( PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nLevel ) { - if( nCount > 0 ) + if( nLevel > 0 ) { + HB_SIZE nCount = nLevel * ( pCtx->iIndent > 0 ? pCtx->iIndent : 1 ); if( pCtx->pHead + nCount >= pCtx->pBuffer + pCtx->nAlloc ) { HB_SIZE nSize = pCtx->pHead - pCtx->pBuffer; @@ -135,7 +136,7 @@ static void _hb_jsonCtxAddIndent( PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nCount ) pCtx->pBuffer = ( char * ) hb_xrealloc( pCtx->pBuffer, pCtx->nAlloc ); pCtx->pHead = pCtx->pBuffer + nSize; } - hb_xmemset( pCtx->pHead, ' ', nCount ); + hb_xmemset( pCtx->pHead, pCtx->iIndent > 0 ? ' ' : '\t', nCount ); pCtx->pHead += nCount; } } @@ -153,8 +154,8 @@ static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, { if( pCtx->pId[ nIndex ] == id ) { - if( ! fEOL && pCtx->fHuman ) - _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); + if( ! fEOL && pCtx->iIndent ) + _hb_jsonCtxAddIndent( pCtx, nLevel ); _hb_jsonCtxAdd( pCtx, "null", 4 ); return; } @@ -301,8 +302,8 @@ static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, { HB_SIZE nIndex; - if( pCtx->fHuman ) - _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); + if( pCtx->iIndent ) + _hb_jsonCtxAddIndent( pCtx, nLevel ); _hb_jsonCtxAdd( pCtx, "[", 1 ); @@ -313,20 +314,20 @@ static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, if( nIndex > 1 ) _hb_jsonCtxAdd( pCtx, ",", 1 ); - if( pCtx->fHuman ) + if( pCtx->iIndent ) _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); - if( pCtx->fHuman && + if( pCtx->iIndent && ! ( ( HB_IS_ARRAY( pItem ) || HB_IS_HASH( pItem ) ) && hb_itemSize( pItem ) > 0 ) ) - _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) * INDENT_SIZE ); + _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) ); _hb_jsonEncode( pItem, pCtx, nLevel + 1, HB_FALSE, cdp ); } - if( pCtx->fHuman ) + if( pCtx->iIndent ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); - _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); + _hb_jsonCtxAddIndent( pCtx, nLevel ); } _hb_jsonCtxAdd( pCtx, "]", 1 ); } @@ -341,8 +342,8 @@ static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, { HB_SIZE nIndex; - if( pCtx->fHuman ) - _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); + if( pCtx->iIndent ) + _hb_jsonCtxAddIndent( pCtx, nLevel ); _hb_jsonCtxAdd( pCtx, "{", 1 ); @@ -357,14 +358,14 @@ static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, if( nIndex > 1 ) _hb_jsonCtxAdd( pCtx, ",", 1 ); - if( pCtx->fHuman ) + if( pCtx->iIndent ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); - _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) * INDENT_SIZE ); + _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) ); } _hb_jsonEncode( pKey, pCtx, nLevel + 1, HB_FALSE, cdp ); - if( pCtx->fHuman ) + if( pCtx->iIndent ) { _hb_jsonCtxAdd( pCtx, ": ", 2 ); fEOL = ( HB_IS_ARRAY( pItem ) || HB_IS_HASH( pItem ) ) && hb_itemSize( pItem ) > 0; @@ -378,10 +379,10 @@ static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, _hb_jsonEncode( pItem, pCtx, nLevel + 1, fEOL, cdp ); } } - if( pCtx->fHuman ) + if( pCtx->iIndent ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); - _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); + _hb_jsonCtxAddIndent( pCtx, nLevel ); } _hb_jsonCtxAdd( pCtx, "}", 1 ); } @@ -659,7 +660,7 @@ static const char * _hb_jsonDecode( const char * szSource, PHB_ITEM pValue, PHB_ /* C level API functions */ -char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman, PHB_CODEPAGE cdp ) +char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent, PHB_CODEPAGE cdp ) { PHB_JSON_ENCODE_CTX pCtx; char * szRet; @@ -670,14 +671,14 @@ char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman, PHB_CO pCtx->pHead = pCtx->pBuffer = ( char * ) hb_xgrab( pCtx->nAlloc ); pCtx->nAllocId = 8; pCtx->pId = ( void ** ) hb_xgrab( sizeof( void * ) * pCtx->nAllocId ); - pCtx->fHuman = fHuman; + pCtx->iIndent = iIndent; pCtx->szEol = hb_setGetEOL(); if( ! pCtx->szEol || ! pCtx->szEol[ 0 ] ) pCtx->szEol = hb_conNewLine(); pCtx->iEolLen = ( int ) strlen( pCtx->szEol ); _hb_jsonEncode( pValue, pCtx, 0, HB_FALSE, cdp ); - if( fHuman ) + if( iIndent ) _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); nLen = pCtx->pHead - pCtx->pBuffer; @@ -690,9 +691,9 @@ char * hb_jsonEncodeCP( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman, PHB_CO return szRet; } -char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, HB_BOOL fHuman ) +char * hb_jsonEncode( PHB_ITEM pValue, HB_SIZE * pnLen, int iIndent ) { - return hb_jsonEncodeCP( pValue, pnLen, fHuman, NULL ); + return hb_jsonEncodeCP( pValue, pnLen, iIndent, NULL ); } HB_SIZE hb_jsonDecodeCP( const char * szSource, PHB_ITEM pValue, PHB_CODEPAGE cdp ) @@ -734,7 +735,8 @@ HB_FUNC( HB_JSONENCODE ) if( pItem ) { HB_SIZE nLen; - char * szRet = hb_jsonEncodeCP( pItem, &nLen, hb_parl( 2 ), _hb_jsonCdpPar( 3 ) ); + int iIndent = hb_parl( 2 ) ? INDENT_SIZE : hb_parni( 2 ); + char * szRet = hb_jsonEncodeCP( pItem, &nLen, iIndent, _hb_jsonCdpPar( 3 ) ); hb_retclen_buffer( szRet, nLen ); } }