Author: sveinung
Date: Sun Apr 26 02:47:25 2015
New Revision: 28876

URL: http://svn.gna.org/viewcvs/freeciv?rev=28876&view=rev
Log:
JSON protocol: Send and receive field arrays as JSON arrays.

This replaces sending each array element as a separate field with the array
element number added to the original field name.

Requested by Andreas Røsdal <andreasr> and Marko Lindqvist <cazfi>

Tested by Andreas Røsdal <andreasr>

See patch #5955

Modified:
    trunk/common/dataio.c
    trunk/common/dataio.h
    trunk/common/dataio_json.c
    trunk/common/dataio_json.h
    trunk/common/generate_packets.py

Modified: trunk/common/dataio.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/dataio.c?rev=28876&r1=28875&r2=28876&view=diff
==============================================================================
--- trunk/common/dataio.c       (original)
+++ trunk/common/dataio.c       Sun Apr 26 02:47:25 2015
@@ -1043,3 +1043,17 @@
 
   return out;
 }
+
+/**************************************************************************
+ Create a new address of the location of an array element inside a packet.
+**************************************************************************/
+struct plocation *plocation_elem_new(int number)
+{
+  struct plocation *out = fc_malloc(sizeof(*out));
+
+  out->kind = PADR_ELEMENT;
+  out->number = number;
+  out->sub_location = NULL;
+
+  return out;
+}

Modified: trunk/common/dataio.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/dataio.h?rev=28876&r1=28875&r2=28876&view=diff
==============================================================================
--- trunk/common/dataio.h       (original)
+++ trunk/common/dataio.h       Sun Apr 26 02:47:25 2015
@@ -75,6 +75,7 @@
 };
 
 struct plocation *plocation_field_new(char *name);
+struct plocation *plocation_elem_new(int number);
 
 #ifdef FREECIV_JSON_CONNECTION
 #include "dataio_json.h"

