|
@@ -0,0 +1,232 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include "json.h"
|
|
|
+
|
|
|
+/* --- Fonctions privées --- */
|
|
|
+
|
|
|
+int skip_object(char* json) {
|
|
|
+ int compteur = 1;
|
|
|
+ json++;
|
|
|
+ //On compte le nombre caractere à sauter
|
|
|
+ while (*json && *json != '}') {
|
|
|
+ //Si on trouve un autre objet dans l'objet
|
|
|
+ if (*json == '{') {
|
|
|
+ skip_object(json);
|
|
|
+ }
|
|
|
+ compteur++;
|
|
|
+ json++;
|
|
|
+ }
|
|
|
+ return compteur;
|
|
|
+}
|
|
|
+
|
|
|
+int skip_array(char* json) {
|
|
|
+ int compteur = 1;
|
|
|
+ json++;
|
|
|
+ //On compte le nombre caractere à sauter
|
|
|
+ while (*json && *json != ']') {
|
|
|
+ json++;
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ return compteur;
|
|
|
+}
|
|
|
+
|
|
|
+int key_counter(char* json){
|
|
|
+ //Declaration variable
|
|
|
+ int compteur = 0;
|
|
|
+ boolean key = true;
|
|
|
+ //On parcours la chaine une 1er fois pour compter le nombre de clef
|
|
|
+ while (*json && *json != '}') {
|
|
|
+ //Si on trouve le debut d'une clef
|
|
|
+ if (*json == '"' && key) {
|
|
|
+ compteur++;
|
|
|
+ key = false;
|
|
|
+ }
|
|
|
+ //Si on tombe sur un autre objet json
|
|
|
+ else if (*json == '{' && !key) {
|
|
|
+ json += skip_object(json);
|
|
|
+ }
|
|
|
+ //Si on tombe sur un tableau
|
|
|
+ else if (*json == '[' && !key) {
|
|
|
+ json += skip_array(json);
|
|
|
+ }
|
|
|
+ //Si on trouve un separateur de valeur
|
|
|
+ else if (*json == ',' && !key) {
|
|
|
+ //Le prochain element est une clefS
|
|
|
+ key = true;
|
|
|
+ }
|
|
|
+ json++;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ return compteur;
|
|
|
+}
|
|
|
+
|
|
|
+int parse_key(JsonParser* this, int index, char* json) {
|
|
|
+ //Declaration variable
|
|
|
+ int compteur = 0;
|
|
|
+ //On parcours jusqu'a la fin de la clef
|
|
|
+ json++;
|
|
|
+ while (*json && *json != '"') {
|
|
|
+ json++;
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ //Si json mal formé
|
|
|
+ if (!*json) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Setup les infos
|
|
|
+ printf("Key[%d] : %d\n", index, compteur);
|
|
|
+ this->key[index] = json - compteur;
|
|
|
+ this->key_length[index] = compteur;
|
|
|
+ //Sinon retourne ok
|
|
|
+ return ++compteur;
|
|
|
+}
|
|
|
+
|
|
|
+int parse_val(JsonParser* this, int index, char* json){
|
|
|
+ //Declaration variable
|
|
|
+ int compteur = 0;
|
|
|
+ //Regarde le type de valeur
|
|
|
+ switch(*json){
|
|
|
+ //String
|
|
|
+ case '"':
|
|
|
+ //Cherche le guillement de fin
|
|
|
+ json++;
|
|
|
+ while (*json && *json != '"') {
|
|
|
+ json++;
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ //Si json mal formé
|
|
|
+ if (!*json) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Setup les infos
|
|
|
+ this->val[index] = json - compteur;
|
|
|
+ this->val_length[index] = compteur;
|
|
|
+ this->type[index] = JSON_STRING;
|
|
|
+ break;
|
|
|
+ //Boolean
|
|
|
+ case 't':
|
|
|
+ compteur = 4;
|
|
|
+ this->val[index] = json;
|
|
|
+ this->val_length[index] = compteur;
|
|
|
+ this->type[index] = JSON_BOOLEAN;
|
|
|
+ break;
|
|
|
+ case 'f':
|
|
|
+ compteur = 5;
|
|
|
+ this->val[index] = json;
|
|
|
+ this->val_length[index] = compteur;
|
|
|
+ this->type[index] = JSON_BOOLEAN;
|
|
|
+ break;
|
|
|
+ //Nombre
|
|
|
+ case '-':
|
|
|
+ case '0':
|
|
|
+ case '1':
|
|
|
+ case '2':
|
|
|
+ case '3':
|
|
|
+ case '4':
|
|
|
+ case '5':
|
|
|
+ case '6':
|
|
|
+ case '7':
|
|
|
+ case '8':
|
|
|
+ case '9':
|
|
|
+ //Cherche espace de fin ou fin json ou suite json
|
|
|
+ while (*json && *json != ' ' && *json != '}' && *json != ',') {
|
|
|
+ json++;
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ //Si json mal formé
|
|
|
+ if (!*json) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Setup les infos
|
|
|
+ printf("cpt : %d\n", compteur);
|
|
|
+ this->val[index] = json - compteur;
|
|
|
+ this->val_length[index] = compteur;
|
|
|
+ this->type[index] = JSON_NUMBER;
|
|
|
+ break;
|
|
|
+ //Tableau
|
|
|
+ case '[':
|
|
|
+ compteur = skip_array(json) + 1;
|
|
|
+ this->val[index] = json;
|
|
|
+ this->val_length[index] = compteur;
|
|
|
+ this->type[index] = JSON_ARRAY;
|
|
|
+ break;
|
|
|
+ //Objet
|
|
|
+ case '{':
|
|
|
+ compteur = skip_object(json) + 1;
|
|
|
+ this->val[index] = json;
|
|
|
+ this->val_length[index] = compteur;
|
|
|
+ this->type[index] = JSON_OBJECT;
|
|
|
+ break;
|
|
|
+ //Autre
|
|
|
+ default:
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ return ++compteur;
|
|
|
+}
|
|
|
+
|
|
|
+int parse_error(JsonParser* this){
|
|
|
+ clean_json_parser(this);
|
|
|
+ return JSON_ERROR;
|
|
|
+}
|
|
|
+
|
|
|
+/* --- Fonctions publiques --- */
|
|
|
+
|
|
|
+int json_parse(JsonParser* this, char* json) {
|
|
|
+ //Declaration variable
|
|
|
+ char* tmp;
|
|
|
+ int temp, compteur;
|
|
|
+ boolean key = true;
|
|
|
+ //Compte le nombre de clef
|
|
|
+ compteur = key_counter(json);
|
|
|
+ //Allocation de la taille des tableaux
|
|
|
+ this->str = malloc(strlen(json) * sizeof (char));
|
|
|
+ strcpy(this->str, json);
|
|
|
+ this->key = malloc(compteur * sizeof (char*));
|
|
|
+ this->key_length = malloc(compteur * sizeof (int));
|
|
|
+ this->val = malloc(compteur * sizeof (char*));
|
|
|
+ this->val_length = malloc(compteur * sizeof (int));
|
|
|
+ this->type = malloc(compteur * sizeof (int));
|
|
|
+ //On reparcours le tableau pour parser
|
|
|
+ tmp = this->str;
|
|
|
+ compteur = 0;
|
|
|
+ while (*tmp && *tmp != '}') {
|
|
|
+ //Si on trouve une clef
|
|
|
+ if (*tmp == '"') {
|
|
|
+ //Lecture clef de la clef
|
|
|
+ if((temp = parse_key(this, compteur, tmp)) == JSON_ERROR){ return parse_error(this); }
|
|
|
+ tmp += temp;
|
|
|
+ key = false;
|
|
|
+ }
|
|
|
+ //Si on trouve une valeur
|
|
|
+ else if(*tmp == ':'){
|
|
|
+ //Si pas de claf avant
|
|
|
+ if(key){ return parse_error(this); }
|
|
|
+ //Saute les espaces
|
|
|
+ tmp++;
|
|
|
+ while(*tmp == ' ') { tmp++; }
|
|
|
+ //Lecture valeur
|
|
|
+ printf("%s\n", tmp);
|
|
|
+ if((temp = parse_val(this, compteur, tmp)) == JSON_ERROR){ return parse_error(this); }
|
|
|
+ tmp += temp;
|
|
|
+ key = true;
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ tmp++;
|
|
|
+ }
|
|
|
+ //Si on s'arrete sur une clef
|
|
|
+ if(!key){
|
|
|
+ return parse_error(this);
|
|
|
+ }
|
|
|
+ //Sinon ok
|
|
|
+ return JSON_OK;
|
|
|
+}
|
|
|
+
|
|
|
+void clean_json_parser(JsonParser* this) {
|
|
|
+ free(this->key);
|
|
|
+ free(this->key_length);
|
|
|
+ free(this->val);
|
|
|
+ free(this->val_length);
|
|
|
+ free(this->type);
|
|
|
+ free(this->str);
|
|
|
+}
|