RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Functions | Variables
cJSON.c File Reference
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include "switch_cJSON.h"
+ Include dependency graph for cJSON.c:

Go to the source code of this file.

Data Structures

struct  error
 
struct  internal_hooks
 
struct  parse_buffer
 
struct  printbuffer
 

Macros

#define true   ((cJSON_bool)1)
 
#define false   ((cJSON_bool)0)
 
#define internal_malloc   malloc
 
#define internal_free   free
 
#define internal_realloc   realloc
 
#define static_strlen(string_literal)   (sizeof(string_literal) - sizeof(""))
 
#define can_read(buffer, size)   ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
 
#define can_access_at_index(buffer, index)   ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
 
#define cannot_access_at_index(buffer, index)   (!can_access_at_index(buffer, index))
 
#define buffer_at_offset(buffer)   ((buffer)->content + (buffer)->offset)
 
#define cjson_min(a, b)   ((a < b) ? a : b)
 

Typedefs

typedef struct internal_hooks internal_hooks
 

Functions

 CJSON_PUBLIC (const char *)
 
 CJSON_PUBLIC (char *)
 
static int case_insensitive_strcmp (const unsigned char *string1, const unsigned char *string2)
 
static unsigned char * cJSON_strdup (const unsigned char *string, const internal_hooks *const hooks)
 
 CJSON_PUBLIC (void)
 
static cJSONcJSON_New_Item (const internal_hooks *const hooks)
 
static unsigned char get_decimal_point (void)
 
static cJSON_bool parse_number (cJSON *const item, parse_buffer *const input_buffer)
 
 CJSON_PUBLIC (double)
 
static unsigned char * ensure (printbuffer *const p, size_t needed)
 
static void update_offset (printbuffer *const buffer)
 
static cJSON_bool print_number (const cJSON *const item, printbuffer *const output_buffer)
 
static unsigned parse_hex4 (const unsigned char *const input)
 
static unsigned char utf16_literal_to_utf8 (const unsigned char *const input_pointer, const unsigned char *const input_end, unsigned char **output_pointer)
 
static cJSON_bool parse_string (cJSON *const item, parse_buffer *const input_buffer)
 
static cJSON_bool print_string_ptr (const unsigned char *const input, printbuffer *const output_buffer)
 
static cJSON_bool print_string (const cJSON *const item, printbuffer *const p)
 
static cJSON_bool parse_value (cJSON *const item, parse_buffer *const input_buffer)
 
static cJSON_bool print_value (const cJSON *const item, printbuffer *const output_buffer)
 
static cJSON_bool parse_array (cJSON *const item, parse_buffer *const input_buffer)
 
static cJSON_bool print_array (const cJSON *const item, printbuffer *const output_buffer)
 
static cJSON_bool parse_object (cJSON *const item, parse_buffer *const input_buffer)
 
static cJSON_bool print_object (const cJSON *const item, printbuffer *const output_buffer)
 
static parse_bufferbuffer_skip_whitespace (parse_buffer *const buffer)
 
static parse_bufferskip_utf8_bom (parse_buffer *const buffer)
 
 CJSON_PUBLIC (cJSON *)
 
static unsigned char * print (const cJSON *const item, cJSON_bool format, const internal_hooks *const hooks)
 
 CJSON_PUBLIC (cJSON_bool)
 
static cJSONget_array_item (const cJSON *array, size_t index)
 
static cJSONget_object_item (const cJSON *const object, const char *const name, const cJSON_bool case_sensitive)
 
static void suffix_object (cJSON *prev, cJSON *item)
 
static cJSONcreate_reference (const cJSON *item, const internal_hooks *const hooks)
 
static cJSON_bool add_item_to_array (cJSON *array, cJSON *item)
 
static void * cast_away_const (const void *string)
 
static cJSON_bool add_item_to_object (cJSON *const object, const char *const string, cJSON *const item, const internal_hooks *const hooks, const cJSON_bool constant_key)
 
static cJSON_bool replace_item_in_object (cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
 
static void skip_oneline_comment (char **input)
 
static void skip_multiline_comment (char **input)
 
static void minify_string (char **input, char **output)
 
 CJSON_PUBLIC (void *)
 

Variables

static error global_error = { NULL, 0 }
 
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }
 

Macro Definition Documentation

◆ buffer_at_offset

#define buffer_at_offset (   buffer)    ((buffer)->content + (buffer)->offset)

◆ can_access_at_index

#define can_access_at_index (   buffer,
  index 
)    ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))

◆ can_read

#define can_read (   buffer,
  size 
)    ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))

Definition at line 265 of file cJSON.c.

Referenced by parse_value().

◆ cannot_access_at_index

#define cannot_access_at_index (   buffer,
  index 
)    (!can_access_at_index(buffer, index))

Definition at line 268 of file cJSON.c.

Referenced by parse_array(), and parse_object().

◆ cjson_min

#define cjson_min (   a,
  b 
)    ((a < b) ? a : b)

Definition at line 1092 of file cJSON.c.

Referenced by print().

◆ false

#define false   ((cJSON_bool)0)

Definition at line 66 of file cJSON.c.

◆ internal_free

#define internal_free   free

Definition at line 147 of file cJSON.c.

◆ internal_malloc

#define internal_malloc   malloc

Definition at line 146 of file cJSON.c.

◆ internal_realloc

#define internal_realloc   realloc

Definition at line 148 of file cJSON.c.

◆ static_strlen

#define static_strlen (   string_literal)    (sizeof(string_literal) - sizeof(""))

Definition at line 152 of file cJSON.c.

Referenced by minify_string(), skip_multiline_comment(), and skip_oneline_comment().

◆ true

#define true   ((cJSON_bool)1)

Definition at line 61 of file cJSON.c.

Referenced by Event::addBody(), Event::addHeader(), Event::delHeader(), and running().

Typedef Documentation

◆ internal_hooks

Function Documentation

◆ add_item_to_array()

static cJSON_bool add_item_to_array ( cJSON array,
cJSON item 
)
static

Definition at line 1847 of file cJSON.c.

References cJSON::child, CJSON_PUBLIC(), item, cJSON::next, and suffix_object().

Referenced by add_item_to_object().

1848 {
1849  cJSON *child = NULL;
1850 
1851  if ((item == NULL) || (array == NULL))
1852  {
1853  return false;
1854  }
1855 
1856  child = array->child;
1857 
1858  if (child == NULL)
1859  {
1860  /* list is empty, start new one */
1861  array->child = item;
1862  }
1863  else
1864  {
1865  /* append to the end */
1866  while (child->next)
1867  {
1868  child = child->next;
1869  }
1870  suffix_object(child, item);
1871  }
1872 
1873  return true;
1874 }
struct cJSON * child
Definition: switch_cJSON.h:101
static void suffix_object(cJSON *prev, cJSON *item)
Definition: cJSON.c:1819
struct cJSON * next
Definition: switch_cJSON.h:98
cJSON * item
Definition: switch_cJSON.h:210

◆ add_item_to_object()

static cJSON_bool add_item_to_object ( cJSON *const  object,
const char *const  string,
cJSON *const  item,
const internal_hooks *const  hooks,
const cJSON_bool  constant_key 
)
static

Definition at line 1898 of file cJSON.c.

References add_item_to_array(), cast_away_const(), cJSON::child, cJSON_Invalid, CJSON_PUBLIC(), cJSON_strdup(), cJSON_StringIsConst, create_reference(), get_array_item(), item, name, newitem, cJSON::next, number, cJSON::prev, raw, replacement, cJSON::string, string, cJSON::type, internal_hooks::void(), and which.

1899 {
1900  char *new_key = NULL;
1901  int new_type = cJSON_Invalid;
1902 
1903  if ((object == NULL) || (string == NULL) || (item == NULL))
1904  {
1905  return false;
1906  }
1907 
1908  if (constant_key)
1909  {
1910  new_key = (char*)cast_away_const(string);
1911  new_type = item->type | cJSON_StringIsConst;
1912  }
1913  else
1914  {
1915  new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
1916  if (new_key == NULL)
1917  {
1918  return false;
1919  }
1920 
1921  new_type = item->type & ~cJSON_StringIsConst;
1922  }
1923 
1924  if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
1925  {
1926  hooks->deallocate(item->string);
1927  }
1928 
1929  item->string = new_key;
1930  item->type = new_type;
1931 
1932  return add_item_to_array(object, item);
1933 }
#define cJSON_Invalid
Definition: switch_cJSON.h:81
static unsigned char * cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
Definition: cJSON.c:156
static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
Definition: cJSON.c:1847
char * string
Definition: switch_cJSON.h:114
const char *const string
Definition: switch_cJSON.h:162
#define cJSON_StringIsConst
Definition: switch_cJSON.h:92
static void * cast_away_const(const void *string)
Definition: cJSON.c:1889
int type
Definition: switch_cJSON.h:104

◆ buffer_skip_whitespace()

static parse_buffer* buffer_skip_whitespace ( parse_buffer *const  buffer)
static

Definition at line 970 of file cJSON.c.