Modified: trunk/common/dataio_json.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/dataio_json.c?rev=28876&r1=28875&r2=28876&view=diff
==============================================================================
--- trunk/common/dataio_json.c  (original)
+++ trunk/common/dataio_json.c  Sun Apr 26 02:47:25 2015
@@ -457,6 +457,24 @@
 }
 
 /**************************************************************************
+  Create an empthy field array.
+**************************************************************************/
+void dio_put_farray_json(struct json_data_out *dout, char *key,
+                         const struct plocation* location, int size)
+{
+  int i;
+  json_t *farray = json_array();
+
+  /* Jansson's json_array_set_new() refuses to create array elements so
+   * they must be created with the array. */
+  for (i = 0; i < size; i++) {
+    json_array_append_new(farray, json_null());
+  }
+
+  plocation_write_data(dout->json, location, farray);
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 void dio_put_uint32_json(struct json_data_out *dout, char *key,

Modified: trunk/common/dataio_json.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/dataio_json.h?rev=28876&r1=28875&r2=28876&view=diff
==============================================================================
--- trunk/common/dataio_json.h  (original)
+++ trunk/common/dataio_json.h  Sun Apr 26 02:47:25 2015
@@ -107,6 +107,9 @@
   dio_get_##f##_json(pc->json_packet, k, l, ## __VA_ARGS__)
 
 /* puts */
+void dio_put_farray_json(struct json_data_out *dout, char *key,
+                         const struct plocation* location, int size);
+
 void dio_put_type_json(struct json_data_out *dout, enum data_type type,
                        char *key, const struct plocation* location,
                        int value);

Modified: trunk/common/generate_packets.py
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/generate_packets.py?rev=28876&r1=28875&r2=28876&view=diff
==============================================================================
--- trunk/common/generate_packets.py    (original)
+++ trunk/common/generate_packets.py    Sun Apr 26 02:47:25 2015
@@ -398,37 +398,93 @@
     {
       int i, j;
 
+      #ifdef FREECIV_JSON_CONNECTION
+      /* Create the outer array. */
+      DIO_PUT(farray, &dout, \"%(name)s\", &field_addr, %(array_size_u)s);
+
+      /* Enter the outer array. */
+      field_addr.sub_location = plocation_elem_new(0);
+      #endif /* FREECIV_JSON_CONNECTION */
+
       for (i = 0; i < %(array_size1_u)s; i++) {
+        #ifdef FREECIV_JSON_CONNECTION
+        /* Next inner array (an element in the outer array). */
+        field_addr.sub_location->number = i;
+
+        /* Create the inner array. */
+        DIO_PUT(farray, &dout, \"%(name)s\", &field_addr, %(array_size_u)s);
+
+        /* Enter the inner array. */
+        field_addr.sub_location->sub_location = plocation_elem_new(0);
+        #endif /* FREECIV_JSON_CONNECTION */
+
         for (j = 0; j < %(array_size2_u)s; j++) {
           char namestr[512];
 
           fc_snprintf(namestr, sizeof(namestr), \"%(name)s_%%%%d_%%%%d\", i, 
j);
           #ifdef FREECIV_JSON_CONNECTION
-          field_addr.name = namestr;
+          /* Next element (in the inner array). */
+          field_addr.sub_location->sub_location->number = j;
           #endif /* FREECIV_JSON_CONNECTION */
           %(c)s
         }
+
+        #ifdef FREECIV_JSON_CONNECTION
+        /* Exit the inner array. */
+        free(field_addr.sub_location->sub_location);
+        field_addr.sub_location->sub_location = NULL;
+        #endif /* FREECIV_JSON_CONNECTION */
       }
+
+      #ifdef FREECIV_JSON_CONNECTION
+      /* Exit the outer array. */
+      free(field_addr.sub_location);
+      field_addr.sub_location = NULL;
+      #endif /* FREECIV_JSON_CONNECTION */
     } '''%self.get_dict(vars())
             else:
                 return '''
     {
       int i;
+
+      #ifdef FREECIV_JSON_CONNECTION
+      /* Create the array. */
+      DIO_PUT(farray, &dout, \"%(name)s\", &field_addr, %(array_size_u)s);
+
+      /* Enter the array. */
+      field_addr.sub_location = plocation_elem_new(0);
+      #endif /* FREECIV_JSON_CONNECTION */
+
       for (i = 0; i < %(array_size_u)s; i++) {
         char namestr[512];
 
         fc_snprintf(namestr, sizeof(namestr), \"%(name)s_%%%%d\", i);
         #ifdef FREECIV_JSON_CONNECTION
-        field_addr.name = namestr;
+        /* Next array element. */
+        field_addr.sub_location->number = i;
         #endif /* FREECIV_JSON_CONNECTION */
         %(c)s
       }
+
+      #ifdef FREECIV_JSON_CONNECTION
+      /* Exit array. */
+      free(field_addr.sub_location);
+      field_addr.sub_location = NULL;
+      #endif /* FREECIV_JSON_CONNECTION */
     } '''%self.get_dict(vars())
         else:
             return '''
     {
       int i, count;
       char namestr[512];
+
+      #ifdef FREECIV_JSON_CONNECTION
+      /* Create the array. */
+      DIO_PUT(farray, &dout, \"%(name)s\", &field_addr, %(array_size_u)s);
+
+      /* Enter array. */
+      field_addr.sub_location = plocation_elem_new(0);
+      #endif /* FREECIV_JSON_CONNECTION */
 
       fc_assert(%(array_size_u)s < 255);
 
@@ -437,17 +493,51 @@
         if (old->%(name)s[i] != real_packet->%(name)s[i]) {
           fc_snprintf(namestr, sizeof(namestr), "index_%%%%d", count++);
           #ifdef FREECIV_JSON_CONNECTION
-          field_addr.name = namestr;
+          /* Next diff array element. */
+          field_addr.sub_location->number = count - 1;
+
+          /* Create the diff array element. */
+          DIO_PUT(farray, &dout, \"%(name)s\", &field_addr, %(array_size_u)s);
+
+          /* Enter diff array element (start at the index address). */
+          field_addr.sub_location->sub_location = plocation_elem_new(0);
           #endif /* FREECIV_JSON_CONNECTION */
           DIO_PUT(uint8, &dout, namestr, &field_addr, i);
+
+          #ifdef FREECIV_JSON_CONNECTION
+          /* Content address. */
+          field_addr.sub_location->sub_location->number = 1;
+          #endif /* FREECIV_JSON_CONNECTION */
           %(c)s
+
+          #ifdef FREECIV_JSON_CONNECTION
+          /* Exit diff array element. */
+          free(field_addr.sub_location->sub_location);
+          field_addr.sub_location->sub_location = NULL;
+          #endif /* FREECIV_JSON_CONNECTION */
         }
       }
       fc_snprintf(namestr, sizeof(namestr), "index_%%%%d", count++);
       #ifdef FREECIV_JSON_CONNECTION
-      field_addr.name = namestr;
+      field_addr.sub_location->number = count - 1;
+
+      /* Create the diff array element. */
+      DIO_PUT(farray, &dout, \"%(name)s\", &field_addr, %(array_size_u)s);
+
+      /* Enter diff array element. Point to index address. */
+      field_addr.sub_location->sub_location = plocation_elem_new(0);
       #endif /* FREECIV_JSON_CONNECTION */
       DIO_PUT(uint8, &dout, namestr, &field_addr, 255);
+
+      #ifdef FREECIV_JSON_CONNECTION
+      /* Exit diff array element. */
+      free(field_addr.sub_location->sub_location);
+      field_addr.sub_location->sub_location = NULL;
+
+      /* Exit array. */
+      free(field_addr.sub_location);
+      field_addr.sub_location = NULL;
+      #endif /* FREECIV_JSON_CONNECTION */
     } '''%self.get_dict(vars())
 
     # Returns a code fragement which will get the field if the
@@ -588,43 +678,103 @@
                 return '''
 {
   int i, j;
+
+  #ifdef FREECIV_JSON_CONNECTION
+  /* Enter outer array. */
+  field_addr.sub_location = plocation_elem_new(0);
+  #endif /* FREECIV_JSON_CONNECTION */
 %(extra)s
   for (i = 0; i < %(array_size1_u)s; i++) {
+    #ifdef FREECIV_JSON_CONNECTION
+    /* Update address of outer array element (inner array). */
+    field_addr.sub_location->number = i;
+
+    /* Enter inner array. */
+    field_addr.sub_location->sub_location = plocation_elem_new(0);
+    #endif /* FREECIV_JSON_CONNECTION */
     for (j = 0; j < %(array_size2_u)s; j++) {
       char namestr[512];
 
       fc_snprintf(namestr, sizeof(namestr), \"%(name)s_%%%%d_%%%%d\", i, j);
       #ifdef FREECIV_JSON_CONNECTION
-      field_addr.name = namestr;
+      /* Update address of element in inner array. */
+      field_addr.sub_location->sub_location->number = j;
       #endif /* FREECIV_JSON_CONNECTION */
       %(c)s
     }
-  }
+
+    #ifdef FREECIV_JSON_CONNECTION
+    /* Exit inner array. */
+    free(field_addr.sub_location->sub_location);
+    field_addr.sub_location->sub_location = NULL;
+    #endif /* FREECIV_JSON_CONNECTION */
+  }
+
+  #ifdef FREECIV_JSON_CONNECTION
+  /* Exit outer array. */
+  free(field_addr.sub_location);
+  field_addr.sub_location = NULL;
+  #endif /* FREECIV_JSON_CONNECTION */
 }'''%self.get_dict(vars())
             else:
                 return '''
 {
   int i;
+
+  #ifdef FREECIV_JSON_CONNECTION
+  /* Enter array. */
+  field_addr.sub_location = plocation_elem_new(0);
+  #endif /* FREECIV_JSON_CONNECTION */
 %(extra)s
   for (i = 0; i < %(array_size_u)s; i++) {
     char namestr[512];
 
     fc_snprintf(namestr, sizeof(namestr), \"%(name)s_%%%%d\", i);
     #ifdef FREECIV_JSON_CONNECTION
-    field_addr.name = namestr;
+    field_addr.sub_location->number = i;
     #endif /* FREECIV_JSON_CONNECTION */
     %(c)s
   }
+
+  #ifdef FREECIV_JSON_CONNECTION
+  /* Exit array. */
+  free(field_addr.sub_location);
+  field_addr.sub_location = NULL;
+  #endif /* FREECIV_JSON_CONNECTION */
 }'''%self.get_dict(vars())
         else:
             return '''
-for (;;) {
+int count;
+
+#ifdef FREECIV_JSON_CONNECTION
+/* Enter array. */
+field_addr.sub_location = plocation_elem_new(0);
+#endif /* FREECIV_JSON_CONNECTION */
+
+for (count = 0;; count++) {
   int i;
+
+  #ifdef FREECIV_JSON_CONNECTION
+  field_addr.sub_location->number = count;
+
+  /* Enter diff array element (start at the index address). */
+  field_addr.sub_location->sub_location = plocation_elem_new(0);
+  #endif /* FREECIV_JSON_CONNECTION */
 
   if (!DIO_GET(uint8, &din, \"%(name)s\", &field_addr, &i)) {
     RECEIVE_PACKET_FIELD_ERROR(%(name)s);
   }
   if (i == 255) {
+    #ifdef FREECIV_JSON_CONNECTION
+    /* Exit diff array element. */
+    free(field_addr.sub_location->sub_location);
+    field_addr.sub_location->sub_location = NULL;
+
+    /* Exit diff array. */
+    free(field_addr.sub_location);
+    field_addr.sub_location = NULL;
+    #endif /* FREECIV_JSON_CONNECTION */
+
     break;
   }
   if (i > %(array_size_u)s) {
@@ -637,11 +787,24 @@
 
     fc_snprintf(namestr, sizeof(namestr), \"%(name)s_%%%%d\", i);
     #ifdef FREECIV_JSON_CONNECTION
-    field_addr.name = namestr;
+    /* Content address. */
+    field_addr.sub_location->sub_location->number = 1;
     #endif /* FREECIV_JSON_CONNECTION */
     %(c)s
   }
-}'''%self.get_dict(vars())
+
+  #ifdef FREECIV_JSON_CONNECTION
+  /* Exit diff array element. */
+  free(field_addr.sub_location->sub_location);
+  field_addr.sub_location->sub_location = NULL;
+  #endif /* FREECIV_JSON_CONNECTION */
+}
+
+#ifdef FREECIV_JSON_CONNECTION
+/* Exit array. */
+free(field_addr.sub_location);
+field_addr.sub_location = NULL;
+#endif /* FREECIV_JSON_CONNECTION */'''%self.get_dict(vars())
 
 #'''
 


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to