static const char * _hb_jsonDecode( const char * szSource, PHB_ITEM pValue ) { if( *szSource == '\"' ) { char * szDest, * szHead; HB_SIZE nAlloc = 16; szHead = szDest = ( char * ) hb_xgrab( nAlloc ); szSource++; while( *szSource != '\"' ) { if( szHead + 6 >= szDest + nAlloc ) { HB_SIZE nLen = szHead - szDest; nAlloc += nAlloc << 1; szDest = ( char * ) hb_xrealloc( szDest, nAlloc ); szHead = szDest + nLen; } if( *szSource == '\\' ) { szSource++; switch( *szSource ) { case '\"': *szHead++ = '\"'; break; case '\\': *szHead++ = '\\'; break; case '/': *szHead++ = '/'; break; case 'b': *szHead++ = '\b'; break; case 'f': *szHead++ = '\f'; break; case 'n': *szHead++ = '\n'; break; case 'r': *szHead++ = '\r'; break; case 't': *szHead++ = '\t'; break; case 'u': { HB_WCHAR wc = 0; int i; for( i = 0; i < 4; i++ ) { char c = *++szSource; wc <<= 4; if( c >= '0' && c <= '9' ) wc += c - '0'; else if( c >= 'A' && c <= 'F' ) wc += c - 'A' + 10; else if( c >= 'a' && c <= 'f' ) wc += c - 'a' + 10; else { hb_xfree( szDest ); return NULL; } } szHead += hb_cdpU16ToStr( hb_vmCDP(), HB_CDP_ENDIAN_NATIVE, &wc, 1, szHead, szDest + nAlloc - szHead ); break; } default: hb_xfree( szDest ); return NULL; } szSource++; } else if( *( const unsigned char * ) szSource >= ' ' ) *szHead++ = *szSource++; else { hb_xfree( szDest ); return NULL; } } hb_itemPutCL( pValue, szDest, szHead - szDest ); hb_xfree( szDest ); return szSource + 1; } else if( *szSource == '-' || ( *szSource >= '0' && *szSource <= '9' ) ) { /* NOTE: this function is much less strict to number format than JSON syntax definition. This is allowed behaviour [Mindaugas] */ HB_MAXINT nValue = 0; double dblValue = 0; HB_BOOL fNeg, fDbl = HB_FALSE; int iDec = 0; fNeg = *szSource == '-'; if( fNeg ) szSource++; while( *szSource >= '0' && *szSource <= '9' ) { nValue = nValue * 10 + *szSource - '0'; szSource++; } if( *szSource == '.' ) { double mult = 1; dblValue = ( double ) nValue; fDbl = HB_TRUE; szSource++; while( *szSource >= '0' && *szSource <= '9' ) { mult /= 10; dblValue += ( ( double ) ( *szSource - '0' ) ) * mult; szSource++; iDec++; } } if( *szSource == 'e' || *szSource == 'E' ) { HB_BOOL fNegExp; int iExp = 0; szSource++; fNegExp = *szSource == '-'; if( fNegExp ) szSource++; while( *szSource >= '0' && *szSource <= '9' ) { iExp = iExp * 10 + *szSource - '0'; szSource++; } if( ! fDbl ) { dblValue = ( double ) nValue; fDbl = HB_TRUE; } dblValue *= pow( 10.0, ( double ) ( fNegExp ? -iExp : iExp ) ); if( fNegExp ) iDec += iExp; } if( fDbl ) hb_itemPutNDDec( pValue, fNeg ? -dblValue : dblValue, iDec ); else hb_itemPutNInt( pValue, fNeg ? -nValue : nValue ); return szSource; } else if( ! strncmp( szSource, "null", 4 ) ) { hb_itemClear( pValue ); return szSource + 4; } else if( ! strncmp( szSource, "true", 4 ) ) { hb_itemPutL( pValue, HB_TRUE ); return szSource + 4; } else if( ! strncmp( szSource, "false", 5 ) ) { hb_itemPutL( pValue, HB_FALSE ); return szSource + 5; } else if( *szSource == '[' ) { hb_arrayNew( pValue, 0 ); szSource = _skipws( szSource + 1 ); if( *szSource != ']' ) { PHB_ITEM pItem = hb_itemNew( NULL ); for( ;; ) { szSource = _hb_jsonDecode( szSource, pItem ); if( ! szSource ) { hb_itemRelease( pItem ); return NULL; } hb_arrayAddForward( pValue, pItem ); szSource = _skipws( szSource ); if( *szSource == ',' ) { szSource = _skipws( szSource + 1 ); continue; } else if( *szSource == ']' ) break; else { hb_itemRelease( pItem ); return NULL; } } hb_itemRelease( pItem ); } return szSource + 1; } else if( *szSource == '{' ) { hb_hashNew( pValue ); hb_hashSetFlags( pValue, HB_HASH_KEEPORDER ); szSource = _skipws( szSource + 1 ); if( *szSource != '}' ) { PHB_ITEM pItemKey = hb_itemNew( NULL ); PHB_ITEM pItemValue = hb_itemNew( NULL ); for( ;; ) { /* Do we need to check if key does not exist yet? */ if( ( szSource = _hb_jsonDecode( szSource, pItemKey ) ) == NULL || ! HB_IS_STRING( pItemKey ) || * ( szSource = _skipws( szSource ) ) != ':' || ( szSource = _hb_jsonDecode( _skipws( szSource + 1 ), pItemValue ) ) == NULL) { hb_itemRelease( pItemKey ); hb_itemRelease( pItemValue ); return NULL; } hb_hashAdd( pValue, pItemKey, pItemValue ); szSource = _skipws( szSource ); if( *szSource == ',' ) { szSource = _skipws( szSource + 1 ); continue; } else if( *szSource == '}' ) break; else { hb_itemRelease( pItemKey ); hb_itemRelease( pItemValue ); return NULL; } } hb_itemRelease( pItemKey ); hb_itemRelease( pItemValue ); } return szSource + 1; } return NULL; }
static const char * hb_i18n_setcodepage( PHB_I18N_TRANS pI18N, const char * szCdpID, HB_BOOL fBase, HB_BOOL fTranslate ) { const char * szOldCdpID = NULL, * szKey; if( pI18N ) { PHB_CODEPAGE cdp = szCdpID ? hb_cdpFind( szCdpID ) : NULL, cdpage; cdpage = fBase ? pI18N->base_cdpage : pI18N->cdpage; if( cdpage ) szOldCdpID = cdpage->id; if( cdp && cdp != cdpage ) { if( fTranslate && cdpage ) { HB_SIZE nHashLen = hb_hashLen( pI18N->context_table ), ul; for( ul = 1; ul <= nHashLen; ++ul ) { PHB_ITEM pContext = hb_hashGetValueAt( pI18N->context_table, ul ); HB_SIZE nCount = hb_hashLen( pContext ), u; for( u = 1; u <= nCount; ++u ) { if( fBase ) { hb_i18n_transitm( hb_hashGetKeyAt( pContext, u ), cdpage, cdp ); } else { PHB_ITEM pResult = hb_hashGetValueAt( pContext, u ); if( HB_IS_STRING( pResult ) ) { hb_i18n_transitm( pResult, cdpage, cdp ); } else if( HB_IS_ARRAY( pResult ) ) { HB_SIZE nTrans = hb_arrayLen( pResult ), u2; for( u2 = 1; u2 <= nTrans; ++u2 ) { hb_i18n_transitm( hb_arrayGetItemPtr( pResult, u2 ), cdpage, cdp ); } } } } if( fBase ) { hb_i18n_transitm( hb_hashGetKeyAt( pI18N->context_table, ul ), cdpage, cdp ); hb_hashSetFlags( pContext, HB_HASH_RESORT ); } } if( fBase ) hb_hashSetFlags( pI18N->context_table, HB_HASH_RESORT ); } if( fBase ) { pI18N->base_cdpage = cdp; szKey = "BASE_CODEPAGE"; } else { pI18N->cdpage = cdp; szKey = "CODEPAGE"; } hb_i18n_setitem( pI18N->table, szKey, szCdpID ); } } return szOldCdpID; }