Permalink
Browse files

Fix for issue #5: Unicode characters are converted to lowercase.

  • Loading branch information...
1 parent f85c4ed commit 5f000f9cf491bf01815a611c4b9d192845f33227 @residuum committed Feb 4, 2012
Showing with 115 additions and 75 deletions.
  1. +2 −14 json-decode.c
  2. +105 −47 libpurest_json.c
  3. +3 −0 purest_json.h
  4. +4 −5 rest-json-help.pd
  5. +1 −9 rest-json.c
View
16 json-decode.c
@@ -18,31 +18,19 @@ void *json_decode_new(t_symbol *selector, int argcount, t_atom *argvec) {
}
void json_decode_string(t_json_decode *x, t_symbol *data) {
- char *json_string = data->s_name;
- json_object *jobj;
- jobj = json_tokener_parse(json_string);
- output_json(jobj, x->x_ob.ob_outlet, x->done_outlet);
- if (!is_error(jobj)) {
- json_object_put(jobj);
- }
+ output_json_string(data->s_name, x->x_ob.ob_outlet, x->done_outlet);
}
void json_decode_list(t_json_decode *x, t_symbol *selector, int argcount, t_atom *argvec) {
char json_string[MAX_STRING_SIZE];
char value[MAX_STRING_SIZE];
int i;
- json_object *jobj;
if (argcount > 1) {
atom_string(argvec + 1, json_string, MAX_STRING_SIZE);
for (i = 2; i < argcount; i++) {
atom_string(argvec + i, value, MAX_STRING_SIZE);
strcat(json_string, value);
}
- /*post("%s", json_string);*/
- jobj = json_tokener_parse(json_string);
- output_json(jobj, x->x_ob.ob_outlet, x->done_outlet);
- if (!is_error(jobj)) {
- json_object_put(jobj);
- }
+ output_json_string(json_string, x->x_ob.ob_outlet, x->done_outlet);
}
}
View
152 libpurest_json.c
@@ -1,5 +1,51 @@
#include "purest_json.h"
+void lowercase_unicode(char *orig) {
+ char *unicode_intro = "\\u";
+ char *tmp = strstr(orig, unicode_intro);
+ char *tmp_without_intro;
+ char orig_return[strlen(orig)];
+ short i;
+ short uni_len = 4; /*TODO: get real length, we just assume 4 for now */
+ if (tmp) {
+ strncpy(orig_return, orig, strlen(orig) - strlen(tmp));
+ do {
+ for (i = 2; i < 2 + uni_len; i++) {
+ switch (tmp[i]) {
+ case 'A':
+ tmp[i] = 'a';
+ break;
+ case 'B':
+ tmp[i] = 'b';
+ break;
+ case 'C':
+ tmp[i] = 'c';
+ break;
+ case 'D':
+ tmp[i] = 'd';
+ break;
+ case 'E':
+ tmp[i] = 'e';
+ break;
+ case 'F':
+ tmp[i] = 'f';
+ break;
+ }
+ }
+ strcat(orig_return, unicode_intro);
+ post("orig_return %s", orig_return);
+ tmp_without_intro = tmp + 2;
+ tmp = strstr(tmp_without_intro, unicode_intro);
+ if (tmp) {
+ strncat(orig_return, tmp_without_intro, strlen(tmp_without_intro) - strlen(tmp));
+ } else {
+ strcat(orig_return, tmp_without_intro);
+ }
+ } while(tmp);
+ strcpy(orig, orig_return);
+ }
+}
+
void output_json(json_object *jobj, t_outlet *data_outlet, t_outlet *done_outlet) {
enum json_type outer_type;
enum json_type inner_type;
@@ -54,58 +100,70 @@ void output_json(json_object *jobj, t_outlet *data_outlet, t_outlet *done_outlet
inner_type = json_object_get_type(val);
switch (inner_type) {
case json_type_boolean:
- SETFLOAT(&out_data[1], json_object_get_boolean(val) ? 1: 0);
- break;
- case json_type_double:
- SETFLOAT(&out_data[1], json_object_get_double(val));
- break;
- case json_type_int:
- SETFLOAT(&out_data[1], json_object_get_int(val));
- break;
- case json_type_string:
- /* Float values might come as string */
- string_value = json_object_get_string(val);
- float_value = (float)strtod(string_value, &remainder);
- /* String to float has no remainder => float */
- if (strlen(remainder) == 0) {
- SETFLOAT(&out_data[1], float_value);
- /* Boolean values might come as string */
- } else if (str_ccmp(string_value, "true") == 0) {
- SETFLOAT(&out_data[1], 1);
- } else if (str_ccmp(string_value, "false") == 0) {
- SETFLOAT(&out_data[1], 0);
- /* String */
- } else {
- SETSYMBOL(&out_data[1], gensym(string_value));
- }
- break;
- case json_type_object:
- SETSYMBOL(&out_data[1], gensym(json_object_get_string(val)));
- break;
- case json_type_array:
- SETSYMBOL(&out_data[1], gensym(json_object_get_string(val)));
- break;
- case json_type_null:
- SETSYMBOL(&out_data[1], gensym(""));
- break;
+ SETFLOAT(&out_data[1], json_object_get_boolean(val) ? 1: 0);
+ break;
+ case json_type_double:
+ SETFLOAT(&out_data[1], json_object_get_double(val));
+ break;
+ case json_type_int:
+ SETFLOAT(&out_data[1], json_object_get_int(val));
+ break;
+ case json_type_string:
+ /* Float values might come as string */
+ string_value = json_object_get_string(val);
+ float_value = (float)strtod(string_value, &remainder);
+ /* String to float has no remainder => float */
+ if (strlen(remainder) == 0) {
+ SETFLOAT(&out_data[1], float_value);
+ /* Boolean values might come as string */
+ } else if (str_ccmp(string_value, "true") == 0) {
+ SETFLOAT(&out_data[1], 1);
+ } else if (str_ccmp(string_value, "false") == 0) {
+ SETFLOAT(&out_data[1], 0);
+ /* String */
+ } else {
+ SETSYMBOL(&out_data[1], gensym(string_value));
+ }
+ break;
+ case json_type_object:
+ SETSYMBOL(&out_data[1], gensym(json_object_get_string(val)));
+ break;
+ case json_type_array:
+ SETSYMBOL(&out_data[1], gensym(json_object_get_string(val)));
+ break;
+ case json_type_null:
+ SETSYMBOL(&out_data[1], gensym(""));
+ break;
+ }
}
+ outlet_list(data_outlet, &s_list, 2, &out_data[0]);
}
- outlet_list(data_outlet, &s_list, 2, &out_data[0]);
- }
- outlet_bang(done_outlet);
- break;
- case json_type_array:
- ;
- array_len = json_object_array_length(jobj);
- for (i = 0; i < array_len; i++) {
- json_object *array_member = json_object_array_get_idx(jobj, i);
- output_json(array_member, data_outlet, done_outlet);
- }
- break;
+ outlet_bang(done_outlet);
+ break;
+ case json_type_array:
+ ;
+ array_len = json_object_array_length(jobj);
+ for (i = 0; i < array_len; i++) {
+ json_object *array_member = json_object_array_get_idx(jobj, i);
+ output_json(array_member, data_outlet, done_outlet);
+ }
+ break;
}
}
}
+void output_json_string(char *json_string, t_outlet *data_outlet, t_outlet *done_outlet) {
+ json_object *jobj;
+ /* Needed because of bug in json-c 0.9 */
+ lowercase_unicode(json_string);
+ /* Parse JSON */
+ jobj = json_tokener_parse(json_string);
+ output_json(jobj, data_outlet, done_outlet);
+ if (!is_error(jobj)) {
+ json_object_put(jobj);
+ }
+}
+
char *remove_backslashes(char *source_string) {
char *dest = NULL;
char remove[2] = "\\,";
@@ -132,7 +190,7 @@ char *remove_backslashes(char *source_string) {
} else {
dest[j] = ',';
}
- j++;
+ j++;
}
return (dest);
}
View
3 purest_json.h
@@ -78,8 +78,11 @@ void *json_decode_new(t_symbol *selector, int argcount, t_atom *argvec);
void json_decode_string(t_json_decode *x, t_symbol *data);
void json_decode_list(t_json_decode *x, t_symbol *selector, int argcount, t_atom *argvec);
void output_json(json_object *jobj, t_outlet *data_outlet, t_outlet *done_outlet);
+void output_json_string(char *json_string, t_outlet *data_outlet, t_outlet *done_outlet);
/* general */
void purest_json_setup(void);
char *remove_backslashes(char *source_string);
int str_ccmp(const char *s1, const char *s2);
+void lowercase_unicode(char *orig);
+
View
9 rest-json-help.pd
@@ -1,4 +1,4 @@
-#N canvas 424 94 871 495 10;
+#N canvas 420 90 871 495 10;
#N canvas 260 56 853 470 CouchDB-basics 0;
#X text 416 71 CRUD documents:;
#X text 15 10 Basic CRUD methods for databases and individual documents
@@ -179,14 +179,12 @@ to be used by a simple sequencer.;
#X connect 44 0 45 1;
#X restore 21 282 pd couchdb;
#X obj 458 216 rest-json;
-#X obj 458 248 print data;
#X msg 497 149 GET http://search.twitter.com/search.json?q=%23puredata
;
#X msg 474 64 GET https://ajax.googleapis.com/ajax/services/search/web?v=2.0&q=puredata
;
#X msg 458 10 GET https://github.com/api/v2/json/commits/list/residuum/PuRestJson/master
;
-#X text 498 131 Getting error while parsing the return value;
#X text 76 -59 - object for HTTP communication with REST webservices
;
#X text 21 191 An example for a RESTful interface is CouchDB:;
@@ -206,7 +204,8 @@ need to have a local installation of CouchDB.;
#X text 18 61 HTTP requests are asynchronous. Do not expect two subsequent
requests to arrive in the same order as sending them. [rest-json] does
all its work in separate threads.;
-#X connect 8 0 9 0;
+#X obj 458 248 print data;
+#X connect 8 0 19 0;
+#X connect 9 0 8 0;
#X connect 10 0 8 0;
#X connect 11 0 8 0;
-#X connect 12 0 8 0;
View
10 rest-json.c
@@ -125,7 +125,6 @@ void *execute_rest_thread(void *thread_args) {
CURLcode result;
t_memory_struct in_memory;
t_memory_struct out_memory;
- json_object *jobj;
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
@@ -152,18 +151,11 @@ void *execute_rest_thread(void *thread_args) {
result = curl_easy_perform(curl_handle);
if (result == CURLE_OK) {
- /* post("%s", out_memory.memory);*/
- /* Parse JSON */
- jobj = json_tokener_parse(out_memory.memory);
- /*outlet_symbol(x->x_ob.ob_outlet, gensym(out_memory.memory));*/
+ output_json_string(out_memory.memory, x->x_ob.ob_outlet, x->done_outlet);
/* Free memory */
if (out_memory.memory) {
free(out_memory.memory);
}
- output_json(jobj, x->x_ob.ob_outlet, x->done_outlet);
- if (!is_error(jobj)) {
- json_object_put(jobj);
- }
} else {
error("Error while performing request: %s", curl_easy_strerror(result));
}

0 comments on commit 5f000f9

Please sign in to comment.