|
@@ -12,6 +12,135 @@
|
|
|
|
|
|
/* --- Fonctions privées parser --- */
|
|
|
|
|
|
+int val_counter(char* json) {
|
|
|
+ char* tmp = json + 1;
|
|
|
+ int nbElt = 0;
|
|
|
+ boolean empty = true;
|
|
|
+ //Parours la chaine
|
|
|
+ while (*tmp != ']' && *tmp) {
|
|
|
+ //printf("%c\n", *tmp);
|
|
|
+ fflush(stdout);
|
|
|
+ //Si on croise autre chose que du vide
|
|
|
+ if (empty && *tmp != ' ' && *tmp != ']') {
|
|
|
+ empty = false;
|
|
|
+ } //Si on croise un tableau ou un objet
|
|
|
+ else if (*tmp == '[' || *tmp == '{') {
|
|
|
+ //Saute
|
|
|
+ int jump;
|
|
|
+ if (*tmp == '{') {
|
|
|
+ jump = skip_object(tmp);
|
|
|
+ } else {
|
|
|
+ jump = skip_array(tmp);
|
|
|
+ }
|
|
|
+ tmp += jump;
|
|
|
+ //Si se termine mal
|
|
|
+ if (!*tmp) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ } //On compte les ',' separatrice
|
|
|
+ else if (*tmp == ',') {
|
|
|
+ nbElt++;
|
|
|
+ }
|
|
|
+ tmp++;
|
|
|
+ }
|
|
|
+ //Si non vide
|
|
|
+ if (!empty) {
|
|
|
+ nbElt++;
|
|
|
+ }
|
|
|
+ //Retourne le nombre d'element trouvé
|
|
|
+ return nbElt;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Extraction d'une valeur
|
|
|
+ * @param JsonParser* La structure pour sauvegarder l'extraction
|
|
|
+ * @param int La position dans la structure
|
|
|
+ * @param char* La chaine json
|
|
|
+ * @return int JSON_ERROR ou le nombre de caractère de la valeur
|
|
|
+ */
|
|
|
+int parse_array_val(JsonArray* 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->parser->val[index] = json - compteur;
|
|
|
+ this->parser->val_length[index] = compteur;
|
|
|
+ this->parser->type[index] = JSON_STRING;
|
|
|
+ break;
|
|
|
+ //Boolean
|
|
|
+ case 't':
|
|
|
+ compteur = 4;
|
|
|
+ this->parser->val[index] = json;
|
|
|
+ this->parser->val_length[index] = compteur;
|
|
|
+ this->parser->type[index] = JSON_BOOLEAN;
|
|
|
+ break;
|
|
|
+ case 'f':
|
|
|
+ compteur = 5;
|
|
|
+ this->parser->val[index] = json;
|
|
|
+ this->parser->val_length[index] = compteur;
|
|
|
+ this->parser->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
|
|
|
+ this->parser->val[index] = json - compteur;
|
|
|
+ this->parser->val_length[index] = compteur;
|
|
|
+ this->parser->type[index] = JSON_NUMBER;
|
|
|
+ break;
|
|
|
+ //Tableau
|
|
|
+ case '[':
|
|
|
+ compteur = skip_array(json) + 1;
|
|
|
+ this->parser->val[index] = json;
|
|
|
+ this->parser->val_length[index] = compteur;
|
|
|
+ this->parser->type[index] = JSON_ARRAY;
|
|
|
+ break;
|
|
|
+ //Objet
|
|
|
+ case '{':
|
|
|
+ compteur = skip_object(json) + 1;
|
|
|
+ this->parser->val[index] = json;
|
|
|
+ this->parser->val_length[index] = compteur;
|
|
|
+ this->parser->type[index] = JSON_OBJECT;
|
|
|
+ break;
|
|
|
+ //Autre
|
|
|
+ default:
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ return ++compteur;
|
|
|
+}
|
|
|
+
|
|
|
/* --- Fonctions privées encoder --- */
|
|
|
|
|
|
/**
|
|
@@ -50,6 +179,239 @@ void delete_json_array_node(JsonNode* node) {
|
|
|
|
|
|
/* --- Fonctions publiques parser --- */
|
|
|
|
|
|
+void ini_array_parser(JsonArray* this) {
|
|
|
+ //Initialisation en mode encoder
|
|
|
+ this->mode = JSON_ARRAY_PARSER;
|
|
|
+ this->parser = malloc(sizeof (JsonArrayParser));
|
|
|
+}
|
|
|
+
|
|
|
+int json_parse_array(JsonArray* this, char* json) {
|
|
|
+ int length, jump, index = 0, compteur = 1;
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ if (json[0] != '[') {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Compte le nombre d'éléments
|
|
|
+ this->parser->length = val_counter(json);
|
|
|
+ if (this->parser->length == JSON_ERROR) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ length = strlen(json) + 1;
|
|
|
+ this->parser->str = malloc(sizeof (char) * length);
|
|
|
+ memset(this->parser->str, 0, length);
|
|
|
+ strncpy(this->parser->str, json, length - 1);
|
|
|
+ //Si vide
|
|
|
+ if (this->parser->length == 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ //Initialisation
|
|
|
+ this->parser->val = malloc(sizeof (char*) * this->parser->length);
|
|
|
+ this->parser->val_length = malloc(sizeof (int) * this->parser->length);
|
|
|
+ this->parser->type = malloc(sizeof (int) * this->parser->length);
|
|
|
+ //Sinon on parse les valeurs
|
|
|
+ json++;
|
|
|
+ while (*json != ']' && *json) {
|
|
|
+ if (*json != ' ' && *json != ',') {
|
|
|
+ jump = parse_array_val(this, index, this->parser->str + compteur);
|
|
|
+ if (jump == JSON_ERROR) {
|
|
|
+ clean_json_array(this);
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ json += jump;
|
|
|
+ compteur += jump;
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ json++;
|
|
|
+ compteur++;
|
|
|
+ }
|
|
|
+ //Retourne le nombre d'element
|
|
|
+ return this->parser->length;
|
|
|
+}
|
|
|
+
|
|
|
+int get_array_length(JsonArray* this) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ return this->parser->length;
|
|
|
+}
|
|
|
+
|
|
|
+int get_array_type(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Retourne le type
|
|
|
+ return this->parser->type[index];
|
|
|
+}
|
|
|
+
|
|
|
+char* get_array_index(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Creation string d'accueil
|
|
|
+ char* val;
|
|
|
+ val = malloc((this->parser->val_length[index] + 1) * sizeof (char)); //+1 pour \0
|
|
|
+ memset(val, 0, this->parser->val_length[index] + 1);
|
|
|
+ //Copie valeur
|
|
|
+ strncpy(val, this->parser->val[index], this->parser->val_length[index]);
|
|
|
+ //Retour
|
|
|
+ return val;
|
|
|
+}
|
|
|
+
|
|
|
+char* get_array_value(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ return get_array_index(this, index);
|
|
|
+}
|
|
|
+
|
|
|
+char* get_array_string(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ if (this->parser->type[index] != JSON_STRING) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ return get_array_index(this, index);
|
|
|
+}
|
|
|
+
|
|
|
+double get_array_number(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ if (this->parser->type[index] != JSON_NUMBER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ char* val;
|
|
|
+ val = get_array_index(this, index);
|
|
|
+ double res;
|
|
|
+ res = atof(val);
|
|
|
+ free(val);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+int get_array_integer(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ if (this->parser->type[index] != JSON_NUMBER) {
|
|
|
+ return JSON_ERROR;
|
|
|
+ }
|
|
|
+ char* val;
|
|
|
+ val = get_array_index(this, index);
|
|
|
+ int res;
|
|
|
+ res = atoi(val);
|
|
|
+ free(val);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+boolean get_array_boolean(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Verif type
|
|
|
+ if (this->parser->type[index] != JSON_BOOLEAN) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //Recup valeur
|
|
|
+ char* val;
|
|
|
+ val = get_array_index(this, index);
|
|
|
+ //Cast et retour
|
|
|
+ if (val[0] == 't') {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+JsonArray* get_array_array(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Verif type
|
|
|
+ if (this->parser->type[index] != JSON_ARRAY) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Recup valeur
|
|
|
+ char* val;
|
|
|
+ val = get_array_index(this, index);
|
|
|
+ //Parse
|
|
|
+ JsonArray* json;
|
|
|
+ json = malloc(sizeof (JsonArray));
|
|
|
+ ini_array_parser(json);
|
|
|
+ if (json_parse_array(json, val) == JSON_ERROR) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Retour JSON utilisable
|
|
|
+ free(val);
|
|
|
+ return json;
|
|
|
+}
|
|
|
+
|
|
|
+JsonParser* get_array_object(JsonArray* this, int index) {
|
|
|
+ //Verification
|
|
|
+ if (this->mode != JSON_ARRAY_PARSER) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= this->parser->length) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Verif type
|
|
|
+ if (this->parser->type[index] != JSON_OBJECT) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Recup valeur
|
|
|
+ char* val;
|
|
|
+ val = get_array_index(this, index);
|
|
|
+ //Parse
|
|
|
+ JsonParser* json;
|
|
|
+ json = malloc(sizeof (JsonParser));
|
|
|
+ if (json_parse(json, val) == JSON_ERROR) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ //Retour JSON utilisable
|
|
|
+ free(val);
|
|
|
+ return json;
|
|
|
+}
|
|
|
+
|
|
|
/* --- Fonctions publiques encoder --- */
|
|
|
|
|
|
void ini_array_encoder(JsonArray* this) {
|
|
@@ -185,7 +547,6 @@ char* json_encode_array(JsonArray* this) {
|
|
|
|
|
|
void clean_json_array(JsonArray* this) {
|
|
|
if (this->mode) {
|
|
|
- //Encoder
|
|
|
JsonNode* node, * tmp;
|
|
|
node = this->encoder->tab;
|
|
|
while (node != NULL) {
|
|
@@ -194,10 +555,15 @@ void clean_json_array(JsonArray* this) {
|
|
|
free(node);
|
|
|
node = tmp;
|
|
|
}
|
|
|
- //Reset la structure
|
|
|
free(this->encoder);
|
|
|
- this->mode = -1;
|
|
|
+
|
|
|
} else {
|
|
|
//Parser
|
|
|
+ free(this->parser->type);
|
|
|
+ free(this->parser->val_length);
|
|
|
+ free(this->parser->val);
|
|
|
+ free(this->parser->str);
|
|
|
+ free(this->parser);
|
|
|
}
|
|
|
+ this->mode = -1;
|
|
|
}
|