/* * Assign a value to a field. */ static HB_ERRCODE hb_delimPutValue( DELIMAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { char szBuffer[ 256 ]; HB_ERRCODE uiError; LPFIELD pField; USHORT uiSize; HB_TRACE(HB_TR_DEBUG, ("hb_delimPutValue(%p,%hu,%p)", pArea, uiIndex, pItem)); if( !pArea->fPositioned ) return HB_SUCCESS; if( !pArea->fRecordChanged ) return HB_FAILURE; uiError = HB_SUCCESS; --uiIndex; pField = pArea->lpFields + uiIndex; if( pField->uiType != HB_FT_MEMO && pField->uiType != HB_FT_NONE ) { if( HB_IS_MEMO( pItem ) || HB_IS_STRING( pItem ) ) { if( pField->uiType == HB_FT_STRING ) { uiSize = ( USHORT ) hb_itemGetCLen( pItem ); if( uiSize > pField->uiLen ) uiSize = pField->uiLen; memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_itemGetCPtr( pItem ), uiSize ); #ifndef HB_CDP_SUPPORT_OFF hb_cdpnTranslate( (char *) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_cdppage(), pArea->cdPage, uiSize ); #endif memset( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] + uiSize, ' ', pField->uiLen - uiSize ); } else uiError = EDBF_DATATYPE; } else if( HB_IS_DATE( pItem ) ) { if( pField->uiType == HB_FT_DATE ) { hb_itemGetDS( pItem, szBuffer ); memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, 8 ); } else uiError = EDBF_DATATYPE; } else if( HB_IS_NUMBER( pItem ) ) { if( pField->uiType == HB_FT_LONG ) { if( hb_itemStrBuf( szBuffer, pItem, pField->uiLen, pField->uiDec ) ) { memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, pField->uiLen ); } else { uiError = EDBF_DATAWIDTH; memset( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], '*', pField->uiLen ); } } else uiError = EDBF_DATATYPE; } else if( HB_IS_LOGICAL( pItem ) ) { if( pField->uiType == HB_FT_LOGICAL ) pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] ] = hb_itemGetL( pItem ) ? 'T' : 'F'; else uiError = EDBF_DATATYPE; } else uiError = EDBF_DATATYPE; } if( uiError != HB_SUCCESS ) { PHB_ITEM pError= hb_errNew(); USHORT uiGenCode = uiError == EDBF_DATAWIDTH ? EG_DATAWIDTH : EDBF_DATATYPE; hb_errPutGenCode( pError, uiGenCode ); hb_errPutDescription( pError, hb_langDGetErrorDesc( uiGenCode ) ); hb_errPutOperation( pError, hb_dynsymName( ( PHB_DYNS ) pField->sym ) ); hb_errPutSubCode( pError, uiError ); hb_errPutFlags( pError, EF_CANDEFAULT ); uiError = SELF_ERROR( ( AREAP ) pArea, pError ); hb_itemRelease( pError ); return uiError == E_DEFAULT ? HB_SUCCESS : HB_FAILURE; } return HB_SUCCESS; }
/* Export field value into the buffer in PG accepted CSV format */ static HB_BOOL exportBufSqlVar( pgCopyContext * context, PHB_ITEM pValue, const char * szQuote, const char * szEsc ) { switch( hb_itemType( pValue ) ) { case HB_IT_STRING: case HB_IT_MEMO: { HB_SIZE nLen = hb_itemGetCLen( pValue ); HB_SIZE nCnt = 0; const char * szVal = hb_itemGetCPtr( pValue ); if( ! addStrToContext( context, szQuote ) ) return HB_FALSE; if( context->str_trim ) { while( nLen && HB_ISSPACE( szVal[ nLen - 1 ] ) ) nLen--; } while( *szVal && nCnt++ < nLen ) { /* if( *szVal == *szDelim || *szVal == *szEsc || *szVal == *szQuote ) we don't need to escape delim in CSV mode, only the quote and the escape itself */ if( *szVal == *szQuote || *szVal == *szEsc ) if( ! addToContext( context, *szEsc ) ) return HB_FALSE; if( ( HB_UCHAR ) *szVal >= 32 ) if( ! addToContext( context, *szVal ) ) return HB_FALSE; szVal++; } if( ! addStrToContext( context, szQuote ) ) return HB_FALSE; break; } case HB_IT_DATE: { char szDate[ 9 ]; if( ! addStrToContext( context, szQuote ) ) return HB_FALSE; hb_itemGetDS( pValue, szDate ); if( szDate[ 0 ] == ' ' ) { if( ! addStrToContext( context, "0100-01-01" ) ) return HB_FALSE; } else { if( ! addStrnToContext( context, &szDate[ 0 ], 4 ) || ! addToContext( context, '-' ) || ! addStrnToContext( context, &szDate[ 4 ], 2 ) || ! addToContext( context, '-' ) || ! addStrnToContext( context, &szDate[ 6 ], 2 ) ) return HB_FALSE; } if( ! addStrToContext( context, szQuote ) ) return HB_FALSE; break; } case HB_IT_TIMESTAMP: { long lDate, lTime; char szDateTime[ 24 ]; hb_itemGetTDT( pValue, &lDate, &lTime ); hb_timeStampStr( szDateTime, lDate, lTime ); if( ! addStrToContext( context, szQuote ) || ! addStrToContext( context, szDateTime ) || ! addStrToContext( context, szQuote ) ) return HB_FALSE; break; } case HB_IT_LOGICAL: #if 0 if( ! addStrToContext( context, szQuote ) || ! addToContext( context, hb_itemGetL( pValue ) ? 'Y' : 'N' ) || ! addStrToContext( context, szQuote ) ) #endif if( ! addToContext( context, hb_itemGetL( pValue ) ? 'Y' : 'N' ) ) return HB_FALSE; break; case HB_IT_INTEGER: case HB_IT_LONG: case HB_IT_DOUBLE: { char szResult[ HB_MAX_DOUBLE_LENGTH ]; int iSize, iWidth, iDec; hb_itemGetNLen( pValue, &iWidth, &iDec ); iSize = ( iDec > 0 ? iWidth + 1 + iDec : iWidth ); if( hb_itemStrBuf( szResult, pValue, iSize, iDec ) ) { int iPos = 0; while( iSize && HB_ISSPACE( szResult[ iPos ] ) ) { iPos++; iSize--; } if( ! addStrnToContext( context, &szResult[ iPos ], iSize ) ) return HB_FALSE; } else if( ! addToContext( context, '0' ) ) return HB_FALSE; break; } /* an "M" field or the other, might be a "V" in SixDriver */ default: return HB_FALSE; } return HB_TRUE; }
/* Export field value into the buffer in SQL format */ static HB_BOOL hb_exportBufSqlVar( PHB_FILEBUF pFileBuf, PHB_ITEM pValue, const char * szDelim, const char * szEsc ) { switch( hb_itemType( pValue ) ) { case HB_IT_STRING: { HB_SIZE nLen = hb_itemGetCLen( pValue ); HB_SIZE nCnt = 0; const char *szVal = hb_itemGetCPtr( pValue ); hb_addStrToFBuffer( pFileBuf, szDelim ); while( nLen && HB_ISSPACE( szVal[ nLen - 1 ] ) ) nLen--; while( *szVal && nCnt++ < nLen ) { if( *szVal == *szDelim || *szVal == *szEsc ) hb_addToFBuffer( pFileBuf, *szEsc ); if( ( HB_UCHAR ) *szVal >= 32 ) hb_addToFBuffer( pFileBuf, *szVal ); else { /* printf( "%d %c", *szVal, *szVal ); */ } szVal++; } hb_addStrToFBuffer( pFileBuf, szDelim ); break; } case HB_IT_DATE: { char szDate[ 9 ]; hb_addStrToFBuffer( pFileBuf, szDelim ); hb_itemGetDS( pValue, szDate ); if( szDate[ 0 ] == ' ' ) { hb_addStrToFBuffer( pFileBuf, "0100-01-01" ); } else { hb_addStrnToFBuffer( pFileBuf, &szDate[0], 4 ); hb_addToFBuffer( pFileBuf, '-' ); hb_addStrnToFBuffer( pFileBuf, &szDate[4], 2 ); hb_addToFBuffer( pFileBuf, '-' ); hb_addStrnToFBuffer( pFileBuf, &szDate[6], 2 ); } hb_addStrToFBuffer( pFileBuf, szDelim ); break; } case HB_IT_TIMESTAMP: { long lDate, lTime; char szDateTime[ 24 ]; hb_itemGetTDT( pValue, &lDate, &lTime ); hb_timeStampStr( szDateTime, lDate, lTime ); hb_addStrToFBuffer( pFileBuf, szDelim ); hb_addStrToFBuffer( pFileBuf, szDateTime ); hb_addStrToFBuffer( pFileBuf, szDelim ); break; } case HB_IT_LOGICAL: hb_addStrToFBuffer( pFileBuf, szDelim ); hb_addToFBuffer( pFileBuf, hb_itemGetL( pValue ) ? 'Y' : 'N' ); hb_addStrToFBuffer( pFileBuf, szDelim ); break; case HB_IT_INTEGER: case HB_IT_LONG: case HB_IT_DOUBLE: { char szResult[ HB_MAX_DOUBLE_LENGTH ]; int iSize, iWidth, iDec; hb_itemGetNLen( pValue, &iWidth, &iDec ); iSize = ( iDec > 0 ? iWidth + 1 + iDec : iWidth ); if( hb_itemStrBuf( szResult, pValue, iSize, iDec ) ) { int iPos = 0; while( iSize && HB_ISSPACE( szResult[ iPos ] ) ) { iPos++; iSize--; } hb_addStrnToFBuffer( pFileBuf, &szResult[ iPos ], iSize ); } else hb_addToFBuffer( pFileBuf, '0' ); break; } /* an "M" field or the other, might be a "V" in SixDriver */ default: /* We do not want MEMO contents */ return HB_FALSE; } return HB_TRUE; }
/* * Assign a value to a field. */ static HB_ERRCODE hb_sdfPutValue( SDFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem ) { char szBuffer[ 256 ]; HB_ERRCODE errCode; LPFIELD pField; HB_SIZE nSize; HB_TRACE( HB_TR_DEBUG, ( "hb_sdfPutValue(%p,%hu,%p)", pArea, uiIndex, pItem ) ); if( ! pArea->fPositioned ) return HB_SUCCESS; if( ! pArea->fRecordChanged ) return HB_FAILURE; if( --uiIndex >= pArea->area.uiFieldCount ) return HB_FAILURE; errCode = HB_SUCCESS; pField = pArea->area.lpFields + uiIndex; if( pField->uiType != HB_FT_MEMO && pField->uiType != HB_FT_NONE ) { if( HB_IS_MEMO( pItem ) || HB_IS_STRING( pItem ) ) { if( pField->uiType == HB_FT_STRING ) { if( ( pField->uiFlags & HB_FF_BINARY ) == 0 ) { nSize = pField->uiLen; hb_cdpnDup2( hb_itemGetCPtr( pItem ), hb_itemGetCLen( pItem ), ( char * ) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], &nSize, hb_vmCDP(), pArea->area.cdPage ); } else { nSize = hb_itemGetCLen( pItem ); if( nSize > ( HB_SIZE ) pField->uiLen ) nSize = pField->uiLen; memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_itemGetCPtr( pItem ), nSize ); } if( nSize < ( HB_SIZE ) pField->uiLen ) memset( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] + nSize, ' ', pField->uiLen - nSize ); } else errCode = EDBF_DATATYPE; } else if( HB_IS_DATETIME( pItem ) ) { if( pField->uiType == HB_FT_DATE ) { hb_itemGetDS( pItem, szBuffer ); memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, 8 ); } else if( pField->uiType == HB_FT_TIMESTAMP && ( pField->uiLen == 12 || pField->uiLen == 23 ) ) { long lDate, lTime; hb_itemGetTDT( pItem, &lDate, &lTime ); if( pField->uiLen == 12 ) hb_timeStr( szBuffer, lTime ); else hb_timeStampStr( szBuffer, lDate, lTime ); memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, pField->uiLen ); } else errCode = EDBF_DATATYPE; } else if( HB_IS_NUMBER( pItem ) ) { if( pField->uiType == HB_FT_LONG ) { if( hb_itemStrBuf( szBuffer, pItem, pField->uiLen, pField->uiDec ) ) { memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], szBuffer, pField->uiLen ); } else { errCode = EDBF_DATAWIDTH; memset( pArea->pRecord + pArea->pFieldOffset[ uiIndex ], '*', pField->uiLen ); } } else errCode = EDBF_DATATYPE; } else if( HB_IS_LOGICAL( pItem ) ) { if( pField->uiType == HB_FT_LOGICAL ) pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] ] = hb_itemGetL( pItem ) ? 'T' : 'F'; else errCode = EDBF_DATATYPE; } else errCode = EDBF_DATATYPE; } if( errCode != HB_SUCCESS ) { PHB_ITEM pError = hb_errNew(); HB_ERRCODE errGenCode = errCode == EDBF_DATAWIDTH ? EG_DATAWIDTH : EDBF_DATATYPE; hb_errPutGenCode( pError, errGenCode ); hb_errPutDescription( pError, hb_langDGetErrorDesc( errGenCode ) ); hb_errPutOperation( pError, hb_dynsymName( ( PHB_DYNS ) pField->sym ) ); hb_errPutSubCode( pError, errCode ); hb_errPutFlags( pError, EF_CANDEFAULT ); errCode = SELF_ERROR( &pArea->area, pError ); hb_itemRelease( pError ); return errCode == E_DEFAULT ? HB_SUCCESS : HB_FAILURE; } return HB_SUCCESS; }
static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nLevel, HB_BOOL fEOL ) { /* Protection against recursive structures */ if( ( HB_IS_ARRAY( pValue ) || HB_IS_HASH( pValue ) ) && hb_itemSize( pValue ) > 0 ) { void * id = HB_IS_HASH( pValue ) ? hb_hashId( pValue ) : hb_arrayId( pValue ); HB_SIZE nIndex; for( nIndex = 0; nIndex < nLevel; nIndex++ ) { if( pCtx->pId[ nIndex ] == id ) { if( ! fEOL && pCtx->fHuman ) _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); _hb_jsonCtxAdd( pCtx, "null", 4 ); return; } } if( nLevel >= pCtx->nAllocId ) { pCtx->nAllocId += 8; pCtx->pId = ( void ** ) hb_xrealloc( pCtx->pId, sizeof( void * ) * pCtx->nAllocId ); } pCtx->pId[ nLevel ] = id; } if( fEOL ) { --pCtx->pHead; _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); } if( HB_IS_STRING( pValue ) ) { const char * szString = hb_itemGetCPtr( pValue ); HB_SIZE nPos, nPos2, nLen = hb_itemGetCLen( pValue ); _hb_jsonCtxAdd( pCtx, "\"", 1 ); nPos = 0; while( nPos < nLen ) { nPos2 = nPos; while( *( ( const unsigned char * ) szString + nPos2 ) >= ' ' && szString[ nPos2 ] != '\\' && szString[ nPos2 ] != '\"' ) nPos2++; if( nPos2 > nPos ) { _hb_jsonCtxAdd( pCtx, szString + nPos, nPos2 - nPos ); nPos = nPos2; continue; } switch( szString[ nPos ] ) { case '\\': _hb_jsonCtxAdd( pCtx, "\\\\", 2 ); break; case '\"': _hb_jsonCtxAdd( pCtx, "\\\"", 2 ); break; case '\b': _hb_jsonCtxAdd( pCtx, "\\b", 2 ); break; case '\f': _hb_jsonCtxAdd( pCtx, "\\f", 2 ); break; case '\n': _hb_jsonCtxAdd( pCtx, "\\n", 2 ); break; case '\r': _hb_jsonCtxAdd( pCtx, "\\r", 2 ); break; case '\t': _hb_jsonCtxAdd( pCtx, "\\t", 2 ); break; default: { char buf[ 8 ]; hb_snprintf( buf, sizeof( buf ), "\\u00%02X", ( unsigned char ) szString[ nPos ] ); _hb_jsonCtxAdd( pCtx, buf, 6 ); break; } } nPos++; } _hb_jsonCtxAdd( pCtx, "\"", 1 ); } else if( HB_IS_NUMINT( pValue ) ) { char buf[ 32 ]; hb_snprintf( buf, sizeof( buf ), "%" PFHL "d", hb_itemGetNInt( pValue ) ); _hb_jsonCtxAdd( pCtx, buf, strlen( buf ) ); } else if( HB_IS_NUMERIC( pValue ) ) { char buf[ 64 ]; int iDec; double dblValue = hb_itemGetNDDec( pValue, &iDec ); hb_snprintf( buf, sizeof( buf ), "%.*f", iDec, dblValue ); _hb_jsonCtxAdd( pCtx, buf, strlen( buf ) ); } else if( HB_IS_NIL( pValue ) ) { _hb_jsonCtxAdd( pCtx, "null", 4 ); } else if( HB_IS_LOGICAL( pValue ) ) { if( hb_itemGetL( pValue ) ) _hb_jsonCtxAdd( pCtx, "true", 4 ); else _hb_jsonCtxAdd( pCtx, "false", 5 ); } else if( HB_IS_DATE( pValue ) ) { char szBuffer[ 10 ]; hb_itemGetDS( pValue, szBuffer + 1 ); szBuffer[ 0 ] = '\"'; szBuffer[ 9 ] = '\"'; _hb_jsonCtxAdd( pCtx, szBuffer, 10 ); } else if( HB_IS_TIMESTAMP( pValue ) ) { char szBuffer[ 19 ]; hb_itemGetTS( pValue, szBuffer + 1 ); szBuffer[ 0 ] = '\"'; szBuffer[ 18 ] = '\"'; _hb_jsonCtxAdd( pCtx, szBuffer, 19 ); } else if( HB_IS_ARRAY( pValue ) ) { HB_SIZE nLen = hb_itemSize( pValue ); if( nLen ) { HB_SIZE nIndex; if( pCtx->fHuman ) _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); _hb_jsonCtxAdd( pCtx, "[", 1 ); for( nIndex = 1; nIndex <= nLen; nIndex++ ) { PHB_ITEM pItem = hb_arrayGetItemPtr( pValue, nIndex ); if( nIndex > 1 ) _hb_jsonCtxAdd( pCtx, ",", 1 ); if( pCtx->fHuman ) _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); if( pCtx->fHuman && ! ( ( HB_IS_ARRAY( pItem ) || HB_IS_HASH( pItem ) ) && hb_itemSize( pItem ) > 0 ) ) _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) * INDENT_SIZE ); _hb_jsonEncode( pItem, pCtx, nLevel + 1, HB_FALSE ); } if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); } _hb_jsonCtxAdd( pCtx, "]", 1 ); } else _hb_jsonCtxAdd( pCtx, "[]", 2 ); } else if( HB_IS_HASH( pValue ) ) { HB_SIZE nLen = hb_hashLen( pValue ); if( nLen ) { HB_SIZE nIndex; if( pCtx->fHuman ) _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); _hb_jsonCtxAdd( pCtx, "{", 1 ); for( nIndex = 1; nIndex <= nLen; nIndex++ ) { PHB_ITEM pKey = hb_hashGetKeyAt( pValue, nIndex ); if( HB_IS_STRING( pKey ) ) { PHB_ITEM pItem = hb_hashGetValueAt( pValue, nIndex ); HB_BOOL fEOL = HB_FALSE; if( nIndex > 1 ) _hb_jsonCtxAdd( pCtx, ",", 1 ); if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) * INDENT_SIZE ); } _hb_jsonEncode( pKey, pCtx, nLevel + 1, HB_FALSE ); if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, ": ", 2 ); fEOL = ( HB_IS_ARRAY( pItem ) || HB_IS_HASH( pItem ) ) && hb_itemSize( pItem ) > 0; } else _hb_jsonCtxAdd( pCtx, ":", 1 ); _hb_jsonEncode( pItem, pCtx, nLevel + 1, fEOL ); } } if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); } _hb_jsonCtxAdd( pCtx, "}", 1 ); } else _hb_jsonCtxAdd( pCtx, "{}", 2 ); } else { /* All unsupported types are replacd by null */ _hb_jsonCtxAdd( pCtx, "null", 4 ); } }
/* Export field values to text file */ static HB_BOOL hb_ExportVar( HB_FHANDLE handle, PHB_ITEM pValue, const char * cDelim, PHB_CODEPAGE cdp ) { switch( hb_itemType( pValue ) ) { /* a "C" field */ case HB_IT_STRING: { char * szStrEsc; char * szString; szStrEsc = hb_strescape( hb_itemGetCPtr( pValue ), hb_itemGetCLen( pValue ), cDelim ); if( cdp ) hb_cdpnDupLen( szStrEsc, strlen( szStrEsc ), hb_vmCDP(), cdp ); szString = hb_xstrcpy( NULL, cDelim, szStrEsc, cDelim, NULL ); /* FWrite( handle, szString ) */ hb_fsWriteLarge( handle, szString, strlen( szString ) ); /* Orphaned, get rif off it */ hb_xfree( szStrEsc ); hb_xfree( szString ); break; } /* a "D" field */ case HB_IT_DATE: { char * szDate = ( char * ) hb_xgrab( 9 ); hb_itemGetDS( pValue, szDate ); hb_fsWriteLarge( handle, szDate, strlen( szDate ) ); hb_xfree( szDate ); break; } /* an "L" field */ case HB_IT_LOGICAL: hb_fsWriteLarge( handle, ( hb_itemGetL( pValue ) ? "T" : "F" ), 1 ); break; /* an "N" field */ case HB_IT_INTEGER: case HB_IT_LONG: case HB_IT_DOUBLE: { char * szResult = hb_itemStr( pValue, NULL, NULL ); if( szResult ) { HB_SIZE nLen = strlen( szResult ); const char * szTrimmed = hb_strLTrim( szResult, &nLen ); hb_fsWriteLarge( handle, szTrimmed, strlen( szTrimmed ) ); hb_xfree( szResult ); } break; } /* an "M" field or the other, might be a "V" in SixDriver */ default: /* We do not want MEMO contents */ return HB_FALSE; } return HB_TRUE; }
static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nLevel, HB_BOOL fEOL, PHB_CODEPAGE cdp ) { /* Protection against recursive structures */ if( ( HB_IS_ARRAY( pValue ) || HB_IS_HASH( pValue ) ) && hb_itemSize( pValue ) > 0 ) { void * id = HB_IS_HASH( pValue ) ? hb_hashId( pValue ) : hb_arrayId( pValue ); HB_SIZE nIndex; for( nIndex = 0; nIndex < nLevel; nIndex++ ) { if( pCtx->pId[ nIndex ] == id ) { if( ! fEOL && pCtx->fHuman ) _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); _hb_jsonCtxAdd( pCtx, "null", 4 ); return; } } if( nLevel >= pCtx->nAllocId ) { pCtx->nAllocId += 8; pCtx->pId = ( void ** ) hb_xrealloc( pCtx->pId, sizeof( void * ) * pCtx->nAllocId ); } pCtx->pId[ nLevel ] = id; } if( fEOL ) { --pCtx->pHead; _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); } if( HB_IS_STRING( pValue ) ) { HB_SIZE nPos, nLen = hb_itemGetCLen( pValue ); const char * szString = hb_itemGetCPtr( pValue ); char buf[ 8 ]; _hb_jsonCtxAdd( pCtx, "\"", 1 ); if( cdp ) { HB_WCHAR wc; nPos = 0; while( HB_CDPCHAR_GET( cdp, szString, nLen, &nPos, &wc ) ) { if( wc >= ' ' && wc < 0x7F && wc != '\\' && wc != '\"' ) { buf[ 0 ] = ( char ) wc; _hb_jsonCtxAdd( pCtx, buf, 1 ); continue; } switch( wc ) { case '\\': _hb_jsonCtxAdd( pCtx, "\\\\", 2 ); break; case '\"': _hb_jsonCtxAdd( pCtx, "\\\"", 2 ); break; case '\b': _hb_jsonCtxAdd( pCtx, "\\b", 2 ); break; case '\f': _hb_jsonCtxAdd( pCtx, "\\f", 2 ); break; case '\n': _hb_jsonCtxAdd( pCtx, "\\n", 2 ); break; case '\r': _hb_jsonCtxAdd( pCtx, "\\r", 2 ); break; case '\t': _hb_jsonCtxAdd( pCtx, "\\t", 2 ); break; default: hb_snprintf( buf, sizeof( buf ), "\\u%04X", wc ); _hb_jsonCtxAdd( pCtx, buf, 6 ); break; } } } else { nPos = 0; while( nPos < nLen ) { unsigned char uch = szString[ nPos ]; HB_SIZE nPos2 = nPos; while( uch >= ' ' && uch != '\\' && uch != '\"' ) uch = szString[ ++nPos2 ]; if( nPos2 > nPos ) { _hb_jsonCtxAdd( pCtx, szString + nPos, nPos2 - nPos ); if( nPos2 >= nLen ) break; nPos = nPos2; } switch( uch ) { case '\\': _hb_jsonCtxAdd( pCtx, "\\\\", 2 ); break; case '\"': _hb_jsonCtxAdd( pCtx, "\\\"", 2 ); break; case '\b': _hb_jsonCtxAdd( pCtx, "\\b", 2 ); break; case '\f': _hb_jsonCtxAdd( pCtx, "\\f", 2 ); break; case '\n': _hb_jsonCtxAdd( pCtx, "\\n", 2 ); break; case '\r': _hb_jsonCtxAdd( pCtx, "\\r", 2 ); break; case '\t': _hb_jsonCtxAdd( pCtx, "\\t", 2 ); break; default: hb_snprintf( buf, sizeof( buf ), "\\u00%02X", uch ); _hb_jsonCtxAdd( pCtx, buf, 6 ); break; } nPos++; } } _hb_jsonCtxAdd( pCtx, "\"", 1 ); } else if( HB_IS_NUMINT( pValue ) ) { char buf[ 24 ]; HB_MAXINT nVal = hb_itemGetNInt( pValue ); HB_BOOL fNeg = nVal < 0; int i = 0; if( fNeg ) nVal = -nVal; do buf[ sizeof( buf ) - ++i ] = ( nVal % 10 ) + '0'; while( ( nVal /= 10 ) != 0 ); if( fNeg ) buf[ sizeof( buf ) - ++i ] = '-'; _hb_jsonCtxAdd( pCtx, &buf[ sizeof( buf ) - i ], i ); } else if( HB_IS_NUMERIC( pValue ) ) { char buf[ 64 ]; int iDec; double dblValue = hb_itemGetNDDec( pValue, &iDec ); hb_snprintf( buf, sizeof( buf ), "%.*f", iDec, dblValue ); _hb_jsonCtxAdd( pCtx, buf, strlen( buf ) ); } else if( HB_IS_NIL( pValue ) ) { _hb_jsonCtxAdd( pCtx, "null", 4 ); } else if( HB_IS_LOGICAL( pValue ) ) { if( hb_itemGetL( pValue ) ) _hb_jsonCtxAdd( pCtx, "true", 4 ); else _hb_jsonCtxAdd( pCtx, "false", 5 ); } else if( HB_IS_DATE( pValue ) ) { char szBuffer[ 10 ]; hb_itemGetDS( pValue, szBuffer + 1 ); szBuffer[ 0 ] = '\"'; szBuffer[ 9 ] = '\"'; _hb_jsonCtxAdd( pCtx, szBuffer, 10 ); } else if( HB_IS_TIMESTAMP( pValue ) ) { char szBuffer[ 19 ]; hb_itemGetTS( pValue, szBuffer + 1 ); szBuffer[ 0 ] = '\"'; szBuffer[ 18 ] = '\"'; _hb_jsonCtxAdd( pCtx, szBuffer, 19 ); } else if( HB_IS_ARRAY( pValue ) ) { HB_SIZE nLen = hb_itemSize( pValue ); if( nLen ) { HB_SIZE nIndex; if( pCtx->fHuman ) _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); _hb_jsonCtxAdd( pCtx, "[", 1 ); for( nIndex = 1; nIndex <= nLen; nIndex++ ) { PHB_ITEM pItem = hb_arrayGetItemPtr( pValue, nIndex ); if( nIndex > 1 ) _hb_jsonCtxAdd( pCtx, ",", 1 ); if( pCtx->fHuman ) _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); if( pCtx->fHuman && ! ( ( HB_IS_ARRAY( pItem ) || HB_IS_HASH( pItem ) ) && hb_itemSize( pItem ) > 0 ) ) _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) * INDENT_SIZE ); _hb_jsonEncode( pItem, pCtx, nLevel + 1, HB_FALSE, cdp ); } if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); } _hb_jsonCtxAdd( pCtx, "]", 1 ); } else _hb_jsonCtxAdd( pCtx, "[]", 2 ); } else if( HB_IS_HASH( pValue ) ) { HB_SIZE nLen = hb_hashLen( pValue ); if( nLen ) { HB_SIZE nIndex; if( pCtx->fHuman ) _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); _hb_jsonCtxAdd( pCtx, "{", 1 ); for( nIndex = 1; nIndex <= nLen; nIndex++ ) { PHB_ITEM pKey = hb_hashGetKeyAt( pValue, nIndex ); if( HB_IS_STRING( pKey ) ) { PHB_ITEM pItem = hb_hashGetValueAt( pValue, nIndex ); if( nIndex > 1 ) _hb_jsonCtxAdd( pCtx, ",", 1 ); if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); _hb_jsonCtxAddIndent( pCtx, ( nLevel + 1 ) * INDENT_SIZE ); } _hb_jsonEncode( pKey, pCtx, nLevel + 1, HB_FALSE, cdp ); if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, ": ", 2 ); fEOL = ( HB_IS_ARRAY( pItem ) || HB_IS_HASH( pItem ) ) && hb_itemSize( pItem ) > 0; } else { _hb_jsonCtxAdd( pCtx, ":", 1 ); fEOL = HB_FALSE; } _hb_jsonEncode( pItem, pCtx, nLevel + 1, fEOL, cdp ); } } if( pCtx->fHuman ) { _hb_jsonCtxAdd( pCtx, pCtx->szEol, pCtx->iEolLen ); _hb_jsonCtxAddIndent( pCtx, nLevel * INDENT_SIZE ); } _hb_jsonCtxAdd( pCtx, "}", 1 ); } else _hb_jsonCtxAdd( pCtx, "{}", 2 ); } else { /* All unsupported types are replacd by null */ _hb_jsonCtxAdd( pCtx, "null", 4 ); } }