json_array.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*
  2. * File: json_array.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 24 novembre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include "json.h"
  11. /* --- Fonctions privées parser --- */
  12. int val_counter(char* json) {
  13. char* tmp = json + 1;
  14. int nbElt = 0;
  15. boolean empty = true;
  16. //Parours la chaine
  17. while (*tmp != ']' && *tmp) {
  18. //printf("%c\n", *tmp);
  19. fflush(stdout);
  20. //Si on croise autre chose que du vide
  21. if (empty && *tmp != ' ' && *tmp != ']') {
  22. empty = false;
  23. } //Si on croise un tableau ou un objet
  24. else if (*tmp == '[' || *tmp == '{') {
  25. //Saute
  26. int jump;
  27. if (*tmp == '{') {
  28. jump = skip_object(tmp);
  29. } else {
  30. jump = skip_array(tmp);
  31. }
  32. tmp += jump;
  33. //Si se termine mal
  34. if (!*tmp) {
  35. return JSON_ERROR;
  36. }
  37. } //On compte les ',' separatrice
  38. else if (*tmp == ',') {
  39. nbElt++;
  40. }
  41. tmp++;
  42. }
  43. //Si non vide
  44. if (!empty) {
  45. nbElt++;
  46. }
  47. //Retourne le nombre d'element trouvé
  48. return nbElt;
  49. }
  50. /**
  51. * Extraction d'une valeur
  52. * @param JsonParser* La structure pour sauvegarder l'extraction
  53. * @param int La position dans la structure
  54. * @param char* La chaine json
  55. * @return int JSON_ERROR ou le nombre de caractère de la valeur
  56. */
  57. int parse_array_val(JsonArray* this, int index, char* json) {
  58. //Declaration variable
  59. int compteur = 0;
  60. //Regarde le type de valeur
  61. switch (*json) {
  62. //String
  63. case '"':
  64. //Cherche le guillement de fin
  65. json++;
  66. while (*json && *json != '"') {
  67. json++;
  68. compteur++;
  69. }
  70. //Si json mal formé
  71. if (!*json) {
  72. return JSON_ERROR;
  73. }
  74. //Setup les infos
  75. this->parser->val[index] = json - compteur;
  76. this->parser->val_length[index] = compteur;
  77. this->parser->type[index] = JSON_STRING;
  78. break;
  79. //Boolean
  80. case 't':
  81. compteur = 4;
  82. this->parser->val[index] = json;
  83. this->parser->val_length[index] = compteur;
  84. this->parser->type[index] = JSON_BOOLEAN;
  85. break;
  86. case 'f':
  87. compteur = 5;
  88. this->parser->val[index] = json;
  89. this->parser->val_length[index] = compteur;
  90. this->parser->type[index] = JSON_BOOLEAN;
  91. break;
  92. //Nombre
  93. case '-':
  94. case '0':
  95. case '1':
  96. case '2':
  97. case '3':
  98. case '4':
  99. case '5':
  100. case '6':
  101. case '7':
  102. case '8':
  103. case '9':
  104. //Cherche espace de fin ou fin json ou suite json
  105. while (*json && *json != ' ' && *json != ']' && *json != ',') {
  106. json++;
  107. compteur++;
  108. }
  109. //Si json mal formé
  110. if (!*json) {
  111. return JSON_ERROR;
  112. }
  113. //Setup les infos
  114. this->parser->val[index] = json - compteur;
  115. this->parser->val_length[index] = compteur;
  116. this->parser->type[index] = JSON_NUMBER;
  117. break;
  118. //Tableau
  119. case '[':
  120. compteur = skip_array(json) + 1;
  121. this->parser->val[index] = json;
  122. this->parser->val_length[index] = compteur;
  123. this->parser->type[index] = JSON_ARRAY;
  124. break;
  125. //Objet
  126. case '{':
  127. compteur = skip_object(json) + 1;
  128. this->parser->val[index] = json;
  129. this->parser->val_length[index] = compteur;
  130. this->parser->type[index] = JSON_OBJECT;
  131. break;
  132. //Autre
  133. default:
  134. return JSON_ERROR;
  135. }
  136. //Retour
  137. return ++compteur;
  138. }
  139. /* --- Fonctions publiques parser --- */
  140. void ini_array_parser(JsonArray* this) {
  141. //Initialisation en mode encoder
  142. this->mode = JSON_ARRAY_PARSER;
  143. this->parser = malloc(sizeof (JsonArrayParser));
  144. }
  145. int json_parse_array(JsonArray* this, char* json) {
  146. int length, jump, index = 0, compteur = 1;
  147. //Verification
  148. if (this->mode != JSON_ARRAY_PARSER) {
  149. return JSON_ERROR;
  150. }
  151. if (json[0] != '[') {
  152. return JSON_ERROR;
  153. }
  154. //Compte le nombre d'éléments
  155. this->parser->length = val_counter(json);
  156. if (this->parser->length == JSON_ERROR) {
  157. return JSON_ERROR;
  158. }
  159. length = strlen(json) + 1;
  160. this->parser->str = malloc(sizeof (char) * length);
  161. memset(this->parser->str, 0, length);
  162. strncpy(this->parser->str, json, length - 1);
  163. //Si vide
  164. if (this->parser->length == 0) {
  165. return 0;
  166. }
  167. //Initialisation
  168. this->parser->val = malloc(sizeof (char*) * this->parser->length);
  169. this->parser->val_length = malloc(sizeof (int) * this->parser->length);
  170. this->parser->type = malloc(sizeof (int) * this->parser->length);
  171. //Sinon on parse les valeurs
  172. json++;
  173. while (*json != ']' && *json) {
  174. if (*json != ' ' && *json != ',') {
  175. jump = parse_array_val(this, index, this->parser->str + compteur);
  176. if (jump == JSON_ERROR) {
  177. clean_json_array(this);
  178. return JSON_ERROR;
  179. }
  180. json += jump;
  181. compteur += jump;
  182. index++;
  183. }
  184. json++;
  185. compteur++;
  186. }
  187. //Retourne le nombre d'element
  188. return this->parser->length;
  189. }
  190. int get_array_length(JsonArray* this) {
  191. //Verification
  192. if (this->mode != JSON_ARRAY_PARSER) {
  193. return JSON_ERROR;
  194. }
  195. //Retour
  196. return this->parser->length;
  197. }
  198. int get_array_type(JsonArray* this, int index) {
  199. //Verification
  200. if (this->mode != JSON_ARRAY_PARSER) {
  201. return JSON_ERROR;
  202. }
  203. if (index < 0 || index >= this->parser->length) {
  204. return JSON_ERROR;
  205. }
  206. //Retourne le type
  207. return this->parser->type[index];
  208. }
  209. char* get_array_index(JsonArray* this, int index) {
  210. //Verification
  211. if (this->mode != JSON_ARRAY_PARSER) {
  212. return NULL;
  213. }
  214. if (index < 0 || index >= this->parser->length) {
  215. return NULL;
  216. }
  217. //Creation string d'accueil
  218. char* val;
  219. val = malloc((this->parser->val_length[index] + 1) * sizeof (char)); //+1 pour \0
  220. memset(val, 0, this->parser->val_length[index] + 1);
  221. //Copie valeur
  222. strncpy(val, this->parser->val[index], this->parser->val_length[index]);
  223. //Retour
  224. return val;
  225. }
  226. char* get_array_value(JsonArray* this, int index) {
  227. //Verification
  228. if (this->mode != JSON_ARRAY_PARSER) {
  229. return NULL;
  230. }
  231. if (index < 0 || index >= this->parser->length) {
  232. return NULL;
  233. }
  234. //Retour
  235. return get_array_index(this, index);
  236. }
  237. char* get_array_string(JsonArray* this, int index) {
  238. //Verification
  239. if (this->mode != JSON_ARRAY_PARSER) {
  240. return NULL;
  241. }
  242. if (index < 0 || index >= this->parser->length) {
  243. return NULL;
  244. }
  245. //Retour
  246. if (this->parser->type[index] != JSON_STRING) {
  247. return NULL;
  248. }
  249. return get_array_index(this, index);
  250. }
  251. double get_array_number(JsonArray* this, int index) {
  252. //Verification
  253. if (this->mode != JSON_ARRAY_PARSER) {
  254. return JSON_ERROR;
  255. }
  256. if (index < 0 || index >= this->parser->length) {
  257. return JSON_ERROR;
  258. }
  259. //Retour
  260. if (this->parser->type[index] != JSON_NUMBER) {
  261. return JSON_ERROR;
  262. }
  263. char* val;
  264. val = get_array_index(this, index);
  265. double res;
  266. res = atof(val);
  267. free(val);
  268. return res;
  269. }
  270. int get_array_integer(JsonArray* this, int index) {
  271. //Verification
  272. if (this->mode != JSON_ARRAY_PARSER) {
  273. return JSON_ERROR;
  274. }
  275. if (index < 0 || index >= this->parser->length) {
  276. return JSON_ERROR;
  277. }
  278. //Retour
  279. if (this->parser->type[index] != JSON_NUMBER) {
  280. return JSON_ERROR;
  281. }
  282. char* val;
  283. val = get_array_index(this, index);
  284. int res;
  285. res = atoi(val);
  286. free(val);
  287. return res;
  288. }
  289. boolean get_array_boolean(JsonArray* this, int index) {
  290. //Verification
  291. if (this->mode != JSON_ARRAY_PARSER) {
  292. return false;
  293. }
  294. if (index < 0 || index >= this->parser->length) {
  295. return false;
  296. }
  297. //Verif type
  298. if (this->parser->type[index] != JSON_BOOLEAN) {
  299. return false;
  300. }
  301. //Recup valeur
  302. char* val;
  303. val = get_array_index(this, index);
  304. //Cast et retour
  305. if (val[0] == 't') {
  306. return true;
  307. }
  308. return false;
  309. }
  310. JsonArray* get_array_array(JsonArray* this, int index) {
  311. //Verification
  312. if (this->mode != JSON_ARRAY_PARSER) {
  313. return NULL;
  314. }
  315. if (index < 0 || index >= this->parser->length) {
  316. return NULL;
  317. }
  318. //Verif type
  319. if (this->parser->type[index] != JSON_ARRAY) {
  320. return NULL;
  321. }
  322. //Recup valeur
  323. char* val;
  324. val = get_array_index(this, index);
  325. //Parse
  326. JsonArray* json;
  327. json = malloc(sizeof (JsonArray));
  328. ini_array_parser(json);
  329. if (json_parse_array(json, val) == JSON_ERROR) {
  330. return NULL;
  331. }
  332. //Retour JSON utilisable
  333. free(val);
  334. return json;
  335. }
  336. JsonParser* get_array_object(JsonArray* this, int index) {
  337. //Verification
  338. if (this->mode != JSON_ARRAY_PARSER) {
  339. return NULL;
  340. }
  341. if (index < 0 || index >= this->parser->length) {
  342. return NULL;
  343. }
  344. //Verif type
  345. if (this->parser->type[index] != JSON_OBJECT) {
  346. return NULL;
  347. }
  348. //Recup valeur
  349. char* val;
  350. val = get_array_index(this, index);
  351. //Parse
  352. JsonParser* json;
  353. json = malloc(sizeof (JsonParser));
  354. if (json_parse(json, val) == JSON_ERROR) {
  355. return NULL;
  356. }
  357. //Retour JSON utilisable
  358. free(val);
  359. return json;
  360. }
  361. /* --- Fonctions publiques encoder --- */
  362. void ini_array_encoder(JsonArray* this) {
  363. this->mode = JSON_ARRAY_ENCODER;
  364. this->encoder = malloc(sizeof(JsonEncoder));
  365. this->encoder->max = JSON_MAX_SIZE;
  366. this->encoder->pos = 1;
  367. memset(this->encoder->json, 0, this->encoder->max);
  368. this->encoder->json[0] = '[';
  369. }
  370. boolean add_array_value(JsonArray* this, char* str) {
  371. //Verification
  372. if (this->mode != JSON_ARRAY_ENCODER) {
  373. return false;
  374. }
  375. //Verif que l'on ne depasse pas (on retire 1 pour garder un \0 et on retire 1 autre pour pouvoir mettre ])
  376. if(this->encoder->pos + strlen(str) >= this->encoder->max - 2){
  377. return false;
  378. }
  379. //Ajoute
  380. for(int i = 0; i < strlen(str); i++){
  381. this->encoder->json[this->encoder->pos++] = str[i];
  382. }
  383. return true;
  384. }
  385. boolean add_array_string(JsonArray* this, char* val) {
  386. //Verification
  387. if (this->mode != JSON_ARRAY_ENCODER) {
  388. return false;
  389. }
  390. int length = strlen(val) + 2 + 2; //val + 2 guillemet + ", "
  391. //Verif que l'on ne depasse pas
  392. if(this->encoder->pos + length >= this->encoder->max - 2){
  393. return false;
  394. }
  395. //Ajoute
  396. if(this->encoder->pos != 1){
  397. //Si pas 1er valeur on ajoute un separateur
  398. this->encoder->json[this->encoder->pos++] = ',';
  399. this->encoder->json[this->encoder->pos++] = ' ';
  400. }
  401. this->encoder->json[this->encoder->pos++] = '"';
  402. for(int i = 0; i < strlen(val); i++){
  403. this->encoder->json[this->encoder->pos++] = val[i];
  404. }
  405. this->encoder->json[this->encoder->pos++] = '"';
  406. return true;
  407. }
  408. boolean add_array_number(JsonArray* this, double ndigit, int val) {
  409. //Verification
  410. if (this->mode != JSON_ARRAY_ENCODER) {
  411. return false;
  412. }
  413. //Double en string
  414. char nombre[20];
  415. memset(nombre, 0, 20);
  416. ftoa(val, nombre, ndigit);
  417. //Creation chaine
  418. int length = strlen(nombre) + 2; //val + ", "
  419. //Verif que l'on ne depasse pas
  420. if(this->encoder->pos + length >= this->encoder->max - 2){
  421. return false;
  422. }
  423. //Ajoute
  424. if(this->encoder->pos != 1){
  425. //Si pas 1er valeur on ajoute un separateur
  426. this->encoder->json[this->encoder->pos++] = ',';
  427. this->encoder->json[this->encoder->pos++] = ' ';
  428. }
  429. for(int i = 0; i < strlen(nombre); i++){
  430. this->encoder->json[this->encoder->pos++] = nombre[i];
  431. }
  432. return true;
  433. }
  434. boolean add_array_integer(JsonArray* this, int val) {
  435. //Verification
  436. if (this->mode != JSON_ARRAY_ENCODER) {
  437. return false;
  438. }
  439. //Int en string
  440. char nombre[20];
  441. memset(nombre, 0, 20);
  442. snprintf(nombre, 20, "%d", val);
  443. //Creation chaine
  444. int length = strlen(nombre) + 2; //val + ", "
  445. //Verif que l'on ne depasse pas
  446. if(this->encoder->pos + length >= this->encoder->max - 2){
  447. return false;
  448. }
  449. //Ajoute
  450. if(this->encoder->pos != 1){
  451. //Si pas 1er valeur on ajoute un separateur
  452. this->encoder->json[this->encoder->pos++] = ',';
  453. this->encoder->json[this->encoder->pos++] = ' ';
  454. }
  455. for(int i = 0; i < strlen(nombre); i++){
  456. this->encoder->json[this->encoder->pos++] = nombre[i];
  457. }
  458. return true;
  459. }
  460. boolean add_array_boolean(JsonArray* this, boolean val) {
  461. //Verification
  462. if (this->mode != JSON_ARRAY_ENCODER) {
  463. return false;
  464. }
  465. //On determine le boolean
  466. char bool[6];
  467. memset(bool, 0, 6);
  468. if (val) {
  469. strncpy(bool, "true", 4);
  470. } else {
  471. strncpy(bool, "false", 5);
  472. }
  473. //Creation chaine
  474. int length = strlen(bool) + 2; //val + ", "
  475. //Verif que l'on ne depasse pas
  476. if(this->encoder->pos + length >= this->encoder->max - 2){
  477. return false;
  478. }
  479. //Ajoute
  480. if(this->encoder->pos != 1){
  481. //Si pas 1er valeur on ajoute un separateur
  482. this->encoder->json[this->encoder->pos++] = ',';
  483. this->encoder->json[this->encoder->pos++] = ' ';
  484. }
  485. for(int i = 0; i < strlen(bool); i++){
  486. this->encoder->json[this->encoder->pos++] = bool[i];
  487. }
  488. return true;
  489. }
  490. boolean add_array_array(JsonArray* this, JsonArray* val) {
  491. //Verification
  492. if (this->mode != JSON_ARRAY_ENCODER) {
  493. return false;
  494. }
  495. //Recup json
  496. char* json = json_encode_array(val);
  497. //Creation chaine
  498. int length = strlen(json) + 2; //val + ", "
  499. //Verif que l'on ne depasse pas
  500. if(this->encoder->pos + length >= this->encoder->max - 2){
  501. return false;
  502. }
  503. //Ajoute
  504. if(this->encoder->pos != 1){
  505. //Si pas 1er valeur on ajoute un separateur
  506. this->encoder->json[this->encoder->pos++] = ',';
  507. this->encoder->json[this->encoder->pos++] = ' ';
  508. }
  509. for(int i = 0; i < strlen(json); i++){
  510. this->encoder->json[this->encoder->pos++] = json[i];
  511. }
  512. //Nettoayge
  513. free(json);
  514. return true;
  515. }
  516. boolean add_array_object(JsonArray* this, JsonEncoder* val) {
  517. //Verification
  518. if (this->mode != JSON_ARRAY_ENCODER) {
  519. return false;
  520. }
  521. //Recup json
  522. char* json = json_encode(val);
  523. //Creation chaine
  524. int length = strlen(json) + 2; //val + ", "
  525. //Verif que l'on ne depasse pas
  526. if(this->encoder->pos + length >= this->encoder->max - 2){
  527. return false;
  528. }
  529. //Ajoute
  530. if(this->encoder->pos != 1){
  531. //Si pas 1er valeur on ajoute un separateur
  532. this->encoder->json[this->encoder->pos++] = ',';
  533. this->encoder->json[this->encoder->pos++] = ' ';
  534. }
  535. for(int i = 0; i < strlen(json); i++){
  536. this->encoder->json[this->encoder->pos++] = json[i];
  537. }
  538. //Nettoayge
  539. free(json);
  540. return true;
  541. }
  542. char* json_encode_array(JsonArray* this) {
  543. char* json;
  544. //Ajoute } fin
  545. this->encoder->json[this->encoder->pos] = ']';
  546. //Creation chaine
  547. json = malloc(sizeof(char) * (this->encoder->pos + 2));
  548. memset(json, 0, this->encoder->pos + 2);
  549. strncpy(json, this->encoder->json, this->encoder->pos + 1);
  550. //Retourne
  551. return json;
  552. }
  553. /* --- Fonctions publiques --- */
  554. void clean_json_array(JsonArray* this) {
  555. if (this->mode == JSON_ARRAY_ENCODER) {
  556. free(this->encoder);
  557. ini_array_encoder(this);
  558. } else {
  559. //Parser
  560. free(this->parser->type);
  561. free(this->parser->val_length);
  562. free(this->parser->val);
  563. free(this->parser->str);
  564. free(this->parser);
  565. }
  566. this->mode = -1;
  567. }