References buffer, buffer_at_offset, can_access_at_index, parse_buffer::content, parse_buffer::length, and parse_buffer::offset.

Referenced by CJSON_PUBLIC(), parse_array(), and parse_object().

971 {
972  if ((buffer == NULL) || (buffer->content == NULL))
973  {
974  return NULL;
975  }
976 
977  while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
978  {
979  buffer->offset++;
980  }
981 
982  if (buffer->offset == buffer->length)
983  {
984  buffer->offset--;
985  }
986 
987  return buffer;
988 }
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
size_t length
Definition: cJSON.c:258
char * buffer
Definition: switch_cJSON.h:153
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257

◆ case_insensitive_strcmp()

static int case_insensitive_strcmp ( const unsigned char *  string1,
const unsigned char *  string2 
)
static

Definition at line 101 of file cJSON.c.

Referenced by get_object_item().

102 {
103  if ((string1 == NULL) || (string2 == NULL))
104  {
105  return 1;
106  }
107 
108  if (string1 == string2)
109  {
110  return 0;
111  }
112 
113  for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
114  {
115  if (*string1 == '\0')
116  {
117  return 0;
118  }
119  }
120 
121  return tolower(*string1) - tolower(*string2);
122 }

◆ cast_away_const()

static void* cast_away_const ( const void *  string)
static

Definition at line 1889 of file cJSON.c.

References string.

Referenced by add_item_to_object(), and replace_item_in_object().

1890 {
1891  return (void*)string;
1892 }
const char *const string
Definition: switch_cJSON.h:162

◆ cJSON_New_Item()

static cJSON* cJSON_New_Item ( const internal_hooks *const  hooks)
static

Definition at line 209 of file cJSON.c.

References internal_hooks::allocate(), cJSON::child, cJSON_IsReference, CJSON_PUBLIC(), cJSON_StringIsConst, item, memset(), cJSON::next, cJSON::string, cJSON::type, and cJSON::valuestring.

Referenced by CJSON_PUBLIC(), create_reference(), parse_array(), parse_object(), and replace_item_in_object().

210 {
211  cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
212  if (node)
213  {
214  memset(node, '\0', sizeof(cJSON));
215  }
216 
217  return node;
218 }
void *CJSON_CDECL * allocate(size_t size)
memset(buf, 0, buflen)

◆ CJSON_PUBLIC() [1/7]

CJSON_PUBLIC ( const char *  )

Definition at line 74 of file cJSON.c.

References error::json, and error::position.

Referenced by add_item_to_array(), add_item_to_object(), cJSON_New_Item(), CJSON_PUBLIC(), get_array_item(), get_object_item(), minify_string(), print(), print_object(), and replace_item_in_object().

75 {
76  return (const char*) (global_error.json + global_error.position);
77 }
static error global_error
Definition: cJSON.c:72
size_t position
Definition: cJSON.c:70
const unsigned char * json
Definition: cJSON.c:69

◆ CJSON_PUBLIC() [2/7]

CJSON_PUBLIC ( char *  )

Definition at line 79 of file cJSON.c.

References CJSON_PUBLIC(), CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH, and cJSON::valuestring.

79  {
80  if (!cJSON_IsString(item)) {
81  return NULL;
82  }
83 
84  return item->valuestring;
85 }
char * valuestring
Definition: switch_cJSON.h:107
cJSON * item
Definition: switch_cJSON.h:210

◆ CJSON_PUBLIC() [3/7]

CJSON_PUBLIC ( void  )

Definition at line 177 of file cJSON.c.

References internal_hooks::allocate(), cJSON_Hooks::malloc_fn(), and internal_hooks::reallocate().

178 {
179  if (hooks == NULL)
180  {
181  /* Reset hooks */
182  global_hooks.allocate = malloc;
183  global_hooks.deallocate = free;
184  global_hooks.reallocate = realloc;
185  return;
186  }
187 
188  global_hooks.allocate = malloc;
189  if (hooks->malloc_fn != NULL)
190  {
191  global_hooks.allocate = hooks->malloc_fn;
192  }
193 
194  global_hooks.deallocate = free;
195  if (hooks->free_fn != NULL)
196  {
197  global_hooks.deallocate = hooks->free_fn;
198  }
199 
200  /* use realloc only if both free and malloc are used */
201  global_hooks.reallocate = NULL;
202  if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
203  {
204  global_hooks.reallocate = realloc;
205  }
206 }
void *CJSON_CDECL * allocate(size_t size)
void *CJSON_CDECL * reallocate(void *pointer, size_t size)
static internal_hooks global_hooks
Definition: cJSON.c:154

◆ CJSON_PUBLIC() [4/7]

CJSON_PUBLIC ( double  )

Definition at line 350 of file cJSON.c.

References number.

351 {
352  if (number >= INT_MAX)
353  {
354  object->valueint = INT_MAX;
355  }
356  else if (number <= (double)INT_MIN)
357  {
358  object->valueint = INT_MIN;
359  }
360  else
361  {
362  object->valueint = (int)number;
363  }
364 
365  return object->valuedouble = number;
366 }
const char *const const double number
Definition: switch_cJSON.h:254

◆ CJSON_PUBLIC() [5/7]

CJSON_PUBLIC ( cJSON )

Definition at line 1007 of file cJSON.c.

References buffer, buffer_at_offset, buffer_skip_whitespace(), cJSON_New_Item(), CJSON_PUBLIC(), parse_buffer::content, fail, global_hooks, parse_buffer::hooks, item, error::json, parse_buffer::length, parse_buffer::offset, parse_value(), error::position, skip_utf8_bom(), and value.

1008 {
1009  parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
1010  cJSON *item = NULL;
1011 
1012  /* reset error position */
1013  global_error.json = NULL;
1014  global_error.position = 0;
1015 
1016  if (value == NULL)
1017  {
1018  goto fail;
1019  }
1020 
1021  buffer.content = (const unsigned char*)value;
1022  buffer.length = strlen((const char*)value) + sizeof("");
1023  buffer.offset = 0;
1024  buffer.hooks = global_hooks;
1025 
1026  item = cJSON_New_Item(&global_hooks);
1027  if (item == NULL) /* memory fail */
1028  {
1029  goto fail;
1030  }
1031 
1032  if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
1033  {
1034  /* parse failure. ep is set. */
1035  goto fail;
1036  }
1037 
1038  /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
1040  {
1041  buffer_skip_whitespace(&buffer);
1042  if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
1043  {
1044  goto fail;
1045  }
1046  }
1047  if (return_parse_end)
1048  {
1049  *return_parse_end = (const char*)buffer_at_offset(&buffer);
1050  }
1051 
1052  return item;
1053 
1054 fail:
1055  if (item != NULL)
1056  {
1057  cJSON_Delete(item);
1058  }
1059 
1060  if (value != NULL)
1061  {
1062  error local_error;
1063  local_error.json = (const unsigned char*)value;
1064  local_error.position = 0;
1065 
1066  if (buffer.offset < buffer.length)
1067  {
1068  local_error.position = buffer.offset;
1069  }
1070  else if (buffer.length > 0)
1071  {
1072  local_error.position = buffer.length - 1;
1073  }
1074 
1075  if (return_parse_end != NULL)
1076  {
1077  *return_parse_end = (const char*)local_error.json + local_error.position;
1078  }
1079 
1080  global_error = local_error;
1081  }
1082 
1083  return NULL;
1084 }
const char cJSON_bool require_null_terminated
Definition: switch_cJSON.h:143
const char ** return_parse_end
Definition: switch_cJSON.h:143
static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1211
internal_hooks hooks
Definition: cJSON.c:261
#define fail()
Definition: tone2wav.c:70
const char *const const char *const const cJSON *const value
static parse_buffer * skip_utf8_bom(parse_buffer *const buffer)
Definition: cJSON.c:991
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
Definition: cJSON.c:68
size_t length
Definition: cJSON.c:258
static error global_error
Definition: cJSON.c:72
static parse_buffer * buffer_skip_whitespace(parse_buffer *const buffer)
Definition: cJSON.c:970
static cJSON * cJSON_New_Item(const internal_hooks *const hooks)
Definition: cJSON.c:209
size_t position
Definition: cJSON.c:70
cJSON * item
Definition: switch_cJSON.h:210
char * buffer
Definition: switch_cJSON.h:153
const unsigned char * json
Definition: cJSON.c:69
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257
static internal_hooks global_hooks
Definition: cJSON.c:154

◆ CJSON_PUBLIC() [6/7]

CJSON_PUBLIC ( cJSON_bool  )

Definition at line 1191 of file cJSON.c.

References printbuffer::buffer, fmt, printbuffer::format, global_hooks, printbuffer::hooks, printbuffer::length, printbuffer::noalloc, printbuffer::offset, and print_value().

