summaryrefslogtreecommitdiff
path: root/ext/json/generator/generator.c
diff options
context:
space:
mode:
-rw-r--r--ext/json/generator/generator.c366
1 files changed, 354 insertions, 12 deletions
@@ -5,6 +5,8 @@
#include <math.h>
#include <ctype.h>
/* ruby api and some helpers */
typedef struct JSON_Generator_StateStruct {
@@ -109,12 +111,40 @@ typedef struct _search_state {
const char *end;
const char *cursor;
FBuffer *buffer;
} search_state;
-static inline void search_flush(search_state *search)
-{
- fbuffer_append(search->buffer, search->cursor, search->ptr - search->cursor);
- search->cursor = search->ptr;
}
static const unsigned char escape_table_basic[256] = {
@@ -130,6 +160,8 @@ static const unsigned char escape_table_basic[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static inline unsigned char search_escape_basic(search_state *search)
{
while (search->ptr < search->end) {
@@ -144,7 +176,8 @@ static inline unsigned char search_escape_basic(search_state *search)
return 0;
}
-static inline void escape_UTF8_char_basic(search_state *search) {
const unsigned char ch = (unsigned char)*search->ptr;
switch (ch) {
case '"': fbuffer_append(search->buffer, "\\\"", 2); break;
@@ -156,11 +189,15 @@ static inline void escape_UTF8_char_basic(search_state *search) {
case '\r': fbuffer_append(search->buffer, "\\r", 2); break;
case '\t': fbuffer_append(search->buffer, "\\t", 2); break;
default: {
- const char *hexdig = "0123456789abcdef";
- char scratch[6] = { '\\', 'u', '0', '0', 0, 0 };
- scratch[4] = hexdig[(ch >> 4) & 0xf];
- scratch[5] = hexdig[ch & 0xf];
- fbuffer_append(search->buffer, scratch, 6);
break;
}
}
@@ -186,12 +223,13 @@ static inline void escape_UTF8_char_basic(search_state *search) {
*/
static inline void convert_UTF8_to_JSON(search_state *search)
{
- while (search_escape_basic(search)) {
escape_UTF8_char_basic(search);
}
}
-static inline void escape_UTF8_char(search_state *search, unsigned char ch_len) {
const unsigned char ch = (unsigned char)*search->ptr;
switch (ch_len) {
case 1: {
@@ -227,6 +265,285 @@ static inline void escape_UTF8_char(search_state *search, unsigned char ch_len)
search->cursor = (search->ptr += ch_len);
}
static const unsigned char script_safe_escape_table[256] = {
// ASCII Control Characters
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
@@ -990,6 +1307,12 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
search.cursor = search.ptr;
search.end = search.ptr + len;
switch(rb_enc_str_coderange(obj)) {
case ENC_CODERANGE_7BIT:
case ENC_CODERANGE_VALID:
@@ -1853,4 +2176,23 @@ void Init_generator(void)
binary_encindex = rb_ascii8bit_encindex();
rb_require("json/ext/generator/state");
}