00001 
00007 #include "gclibo.h"
00008 
00010 struct H_ArrayData
00011 {
00012   char name[16]; 
00013   char* data; 
00014   int len; 
00015   int elements; 
00016   int index; 
00017 
00018   struct H_ArrayData* next; 
00019 
00020   
00021   struct H_ArrayData * tail; 
00022   int count; 
00023   
00024 };
00025 typedef struct H_ArrayData ArrayNode;
00026 
00028 void H_InitArrayNode(ArrayNode* node)
00029 {
00030   node->count = 0;
00031   node->data = 0;
00032   node->index = 0;
00033   node->len = 0;
00034   node->name[0] = 0;
00035   node->next = 0; 
00036   node->tail = 0;
00037   node->elements = 0;
00038   
00039 }
00040 
00042 GReturn H_AddArray(ArrayNode* head, char* name, char* data)
00043 {
00044   ArrayNode* node; 
00045   if (head->count == 0) 
00046     node = head;
00047   else
00048   {
00049     node = malloc(sizeof(ArrayNode));
00050     if (node) 
00051       H_InitArrayNode(node);
00052     else
00053       return G_BAD_FULL_MEMORY; 
00054   }
00055 
00056   node->data = data; 
00057   strcpy(node->name, name); 
00058   node->len = strlen(node->data); 
00059 
00060   head->count++; 
00061   head->tail->next = node; 
00062   node->next = 0; 
00063   head->tail = node; 
00064   
00065   return G_NO_ERROR;
00066 }
00067 
00069 void H_FreeArrays(ArrayNode* node)
00070 {
00071   if (node == 0) return; 
00072   free(node->data); 
00073   H_FreeArrays(node->next); 
00074   free(node->next); 
00075   
00076 }
00077 
00079 GReturn H_UploadArrayToList(GCon g, ArrayNode* head, char* name)
00080 {
00081   GReturn rc = G_NO_ERROR; 
00082   char* array_buf; 
00083   if (!(array_buf = malloc(MAXARRAY))) 
00084     return G_BAD_FULL_MEMORY;
00085 
00086   if ((rc = GArrayUpload(g, name, G_BOUNDS, G_BOUNDS, G_CR, array_buf, MAXARRAY)) != G_NO_ERROR) 
00087     return rc;
00088 
00089   return H_AddArray(head, name, array_buf); 
00090 }
00091 
00093 GReturn H_CreateArrayNode(ArrayNode* head, char* name)
00094 {
00095   char* array_buf; 
00096   if (!(array_buf = malloc(MAXARRAY))) 
00097     return G_BAD_FULL_MEMORY;
00098   array_buf[0] = 0; 
00099   return H_AddArray(head, name, array_buf); 
00100 }
00101 
00103 GReturn H_ArrayAddElement(ArrayNode* node, GCStringIn element)
00104 {
00105   int len = strlen(element);
00106   if ((len + node->index + 1) >= MAXARRAY) 
00107     return G_BAD_FULL_MEMORY;
00108 
00109   strcpy(node->data + node->index, element); 
00110   node->index += len;
00111   node->data[node->index++] = '\r'; 
00112   node->data[node->index] = 0; 
00113   node->len = node->index; 
00114   node->elements++; 
00115   return G_NO_ERROR;
00116 }
00117 
00119 
00126 GReturn H_DownloadArraysFromList(GCon g, ArrayNode* head)
00127 {
00128   ArrayNode* node = head;
00129   GReturn rc = G_NO_ERROR;
00130   char command[32]; 
00131   while ((node != 0) && (rc == G_NO_ERROR))
00132   {
00133 
00134     
00135     
00136     sprintf(command, "DA %s[]", node->name);
00137     if ((rc = GCmd(g, command)) != G_NO_ERROR)
00138       return rc;
00139 
00140     
00141     sprintf(command, "DM %s[%i]", node->name, node->elements);
00142     if ((rc = GCmd(g, command)) != G_NO_ERROR)
00143       return rc;
00144     
00145 
00146     rc = GArrayDownload(g, node->name, G_BOUNDS, G_BOUNDS, node->data); 
00147     node = node->next;
00148   }
00149   return rc;
00150 }
00151 
00153 GReturn H_WriteArrayCsv(ArrayNode* head, GCStringIn file_path)
00154 {
00155   if (head->count == 0) 
00156     return G_NO_ERROR;
00157 
00158   FILE *file; 
00159   size_t bytes; 
00160   size_t bytes_written; 
00161   int colcount = 0; 
00162   int data_left = head->count; 
00163   ArrayNode* node = head; 
00164 
00165   if (!(file = fopen(file_path, "wb"))) 
00166     return G_BAD_FILE;
00167 
00168   
00169   do
00170   {
00171     bytes = strlen(node->name);
00172     bytes_written = fwrite(node->name, 1, bytes, file);
00173     colcount++;
00174 
00175     if (colcount != head->count) 
00176     {
00177       bytes_written += fwrite(",", 1, 1, file);
00178       bytes++;
00179     }
00180     else 
00181     {
00182       bytes_written += fwrite("\r", 1, 1, file);
00183       bytes++;
00184     }
00185 
00186     if (bytes_written != bytes) 
00187     {
00188       fclose(file);
00189       return G_BAD_FILE;
00190     }
00191     node = node->next;
00192   } while (node != 0);
00193 
00194 
00195   
00196   while (data_left) 
00197   {
00198     node = head;
00199     colcount = 0;
00200     do 
00201     {
00202       bytes_written = 0;
00203       bytes = 0;
00204       if (node->index != node->len) 
00205       {
00206         while ((node->data[node->index] != '\r') 
00207           && (node->index < node->len)) 
00208         {
00209           if (node->data[node->index] != ' ') 
00210           {
00211             bytes_written += fwrite(node->data + node->index, 1, 1, file);
00212             bytes++;
00213           }
00214           node->index++;
00215         }
00216 
00217         if (node->index == node->len) 
00218           data_left--; 
00219 
00220         node->index++; 
00221       }
00222 
00223       colcount++; 
00224       if (colcount != head->count) 
00225       {
00226         bytes_written += fwrite(",", 1, 1, file);
00227         bytes++;
00228       }
00229       else 
00230       {
00231         bytes_written += fwrite("\r", 1, 1, file);
00232         bytes++;
00233       }
00234 
00235       
00236       if (bytes_written != bytes)
00237       {
00238         fclose(file);
00239         return G_BAD_FILE;
00240       }
00241 
00242       node = node->next;
00243     } while (node != 0);
00244   } 
00245 
00246   fclose(file);
00247   return G_NO_ERROR;
00248 }
00249 
00250 
00251 GReturn GCALL GArrayDownloadFile(GCon g, GCStringIn file_path)
00252 {
00253   FILE *file;
00254   GReturn rc = G_NO_ERROR;
00255   char name[32]; 
00256   int n; 
00257   char element[32]; 
00258   int e; 
00259   char c; 
00260 
00261   
00262   ArrayNode head; 
00263   ArrayNode* node; 
00264   H_InitArrayNode(&head);
00265   head.tail = &head; 
00266 
00267   if (!(file = fopen(file_path, "rb"))) 
00268     return G_BAD_FILE;
00269 
00270   
00271   n = 0;
00272   c = 0;
00273   while (fread(&c, 1, 1, file))
00274   {
00275     if ((c == ',') || (c == '\r'))
00276     {
00277       if (n)
00278       {
00279         name[n] = 0; 
00280         n = 0; 
00281         H_CreateArrayNode(&head, name);
00282       }
00283 
00284       if (c == '\r') 
00285         break; 
00286     }
00287     else
00288     {
00289       name[n++] = c;
00290     }
00291   }
00292 
00293   
00294   node = &head;
00295   e = 0;
00296   while (fread(&c, 1, 1, file))
00297   {
00298     if ((c == ',') || (c == '\r'))
00299     {
00300       if (e) 
00301       {
00302         element[e] = 0; 
00303         H_ArrayAddElement(node, element);
00304         e = 0; 
00305       }
00306       node = node->next; 
00307       if (node == 0) node = &head; 
00308     }
00309     else
00310     {
00311       element[e++] = c;
00312     }
00313   }
00314 
00315 
00316 
00317   fclose(file); 
00318 
00319   
00320   rc = H_DownloadArraysFromList(g, &head);
00321   H_FreeArrays(&head); 
00322   return rc;
00323 }
00324 
00325 
00326 GReturn GCALL GArrayUploadFile(GCon g, GCStringIn file_path, GCStringIn names)
00327 {
00328 
00329   GReturn rc = G_NO_ERROR; 
00330   long bytes; 
00331   char array_names[1024]; 
00332   char name[32]; 
00333   int i, n; 
00334   char c; 
00335   int bracket = 0; 
00336 
00337   
00338   ArrayNode head; 
00339   H_InitArrayNode(&head);
00340   head.tail = &head; 
00341 
00342   if (names == 0) 
00343     bytes = 0;
00344   else
00345     bytes = strlen(strcpy(array_names, names));
00346 
00347   if (bytes == 0) 
00348   {
00349     if ((rc = GCmdT(g, "LA", array_names, sizeof(array_names), 0)) != G_NO_ERROR) 
00350       return rc; 
00351 
00352     bytes = strlen(array_names); 
00353   }
00354 
00355   n = 0; 
00356   for (i = 0; i < bytes; i++)
00357   {
00358     c = array_names[i];
00359 
00360     if (c == '[')
00361       bracket++; 
00362     
00363     if ((c != ' ') && (c != '\r') && (c != '\n') && !bracket)
00364     {
00365       name[n++] = array_names[i]; 
00366     }
00367     
00368     
00369     if ((c == ' ') || (c == '\r') || (i == bytes - 1))
00370     {
00371       if (n) 
00372       {
00373         name[n] = 0; 
00374         n = 0; 
00375         bracket = 0; 
00376 
00377         if ((rc = H_UploadArrayToList(g, &head, name)) != G_NO_ERROR) 
00378         {
00379           H_FreeArrays(&head); 
00380           return rc;
00381         }
00382       }
00383       continue;
00384     }
00385 
00386   }
00387 
00388   
00389   rc = H_WriteArrayCsv(&head, file_path);
00390   H_FreeArrays(&head); 
00391   return rc;
00392 }