Datum postal_parse(PG_FUNCTION_ARGS) { text *address = PG_GETARG_TEXT_P(0); size_t i; libpostal_address_parser_options_t options = libpostal_get_address_parser_default_options(); libpostal_address_parser_response_t *parsed = libpostal_parse_address(text_to_cstring(address), options); StringInfoData strbuf; /* * There's no easy way to directly create a JSONB in the * PgSQL external API, so instead we (yuck) just build * a JSON string and then have PgSQL parse that. */ initStringInfo(&strbuf); appendStringInfoChar(&strbuf, '{'); for (i = 0; i < parsed->num_components; i++) { char *component; if (i > 0) { appendStringInfoChar(&strbuf, ','); } component = escape_json_string(parsed->components[i]); appendStringInfo(&strbuf, "\"%s\":\"%s\"", parsed->labels[i], component); pfree(component); } appendStringInfoChar(&strbuf, '}'); /* Clean up unmanaged memory */ libpostal_address_parser_response_destroy(parsed); /* Call JSONB parser */ PG_RETURN_DATUM(DirectFunctionCall1(jsonb_in, CStringGetDatum(strbuf.data))); }
static void XMLCALL endElement(void *userData, const char *name) { struct req_data* d = (struct req_data*) userData; d->xmlData[d->xmlDataOff] = '\0'; if(!strcmp(name, "channnel")) { d->in_channel = 0; } else if(!strcmp(name, "description")) { d->description = escape_json_string(d->xmlData); } else if(!strcmp(name, "login")) { d->login = escape_json_string(d->xmlData); } else if(!strcmp(name, "title")) { if(d->in_channel) d->channel_title = escape_json_string(d->xmlData); else d->event_title = escape_json_string(d->xmlData); } else if(!strcmp(name, "image_url_large")) { d->profile_image = escape_json_string(d->xmlData); } else if(!strcmp(name, "length")) { d->duration = atoi(d->xmlData); } else if(!strcmp(name, "start_time")) { struct tm date; memset(&date, 0, sizeof(struct tm)); strptime(d->xmlData, "%Y-%m-%dT%H:%M:%SZ", &date); d->start = mktime(&date); } d->xmlDataOff = 0; }
int escape_json_string0(YUString *out, char *in) { return escape_json_string(out,in,strlen(in)); }
struct jsontring *json_to_string(json_item *head, struct jsontring *string, int free_tree) { if (string == NULL) { string = xmalloc(sizeof(struct jsontring)); /* Ok, this can cost a lot (traversing the tree), but avoid realloc at each iteration */ string->jsize = json_evaluate_string_size(head) * 2; /* TODO : Remove * 2, add some padding, realloc when necessary (or at least just x2 str val) */ string->jstring = xmalloc(sizeof(char) * (string->jsize + 1)); string->len = 0; } while (head != NULL) { if (head->key.val != NULL) { string->jstring[string->len++] = '"'; memcpy(string->jstring + string->len, head->key.val, head->key.len); string->len += head->key.len; string->jstring[string->len++] = '"'; string->jstring[string->len++] = ':'; if (free_tree) { free(head->key.val); } } if (head->jval.vu.str.value != NULL) { string->jstring[string->len++] = '"'; string->len += escape_json_string(head->jval.vu.str.value, string->jstring + string->len, head->jval.vu.str.length); /* TODO : Add a "escape" argument to json_to_string */ string->jstring[string->len++] = '"'; if (free_tree) { free(head->jval.vu.str.value); } } else if (head->jval.vu.integer_value) { long int l = LENGTH_N(head->jval.vu.integer_value); long int offset; char integer_str[l+2]; offset = itos(head->jval.vu.integer_value, integer_str, l+2); memcpy(string->jstring + string->len, &integer_str[offset], ((l+2)-1)-offset); string->len += ((l+2)-1)-offset; } else if (head->jval.vu.float_value) { int length; /* TODO: check for -1 */ /* TODO: fix max length 16 together with json_evaluate_string_size() */ length = snprintf(string->jstring + string->len, 16 + 1, "%f", head->jval.vu.float_value); if(length > 16) /* cut-off number */ length = 16; string->len += length; } else if (head->type == JSON_T_TRUE) { memcpy(string->jstring + string->len, "true", 4); string->len += 4; } else if (head->type == JSON_T_FALSE) { memcpy(string->jstring + string->len, "false", 5); string->len += 5; } else if (head->type == JSON_T_NULL) { memcpy(string->jstring + string->len, "null", 4); string->len += 4; } else if (head->jchild.child == NULL) { memcpy(string->jstring + string->len, "0", 1); string->len++; } if (head->jchild.child != NULL) { switch(head->jchild.type) { case JSON_C_T_OBJ: string->jstring[string->len++] = '{'; break; case JSON_C_T_ARR: string->jstring[string->len++] = '['; break; default: break; } json_to_string(head->jchild.child, string, free_tree); } if (head->father != NULL) { if (head->next != NULL) { string->jstring[string->len++] = ','; } else { switch(head->father->jchild.type) { case JSON_C_T_OBJ: string->jstring[string->len++] = '}'; break; case JSON_C_T_ARR: string->jstring[string->len++] = ']'; break; default: break; } } } if (free_tree) { json_item *jtmp = head->next; free(head); head = jtmp; } else { head = head->next; } } string->jstring[string->len] = '\0'; return string; }