json_parser.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "json.h"
  4. /* --- Fonctions privées --- */
  5. int skip_object(char* json) {
  6. int compteur = 1;
  7. json++;
  8. //On compte le nombre caractere à sauter
  9. while (*json && *json != '}') {
  10. //Si on trouve un autre objet dans l'objet
  11. if (*json == '{') {
  12. skip_object(json);
  13. }
  14. compteur++;
  15. json++;
  16. }
  17. return compteur;
  18. }
  19. int skip_array(char* json) {
  20. int compteur = 1;
  21. json++;
  22. //On compte le nombre caractere à sauter
  23. while (*json && *json != ']') {
  24. json++;
  25. compteur++;
  26. }
  27. return compteur;
  28. }
  29. int key_counter(char* json){
  30. //Declaration variable
  31. int compteur = 0;
  32. boolean key = true;
  33. //On parcours la chaine une 1er fois pour compter le nombre de clef
  34. while (*json && *json != '}') {
  35. //Si on trouve le debut d'une clef
  36. if (*json == '"' && key) {
  37. compteur++;
  38. key = false;
  39. }
  40. //Si on tombe sur un autre objet json
  41. else if (*json == '{' && !key) {
  42. json += skip_object(json);
  43. }
  44. //Si on tombe sur un tableau
  45. else if (*json == '[' && !key) {
  46. json += skip_array(json);
  47. }
  48. //Si on trouve un separateur de valeur
  49. else if (*json == ',' && !key) {
  50. //Le prochain element est une clefS
  51. key = true;
  52. }
  53. json++;
  54. }
  55. //Retour
  56. return compteur;
  57. }
  58. int parse_key(JsonParser* this, int index, char* json) {
  59. //Declaration variable
  60. int compteur = 0;
  61. //On parcours jusqu'a la fin de la clef
  62. json++;
  63. while (*json && *json != '"') {
  64. json++;
  65. compteur++;
  66. }
  67. //Si json mal formé
  68. if (!*json) {
  69. return JSON_ERROR;
  70. }
  71. //Setup les infos
  72. this->key[index] = json - compteur;
  73. this->key_length[index] = compteur;
  74. //Sinon retourne ok
  75. return ++compteur;
  76. }
  77. int parse_val(JsonParser* this, int index, char* json){
  78. //Declaration variable
  79. int compteur = 0;
  80. //Regarde le type de valeur
  81. switch(*json){
  82. //String
  83. case '"':
  84. //Cherche le guillement de fin
  85. json++;
  86. while (*json && *json != '"') {
  87. json++;
  88. compteur++;
  89. }
  90. //Si json mal formé
  91. if (!*json) {
  92. return JSON_ERROR;
  93. }
  94. //Setup les infos
  95. this->val[index] = json - compteur;
  96. this->val_length[index] = compteur;
  97. this->type[index] = JSON_STRING;
  98. break;
  99. //Boolean
  100. case 't':
  101. compteur = 4;
  102. this->val[index] = json;
  103. this->val_length[index] = compteur;
  104. this->type[index] = JSON_BOOLEAN;
  105. break;
  106. case 'f':
  107. compteur = 5;
  108. this->val[index] = json;
  109. this->val_length[index] = compteur;
  110. this->type[index] = JSON_BOOLEAN;
  111. break;
  112. //Nombre
  113. case '-':
  114. case '0':
  115. case '1':
  116. case '2':
  117. case '3':
  118. case '4':
  119. case '5':
  120. case '6':
  121. case '7':
  122. case '8':
  123. case '9':
  124. //Cherche espace de fin ou fin json ou suite json
  125. while (*json && *json != ' ' && *json != '}' && *json != ',') {
  126. json++;
  127. compteur++;
  128. }
  129. //Si json mal formé
  130. if (!*json) {
  131. return JSON_ERROR;
  132. }
  133. //Setup les infos
  134. this->val[index] = json - compteur;
  135. this->val_length[index] = compteur;
  136. this->type[index] = JSON_NUMBER;
  137. break;
  138. //Tableau
  139. case '[':
  140. compteur = skip_array(json) + 1;
  141. this->val[index] = json;
  142. this->val_length[index] = compteur;
  143. this->type[index] = JSON_ARRAY;
  144. break;
  145. //Objet
  146. case '{':
  147. compteur = skip_object(json) + 1;
  148. this->val[index] = json;
  149. this->val_length[index] = compteur;
  150. this->type[index] = JSON_OBJECT;
  151. break;
  152. //Autre
  153. default:
  154. return JSON_ERROR;
  155. }
  156. //Retour
  157. return ++compteur;
  158. }
  159. int parse_error(JsonParser* this){
  160. clean_json_parser(this);
  161. return JSON_ERROR;
  162. }
  163. int search_index(JsonParser* this, char* key){
  164. int length = strlen(key);
  165. //Cherche la clef
  166. for(int i = 0; i < this->elt; i++){
  167. if(strncmp(this->key[i], key, length) == 0){
  168. return i;
  169. }
  170. }
  171. //Si rien trouver
  172. return JSON_ERROR;
  173. }
  174. /* --- Fonctions publiques --- */
  175. int json_parse(JsonParser* this, char* json) {
  176. //Declaration variable
  177. char* tmp;
  178. int temp, compteur;
  179. boolean key = true;
  180. //Compte le nombre de clef
  181. compteur = key_counter(json);
  182. //Allocation de la taille des tableaux
  183. this->str = malloc(strlen(json) * sizeof (char));
  184. strcpy(this->str, json);
  185. this->elt = compteur;
  186. this->key = malloc(compteur * sizeof (char*));
  187. this->key_length = malloc(compteur * sizeof (int));
  188. this->val = malloc(compteur * sizeof (char*));
  189. this->val_length = malloc(compteur * sizeof (int));
  190. this->type = malloc(compteur * sizeof (int));
  191. //On reparcours le tableau pour parser
  192. tmp = this->str;
  193. compteur = 0;
  194. while (*tmp && *tmp != '}') {
  195. //Si on trouve une clef
  196. if (*tmp == '"') {
  197. //Lecture clef de la clef
  198. if((temp = parse_key(this, compteur, tmp)) == JSON_ERROR){ return parse_error(this); }
  199. tmp += temp;
  200. key = false;
  201. }
  202. //Si on trouve une valeur
  203. else if(*tmp == ':'){
  204. //Si pas de claf avant
  205. if(key){ return parse_error(this); }
  206. //Saute les espaces
  207. tmp++;
  208. while(*tmp == ' ') { tmp++; }
  209. //Lecture valeur
  210. if((temp = parse_val(this, compteur, tmp)) == JSON_ERROR){ return parse_error(this); }
  211. tmp += temp;
  212. key = true;
  213. compteur++;
  214. }
  215. tmp++;
  216. }
  217. //Si on s'arrete sur une clef
  218. if(!key){
  219. return parse_error(this);
  220. }
  221. //Sinon ok
  222. return JSON_OK;
  223. }
  224. int get_type(JsonParser* this, char* key){
  225. //Recup index
  226. int index;
  227. if((index = search_index(this, key)) == JSON_ERROR){
  228. return JSON_ERROR;
  229. }
  230. return this->type[index];
  231. }
  232. char* get(JsonParser* this, char* key){
  233. //Recup index
  234. int index;
  235. if((index = search_index(this, key)) == JSON_ERROR){
  236. return NULL;
  237. }
  238. return get_index(this, index);
  239. }
  240. char* get_index(JsonParser* this, int index){
  241. //Index incorrect
  242. if(index < 0 || index >= this->elt){
  243. return NULL;
  244. }
  245. //Creation string d'accueil
  246. char* val;
  247. val = malloc(this->val_length[index] * sizeof(char));
  248. //Copie valeur
  249. strncpy(val, this->val[index], this->val_length[index]);
  250. //Retour
  251. return val;
  252. }
  253. void clean_json_parser(JsonParser* this) {
  254. free(this->key);
  255. free(this->key_length);
  256. free(this->val);
  257. free(this->val_length);
  258. free(this->type);
  259. free(this->str);
  260. }