1192 {
1193  printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1194 
1195  if ((len < 0) || (buf == NULL))
1196  {
1197  return false;
1198  }
1199 
1200  p.buffer = (unsigned char*)buf;
1201  p.length = (size_t)len;
1202  p.offset = 0;
1203  p.noalloc = true;
1204  p.format = fmt;
1205  p.hooks = global_hooks;
1206 
1207  return print_value(item, &p);
1208 }
cJSON_bool format
Definition: cJSON.c:375
size_t offset
Definition: cJSON.c:372
unsigned char * buffer
Definition: cJSON.c:370
internal_hooks hooks
Definition: cJSON.c:376
int cJSON_bool fmt
Definition: switch_cJSON.h:150
switch_byte_t switch_byte_t * buf
size_t length
Definition: cJSON.c:371
cJSON_bool noalloc
Definition: cJSON.c:374
static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1266
cJSON * item
Definition: switch_cJSON.h:210
static internal_hooks global_hooks
Definition: cJSON.c:154

◆ CJSON_PUBLIC() [7/7]

CJSON_PUBLIC ( void *  )

Definition at line 2962 of file cJSON.c.

References internal_hooks::allocate(), and CJSON_PUBLIC().

2963 {
2964  return global_hooks.allocate(size);
2965 }
void *CJSON_CDECL * allocate(size_t size)
static internal_hooks global_hooks
Definition: cJSON.c:154

◆ cJSON_strdup()

static unsigned char* cJSON_strdup ( const unsigned char *  string,
const internal_hooks *const  hooks 
)
static

Definition at line 156 of file cJSON.c.

References internal_hooks::allocate(), and length.

Referenced by add_item_to_object(), and replace_item_in_object().

157 {
158  size_t length = 0;
159  unsigned char *copy = NULL;
160 
161  if (string == NULL)
162  {
163  return NULL;
164  }
165 
166  length = strlen((const char*)string) + sizeof("");
167  copy = (unsigned char*)hooks->allocate(length);
168  if (copy == NULL)
169  {
170  return NULL;
171  }
172  memcpy(copy, string, length);
173 
174  return copy;
175 }
void *CJSON_CDECL * allocate(size_t size)
char const int length
Definition: switch_cJSON.h:153

◆ create_reference()

static cJSON* create_reference ( const cJSON item,
const internal_hooks *const  hooks 
)
static

Definition at line 1826 of file cJSON.c.

References cJSON_IsReference, cJSON_New_Item(), cJSON::next, cJSON::prev, cJSON::string, and cJSON::type.

Referenced by add_item_to_object().

1827 {
1828  cJSON *reference = NULL;
1829  if (item == NULL)
1830  {
1831  return NULL;
1832  }
1833 
1834  reference = cJSON_New_Item(hooks);
1835  if (reference == NULL)
1836  {
1837  return NULL;
1838  }
1839 
1840  memcpy(reference, item, sizeof(cJSON));
1841  reference->string = NULL;
1842  reference->type |= cJSON_IsReference;
1843  reference->next = reference->prev = NULL;
1844  return reference;
1845 }
struct cJSON * prev
Definition: switch_cJSON.h:99
char * string
Definition: switch_cJSON.h:114
struct cJSON * next
Definition: switch_cJSON.h:98
static cJSON * cJSON_New_Item(const internal_hooks *const hooks)
Definition: cJSON.c:209
int type
Definition: switch_cJSON.h:104
#define cJSON_IsReference
Definition: switch_cJSON.h:91

◆ ensure()

static unsigned char* ensure ( printbuffer *const  p,
size_t  needed 
)
static

Definition at line 380 of file cJSON.c.

References internal_hooks::allocate(), printbuffer::buffer, printbuffer::hooks, length, printbuffer::length, printbuffer::noalloc, printbuffer::offset, and internal_hooks::reallocate().

Referenced by print_array(), print_number(), print_object(), print_string_ptr(), and print_value().

381 {
382  unsigned char *newbuffer = NULL;
383  size_t newsize = 0;
384 
385  if ((p == NULL) || (p->buffer == NULL))
386  {
387  return NULL;
388  }
389 
390  if ((p->length > 0) && (p->offset >= p->length))
391  {
392  /* make sure that offset is valid */
393  return NULL;
394  }
395 
396  if (needed > INT_MAX)
397  {
398  /* sizes bigger than INT_MAX are currently not supported */
399  return NULL;
400  }
401 
402  needed += p->offset + 1;
403  if (needed <= p->length)
404  {
405  return p->buffer + p->offset;
406  }
407 
408  if (p->noalloc) {
409  return NULL;
410  }
411 
412  /* calculate new buffer size */
413  if (needed > (INT_MAX / 2))
414  {
415  /* overflow of int, use INT_MAX if possible */
416  if (needed <= INT_MAX)
417  {
418  newsize = INT_MAX;
419  }
420  else
421  {
422  return NULL;
423  }
424  }
425  else
426  {
427  newsize = needed * 2;
428  }
429 
430  if (p->hooks.reallocate != NULL)
431  {
432  /* reallocate with realloc if available */
433  newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
434  if (newbuffer == NULL)
435  {
436  p->hooks.deallocate(p->buffer);
437  p->length = 0;
438  p->buffer = NULL;
439 
440  return NULL;
441  }
442  }
443  else
444  {
445  /* otherwise reallocate manually */
446  newbuffer = (unsigned char*)p->hooks.allocate(newsize);
447  if (!newbuffer)
448  {
449  p->hooks.deallocate(p->buffer);
450  p->length = 0;
451  p->buffer = NULL;
452 
453  return NULL;
454  }
455  if (newbuffer)
456  {
457  memcpy(newbuffer, p->buffer, p->offset + 1);
458  }
459  p->hooks.deallocate(p->buffer);
460  }
461  p->length = newsize;
462  p->buffer = newbuffer;
463 
464  return newbuffer + p->offset;
465 }
size_t offset
Definition: cJSON.c:372
void *CJSON_CDECL * allocate(size_t size)
void *CJSON_CDECL * reallocate(void *pointer, size_t size)
unsigned char * buffer
Definition: cJSON.c:370
internal_hooks hooks
Definition: cJSON.c:376
size_t length
Definition: cJSON.c:371
cJSON_bool noalloc
Definition: cJSON.c:374
char const int length
Definition: switch_cJSON.h:153

◆ get_array_item()

static cJSON* get_array_item ( const cJSON array,
size_t  index 
)
static

Definition at line 1742 of file cJSON.c.

References cJSON::child, CJSON_PUBLIC(), index, and cJSON::next.

Referenced by add_item_to_object().

1743 {
1744  cJSON *current_child = NULL;
1745 
1746  if (array == NULL)
1747  {
1748  return NULL;
1749  }
1750 
1751  current_child = array->child;
1752  while ((current_child != NULL) && (index > 0))
1753  {
1754  index--;
1755  current_child = current_child->next;
1756  }
1757 
1758  return current_child;
1759 }
struct cJSON * child
Definition: switch_cJSON.h:101
int index
Definition: switch_cJSON.h:160
struct cJSON * next
Definition: switch_cJSON.h:98

◆ get_decimal_point()

static unsigned char get_decimal_point ( void  )
static

Definition at line 245 of file cJSON.c.

Referenced by parse_number(), and print_number().

246 {
247 #ifdef ENABLE_LOCALES
248  struct lconv *lconv = localeconv();
249  return (unsigned char) lconv->decimal_point[0];
250 #else
251  return '.';
252 #endif
253 }

◆ get_object_item()

static cJSON* get_object_item ( const cJSON *const  object,
const char *const  name,
const cJSON_bool  case_sensitive 
)
static

Definition at line 1771 of file cJSON.c.

References case_insensitive_strcmp(), cJSON::child, CJSON_PUBLIC(), cJSON::next, and cJSON::string.

Referenced by minify_string(), and replace_item_in_object().

1772 {
1773  cJSON *current_element = NULL;
1774 
1775  if ((object == NULL) || (name == NULL))
1776  {
1777  return NULL;
1778  }
1779 
1780  current_element = object->child;
1781  if (case_sensitive)
1782  {
1783  while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
1784  {
1785  current_element = current_element->next;
1786  }
1787  }
1788  else
1789  {
1790  while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
1791  {
1792  current_element = current_element->next;
1793  }
1794  }
1795 
1796  if ((current_element == NULL) || (current_element->string == NULL)) {
1797  return NULL;
1798  }
1799 
1800  return current_element;
1801 }
static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
Definition: cJSON.c:101
struct cJSON * child
Definition: switch_cJSON.h:101
char * string
Definition: switch_cJSON.h:114
struct cJSON * next
Definition: switch_cJSON.h:98
const cJSON *const const cJSON_bool case_sensitive
Definition: switch_cJSON.h:243
const char *const name
Definition: switch_cJSON.h:250

◆ minify_string()

static void minify_string ( char **  input,
char **  output 
)
static

Definition at line 2667 of file cJSON.c.

References b, case_sensitive, cJSON::child, cJSON_Array, cJSON_ArrayForEach, cJSON_False, cJSON_Invalid, cJSON_NULL, cJSON_Number, cJSON_Object, CJSON_PUBLIC(), cJSON_Raw, cJSON_String, cJSON_True, get_object_item(), cJSON::next, skip_multiline_comment(), skip_oneline_comment(), static_strlen, cJSON::string, cJSON::type, cJSON::valuedouble, cJSON::valuestring, and internal_hooks::void().

