/* Render an array to text */ static char *print_array(struct json *item, int depth, int fmt) { char **entries; char *out = 0, *ptr, *ret; int len = 5; struct json *child = item->child; int numentries = 0, i = 0, fail = 0; /* How many entries in the array? */ while (child) numentries++, child = child->next; /* Allocate an array to hold the values for each */ entries = (char **)json_malloc(numentries * sizeof(char *)); if (!entries) return 0; memset(entries, 0, numentries * sizeof(char *)); /* Retrieve all the results: */ child = item->child; while (child && !fail) { ret = print_value(child, depth + 1, fmt); entries[i++] = ret; if (ret) len += strlen(ret) + 2 + (fmt ? 1 : 0); else fail = 1; child = child->next; } /* If we didn't fail, try to malloc the output string */ if (!fail) out = (char *)json_malloc(len); /* If that fails, we fail. */ if (!out) fail = 1; /* Handle failure. */ if (fail) { json_free(entries); return 0; } /* Compose the output array. */ *out = '['; ptr = out + 1; *ptr = 0; for (i = 0; i < numentries; i++) { strcpy(ptr, entries[i]); ptr += strlen(entries[i]); if (i != numentries - 1) { *ptr++ = ','; if (fmt) *ptr++ = ' '; *ptr = 0; } } json_free(entries); *ptr++ = ']'; *ptr++ = 0; return out; }
/* Internal constructor. */ static struct json *json_new_item(void) { struct json *node = (struct json *) json_malloc(sizeof(struct json)); if (node) memset(node, 0, sizeof(*node)); return node; }
json_t * json_alloc(json_type objectType, size_t childrenCount) { json_t *newObject = (json_t*) json_malloc(sizeof(json_t)); if(!newObject) { return NULL; } newObject->type = objectType; if(newObject->type == JSON_OBJECT) { if(childrenCount % 2 != 0) { return NULL; /* object children count should be even */ } newObject->size = childrenCount/2; /* childrenCount = key value pairs. we need only keys count*/ } else { newObject->size = childrenCount; } newObject->children = NULL; newObject->next = NULL; newObject->last = NULL; newObject->value = NULL; return newObject; }
// Adapated from vsnprintf() char *json_strvprintf(const char *fmt, va_list ap_in) { int n, size = 64 /*guess*/; char *p, *np; va_list ap; assert(fmt != NULL); if ( !(p = json_malloc(size)) ) return NULL; while (true) { va_copy(ap, ap_in); n = vsnprintf(p, size, fmt, ap); va_end(ap); if (n > -1 && n < size) return p; if (n > -1) size = n + 1; else size *= 2; if ( (np = json_realloc(p, size)) == NULL ) { json_free(p); return NULL; } p = np; } }
char *json_make_indent_string(int level) { size_t n_chars = level * JSON_INDENT_WIDTH; char *out = json_malloc(n_chars + 1); if (n_chars > 0) memset(out, ' ', n_chars); out[n_chars] = '\0'; return out; }
static char *json_strdup(const char *str) { size_t len; char *copy; len = strlen(str) + 1; if (!(copy = (char *)json_malloc(len))) return 0; memcpy(copy, str, len); return copy; }
char *json_strndup(const char *other, size_t n) { char *buf; if (!other) return NULL; buf = json_malloc(n + 1); if (!buf) return NULL; memcpy(buf, other, n); buf[n] = '\0'; return buf; }
/* Render the number nicely from the given item into a string. */ static char *print_number(struct json *item) { char *str; double d = item->valuedouble; if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= LLONG_MAX && d >= LLONG_MIN) { str = (char *)json_malloc(21); /* 2^64+1 can be represented in 21 chars. */ if (str) sprintf(str, "%"PRId64, item->valueint); } else { str = (char *)json_malloc(64); /* This is a nice tradeoff. */ if (str) { if (fabs(floor(d) - d) <= DBL_EPSILON) sprintf(str, "%.0f", d); else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9) sprintf(str, "%e", d); else sprintf(str, "%f", d); } } return str; }
char *json_strdup(const char *other) { size_t len; char *buf; if (!other) return NULL; len = strlen(other); buf = json_malloc(len + 1); if (!buf) return NULL; memcpy(buf, other, len + 1); return buf; }
json_error_t* parsingError( json_error_code_t errCode, char* errMsg, jsmntok_t *token, char* jsonString ) { json_error_t* err = (json_error_t*) json_malloc(sizeof(json_error_t)); err->errorMsg = (strbuffer_t*) json_malloc(sizeof(json_error_t)); strbuffer_init(err->errorMsg); err->errorCode = errCode; strbuffer_append(err->errorMsg, errMsg); if( token != NULL && jsonString != NULL) { strbuffer_t *tokenText = json_token_tostr(jsonString, token); strbuffer_append(err->errorMsg, " Error was in: "); strbuffer_append(err->errorMsg, tokenText->value); strbuffer_destroy(tokenText); } return err; }
void *json_value_alloc(void *class_) { JSON_ValueClass *value_class = class_; JSON_Value *value; assert(value_class != NULL); value = json_malloc(value_class->size); if (value != NULL) { json_value_init(class_, value); value->flags |= JSON_VALUE_FLAG_ON_HEAP; } return value; }
inline int add_value_from_token(json_t *obj, char* jsonString, jsmntok_t* token) { if ((obj != NULL) && (jsonString != NULL) && (token != NULL)) { strbuffer_t *tokenStr = json_token_tostr(jsonString, token); obj->value = (char*) json_malloc((tokenStr->length+1) * sizeof(char)); memset(obj->value, 0, (tokenStr->length+1)); strncpy(obj->value, tokenStr->value, tokenStr->length); strbuffer_destroy(tokenStr); return 0; } return -1; }
strbuffer_t * json_token_tostr(char *js, jsmntok_t *t) { if(t->start > strlen(js) || t->end > strlen(js) || t->end > strlen(js) || (t->end - t->start) > strlen(js) ) { return NULL; } strbuffer_t *string = (strbuffer_t *) json_malloc(sizeof(strbuffer_t)); strbuffer_init(string); strbuffer_append_bytes(string, js + t->start, (t->end - t->start) ); return string; }
/* Render an object to text. */ static char *print_object(struct json *item, int depth, int fmt) { char **entries = 0, **names = 0; char *out = 0, *ptr, *ret, *str; int len = 7, i = 0, j; struct json *child = item->child; int numentries = 0, fail = 0; /* Count the number of entries. */ while (child) numentries++, child = child->next; /* Allocate space for the names and the objects */ entries = (char **)json_malloc(numentries * sizeof(char *)); if (!entries) return 0; names = (char **)json_malloc(numentries * sizeof(char *)); if (!names) { json_free(entries); return 0; } memset(entries, 0, sizeof(char *) * numentries); memset(names, 0, sizeof(char *) * numentries); /* Collect all the results into our arrays: */ child = item->child; depth++; if (fmt) len += depth; while (child) { names[i] = str = print_string_ptr(child->string); entries[i++] = ret = print_value(child, depth, fmt); if (str && ret) len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); else fail = 1; child = child->next; } /* Try to allocate the output string */ if (!fail) out = (char *)json_malloc(len); if (!out) fail = 1; /* Handle failure */ if (fail) { for (i = 0; i < numentries; i++) { if (names[i]) json_free(names[i]); } json_free(names); json_free(entries); return 0; } /* Compose the output: */ *out = '{'; ptr = out + 1; if (fmt) *ptr++ = '\n'; *ptr = 0; for (i = 0; i < numentries; i++) { if (fmt) for (j = 0; j < depth; j++) *ptr++ = '\t'; strcpy(ptr, names[i]); ptr += strlen(names[i]); *ptr++ = ':'; if (fmt) *ptr++ = '\t'; strcpy(ptr, entries[i]); ptr += strlen(entries[i]); if (i != numentries - 1) *ptr++ = ','; if (fmt) *ptr++ = '\n'; *ptr = 0; json_free(names[i]); } json_free(names); json_free(entries); if (fmt) for (i = 0; i < depth - 1; i++) *ptr++ = '\t'; *ptr++ = '}'; *ptr++ = 0; return out; }
/* Render the cstring provided to an escaped version that can be printed. */ static char *print_string_ptr(const char *str) { const char *ptr; char *ptr2, *out; int len = 0; unsigned char token; if (!str) return json_strdup(""); ptr = str; while ((token = *ptr) && ++len) { if (strchr("\"\\\b\f\n\r\t", token)) len++; else if (token < 32) len += 5; ptr++; } out = (char *)json_malloc(len + 3); if (!out) return 0; ptr2 = out; ptr = str; *ptr2++ = '\"'; while (*ptr) { if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\') *ptr2++ = *ptr++; else { *ptr2++ = '\\'; switch (token = *ptr++) { case '\\': *ptr2++ = '\\'; break; case '\"': *ptr2++ = '\"'; break; case '\b': *ptr2++ = 'b'; break; case '\f': *ptr2++ = 'f'; break; case '\n': *ptr2++ = 'n'; break; case '\r': *ptr2++ = 'r'; break; case '\t': *ptr2++ = 't'; break; default: sprintf(ptr2, "u%04x", token); ptr2 += 5; break; /* escape and print */ } } } *ptr2++ = '\"'; *ptr2++ = 0; return out; }