66#ifndef SQDBG_JSON_H
77#define SQDBG_JSON_H
88
9- // Most messages are going to require less than 256 bytes,
10- // only approaching 1024 on large breakpoint requests
11- #define JSON_SCRATCH_CHUNK_SIZE 1024
12-
139typedef enum
1410{
1511 JSON_NULL = 0x0000 ,
@@ -62,12 +58,12 @@ class json_array_t
6258{
6359public:
6460 const char *m_pBase;
65- CScratch< true , JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
66- int *m_Elements;
61+ CScratch< true > *m_Allocator;
62+ scratchindex_t *m_Elements;
6763 unsigned short m_nElementCount;
6864 unsigned short m_nElementsSize;
6965
70- void Init ( const char *base, CScratch< true , JSON_SCRATCH_CHUNK_SIZE > *allocator )
66+ void Init ( const char *base, CScratch< true > *allocator )
7167 {
7268 m_pBase = base;
7369 m_Allocator = allocator;
@@ -81,16 +77,16 @@ class json_array_t
8177 {
8278 // doesn't free old ptr, this is an uncommon operation and extra allocation is fine
8379 int oldsize = m_nElementsSize;
84- int *oldptr = m_Elements;
80+ scratchindex_t *oldptr = m_Elements;
8581
8682 m_nElementsSize = !m_nElementsSize ? 8 : ( m_nElementsSize << 1 );
87- m_Elements = (int *)m_Allocator->Alloc ( m_nElementsSize * sizeof (int ) );
83+ m_Elements = (scratchindex_t *)m_Allocator->Alloc ( m_nElementsSize * sizeof (*m_Elements ) );
8884
8985 if ( oldsize )
90- memcpy ( m_Elements, oldptr, oldsize * sizeof (int ) );
86+ memcpy ( m_Elements, oldptr, oldsize * sizeof (*m_Elements ) );
9187 }
9288
93- int index;
89+ scratchindex_t index;
9490 json_value_t *ret = (json_value_t *)m_Allocator->Alloc ( sizeof (json_value_t ), &index );
9591 m_Elements[ m_nElementCount++ ] = index;
9692 return ret;
@@ -138,12 +134,12 @@ class json_table_t
138134{
139135public:
140136 const char *m_pBase;
141- CScratch< true , JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
142- int *m_Elements;
137+ CScratch< true > *m_Allocator;
138+ scratchindex_t *m_Elements;
143139 unsigned short m_nElementCount;
144140 unsigned short m_nElementsSize;
145141
146- void Init ( const char *base, CScratch< true , JSON_SCRATCH_CHUNK_SIZE > *allocator )
142+ void Init ( const char *base, CScratch< true > *allocator )
147143 {
148144 m_pBase = base;
149145 m_Allocator = allocator;
@@ -174,16 +170,16 @@ class json_table_t
174170 if ( m_nElementCount == m_nElementsSize )
175171 {
176172 int oldsize = m_nElementsSize;
177- int *oldptr = m_Elements;
173+ scratchindex_t *oldptr = m_Elements;
178174
179175 m_nElementsSize = !m_nElementsSize ? 8 : ( m_nElementsSize << 1 );
180- m_Elements = (int *)m_Allocator->Alloc ( m_nElementsSize * sizeof (int ) );
176+ m_Elements = (scratchindex_t *)m_Allocator->Alloc ( m_nElementsSize * sizeof (*m_Elements ) );
181177
182178 if ( oldsize )
183- memcpy ( m_Elements, oldptr, oldsize * sizeof (int ) );
179+ memcpy ( m_Elements, oldptr, oldsize * sizeof (*m_Elements ) );
184180 }
185181
186- int index;
182+ scratchindex_t index;
187183 json_field_t *ret = (json_field_t *)m_Allocator->Alloc ( sizeof (json_field_t ), &index );
188184 m_Elements[ m_nElementCount++ ] = index;
189185 return ret;
@@ -275,7 +271,12 @@ static inline void PutStr( CBuffer *buffer, const string_t &str )
275271#ifdef SQDBG_VALIDATE_SENT_MSG
276272 for ( unsigned int i = 0 ; i < str.len ; i++ )
277273 {
278- if ( str.ptr [i] == ' \\ ' && ( str.ptr [i+1 ] == ' \\ ' || str.ptr [i+1 ] == ' \" ' ) )
274+ if ( str.ptr [i] == ' \\ ' &&
275+ ( str.ptr [i+1 ] == ' \\ ' ||
276+ str.ptr [i+1 ] == ' \" ' ||
277+ str.ptr [i+1 ] == ' n' ||
278+ str.ptr [i+1 ] == ' r' ||
279+ str.ptr [i+1 ] == ' t' ) )
279280 {
280281 i++;
281282 continue ;
@@ -314,7 +315,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
314315 default :
315316 if ( !IN_RANGE_CHAR ( *c, 0x20 , 0x7E ) )
316317 {
317- int ret = IsValidUTF8 ( ( unsigned char *) c, i + 1 );
318+ int ret = IsValidUTF8 ( c, i + 1 );
318319 if ( ret != 0 )
319320 {
320321 i -= ret - 1 ;
@@ -410,7 +411,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
410411 default :
411412 if ( !IN_RANGE_CHAR ( *c, 0x20 , 0x7E ) )
412413 {
413- int ret = IsValidUTF8 ( ( unsigned char *) c, i + 1 );
414+ int ret = IsValidUTF8 ( c, i + 1 );
414415 if ( ret != 0 )
415416 {
416417 memcpy ( mem + idx, c + 1 , ret - 1 );
@@ -425,19 +426,26 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
425426 if ( !quote )
426427 {
427428 mem[idx++] = ' u' ;
428- idx += printhex< true , false >(
429+ uint16_t val = (uint16_t )*(unsigned char *)c;
430+ idx += printhex< false >(
429431 mem + idx,
430432 buffer->Capacity () - idx,
431- ( uint16_t )*( unsigned char *)c );
433+ val );
432434 }
433435 else
434436 {
435437 mem[idx++] = ' \\ ' ;
438+ #ifdef SQUNICODE
439+ mem[idx++] = ' u' ;
440+ uint16_t val = (uint16_t )*(unsigned char *)c;
441+ #else
436442 mem[idx++] = ' x' ;
437- idx += printhex< true , false >(
443+ unsigned char val = *(unsigned char *)c;
444+ #endif
445+ idx += printhex< false >(
438446 mem + idx,
439447 buffer->Capacity () - idx,
440- (SQUnsignedChar)*( unsigned char *)c );
448+ val );
441449 }
442450 }
443451 }
@@ -504,12 +512,12 @@ static inline void PutInt( CBuffer *buffer, I val )
504512 buffer->size += len;
505513}
506514
507- template < bool padding, typename I >
508- static inline void PutHex ( CBuffer *buffer, I val )
515+ template < typename I >
516+ static inline void PutHex ( CBuffer *buffer, I val, bool padding )
509517{
510518 STATIC_ASSERT ( IS_UNSIGNED ( I ) );
511- buffer->base .Ensure ( buffer->Size () + countdigits<16 >( val ) + 1 );
512- int len = printhex< padding > ( buffer->Base () + buffer->Size (), buffer->Capacity () - buffer->Size (), val );
519+ buffer->base .Ensure ( buffer->Size () + ( padding ? sizeof (I) * 2 : countdigits<16 >( val ) ) + 2 );
520+ int len = printhex ( buffer->Base () + buffer->Size (), buffer->Capacity () - buffer->Size (), val, -( int )padding );
513521 buffer->size += len;
514522}
515523
@@ -571,14 +579,7 @@ struct jstringbuf_t
571579 template < typename I >
572580 void PutHex ( I val, bool padding = true )
573581 {
574- if ( padding )
575- {
576- ::PutHex< true >( m_pBuffer, val );
577- }
578- else
579- {
580- ::PutHex< false >( m_pBuffer, val );
581- }
582+ ::PutHex ( m_pBuffer, val, padding );
582583 }
583584};
584585
@@ -704,7 +705,7 @@ class wjson_table_t : public wjson_t
704705 }
705706 else
706707 {
707- PutHex< false > ( m_pBuffer, cast_unsigned ( I, val ) );
708+ PutHex ( m_pBuffer, cast_unsigned ( val ), false );
708709 }
709710 PutChar ( m_pBuffer, ' ]' );
710711 PutChar ( m_pBuffer, ' \" ' );
@@ -788,7 +789,7 @@ class JSONParser
788789 char *m_cur;
789790 char *m_end;
790791 char *m_start;
791- CScratch< true , JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
792+ CScratch< true > *m_Allocator;
792793 char *m_error;
793794
794795 enum
@@ -805,7 +806,7 @@ class JSONParser
805806 };
806807
807808public:
808- JSONParser ( CScratch< true , JSON_SCRATCH_CHUNK_SIZE > *allocator, char *ptr, int len, json_table_t *pTable ) :
809+ JSONParser ( CScratch< true > *allocator, char *ptr, int len, json_table_t *pTable ) :
809810 m_cur ( ptr ),
810811 m_end ( ptr + len + 1 ),
811812 m_start ( ptr ),
@@ -855,7 +856,7 @@ class JSONParser
855856 else
856857 {
857858 buf = m_Allocator->Alloc (5 );
858- int i = printhex< true , true , false >( buf, 5 , (unsigned char )token );
859+ int i = printhex< true , false >( buf, 5 , (unsigned char )token );
859860 Assert ( i == 4 );
860861 buf[i] = 0 ;
861862 }
@@ -1041,10 +1042,12 @@ class JSONParser
10411042 }
10421043
10431044#define _shift ( bytesWritten, bytesRead ) \
1045+ do { \
10441046 Assert ( (bytesWritten) < (bytesRead) ); \
10451047 memmove ( cur + (bytesWritten), cur + (bytesRead), end - ( cur + (bytesRead) ) ); \
10461048 cur += (bytesWritten); \
1047- end -= (bytesRead) - (bytesWritten);
1049+ end -= (bytesRead) - (bytesWritten); \
1050+ } while (0 )
10481051
10491052 switch ( cur[1 ] )
10501053 {
@@ -1222,7 +1225,7 @@ class JSONParser
12221225
12231226 json_field_t *kv = pTable->NewElement ();
12241227
1225- Assert ( token.ptr - m_start < (ostr_t ::index_t )-1 );
1228+ Assert ( ( ostr_t :: index_t )( token.ptr - m_start ) < (ostr_t ::index_t )-1 );
12261229 kv->key .ofs = token.ptr - m_start;
12271230 kv->key .len = (ostr_t ::index_t )token.len ;
12281231
@@ -1315,7 +1318,7 @@ class JSONParser
13151318 return type;
13161319 case Token_String:
13171320 value->type = JSON_STRING ;
1318- Assert ( token.ptr - m_start < (ostr_t ::index_t )-1 );
1321+ Assert ( ( ostr_t :: index_t )( token.ptr - m_start ) < (ostr_t ::index_t )-1 );
13191322 value->_string .ofs = token.ptr - m_start;
13201323 value->_string .len = (ostr_t ::index_t )token.len ;
13211324 return type;
0 commit comments