2667  {
2668  (*output)[0] = (*input)[0];
2669  *input += static_strlen("\"");
2670  *output += static_strlen("\"");
2671 
2672 
2673  for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
2674  (*output)[0] = (*input)[0];
2675 
2676  if ((*input)[0] == '\"') {
2677  (*output)[0] = '\"';
2678  *input += static_strlen("\"");
2679  *output += static_strlen("\"");
2680  return;
2681  } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
2682  (*output)[1] = (*input)[1];
2683  *input += static_strlen("\"");
2684  *output += static_strlen("\"");
2685  }
2686  }
2687 }
#define static_strlen(string_literal)
Definition: cJSON.c:152

◆ parse_array()

static cJSON_bool parse_array ( cJSON *const  item,
parse_buffer *const  input_buffer 
)
static

Definition at line 1340 of file cJSON.c.

References buffer_at_offset, buffer_skip_whitespace(), can_access_at_index, cannot_access_at_index, cJSON::child, cJSON_Array, CJSON_NESTING_LIMIT, cJSON_New_Item(), parse_buffer::depth, fail, parse_buffer::hooks, cJSON::next, parse_buffer::offset, parse_value(), cJSON::prev, and cJSON::type.

Referenced by parse_value(), and print_string().

1341 {
1342  cJSON *head = NULL; /* head of the linked list */
1343  cJSON *current_item = NULL;
1344 
1345  if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1346  {
1347  return false; /* to deeply nested */
1348  }
1349  input_buffer->depth++;
1350 
1351  if (buffer_at_offset(input_buffer)[0] != '[')
1352  {
1353  /* not an array */
1354  goto fail;
1355  }
1356 
1357  input_buffer->offset++;
1358  buffer_skip_whitespace(input_buffer);
1359  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
1360  {
1361  /* empty array */
1362  goto success;
1363  }
1364 
1365  /* check if we skipped to the end of the buffer */
1366  if (cannot_access_at_index(input_buffer, 0))
1367  {
1368  input_buffer->offset--;
1369  goto fail;
1370  }
1371 
1372  /* step back to character in front of the first element */
1373  input_buffer->offset--;
1374  /* loop through the comma separated array elements */
1375  do
1376  {
1377  /* allocate next item */
1378  cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1379  if (new_item == NULL)
1380  {
1381  goto fail; /* allocation failure */
1382  }
1383 
1384  /* attach next item to list */
1385  if (head == NULL)
1386  {
1387  /* start the linked list */
1388  current_item = head = new_item;
1389  }
1390  else
1391  {
1392  /* add to the end and advance */
1393  current_item->next = new_item;
1394  new_item->prev = current_item;
1395  current_item = new_item;
1396  }
1397 
1398  /* parse next value */
1399  input_buffer->offset++;
1400  buffer_skip_whitespace(input_buffer);
1401  if (!parse_value(current_item, input_buffer))
1402  {
1403  goto fail; /* failed to parse value */
1404  }
1405  buffer_skip_whitespace(input_buffer);
1406  }
1407  while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1408 
1409  if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
1410  {
1411  goto fail; /* expected end of array */
1412  }
1413 
1414 success:
1415  input_buffer->depth--;
1416 
1417  item->type = cJSON_Array;
1418  item->child = head;
1419 
1420  input_buffer->offset++;
1421 
1422  return true;
1423 
1424 fail:
1425  if (head != NULL)
1426  {
1427  cJSON_Delete(head);
1428  }
1429 
1430  return false;
1431 }
#define CJSON_NESTING_LIMIT
Definition: switch_cJSON.h:129
static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1211
internal_hooks hooks
Definition: cJSON.c:261
#define fail()
Definition: tone2wav.c:70
struct cJSON * prev
Definition: switch_cJSON.h:99
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define cJSON_Array
Definition: switch_cJSON.h:87
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
struct cJSON * child
Definition: switch_cJSON.h:101
#define cannot_access_at_index(buffer, index)
Definition: cJSON.c:268
struct cJSON * next
Definition: switch_cJSON.h:98
static parse_buffer * buffer_skip_whitespace(parse_buffer *const buffer)
Definition: cJSON.c:970
static cJSON * cJSON_New_Item(const internal_hooks *const hooks)
Definition: cJSON.c:209
int type
Definition: switch_cJSON.h:104
size_t offset
Definition: cJSON.c:259
size_t depth
Definition: cJSON.c:260

◆ parse_hex4()

static unsigned parse_hex4 ( const unsigned char *const  input)
static

Definition at line 547 of file cJSON.c.

Referenced by utf16_literal_to_utf8().

548 {
549  unsigned int h = 0;
550  size_t i = 0;
551 
552  for (i = 0; i < 4; i++)
553  {
554  /* parse digit */
555  if ((input[i] >= '0') && (input[i] <= '9'))
556  {
557  h += (unsigned int) input[i] - '0';
558  }
559  else if ((input[i] >= 'A') && (input[i] <= 'F'))
560  {
561  h += (unsigned int) 10 + input[i] - 'A';
562  }
563  else if ((input[i] >= 'a') && (input[i] <= 'f'))
564  {
565  h += (unsigned int) 10 + input[i] - 'a';
566  }
567  else /* invalid */
568  {
569  return 0;
570  }
571 
572  if (i < 3)
573  {
574  /* shift left to make place for the next nibble */
575  h = h << 4;
576  }
577  }
578 
579  return h;
580 }

◆ parse_number()

static cJSON_bool parse_number ( cJSON *const  item,
parse_buffer *const  input_buffer 
)
static

Definition at line 273 of file cJSON.c.

References buffer_at_offset, can_access_at_index, cJSON_Number, parse_buffer::content, get_decimal_point(), number, parse_buffer::offset, cJSON::type, cJSON::valuedouble, and cJSON::valueint.

Referenced by parse_value().

274 {
275  double number = 0;
276  unsigned char *after_end = NULL;
277  unsigned char number_c_string[64];
278  unsigned char decimal_point = get_decimal_point();
279  size_t i = 0;
280 
281  if ((input_buffer == NULL) || (input_buffer->content == NULL))
282  {
283  return false;
284  }
285 
286  /* copy the number into a temporary buffer and replace '.' with the decimal point
287  * of the current locale (for strtod)
288  * This also takes care of '\0' not necessarily being available for marking the end of the input */
289  for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
290  {
291  switch (buffer_at_offset(input_buffer)[i])
292  {
293  case '0':
294  case '1':
295  case '2':
296  case '3':
297  case '4':
298  case '5':
299  case '6':
300  case '7':
301  case '8':
302  case '9':
303  case '+':
304  case '-':
305  case 'e':
306  case 'E':
307  number_c_string[i] = buffer_at_offset(input_buffer)[i];
308  break;
309 
310  case '.':
311  number_c_string[i] = decimal_point;
312  break;
313 
314  default:
315  goto loop_end;
316  }
317  }
318 loop_end:
319  number_c_string[i] = '\0';
320 
321  number = strtod((const char*)number_c_string, (char**)&after_end);
322  if (number_c_string == after_end)
323  {
324  return false; /* parse_error */
325  }
326 
327  item->valuedouble = number;
328 
329  /* use saturation in case of overflow */
330  if (number >= INT_MAX)
331  {
332  item->valueint = INT_MAX;
333  }
334  else if (number <= (double)INT_MIN)
335  {
336  item->valueint = INT_MIN;
337  }
338  else
339  {
340  item->valueint = (int)number;
341  }
342 
343  item->type = cJSON_Number;
344 
345  input_buffer->offset += (size_t)(after_end - number_c_string);
346  return true;
347 }
const char *const const double number
Definition: switch_cJSON.h:254
int valueint
Definition: switch_cJSON.h:109
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
static unsigned char get_decimal_point(void)
Definition: cJSON.c:245
int type
Definition: switch_cJSON.h:104
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257
double valuedouble
Definition: switch_cJSON.h:111
#define cJSON_Number
Definition: switch_cJSON.h:85

◆ parse_object()

static cJSON_bool parse_object ( cJSON *const  item,
parse_buffer *const  input_buffer 
)
static

Definition at line 1496 of file cJSON.c.

References buffer_at_offset, buffer_skip_whitespace(), can_access_at_index, cannot_access_at_index, cJSON::child, CJSON_NESTING_LIMIT, cJSON_New_Item(), cJSON_Object, parse_buffer::depth, fail, parse_buffer::hooks, cJSON::next, parse_buffer::offset, parse_string(), parse_value(), cJSON::prev, cJSON::string, cJSON::type, and cJSON::valuestring.

Referenced by parse_value(), and print_string().

