@@ -1213,107 +1213,137 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
1213
1213
static ecma_value_t
1214
1214
ecma_builtin_json_quote (ecma_string_t * string_p ) /**< string that should be quoted*/
1215
1215
{
1216
- /* 1. */
1217
- ecma_string_t * product_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR );
1218
-
1219
1216
ECMA_STRING_TO_UTF8_STRING (string_p , string_buff , string_buff_size );
1220
-
1221
1217
const lit_utf8_byte_t * str_p = string_buff ;
1222
- const lit_utf8_byte_t * str_end_p = string_buff + string_buff_size ;
1218
+ const lit_utf8_byte_t * str_end_p = str_p + string_buff_size ;
1219
+ size_t n_bytes = 2 ; /* Start with 2 for surrounding quotes. */
1223
1220
1224
1221
while (str_p < str_end_p )
1225
1222
{
1226
- ecma_char_t current_char = lit_utf8_read_next ( & str_p ) ;
1223
+ lit_utf8_byte_t c = * str_p ++ ;
1227
1224
1228
- /* 2.a, b */
1229
- if (current_char == LIT_CHAR_BACKSLASH
1230
- || current_char == LIT_CHAR_DOUBLE_QUOTE
1231
- || current_char == LIT_CHAR_BS
1232
- || current_char == LIT_CHAR_FF
1233
- || current_char == LIT_CHAR_LF
1234
- || current_char == LIT_CHAR_CR
1235
- || current_char == LIT_CHAR_TAB )
1225
+ if (c == LIT_CHAR_BACKSLASH || c == LIT_CHAR_DOUBLE_QUOTE )
1226
+ {
1227
+ n_bytes += 2 ;
1228
+ }
1229
+ else if (c >= LIT_CHAR_SP && c < LIT_UTF8_1_BYTE_CODE_POINT_MAX )
1230
+ {
1231
+ n_bytes ++ ;
1232
+ }
1233
+ else if (c > LIT_UTF8_1_BYTE_CODE_POINT_MAX )
1236
1234
{
1237
- lit_utf8_byte_t abbrev = (lit_utf8_byte_t ) current_char ;
1235
+ lit_utf8_size_t sz = lit_get_unicode_char_size_by_utf8_first_byte (c );
1236
+ n_bytes += sz ;
1237
+ str_p += sz - 1 ;
1238
+ }
1239
+ else
1240
+ {
1241
+ switch (c )
1242
+ {
1243
+ case LIT_CHAR_BS :
1244
+ case LIT_CHAR_FF :
1245
+ case LIT_CHAR_LF :
1246
+ case LIT_CHAR_CR :
1247
+ case LIT_CHAR_TAB :
1248
+ {
1249
+ n_bytes += 2 ;
1250
+ break ;
1251
+ }
1252
+ default : /* Hexadecimal. */
1253
+ {
1254
+ n_bytes += 2 + 4 ;
1255
+ break ;
1256
+ }
1257
+ }
1258
+ }
1259
+ }
1260
+
1261
+ lit_utf8_byte_t * buf_begin = jmem_heap_alloc_block (n_bytes );
1262
+ JERRY_ASSERT (buf_begin != NULL );
1263
+ lit_utf8_byte_t * buf = buf_begin ;
1264
+ str_p = string_buff ;
1265
+
1266
+ * buf ++ = LIT_CHAR_DOUBLE_QUOTE ;
1267
+
1268
+ while (str_p < str_end_p )
1269
+ {
1270
+ lit_utf8_byte_t c = * str_p ++ ;
1238
1271
1239
- switch (current_char )
1272
+ if (c == LIT_CHAR_BACKSLASH || c == LIT_CHAR_DOUBLE_QUOTE )
1273
+ {
1274
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1275
+ * buf ++ = c ;
1276
+ }
1277
+ else if (c >= LIT_CHAR_SP && c < LIT_UTF8_1_BYTE_CODE_POINT_MAX )
1278
+ {
1279
+ * buf ++ = c ;
1280
+ }
1281
+ else if (c > LIT_UTF8_1_BYTE_CODE_POINT_MAX )
1282
+ {
1283
+ str_p -- ;
1284
+ ecma_char_t current_char = lit_utf8_read_next (& str_p );
1285
+ buf += lit_code_unit_to_utf8 (current_char , (lit_utf8_byte_t * ) buf );
1286
+ }
1287
+ else
1288
+ {
1289
+ switch (c )
1240
1290
{
1241
1291
case LIT_CHAR_BS :
1242
1292
{
1243
- abbrev = LIT_CHAR_LOWERCASE_B ;
1293
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1294
+ * buf ++ = LIT_CHAR_LOWERCASE_B ;
1244
1295
break ;
1245
1296
}
1246
1297
case LIT_CHAR_FF :
1247
1298
{
1248
- abbrev = LIT_CHAR_LOWERCASE_F ;
1299
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1300
+ * buf ++ = LIT_CHAR_LOWERCASE_F ;
1249
1301
break ;
1250
1302
}
1251
1303
case LIT_CHAR_LF :
1252
1304
{
1253
- abbrev = LIT_CHAR_LOWERCASE_N ;
1305
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1306
+ * buf ++ = LIT_CHAR_LOWERCASE_N ;
1254
1307
break ;
1255
1308
}
1256
1309
case LIT_CHAR_CR :
1257
1310
{
1258
- abbrev = LIT_CHAR_LOWERCASE_R ;
1311
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1312
+ * buf ++ = LIT_CHAR_LOWERCASE_R ;
1259
1313
break ;
1260
1314
}
1261
1315
case LIT_CHAR_TAB :
1262
1316
{
1263
- abbrev = LIT_CHAR_LOWERCASE_T ;
1317
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1318
+ * buf ++ = LIT_CHAR_LOWERCASE_T ;
1264
1319
break ;
1265
1320
}
1266
- default :
1321
+ default : /* Hexadecimal. */
1267
1322
{
1268
- JERRY_ASSERT (current_char == LIT_CHAR_BACKSLASH || current_char == LIT_CHAR_DOUBLE_QUOTE );
1269
-
1323
+ JERRY_ASSERT (c < 0x9f );
1324
+ * buf ++ = LIT_CHAR_BACKSLASH ;
1325
+ * buf ++ = LIT_CHAR_LOWERCASE_U ;
1326
+ * buf ++ = LIT_CHAR_0 ;
1327
+ * buf ++ = LIT_CHAR_0 ;
1328
+ * buf ++ = (lit_utf8_byte_t ) (LIT_CHAR_0 + (c >> 4 )); /* Max range 0-9, hex digits unnecessary. */
1329
+ lit_utf8_byte_t c2 = (c & 0xf );
1330
+ * buf ++ = (lit_utf8_byte_t ) (c2 + ((c2 <= 9 ) ? LIT_CHAR_0 : (LIT_CHAR_LOWERCASE_A - 10 )));
1270
1331
break ;
1271
1332
}
1272
1333
}
1273
-
1274
- lit_utf8_byte_t chars [2 ] = { LIT_CHAR_BACKSLASH , abbrev };
1275
-
1276
- product_str_p = ecma_append_chars_to_string (product_str_p , chars , 2 , 2 );
1277
1334
}
1278
- /* 2.c */
1279
- else if (current_char < LIT_CHAR_SP )
1280
- {
1281
- lit_utf8_byte_t chars [6 ] = { LIT_CHAR_BACKSLASH , LIT_CHAR_LOWERCASE_U , LIT_CHAR_0 , LIT_CHAR_0 };
1282
-
1283
- JERRY_ASSERT (current_char < 0x9f );
1284
-
1285
- chars [4 ] = (lit_utf8_byte_t ) (LIT_CHAR_0 + (current_char >> 4 ));
1286
-
1287
- int last_char = current_char & 0xf ;
1288
- last_char += (last_char <= 9 ) ? LIT_CHAR_0 : (LIT_CHAR_LOWERCASE_A - 10 );
1289
-
1290
- chars [5 ] = (lit_utf8_byte_t ) last_char ;
1291
-
1292
- product_str_p = ecma_append_chars_to_string (product_str_p , chars , 6 , 6 );
1293
- }
1294
- /* 2.d */
1295
- else if (current_char < LIT_UTF8_1_BYTE_CODE_POINT_MAX )
1296
- {
1297
- /* Fast case for ascii characters. */
1298
- lit_utf8_byte_t chars [1 ] = { (lit_utf8_byte_t ) current_char };
1335
+ }
1299
1336
1300
- product_str_p = ecma_append_chars_to_string (product_str_p , chars , 1 , 1 );
1301
- }
1302
- else
1303
- {
1304
- ecma_string_t * current_char_str_p = ecma_new_ecma_string_from_code_unit (current_char );
1337
+ * buf ++ = LIT_CHAR_DOUBLE_QUOTE ;
1305
1338
1306
- product_str_p = ecma_concat_ecma_strings (product_str_p , current_char_str_p );
1307
- ecma_deref_ecma_string (current_char_str_p );
1308
- }
1309
- }
1339
+ /* Make sure we didn't run off the end or allocated more than we actually wanted. */
1340
+ JERRY_ASSERT ((size_t ) (buf - buf_begin ) == n_bytes );
1310
1341
1342
+ ecma_string_t * product_str_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t * ) buf_begin ,
1343
+ (lit_utf8_size_t ) (buf - buf_begin ));
1344
+ jmem_heap_free_block (buf_begin , n_bytes );
1311
1345
ECMA_FINALIZE_UTF8_STRING (string_buff , string_buff_size );
1312
1346
1313
- /* 3. */
1314
- product_str_p = ecma_append_magic_string_to_string (product_str_p , LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR );
1315
-
1316
- /* 4. */
1317
1347
return ecma_make_string_value (product_str_p );
1318
1348
} /* ecma_builtin_json_quote */
1319
1349
0 commit comments