Browse Source

Refonte JsonEncoder

Arthur Brandao 6 years ago
parent
commit
eb2176bb85
2 changed files with 146 additions and 187 deletions
  1. 4 3
      Serveur/json.h
  2. 142 184
      Serveur/json_encoder.c

+ 4 - 3
Serveur/json.h

@@ -12,6 +12,7 @@
 #include "constante.h"
 
 /* --- Constante --- */
+#define JSON_MAX_SIZE 16384
 #define JSON_ERROR -1
 #define JSON_OK 0
 #define JSON_STRING 1
@@ -36,9 +37,9 @@ typedef struct{
 }JsonParser;
 
 typedef struct{
-    JsonNode* head;
-    JsonNode* tail;
-    int length;
+    char json[JSON_MAX_SIZE];
+    int max;
+    int pos;
 }JsonEncoder;
 
 typedef struct{

+ 142 - 184
Serveur/json_encoder.c

@@ -9,78 +9,50 @@
 #include <math.h>
 #include "json.h"
 
-/* --- Fonctions privée --- */
-
-/**
- * Ajout un noeud au JsonEncoder
- * @param JsonEncoder* La structure pour encoder 
- * @param char* La chaine à mettre dans le noeud
- */
-void add_json_node(JsonEncoder* this, char* str){
-    //Création node
-    JsonNode* node;
-    node = malloc(sizeof(JsonNode));
-    //Allocation node
-    int length = strlen(str) + 1;
-    node->str = malloc(length * sizeof(char));
-    memset(node->str, 0, length);
-    strncpy(node->str, str, length - 1);
-    //Si 1er node
-    if(this->head == NULL){
-        this->head = node;
-        node->prev = NULL;
-    } else {
-        node->prev = this->tail;
-        node->prev->next = node;
-    }
-    this->tail = node;
-    node->next = NULL;
-}
-
-/**
- * Supprimme un noeud
- * @param JsonNode* Le noeud à supprimer
- */
-void delete_json_node(JsonNode* node){
-    free(node->str);
-}
-
 /* --- Fonctions publique --- */
 
 void ini_encoder(JsonEncoder* this){
-    this->head = NULL;
-    this->tail = NULL;
-    this->length = 0;
+    this->max = JSON_MAX_SIZE;
+    this->pos = 1;
+    memset(this->json, 0, this->max);
+    this->json[0] = '{';
 }
 
 void add_value(JsonEncoder* this, char* str){
-    //Ajoute la longueur de la chaine au total
-    this->length += strlen(str) + 2; //Chaine + ", "
-    //Ajoute le noeud
-    add_json_node(this, str);
+    //Verif que l'on ne depasse pas (on retire 1 pour garder un \0 et on retire 1 autre pour pouvoir mettre })
+    if(this->pos + strlen(str) >= this->max - 2){
+        return;
+    }
+    //Ajoute
+    for(int i = 0; i < strlen(str); i++){
+        this->json[this->pos++] = str[i];
+    }
 }
 
 void add_string(JsonEncoder* this, char* key, char* val){
-    //Creation chaine
-    int index = 0, length = strlen(key) + strlen(val) + 4 + 2 + 1; //clef + val + 4 guillemet + ": " + \0
-    char* str = malloc(length * sizeof(char)); 
-    memset(str, 0, length);
-    //Copie
-    str[index++] = '"';
-    for(int i = 0; i < strlen(key); i++, index++){
-        str[index] = key[i];
+    int length = strlen(key) + strlen(val) + 4 + 2 + 2; //clef + val + 4 guillemet + ": " + ", "
+    //Verif que l'on ne depasse pas
+    if(this->pos + length >= this->max - 2){
+        return;
     }
-    str[index++] = '"';
-    str[index++] = ':';
-    str[index++] = ' ';
-    str[index++] = '"';
-    for(int i = 0; i < strlen(val); i++, index++){
-        str[index] = val[i];
+    //Ajoute
+    if(this->pos != 1){
+        //Si pas 1er valeur on ajoute un separateur
+        this->json[this->pos++] = ',';
+        this->json[this->pos++] = ' ';
     }
-    str[index++] = '"';
-    //Ajout
-    add_value(this, str);
-    free(str);
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(key); i++){
+        this->json[this->pos++] = key[i];
+    }
+    this->json[this->pos++] = '"';
+    this->json[this->pos++] = ':';
+    this->json[this->pos++] = ' ';
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(val); i++){
+        this->json[this->pos++] = val[i];
+    }
+    this->json[this->pos++] = '"';
 }
 
 void add_number(JsonEncoder* this, char* key, double val, int ndigit){
@@ -88,23 +60,27 @@ void add_number(JsonEncoder* this, char* key, double val, int ndigit){
     char nombre[20];
     ftoa(val, nombre, ndigit);
     //Creation chaine
-    int index = 0, length = strlen(key) + strlen(nombre) + 2 + 2 + 1; //clef + val + 2 guillemets + ": " + \0
-    char* str = malloc(length * sizeof(char));
-    memset(str, 0, length);
-    //Copie
-    str[index++] = '"';
-    for(int i = 0; i < strlen(key); i++, index++){
-        str[index] = key[i];
+    int length = strlen(key) + strlen(nombre) + 2 + 2 + 2; //clef + val + 2 guillemet + ": " + ", "
+    //Verif que l'on ne depasse pas
+    if(this->pos + length >= this->max - 2){
+        return;
+    }
+    //Ajoute
+    if(this->pos != 1){
+        //Si pas 1er valeur on ajoute un separateur
+        this->json[this->pos++] = ',';
+        this->json[this->pos++] = ' ';
     }
-    str[index++] = '"';
-    str[index++] = ':';
-    str[index++] = ' ';
-    for(int i = 0; i < strlen(nombre); i++, index++){
-        str[index] = nombre[i];
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(key); i++){
+        this->json[this->pos++] = key[i];
+    }
+    this->json[this->pos++] = '"';
+    this->json[this->pos++] = ':';
+    this->json[this->pos++] = ' ';
+    for(int i = 0; i < strlen(nombre); i++){
+        this->json[this->pos++] = nombre[i];
     }
-    //Ajout
-    add_value(this, str);
-    free(str);
 }
 
 void add_integer(JsonEncoder* this, char* key, int val){
@@ -112,23 +88,27 @@ void add_integer(JsonEncoder* this, char* key, int val){
     char nombre[20];
     snprintf(nombre, 20, "%d", val);
     //Creation chaine
-    int index = 0, length = strlen(key) + strlen(nombre) + 2 + 2 + 1; //clef + val + 2 guillemets + ": " + \0
-    char* str = malloc(length * sizeof(char));
-    memset(str, 0, length);
-    //Copie
-    str[index++] = '"';
-    for(int i = 0; i < strlen(key); i++, index++){
-        str[index] = key[i];
+    int length = strlen(key) + strlen(nombre) + 2 + 2 + 2; //clef + val + 2 guillemet + ": " + ", "
+    //Verif que l'on ne depasse pas
+    if(this->pos + length >= this->max - 2){
+        return;
+    }
+    //Ajoute
+    if(this->pos != 1){
+        //Si pas 1er valeur on ajoute un separateur
+        this->json[this->pos++] = ',';
+        this->json[this->pos++] = ' ';
     }
-    str[index++] = '"';
-    str[index++] = ':';
-    str[index++] = ' ';
-    for(int i = 0; i < strlen(nombre); i++, index++){
-        str[index] = nombre[i];
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(key); i++){
+        this->json[this->pos++] = key[i];
+    }
+    this->json[this->pos++] = '"';
+    this->json[this->pos++] = ':';
+    this->json[this->pos++] = ' ';
+    for(int i = 0; i < strlen(nombre); i++){
+        this->json[this->pos++] = nombre[i];
     }
-    //Ajout
-    add_value(this, str);
-    free(str);
 }
 
 void add_boolean(JsonEncoder* this, char* key, boolean val){
@@ -140,23 +120,27 @@ void add_boolean(JsonEncoder* this, char* key, boolean val){
         strcpy(bool, "false");
     }
     //Creation chaine
-    int index = 0, length = strlen(key) + strlen(bool) + 2 + 2 + 1; //clef + val + 2 guillemets + ": " + \0
-    char* str = malloc(length * sizeof(char));
-    memset(str, 0, length);
-    //Copie
-    str[index++] = '"';
-    for(int i = 0; i < strlen(key); i++, index++){
-        str[index] = key[i];
+    int length = strlen(key) + strlen(bool) + 2 + 2 + 2; //clef + val + 2 guillemet + ": " + ", "
+    //Verif que l'on ne depasse pas
+    if(this->pos + length >= this->max - 2){
+        return;
     }
-    str[index++] = '"';
-    str[index++] = ':';
-    str[index++] = ' ';
-    for(int i = 0; i < strlen(bool); i++, index++){
-        str[index] = bool[i];
+    //Ajoute
+    if(this->pos != 1){
+        //Si pas 1er valeur on ajoute un separateur
+        this->json[this->pos++] = ',';
+        this->json[this->pos++] = ' ';
+    }
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(key); i++){
+        this->json[this->pos++] = key[i];
+    }
+    this->json[this->pos++] = '"';
+    this->json[this->pos++] = ':';
+    this->json[this->pos++] = ' ';
+    for(int i = 0; i < strlen(bool); i++){
+        this->json[this->pos++] = bool[i];
     }
-    //Ajout
-    add_value(this, str);
-    free(str);
 }
 
 void add_array(JsonEncoder* this, char* key, JsonArray* val){
@@ -168,23 +152,29 @@ void add_array(JsonEncoder* this, char* key, JsonArray* val){
     char* json;
     json = json_encode_array(val);
     //Creation chaine
-    int index = 0, length = strlen(key) + strlen(json) + 2 + 2 + 1; //clef + val + 2 guillemets + ": " + \0
-    char* str = malloc(length * sizeof(char));
-    memset(str, 0, length);
-    //Copie
-    str[index++] = '"';
-    for(int i = 0; i < strlen(key); i++, index++){
-        str[index] = key[i];
+    int length = strlen(key) + strlen(json) + 2 + 2 + 2; //clef + val + 2 guillemet + ": " + ", "
+    //Verif que l'on ne depasse pas
+    if(this->pos + length >= this->max - 2){
+        free(json);
+        return;
+    }
+    //Ajoute
+    if(this->pos != 1){
+        //Si pas 1er valeur on ajoute un separateur
+        this->json[this->pos++] = ',';
+        this->json[this->pos++] = ' ';
     }
-    str[index++] = '"';
-    str[index++] = ':';
-    str[index++] = ' ';
-    for(int i = 0; i < strlen(json); i++, index++){
-        str[index] = json[i];
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(key); i++){
+        this->json[this->pos++] = key[i];
     }
-    //Ajout
-    add_value(this, str);
-    free(str);
+    this->json[this->pos++] = '"';
+    this->json[this->pos++] = ':';
+    this->json[this->pos++] = ' ';
+    for(int i = 0; i < strlen(json); i++){
+        this->json[this->pos++] = json[i];
+    }
+    //Nettoyage
     free(json);
 }
 
@@ -193,76 +183,44 @@ void add_object(JsonEncoder* this, char* key, JsonEncoder* val){
     char* json;
     json = json_encode(val);
     //Creation chaine
-    int index = 0, length = strlen(key) + strlen(json) + 2 + 2 + 1; //clef + val + 2 guillemets + ": " + \0
-    char* str = malloc(length * sizeof(char));
-    memset(str, 0, length);
-    //Copie
-    str[index++] = '"';
-    for(int i = 0; i < strlen(key); i++, index++){
-        str[index] = key[i];
+    int length = strlen(key) + strlen(json) + 2 + 2 + 2; //clef + val + 2 guillemet + ": " + ", "
+    //Verif que l'on ne depasse pas
+    if(this->pos + length >= this->max - 2){
+        free(json);
+        return;
+    }
+    //Ajoute
+    if(this->pos != 1){
+        //Si pas 1er valeur on ajoute un separateur
+        this->json[this->pos++] = ',';
+        this->json[this->pos++] = ' ';
+    }
+    this->json[this->pos++] = '"';
+    for(int i = 0; i < strlen(key); i++){
+        this->json[this->pos++] = key[i];
     }
-    str[index++] = '"';
-    str[index++] = ':';
-    str[index++] = ' ';
-    for(int i = 0; i < strlen(json); i++, index++){
-        str[index] = json[i];
+    this->json[this->pos++] = '"';
+    this->json[this->pos++] = ':';
+    this->json[this->pos++] = ' ';
+    for(int i = 0; i < strlen(json); i++){
+        this->json[this->pos++] = json[i];
     }
-    //Ajout
-    add_value(this, str);
-    free(str);
+    //Nettoyage
     free(json);
 }
 
 char* json_encode(JsonEncoder* this){
-    boolean first = true;
-    int length, index = 0;
-    //Allocation chaine
-    char* str;
-    str = malloc((this->length + 2) * sizeof(char)); // La chaine + {}
-    memset(str, 0, this->length + 2);
-    //Creation de la chaine
-    JsonNode* node;
-    node = this->head;
-    str[index++] = '{';
-    while(node != NULL){
-        if(!first){
-            str[index++] = ',';
-            str[index++] = ' ';
-        }
-        length = strlen(node->str);
-        for(int i = 0; i < length; i++, index++){
-            str[index] = node->str[i];
-        }
-        if(first){
-            first = false;
-        }
-        /*if(first){
-            snprintf(str, this->length + 2, "%s%s", str, node->str);
-            printf("Json %s\n", str);
-            first = false;
-        } else {
-            snprintf(str, this->length + 2, "%s, %s", str, node->str);
-            printf("Json %s\n", str);
-        }*/
-        node = node->next;
-    }
-    str[index++] = '}';
-    //Retour
-    return str;
+    char* json;
+    //Ajoute } fin
+    this->json[this->pos] = '}';
+    //Creation chaine
+    json = malloc(sizeof(char) * (this->pos + 2));
+    memset(json, 0, this->pos + 2);
+    strncpy(json, this->json, this->pos + 1);
+    //Retourne
+    return json;
 }
 
 void clean_json_encoder(JsonEncoder* this){
-    //Parcours les noeuds et les supprimes
-    JsonNode* node, * tmp;
-    node = this->head;
-    while(node != NULL){
-        tmp = node->next;
-        delete_json_node(node);
-        free(node);
-        node = tmp;
-    }
-    //Reset la structure
-    this->head = NULL;
-    this->tail = NULL;
-    this->length = 0;
+    ini_encoder(this);
 }