1497 {
1498  cJSON *head = NULL; /* linked list head */
1499  cJSON *current_item = NULL;
1500 
1501  if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1502  {
1503  return false; /* to deeply nested */
1504  }
1505  input_buffer->depth++;
1506 
1507  if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
1508  {
1509  goto fail; /* not an object */
1510  }
1511 
1512  input_buffer->offset++;
1513  buffer_skip_whitespace(input_buffer);
1514  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
1515  {
1516  goto success; /* empty object */
1517  }
1518 
1519  /* check if we skipped to the end of the buffer */
1520  if (cannot_access_at_index(input_buffer, 0))
1521  {
1522  input_buffer->offset--;
1523  goto fail;
1524  }
1525 
1526  /* step back to character in front of the first element */
1527  input_buffer->offset--;
1528  /* loop through the comma separated array elements */
1529  do
1530  {
1531  /* allocate next item */
1532  cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1533  if (new_item == NULL)
1534  {
1535  goto fail; /* allocation failure */
1536  }
1537 
1538  /* attach next item to list */
1539  if (head == NULL)
1540  {
1541  /* start the linked list */
1542  current_item = head = new_item;
1543  }
1544  else
1545  {
1546  /* add to the end and advance */
1547  current_item->next = new_item;
1548  new_item->prev = current_item;
1549  current_item = new_item;
1550  }
1551 
1552  /* parse the name of the child */
1553  input_buffer->offset++;
1554  buffer_skip_whitespace(input_buffer);
1555  if (!parse_string(current_item, input_buffer))
1556  {
1557  goto fail; /* failed to parse name */
1558  }
1559  buffer_skip_whitespace(input_buffer);
1560 
1561  /* swap valuestring and string, because we parsed the name */
1562  current_item->string = current_item->valuestring;
1563  current_item->valuestring = NULL;
1564 
1565  if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
1566  {
1567  goto fail; /* invalid object */
1568  }
1569 
1570  /* parse the value */
1571  input_buffer->offset++;
1572  buffer_skip_whitespace(input_buffer);
1573  if (!parse_value(current_item, input_buffer))
1574  {
1575  goto fail; /* failed to parse value */
1576  }
1577  buffer_skip_whitespace(input_buffer);
1578  }
1579  while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1580 
1581  if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
1582  {
1583  goto fail; /* expected end of object */
1584  }
1585 
1586 success:
1587  input_buffer->depth--;
1588 
1589  item->type = cJSON_Object;
1590  item->child = head;
1591 
1592  input_buffer->offset++;
1593  return true;
1594 
1595 fail:
1596  if (head != NULL)
1597  {
1598  cJSON_Delete(head);
1599  }
1600 
1601  return false;
1602 }
#define CJSON_NESTING_LIMIT
Definition: switch_cJSON.h:129
#define cJSON_Object
Definition: switch_cJSON.h:88
static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1211
internal_hooks hooks
Definition: cJSON.c:261
#define fail()
Definition: tone2wav.c:70
char * valuestring
Definition: switch_cJSON.h:107
struct cJSON * prev
Definition: switch_cJSON.h:99
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
struct cJSON * child
Definition: switch_cJSON.h:101
char * string
Definition: switch_cJSON.h:114
#define cannot_access_at_index(buffer, index)
Definition: cJSON.c:268
struct cJSON * next
Definition: switch_cJSON.h:98
static parse_buffer * buffer_skip_whitespace(parse_buffer *const buffer)
Definition: cJSON.c:970
static cJSON * cJSON_New_Item(const internal_hooks *const hooks)
Definition: cJSON.c:209
static cJSON_bool parse_string(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:705
int type
Definition: switch_cJSON.h:104
size_t offset
Definition: cJSON.c:259
size_t depth
Definition: cJSON.c:260

◆ parse_string()

static cJSON_bool parse_string ( cJSON *const  item,
parse_buffer *const  input_buffer 
)
static

Definition at line 705 of file cJSON.c.

References internal_hooks::allocate(), buffer_at_offset, cJSON_String, parse_buffer::content, fail, parse_buffer::hooks, parse_buffer::length, parse_buffer::offset, cJSON::type, utf16_literal_to_utf8(), and cJSON::valuestring.

Referenced by parse_object(), and parse_value().

706 {
707  const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
708  const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
709  unsigned char *output_pointer = NULL;
710  unsigned char *output = NULL;
711 
712  /* not a string */
713  if (buffer_at_offset(input_buffer)[0] != '\"')
714  {
715  goto fail;
716  }
717 
718  {
719  /* calculate approximate size of the output (overestimate) */
720  size_t allocation_length = 0;
721  size_t skipped_bytes = 0;
722  while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
723  {
724  /* is escape sequence */
725  if (input_end[0] == '\\')
726  {
727  if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
728  {
729  /* prevent buffer overflow when last input character is a backslash */
730  goto fail;
731  }
732  skipped_bytes++;
733  input_end++;
734  }
735  input_end++;
736  }
737  if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
738  {
739  goto fail; /* string ended unexpectedly */
740  }
741 
742  /* This is at most how much we need for the output */
743  allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
744  output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
745  if (output == NULL)
746  {
747  goto fail; /* allocation failure */
748  }
749  }
750 
751  output_pointer = output;
752  /* loop through the string literal */
753  while (input_pointer < input_end)
754  {
755  if (*input_pointer != '\\')
756  {
757  *output_pointer++ = *input_pointer++;
758  }
759  /* escape sequence */
760  else
761  {
762  unsigned char sequence_length = 2;
763  if ((input_end - input_pointer) < 1)
764  {
765  goto fail;
766  }
767 
768  switch (input_pointer[1])
769  {
770  case 'b':
771  *output_pointer++ = '\b';
772  break;
773  case 'f':
774  *output_pointer++ = '\f';
775  break;
776  case 'n':
777  *output_pointer++ = '\n';
778  break;
779  case 'r':
780  *output_pointer++ = '\r';
781  break;
782  case 't':
783  *output_pointer++ = '\t';
784  break;
785  case '\"':
786  case '\\':
787  case '/':
788  *output_pointer++ = input_pointer[1];
789  break;
790 
791  /* UTF-16 literal */
792  case 'u':
793  sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
794  if (sequence_length == 0)
795  {
796  /* failed to convert UTF16-literal to UTF-8 */
797  goto fail;
798  }
799  break;
800 
801  default:
802  goto fail;
803  }
804  input_pointer += sequence_length;
805  }
806  }
807 
808  /* zero terminate the output */
809  *output_pointer = '\0';
810 
811  item->type = cJSON_String;
812  item->valuestring = (char*)output;
813 
814  input_buffer->offset = (size_t) (input_end - input_buffer->content);
815  input_buffer->offset++;
816 
817  return true;
818 
819 fail:
820  if (output != NULL)
821  {
822  input_buffer->hooks.deallocate(output);
823  }
824 
825  if (input_pointer != NULL)
826  {
827  input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
828  }
829 
830  return false;
831 }
void *CJSON_CDECL * allocate(size_t size)
internal_hooks hooks
Definition: cJSON.c:261
#define fail()
Definition: tone2wav.c:70
char * valuestring
Definition: switch_cJSON.h:107
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define cJSON_String
Definition: switch_cJSON.h:86
size_t length
Definition: cJSON.c:258
static unsigned char utf16_literal_to_utf8(const unsigned char *const input_pointer, const unsigned char *const input_end, unsigned char **output_pointer)
Definition: cJSON.c:584
int type
Definition: switch_cJSON.h:104
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257

◆ parse_value()

static cJSON_bool parse_value ( cJSON *const  item,
parse_buffer *const  input_buffer 
)
static

Definition at line 1211 of file cJSON.c.

References buffer_at_offset, can_access_at_index, can_read, cJSON_False, cJSON_NULL, cJSON_True, parse_buffer::content, parse_buffer::offset, parse_array(), parse_number(), parse_object(), parse_string(), cJSON::type, and cJSON::valueint.

Referenced by CJSON_PUBLIC(), parse_array(), parse_object(), and print_string().

1212 {
1213  if ((input_buffer == NULL) || (input_buffer->content == NULL))
1214  {
1215  return false; /* no input */
1216  }
1217 
1218  /* parse the different types of values */
1219  /* null */
1220  if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
1221  {
1222  item->type = cJSON_NULL;
1223  input_buffer->offset += 4;
1224  return true;
1225  }
1226  /* false */
1227  if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
1228  {
1229  item->type = cJSON_False;
1230  input_buffer->offset += 5;
1231  return true;
1232  }
1233  /* true */
1234  if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
1235  {
1236  item->type = cJSON_True;
1237  item->valueint = 1;
1238  input_buffer->offset += 4;
1239  return true;
1240  }
1241  /* string */
1242  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
1243  {
1244  return parse_string(item, input_buffer);
1245  }
1246  /* number */
1247  if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
1248  {
1249  return parse_number(item, input_buffer);
1250  }
1251  /* array */
1252  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
1253  {
1254  return parse_array(item, input_buffer);
1255  }
1256  /* object */
1257  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
1258  {
1259  return parse_object(item, input_buffer);
1260  }
1261 
1262  return false;
1263 }
#define cJSON_NULL
Definition: switch_cJSON.h:84
static cJSON_bool parse_object(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1496
int valueint
Definition: switch_cJSON.h:109
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
static cJSON_bool parse_number(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:273
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
#define cJSON_True
Definition: switch_cJSON.h:83
static cJSON_bool parse_string(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:705
#define can_read(buffer, size)
Definition: cJSON.c:265
static cJSON_bool parse_array(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1340
int type
Definition: switch_cJSON.h:104
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257
#define cJSON_False
Definition: switch_cJSON.h:82

◆ print()

static unsigned char* print ( const cJSON *const  item,
cJSON_bool  format,
const internal_hooks *const  hooks 
)
static

Definition at line 1094 of file cJSON.c.

References internal_hooks::allocate(), buffer, printbuffer::buffer, cjson_min, CJSON_PUBLIC(), fail, fmt, format, printbuffer::format, global_hooks, printbuffer::hooks, printbuffer::length, memset(), printbuffer::noalloc, printbuffer::offset, prebuffer, print_value(), internal_hooks::reallocate(), and update_offset().

1095 {
1096  static const size_t default_buffer_size = 256;
1097  printbuffer buffer[1];
1098  unsigned char *printed = NULL;
1099 
1100  memset(buffer, 0, sizeof(buffer));
1101 
1102  /* create buffer */
1103  buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
1104  buffer->length = default_buffer_size;
1105  buffer->format = format;
1106  buffer->hooks = *hooks;
1107 
1108  if (buffer->buffer == NULL) {
1109  goto fail;
1110  }
1111 
1112  /* print the value */
1113  if (!print_value(item, buffer)) {
1114  goto fail;
1115  }
1116 
1117  update_offset(buffer);
1118 
1119  /* check if reallocate is available */
1120  if (hooks->reallocate != NULL) {
1121  printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
1122  if (printed == NULL) {
1123  goto fail;
1124  }
1125 
1126  buffer->buffer = NULL;
1127  } else { /* otherwise copy the JSON over to a new buffer */
1128  printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
1129  if (printed == NULL) {
1130  goto fail;
1131  }
1132 
1133  memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
1134  printed[buffer->offset] = '\0'; /* just to be sure */
1135 
1136  /* free the buffer */
1137  hooks->deallocate(buffer->buffer);
1138  }
1139 
1140  return printed;
1141 
1142 fail:
1143  if (buffer->buffer != NULL) {
1144  hooks->deallocate(buffer->buffer);
1145  }
1146 
1147  return NULL;
1148 }
cJSON_bool format
Definition: cJSON.c:375
size_t offset
Definition: cJSON.c:372
void *CJSON_CDECL * allocate(size_t size)
void *CJSON_CDECL * reallocate(void *pointer, size_t size)
#define cjson_min(a, b)
Definition: cJSON.c:1092
#define fail()
Definition: tone2wav.c:70
char const int const cJSON_bool format
Definition: switch_cJSON.h:153
unsigned char * buffer
Definition: cJSON.c:370
internal_hooks hooks
Definition: cJSON.c:376
size_t length
Definition: cJSON.c:371
static void update_offset(printbuffer *const buffer)
Definition: cJSON.c:468
static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1266
char * buffer
Definition: switch_cJSON.h:153
memset(buf, 0, buflen)

◆ print_array()

static cJSON_bool print_array ( const cJSON *const  item,
printbuffer *const  output_buffer 
)
static

Definition at line 1434 of file cJSON.c.

References cJSON::child, printbuffer::depth, ensure(), printbuffer::format, length, cJSON::next, printbuffer::offset, print_value(), and update_offset().

Referenced by print_string(), and print_value().

1435 {
1436  unsigned char *output_pointer = NULL;
1437  size_t length = 0;
1438  cJSON *current_element = item->child;
1439 
1440  if (output_buffer == NULL)
1441  {
1442  return false;
1443  }
1444 
1445  /* Compose the output array. */
1446  /* opening square bracket */
1447  output_pointer = ensure(output_buffer, 1);
1448  if (output_pointer == NULL)
1449  {
1450  return false;
1451  }
1452 
1453  *output_pointer = '[';
1454  output_buffer->offset++;
1455  output_buffer->depth++;
1456 
1457  while (current_element != NULL)
1458  {
1459  if (!print_value(current_element, output_buffer))
1460  {
1461  return false;
1462  }
1463  update_offset(output_buffer);
1464  if (current_element->next)
1465  {
1466  length = (size_t) (output_buffer->format ? 2 : 1);
1467  output_pointer = ensure(output_buffer, length + 1);
1468  if (output_pointer == NULL)
1469  {
1470  return false;
1471  }
1472  *output_pointer++ = ',';
1473  if(output_buffer->format)
1474  {
1475  *output_pointer++ = ' ';
1476  }
1477  *output_pointer = '\0';
1478  output_buffer->offset += length;
1479  }
1480  current_element = current_element->next;
1481  }
1482 
1483  output_pointer = ensure(output_buffer, 2);
1484  if (output_pointer == NULL)
1485  {
1486  return false;
1487  }
1488  *output_pointer++ = ']';
1489  *output_pointer = '\0';
1490  output_buffer->depth--;
1491 
1492  return true;
1493 }
cJSON_bool format
Definition: cJSON.c:375
size_t offset
Definition: cJSON.c:372
size_t depth
Definition: cJSON.c:373
struct cJSON * child
Definition: switch_cJSON.h:101
struct cJSON * next
Definition: switch_cJSON.h:98
static unsigned char * ensure(printbuffer *const p, size_t needed)
Definition: cJSON.c:380
char const int length
Definition: switch_cJSON.h:153
static void update_offset(printbuffer *const buffer)
Definition: cJSON.c:468
static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1266

◆ print_number()

static cJSON_bool print_number ( const cJSON *const  item,
printbuffer *const  output_buffer 
)
static

Definition at line 481 of file cJSON.c.

References ensure(), get_decimal_point(), length, printbuffer::offset, and cJSON::valuedouble.

Referenced by print_value().

482 {
483  unsigned char *output_pointer = NULL;
484  double d = item->valuedouble;
485  int length = 0;
486  size_t i = 0;
487  unsigned char number_buffer[26]; /* temporary buffer to print the number into */
488  unsigned char decimal_point = get_decimal_point();
489  double test;
490 
491  if (output_buffer == NULL)
492  {
493  return false;
494  }
495 
496  /* This checks for NaN and Infinity */
497  if ((d * 0) != 0)
498  {
499  length = sprintf((char*)number_buffer, "null");
500  }
501  else
502  {
503  /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
504  length = sprintf((char*)number_buffer, "%1.15g", d);
505 
506  /* Check whether the original double can be recovered */
507  if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
508  {
509  /* If not, print with 17 decimal places of precision */
510  length = sprintf((char*)number_buffer, "%1.17g", d);
511  }
512  }
513 
514  /* sprintf failed or buffer overrun occurred */
515  if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
516  {
517  return false;
518  }
519 
520  /* reserve appropriate space in the output */
521  output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
522  if (output_pointer == NULL)
523  {
524  return false;
525  }
526 
527  /* copy the printed number to the output and replace locale
528  * dependent decimal point with '.' */
529  for (i = 0; i < ((size_t)length); i++)
530  {
531  if (number_buffer[i] == decimal_point)
532  {
533  output_pointer[i] = '.';
534  continue;
535  }
536 
537  output_pointer[i] = number_buffer[i];
538  }
539  output_pointer[i] = '\0';
540 
541  output_buffer->offset += (size_t)length;
542 
543  return true;
544 }
size_t offset
Definition: cJSON.c:372
static unsigned char get_decimal_point(void)
Definition: cJSON.c:245
static unsigned char * ensure(printbuffer *const p, size_t needed)
Definition: cJSON.c:380
char const int length
Definition: switch_cJSON.h:153
double valuedouble
Definition: switch_cJSON.h:111

◆ print_object()

static cJSON_bool print_object ( const cJSON *const  item,
printbuffer *const  output_buffer 
)
static

Definition at line 1605 of file cJSON.c.

References cJSON::child, CJSON_PUBLIC(), printbuffer::depth, ensure(), printbuffer::format, length, cJSON::next, printbuffer::offset, print_string_ptr(), print_value(), cJSON::string, and update_offset().

Referenced by print_string(), and print_value().

1606 {
1607  unsigned char *output_pointer = NULL;
1608  size_t length = 0;
1609  cJSON *current_item = item->child;
1610 
1611  if (output_buffer == NULL)
1612  {
1613  return false;
1614  }
1615 
1616  /* Compose the output: */
1617  length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
1618  output_pointer = ensure(output_buffer, length + 1);
1619  if (output_pointer == NULL)
1620  {
1621  return false;
1622  }
1623 
1624  *output_pointer++ = '{';
1625  output_buffer->depth++;
1626  if (output_buffer->format)
1627  {
1628  *output_pointer++ = '\n';
1629  }
1630  output_buffer->offset += length;
1631 
1632  while (current_item)
1633  {
1634  if (output_buffer->format)
1635  {
1636  size_t i;
1637  output_pointer = ensure(output_buffer, output_buffer->depth);
1638  if (output_pointer == NULL)
1639  {
1640  return false;
1641  }
1642  for (i = 0; i < output_buffer->depth; i++)
1643  {
1644  *output_pointer++ = '\t';
1645  }
1646  output_buffer->offset += output_buffer->depth;
1647  }
1648 
1649  /* print key */
1650  if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
1651  {
1652  return false;
1653  }
1654  update_offset(output_buffer);
1655 
1656  length = (size_t) (output_buffer->format ? 2 : 1);
1657  output_pointer = ensure(output_buffer, length);
1658  if (output_pointer == NULL)
1659  {
1660  return false;
1661  }
1662  *output_pointer++ = ':';
1663  if (output_buffer->format)
1664  {
1665  *output_pointer++ = '\t';
1666  }
1667  output_buffer->offset += length;
1668 
1669  /* print value */
1670  if (!print_value(current_item, output_buffer))
1671  {
1672  return false;
1673  }
1674  update_offset(output_buffer);
1675 
1676  /* print comma if not last */
1677  length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
1678  output_pointer = ensure(output_buffer, length + 1);
1679  if (output_pointer == NULL)
1680  {
1681  return false;
1682  }
1683  if (current_item->next)
1684  {
1685  *output_pointer++ = ',';
1686  }
1687 
1688  if (output_buffer->format)
1689  {
1690  *output_pointer++ = '\n';
1691  }
1692  *output_pointer = '\0';
1693  output_buffer->offset += length;
1694 
1695  current_item = current_item->next;
1696  }
1697 
1698  output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
1699  if (output_pointer == NULL)
1700  {
1701  return false;
1702  }
1703  if (output_buffer->format)
1704  {
1705  size_t i;
1706  for (i = 0; i < (output_buffer->depth - 1); i++)
1707  {
1708  *output_pointer++ = '\t';
1709  }
1710  }
1711  *output_pointer++ = '}';
1712  *output_pointer = '\0';
1713  output_buffer->depth--;
1714 
1715  return true;
1716 }
cJSON_bool format
Definition: cJSON.c:375
size_t offset
Definition: cJSON.c:372
static cJSON_bool print_string_ptr(const unsigned char *const input, printbuffer *const output_buffer)
Definition: cJSON.c:834
size_t depth
Definition: cJSON.c:373
struct cJSON * child
Definition: switch_cJSON.h:101
char * string
Definition: switch_cJSON.h:114
struct cJSON * next
Definition: switch_cJSON.h:98
static unsigned char * ensure(printbuffer *const p, size_t needed)
Definition: cJSON.c:380
char const int length
Definition: switch_cJSON.h:153
static void update_offset(printbuffer *const buffer)
Definition: cJSON.c:468
static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1266

◆ print_string()

static cJSON_bool print_string ( const cJSON *const  item,
printbuffer *const  p 
)
static

Definition at line 956 of file cJSON.c.

References parse_array(), parse_object(), parse_value(), print_array(), print_object(), print_string_ptr(), print_value(), and cJSON::valuestring.

Referenced by print_value().

957 {
958  return print_string_ptr((unsigned char*)item->valuestring, p);
959 }
char * valuestring
Definition: switch_cJSON.h:107
static cJSON_bool print_string_ptr(const unsigned char *const input, printbuffer *const output_buffer)
Definition: cJSON.c:834

◆ print_string_ptr()

static cJSON_bool print_string_ptr ( const unsigned char *const  input,
printbuffer *const  output_buffer 
)
static

Definition at line 834 of file cJSON.c.

References ensure(), and internal_hooks::void().

Referenced by print_object(), and print_string().

835 {
836  const unsigned char *input_pointer = NULL;
837  unsigned char *output = NULL;
838  unsigned char *output_pointer = NULL;
839  size_t output_length = 0;
840  /* numbers of additional characters needed for escaping */
841  size_t escape_characters = 0;
842 
843  if (output_buffer == NULL)
844  {
845  return false;
846  }
847 
848  /* empty string */
849  if (input == NULL)
850  {
851  output = ensure(output_buffer, sizeof("\"\""));
852  if (output == NULL)
853  {
854  return false;
855  }
856  strcpy((char*)output, "\"\"");
857 
858  return true;
859  }
860 
861  /* set "flag" to 1 if something needs to be escaped */
862  for (input_pointer = input; *input_pointer; input_pointer++)
863  {
864  switch (*input_pointer)
865  {
866  case '\"':
867  case '\\':
868  case '\b':
869  case '\f':
870  case '\n':
871  case '\r':
872  case '\t':
873  /* one character escape sequence */
874  escape_characters++;
875  break;
876  default:
877  if (*input_pointer < 32)
878  {
879  /* UTF-16 escape sequence uXXXX */
880  escape_characters += 5;
881  }
882  break;
883  }
884  }
885  output_length = (size_t)(input_pointer - input) + escape_characters;
886 
887  output = ensure(output_buffer, output_length + sizeof("\"\""));
888  if (output == NULL)
889  {
890  return false;
891  }
892 
893  /* no characters have to be escaped */
894  if (escape_characters == 0)
895  {
896  output[0] = '\"';
897  memcpy(output + 1, input, output_length);
898  output[output_length + 1] = '\"';
899  output[output_length + 2] = '\0';
900 
901  return true;
902  }
903 
904  output[0] = '\"';
905  output_pointer = output + 1;
906  /* copy the string */
907  for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
908  {
909  if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
910  {
911  /* normal character, copy */
912  *output_pointer = *input_pointer;
913  }
914  else
915  {
916  /* character needs to be escaped */
917  *output_pointer++ = '\\';
918  switch (*input_pointer)
919  {
920  case '\\':
921  *output_pointer = '\\';
922  break;
923  case '\"':
924  *output_pointer = '\"';
925  break;
926  case '\b':
927  *output_pointer = 'b';
928  break;
929  case '\f':
930  *output_pointer = 'f';
931  break;
932  case '\n':
933  *output_pointer = 'n';
934  break;
935  case '\r':
936  *output_pointer = 'r';
937  break;
938  case '\t':
939  *output_pointer = 't';
940  break;
941  default:
942  /* escape and print as unicode codepoint */
943  sprintf((char*)output_pointer, "u%04x", *input_pointer);
944  output_pointer += 4;
945  break;
946  }
947  }
948  }
949  output[output_length + 1] = '\"';
950  output[output_length + 2] = '\0';
951 
952  return true;
953 }
static unsigned char * ensure(printbuffer *const p, size_t needed)
Definition: cJSON.c:380

◆ print_value()

static cJSON_bool print_value ( const cJSON *const  item,
printbuffer *const  output_buffer 
)
static

Definition at line 1266 of file cJSON.c.

References cJSON_Array, cJSON_False, cJSON_NULL, cJSON_Number, cJSON_Object, cJSON_Raw, cJSON_String, cJSON_True, ensure(), print_array(), print_number(), print_object(), print_string(), cJSON::type, and cJSON::valuestring.

Referenced by CJSON_PUBLIC(), print(), print_array(), print_object(), and print_string().

1267 {
1268  unsigned char *output = NULL;
1269 
1270  if ((item == NULL) || (output_buffer == NULL))
1271  {
1272  return false;
1273  }
1274 
1275  switch ((item->type) & 0xFF)
1276  {
1277  case cJSON_NULL:
1278  output = ensure(output_buffer, 5);
1279  if (output == NULL)
1280  {
1281  return false;
1282  }
1283  strcpy((char*)output, "null");
1284  return true;
1285 
1286  case cJSON_False:
1287  output = ensure(output_buffer, 6);
1288  if (output == NULL)
1289  {
1290  return false;
1291  }
1292  strcpy((char*)output, "false");
1293  return true;
1294 
1295  case cJSON_True:
1296  output = ensure(output_buffer, 5);
1297  if (output == NULL)
1298  {
1299  return false;
1300  }
1301  strcpy((char*)output, "true");
1302  return true;
1303 
1304  case cJSON_Number:
1305  return print_number(item, output_buffer);
1306 
1307  case cJSON_Raw:
1308  {
1309  size_t raw_length = 0;
1310  if (item->valuestring == NULL)
1311  {
1312  return false;
1313  }
1314 
1315  raw_length = strlen(item->valuestring) + sizeof("");
1316  output = ensure(output_buffer, raw_length);
1317  if (output == NULL)
1318  {
1319  return false;
1320  }
1321  memcpy(output, item->valuestring, raw_length);
1322  return true;
1323  }
1324 
1325  case cJSON_String:
1326  return print_string(item, output_buffer);
1327 
1328  case cJSON_Array:
1329  return print_array(item, output_buffer);
1330 
1331  case cJSON_Object:
1332  return print_object(item, output_buffer);
1333 
1334  default:
1335  return false;
1336  }
1337 }
#define cJSON_Object
Definition: switch_cJSON.h:88
#define cJSON_Raw
Definition: switch_cJSON.h:89
#define cJSON_NULL
Definition: switch_cJSON.h:84
char * valuestring
Definition: switch_cJSON.h:107
static cJSON_bool print_number(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:481
static cJSON_bool print_array(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1434
#define cJSON_Array
Definition: switch_cJSON.h:87
#define cJSON_String
Definition: switch_cJSON.h:86
#define cJSON_True
Definition: switch_cJSON.h:83
static unsigned char * ensure(printbuffer *const p, size_t needed)
Definition: cJSON.c:380
static cJSON_bool print_object(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1605
static cJSON_bool print_string(const cJSON *const item, printbuffer *const p)
Definition: cJSON.c:956
int type
Definition: switch_cJSON.h:104
#define cJSON_False
Definition: switch_cJSON.h:82
#define cJSON_Number
Definition: switch_cJSON.h:85

◆ replace_item_in_object()

static cJSON_bool replace_item_in_object ( cJSON object,
const char *  string,
cJSON replacement,
cJSON_bool  case_sensitive 
)
static

Definition at line 2226 of file cJSON.c.

References b, cast_away_const(), cJSON::child, cJSON_Array, cJSON_False, cJSON_IsReference, cJSON_New_Item(), cJSON_NULL, cJSON_Number, cJSON_Object, CJSON_PUBLIC(), cJSON_Raw, cJSON_strdup(), cJSON_String, cJSON_StringIsConst, cJSON_True, count, fail, get_object_item(), global_hooks, item, newitem, cJSON::next, cJSON::prev, raw, recurse, cJSON::string, string, suffix_object(), cJSON::type, cJSON::valuedouble, cJSON::valueint, and cJSON::valuestring.

2227 {
2228  if ((replacement == NULL) || (string == NULL))
2229  {
2230  return false;
2231  }
2232 
2233  /* replace the name in the replacement */
2234  if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
2235  {
2236  cJSON_free(replacement->string);
2237  }
2238  replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2239  replacement->type &= ~cJSON_StringIsConst;
2240 
2241  cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
2242 
2243  return true;
2244 }
static cJSON * get_object_item(const cJSON *const object, const char *const name, const cJSON_bool case_sensitive)
Definition: cJSON.c:1771
static unsigned char * cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
Definition: cJSON.c:156
char * string
Definition: switch_cJSON.h:114
const char *const string
Definition: switch_cJSON.h:162
const cJSON *const const cJSON_bool case_sensitive
Definition: switch_cJSON.h:243
#define cJSON_StringIsConst
Definition: switch_cJSON.h:92
int type
Definition: switch_cJSON.h:104
static internal_hooks global_hooks
Definition: cJSON.c:154

◆ skip_multiline_comment()

static void skip_multiline_comment ( char **  input)
static

Definition at line 2653 of file cJSON.c.

References static_strlen.

Referenced by minify_string().

2654 {
2655  *input += static_strlen("/*");
2656 
2657  for (; (*input)[0] != '\0'; ++(*input))
2658  {
2659  if (((*input)[0] == '*') && ((*input)[1] == '/'))
2660  {
2661  *input += static_strlen("*/");
2662  return;
2663  }
2664  }
2665 }
#define static_strlen(string_literal)
Definition: cJSON.c:152

◆ skip_oneline_comment()

static void skip_oneline_comment ( char **  input)
static

Definition at line 2640 of file cJSON.c.

References static_strlen.

Referenced by minify_string().

2641 {
2642  *input += static_strlen("//");
2643 
2644  for (; (*input)[0] != '\0'; ++(*input))
2645  {
2646  if ((*input)[0] == '\n') {
2647  *input += static_strlen("\n");
2648  return;
2649  }
2650  }
2651 }
#define static_strlen(string_literal)
Definition: cJSON.c:152

◆ skip_utf8_bom()

static parse_buffer* skip_utf8_bom ( parse_buffer *const  buffer)
static

Definition at line 991 of file cJSON.c.

References buffer, buffer_at_offset, can_access_at_index, parse_buffer::content, and parse_buffer::offset.

Referenced by CJSON_PUBLIC().

992 {
993  if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
994  {
995  return NULL;
996  }
997 
998  if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
999  {
1000  buffer->offset += 3;
1001  }
1002 
1003  return buffer;
1004 }
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
char * buffer
Definition: switch_cJSON.h:153
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257

◆ suffix_object()

static void suffix_object ( cJSON prev,
cJSON item 
)
static

Definition at line 1819 of file cJSON.c.

References item, cJSON::next, and cJSON::prev.

Referenced by add_item_to_array(), and replace_item_in_object().

1820 {
1821  prev->next = item;
1822  item->prev = prev;
1823 }
struct cJSON * prev
Definition: switch_cJSON.h:99
struct cJSON * next
Definition: switch_cJSON.h:98
cJSON * item
Definition: switch_cJSON.h:210

◆ update_offset()

static void update_offset ( printbuffer *const  buffer)
static

Definition at line 468 of file cJSON.c.

References printbuffer::buffer, and printbuffer::offset.

Referenced by print(), print_array(), and print_object().

469 {
470  const unsigned char *buffer_pointer = NULL;
471  if ((buffer == NULL) || (buffer->buffer == NULL))
472  {
473  return;
474  }
475  buffer_pointer = buffer->buffer + buffer->offset;
476 
477  buffer->offset += strlen((const char*)buffer_pointer);
478 }
size_t offset
Definition: cJSON.c:372
unsigned char * buffer
Definition: cJSON.c:370

◆ utf16_literal_to_utf8()

static unsigned char utf16_literal_to_utf8 ( const unsigned char *const  input_pointer,
const unsigned char *const  input_end,
unsigned char **  output_pointer 
)
static

Definition at line 584 of file cJSON.c.

References fail, and parse_hex4().

Referenced by parse_string().

585 {
586  long unsigned int codepoint = 0;
587  unsigned int first_code = 0;
588  const unsigned char *first_sequence = input_pointer;
589  unsigned char utf8_length = 0;
590  unsigned char utf8_position = 0;
591  unsigned char sequence_length = 0;
592  unsigned char first_byte_mark = 0;
593 
594  if ((input_end - first_sequence) < 6)
595  {
596  /* input ends unexpectedly */
597  goto fail;
598  }
599 
600  /* get the first utf16 sequence */
601  first_code = parse_hex4(first_sequence + 2);
602 
603  /* check that the code is valid */
604  if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
605  {
606  goto fail;
607  }
608 
609  /* UTF16 surrogate pair */
610  if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
611  {
612  const unsigned char *second_sequence = first_sequence + 6;
613  unsigned int second_code = 0;
614  sequence_length = 12; /* \uXXXX\uXXXX */
615 
616  if ((input_end - second_sequence) < 6)
617  {
618  /* input ends unexpectedly */
619  goto fail;
620  }
621 
622  if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
623  {
624  /* missing second half of the surrogate pair */
625  goto fail;
626  }
627 
628  /* get the second utf16 sequence */
629  second_code = parse_hex4(second_sequence + 2);
630  /* check that the code is valid */
631  if ((second_code < 0xDC00) || (second_code > 0xDFFF))
632  {
633  /* invalid second half of the surrogate pair */
634  goto fail;
635  }
636 
637 
638  /* calculate the unicode codepoint from the surrogate pair */
639  codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
640  }
641  else
642  {
643  sequence_length = 6; /* \uXXXX */
644  codepoint = first_code;
645  }
646 
647  /* encode as UTF-8
648  * takes at maximum 4 bytes to encode:
649  * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
650  if (codepoint < 0x80)
651  {
652  /* normal ascii, encoding 0xxxxxxx */
653  utf8_length = 1;
654  }
655  else if (codepoint < 0x800)
656  {
657  /* two bytes, encoding 110xxxxx 10xxxxxx */
658  utf8_length = 2;
659  first_byte_mark = 0xC0; /* 11000000 */
660  }
661  else if (codepoint < 0x10000)
662  {
663  /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
664  utf8_length = 3;
665  first_byte_mark = 0xE0; /* 11100000 */
666  }
667  else if (codepoint <= 0x10FFFF)
668  {
669  /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
670  utf8_length = 4;
671  first_byte_mark = 0xF0; /* 11110000 */
672  }
673  else
674  {
675  /* invalid unicode codepoint */
676  goto fail;
677  }
678 
679  /* encode as utf8 */
680  for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
681  {
682  /* 10xxxxxx */
683  (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
684  codepoint >>= 6;
685  }
686  /* encode first byte */
687  if (utf8_length > 1)
688  {
689  (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
690  }
691  else
692  {
693  (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
694  }
695 
696  *output_pointer += utf8_length;
697 
698  return sequence_length;
699 
700 fail:
701  return 0;
702 }
static unsigned parse_hex4(const unsigned char *const input)
Definition: cJSON.c:547
#define fail()
Definition: tone2wav.c:70

Variable Documentation

◆ global_error

error global_error = { NULL, 0 }
static

Definition at line 72 of file cJSON.c.

◆ global_hooks

Definition at line 154 of file cJSON.c.

Referenced by CJSON_PUBLIC(), print(), and replace_item_in_object().