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 }