ext/iodine/fiobj_json.c
/** Writes a JSON friendly version of the src String */
Writes a JSON friendly version of the src String
Writes a JSON friendly version of the src String
static void write_safe_str(FIOBJ dest, const FIOBJ str) {
  fio_str_info_s s = fiobj_obj2cstr(str);
  fio_str_info_s t = fiobj_obj2cstr(dest);
  t.data[t.len] = '"';
  t.len++;
  fiobj_str_resize(dest, t.len);
  t = fiobj_obj2cstr(dest);
  const uint8_t *restrict src = (const uint8_t *)s.data;
  size_t len = s.len;
  uint64_t end = t.len;
  size_t added = 0;
  size_t capa = fiobj_str_capa(dest);
  if (capa <= end + s.len + 64) {
    if (0) {
      capa = (((capa >> 12) + 1) << 12) - 1;
      capa = fiobj_str_capa_assert(dest, capa);
    } else {
      capa = fiobj_str_capa_assert(dest, (end + s.len + 64));
    }
    fio_str_info_s tmp = fiobj_obj2cstr(dest);
    t = tmp;
  }
  while (len) {
    char *restrict writer = (char *)t.data;
    while (len && src[0] > 32 && src[0] != '"' && src[0] != '\\') {
      len--;
      writer[end++] = *(src++);
    }
    if (!len)
      break;
    switch (src[0]) {
    case '\b':
      writer[end++] = '\\';
      writer[end++] = 'b';
      added++;
      break; 
    case '\f':
      writer[end++] = '\\';
      writer[end++] = 'f';
      added++;
      break; 
    case '\n':
      writer[end++] = '\\';
      writer[end++] = 'n';
      added++;
      break; 
    case '\r':
      writer[end++] = '\\';
      writer[end++] = 'r';
      added++;
      break; 
    case '\t':
      writer[end++] = '\\';
      writer[end++] = 't';
      added++;
      break; 
    case '"':
    case '\\':
    case '/':
      writer[end++] = '\\';
      writer[end++] = src[0];
      added++;
      break; 
    default:
      if (src[0] <= 31) {
        writer[end++] = '\\';
        writer[end++] = 'u';
        writer[end++] = '0';
        writer[end++] = '0';
        writer[end++] = hex_chars[src[0] >> 4];
        writer[end++] = hex_chars[src[0] & 15];
        added += 4;
      } else
        writer[end++] = src[0];
      break; 
    }
    src++;
    len--;
    if (added >= 48 && capa <= end + len + 64) {
      writer[end] = 0;
      fiobj_str_resize(dest, end);
      fiobj_str_capa_assert(dest, (end + len + 64));
      t = fiobj_obj2cstr(dest);
      writer = (char *)t.data;
      capa = t.capa;
      added = 0;
    }
  }
  t.data[end++] = '"';
  fiobj_str_resize(dest, end);
}
static void write_safe_str ( FIOBJ dest , const FIOBJ str ) { fio_str_info_s s = fiobj_obj2cstr ( str ) ; fio_str_info_s t = fiobj_obj2cstr ( dest ) ; t . data [ t . len ] = ' ' ; t . len ++ ; fiobj_str_resize ( dest , t . len ) ; t = fiobj_obj2cstr ( dest ) ; const uint8_t * restrict src = ( const uint8_t * ) s . data ; size_t len = s . len ; uint64_t end = t . len ; size_t added = 0 ; size_t capa = fiobj_str_capa ( dest ) ; if ( capa <= end + s . len + 64 ) { if ( 0 ) { capa = ( ( ( capa >> 12 ) + 1 ) << 12 ) - 1 ; capa = fiobj_str_capa_assert ( dest , capa ) ; } else { capa = fiobj_str_capa_assert ( dest , ( end + s . len + 64 ) ) ; } fio_str_info_s tmp = fiobj_obj2cstr ( dest ) ; t = tmp ; } while ( len ) { char * restrict writer = ( char * ) t . data ; while ( len && src [ 0 ] > 32 && src [ 0 ] != ' ' && src [ 0 ] != ' \\ ' ) { len -- ; writer [ end ++ ] = * ( src ++ ) ; } if ( ! len ) break ; switch ( src [ 0 ] ) { case ' \b ' : writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = ' ' ; added ++ ; break ; case ' \f ' : writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = ' ' ; added ++ ; break ; case ' \n ' : writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = ' ' ; added ++ ; break ; case ' \r ' : writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = ' ' ; added ++ ; break ; case ' \t ' : writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = ' ' ; added ++ ; break ; case ' ' : case ' \\ ' : case ' ' : writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = src [ 0 ] ; added ++ ; break ; default : if ( src [ 0 ] <= 31 ) { writer [ end ++ ] = ' \\ ' ; writer [ end ++ ] = ' ' ; writer [ end ++ ] = ' ' ; writer [ end ++ ] = ' ' ; writer [ end ++ ] = hex_chars [ src [ 0 ] >> 4 ] ; writer [ end ++ ] = hex_chars [ src [ 0 ] & 15 ] ; added += 4 ; } else writer [ end ++ ] = src [ 0 ] ; break ; } src ++ ; len -- ; if ( added >= 48 && capa <= end + len + 64 ) { writer [ end ] = 0 ; fiobj_str_resize ( dest , end ) ; fiobj_str_capa_assert ( dest , ( end + len + 64 ) ) ; t = fiobj_obj2cstr ( dest ) ; writer = ( char * ) t . data ; capa = t . capa ; added = 0 ; } } t . data [ end ++ ] = ' ' ; fiobj_str_resize ( dest , end ) ; }
Writes a JSON friendly version of the src String
Writes a JSON friendly version of the src String
/* make sure we have some room */ /* from switch */ /* from switch */ /* from switch */ /* from switch */ /* from switch */ /* from switch */ /* MUST escape all control values less than 32 */ /* from switch */