gwenhywfar  5.10.1
csv.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Thu Oct 30 2003
3  copyright : (C) 2021 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 /* disable DBG_DEBUG() and DBG_VERBOUS() */
31 #define DISABLE_DEBUGLOG
32 
33 #include <gwenhywfar/text.h>
34 #include <gwenhywfar/debug.h>
35 #include <gwenhywfar/stringlist.h>
36 #include <gwenhywfar/dbio_be.h>
37 #include <gwenhywfar/syncio_file.h>
38 
39 #include <stdlib.h>
40 #include <string.h>
41 #include <assert.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <string.h>
46 #include <errno.h>
47 
48 
49 
50 GWENHYWFAR_EXPORT GWEN_PLUGIN *dbio_csv_factory(GWEN_PLUGIN_MANAGER *pm, const char *modName, const char *fileName);
51 
52 static GWEN_DBIO *_csvFactory(GWEN_PLUGIN *pl);
53 static int _csvExport(GWEN_DBIO *dbio,
54  GWEN_SYNCIO *sio,
55  GWEN_DB_NODE *data,
56  GWEN_DB_NODE *cfg,
57  uint32_t flags);
58 
59 static int _csvImport(GWEN_DBIO *dbio,
60  GWEN_SYNCIO *sio,
61  GWEN_DB_NODE *data,
62  GWEN_DB_NODE *cfg,
63  uint32_t flags);
64 
65 static GWEN_DBIO_CHECKFILE_RESULT _csvCheckFile(GWEN_DBIO *dbio, const char *fname);
66 
67 
68 static void _stringListToDb(GWEN_STRINGLIST *sl, GWEN_DB_NODE *colgr, GWEN_DB_NODE *dbData);
69 static GWEN_STRINGLIST *_splitFixedWithStringIntoStringlist(const char *s, int condense, GWEN_DB_NODE *cfg);
70 static int _getNameAndIndex(const char *name, char *buffer, unsigned int size);
71 static int _readCsvLine(GWEN_FAST_BUFFER *fb, GWEN_STRINGLIST *sl);
72 
73 
74 
75 
77 {
78  GWEN_DBIO *dbio;
79 
80  dbio=GWEN_DBIO_new("csv", "Imports and exports CSV data");
84  return dbio;
85 }
86 
87 
88 GWEN_PLUGIN *dbio_csv_factory(GWEN_PLUGIN_MANAGER *pm, const char *modName, const char *fileName)
89 {
90  GWEN_PLUGIN *pl;
91 
92  pl=GWEN_DBIO_Plugin_new(pm, modName, fileName);
93  assert(pl);
94 
96 
97  return pl;
98 
99 }
100 
101 
102 
103 int _csvExport(GWEN_DBIO *dbio, GWEN_SYNCIO *sio, GWEN_DB_NODE *data, GWEN_DB_NODE *cfg, GWEN_UNUSED uint32_t flags)
104 {
105  GWEN_DB_NODE *colgr;
106  GWEN_DB_NODE *n;
107  int delimiter;
108  int quote;
109  const char *p;
110  const char *groupName;
111  int err;
112  unsigned int column;
113  int title;
114  GWEN_FAST_BUFFER *fb;
115 
116  assert(dbio);
117  assert(sio);
118  assert(cfg);
119  assert(data);
120 
121  fb=GWEN_FastBuffer_new(512, sio);
122 
123  /* get general configuration */
124  colgr=GWEN_DB_GetGroup(cfg, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "columns");
125  if (!colgr) {
126  DBG_ERROR(0, "Error in configuration: No columns specified");
128  return GWEN_ERROR_INVALID;
129  }
130  p=GWEN_DB_GetCharValue(cfg, "delimiter", 0, ";");
131  if (strcasecmp(p, "TAB")==0)
132  delimiter=9;
133  else if (strcasecmp(p, "SPACE")==0)
134  delimiter=32;
135  else
136  delimiter=p[0];
137  quote=GWEN_DB_GetIntValue(cfg, "quote", 0, 1);
138  groupName=GWEN_DB_GetCharValue(cfg, "group", 0, "");
139  title=GWEN_DB_GetIntValue(cfg, "title", 0, 1);
140 
141  if (title) {
142  /* write title */
143  for (column=1; ; column++) {
144  int idx;
145  char namebuffer[64];
146  char numbuffer[16];
147  char *np;
148 
149  /* create name for column */
150  GWEN_Text_NumToString(column, numbuffer, sizeof(numbuffer), 0);
151  p=GWEN_DB_GetCharValue(colgr, numbuffer, 0, 0);
152  if (!p) {
153  /* no value. finished */
154  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
155  if (err<0) {
156  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
158  return err;
159  }
160  DBG_VERBOUS(GWEN_LOGDOMAIN, "No colums left, line finished");
161  break;
162  }
163  /* break down to name and index */
164  idx=_getNameAndIndex(p, namebuffer, sizeof(namebuffer));
165  if (idx==-1) {
166  DBG_INFO(0, "Error in configuration: Bad name for column %d",
167  column);
169  return GWEN_ERROR_GENERIC;
170  }
171 
172  /* add idx to name, if not 0 */
173  if (idx) {
174  GWEN_Text_NumToString(idx, numbuffer, sizeof(numbuffer), 0);
175  if (strlen(namebuffer)+strlen(numbuffer)+1>=sizeof(namebuffer)) {
176  DBG_ERROR(0, "Internal: namebuffer too small");
178  return -1;
179  }
180  strcat(namebuffer, numbuffer);
181  }
182  /* convert slashes to underscores */
183  np=namebuffer;
184  while (*np) {
185  if (*np=='/')
186  *np='_';
187  np++;
188  }
189 
190  if (column!=1) {
191  /* write delimiter */
192  GWEN_FASTBUFFER_WRITEBYTE(fb, err, delimiter);
193  if (err<0) {
194  DBG_INFO(0, "Called from here");
196  return err;
197  }
198  } /* if not first column */
199  if (quote) {
200  /* write quotation mark */
201  GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
202  if (err<0) {
203  DBG_INFO(0, "Called from here");
205  return err;
206  }
207  } /* if quote */
208  /* write value */
209  GWEN_FASTBUFFER_WRITEFORCED(fb, err, namebuffer, -1);
210  if (err<0) {
211  DBG_INFO(0, "Called from here");
213  return err;
214  }
215  if (quote) {
216  /* write quotation mark */
217  GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
218  if (err<0) {
219  DBG_INFO(0, "Called from here");
221  return err;
222  }
223  } /* if quote */
224  } /* for */
225  } /* if title */
226 
227  n=GWEN_DB_GetFirstGroup(data);
228  while (n) {
229  if (*groupName==0 || strcasecmp(groupName, GWEN_DB_GroupName(n))==0) {
230  for (column=1; ; column++) {
231  int idx;
232  char namebuffer[64];
233  char numbuffer[16];
235  char valbuffer[64];
236  int iv;
237 
238  /* create name for column */
239  GWEN_Text_NumToString(column, numbuffer, sizeof(numbuffer), 0);
240  p=GWEN_DB_GetCharValue(colgr, numbuffer, 0, 0);
241  if (!p) {
242  /* no value. finished */
243  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
244  if (err<0) {
245  DBG_INFO(0, "Called from here");
247  return err;
248  }
249  DBG_VERBOUS(GWEN_LOGDOMAIN, "No colums left, line finished");
250  break;
251  }
252 
253  /* break down to name and index */
254  idx=_getNameAndIndex(p, namebuffer, sizeof(namebuffer));
255  if (idx==-1) {
256  DBG_INFO(GWEN_LOGDOMAIN, "Error in configuration: Bad name for column %d",
257  column);
259  return GWEN_ERROR_GENERIC;
260  }
261  /* get data */
262  DBG_VERBOUS(GWEN_LOGDOMAIN, "Checking value of %s[%d]", namebuffer, idx);
263  if (GWEN_DB_VariableExists(n, namebuffer)) {
264  vt=GWEN_DB_GetValueTypeByPath(n, namebuffer, idx);
265  switch (vt) {
267  p=GWEN_DB_GetCharValue(n, namebuffer, idx, "");
268  break;
270  iv=GWEN_DB_GetIntValue(n, namebuffer, idx, 0);
271  snprintf(valbuffer, sizeof(valbuffer), "%d", iv);
272  p=valbuffer;
273  break;
274  default:
275  DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled value type %d", vt);
276  p="";
277  }
278  }
279  else
280  p="";
281 
282  if (column!=1) {
283  /* write delimiter */
284  GWEN_FASTBUFFER_WRITEBYTE(fb, err, delimiter);
285  if (err<0) {
286  DBG_INFO(0, "Called from here");
288  return err;
289  }
290  } /* if not first column */
291  if (quote) {
292  /* write quotation mark */
293  GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
294  if (err<0) {
295  DBG_INFO(0, "Called from here");
297  return err;
298  }
299  } /* if quote */
300  /* write value */
301  GWEN_FASTBUFFER_WRITEFORCED(fb, err, p, -1);
302  if (err<0) {
303  DBG_INFO(0, "Called from here");
305  return err;
306  }
307  if (quote) {
308  /* write quotation mark */
309  GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
310  if (err<0) {
311  DBG_INFO(0, "Called from here");
313  return err;
314  }
315  } /* if quote */
316 
317  } /* for */
318  } /* if group name matches */
320  } /* while n */
321 
322  /* flush */
323  GWEN_FASTBUFFER_FLUSH(fb, err);
324  if (err<0) {
325  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
327  return err;
328  }
329 
331  return 0;
332 }
333 
334 
335 
336 int _csvImport(GWEN_DBIO *dbio, GWEN_SYNCIO *sio, GWEN_DB_NODE *data, GWEN_DB_NODE *cfg, GWEN_UNUSED uint32_t flags)
337 {
338  GWEN_DB_NODE *colgr;
339  int delimiter;
340  /*int quote;*/
341  const char *p;
342  const char *groupName;
343  int err;
344  int title;
345  GWEN_BUFFER *lbuffer;
346  char delimiters[2];
347  int lines;
348  int ignoreLines;
349  int fixedWidth;
350  int condense;
351  GWEN_FAST_BUFFER *fb;
352 
353  assert(dbio);
354  assert(sio);
355  assert(cfg);
356  assert(data);
357 
358  fb=GWEN_FastBuffer_new(512, sio);
359 
360  /* get general configuration */
361  colgr=GWEN_DB_GetGroup(cfg, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "columns");
362  if (!colgr) {
363  DBG_ERROR(0, "Error in configuration: No columns specified");
365  return GWEN_ERROR_INVALID;
366  }
367  p=GWEN_DB_GetCharValue(cfg, "delimiter", 0, ";");
368  if (strcasecmp(p, "TAB")==0)
369  delimiter=9;
370  else if (strcasecmp(p, "SPACE")==0)
371  delimiter=32;
372  else
373  delimiter=p[0];
374  delimiters[0]=delimiter;
375  delimiters[1]=0;
376  /*quote=GWEN_DB_GetIntValue(cfg, "quote", 0, 1);*/
377  fixedWidth=GWEN_DB_GetIntValue(cfg, "fixedWidth", 0, 0);
378  condense=GWEN_DB_GetIntValue(cfg, "condense", 0, 0);
379  groupName=GWEN_DB_GetCharValue(cfg, "group", 0, "line");
380  title=GWEN_DB_GetIntValue(cfg, "title", 0, 1);
381  ignoreLines=GWEN_DB_GetIntValue(cfg, "ignoreLines", 0, 0);
382  if (title)
383  ignoreLines++;
384 
385  lbuffer=GWEN_Buffer_new(0, 256, 0, 1);
386 
387  lines=0;
388  for (;;) {
389  const char *s;
390 
391  /* read line */
392  DBG_DEBUG(GWEN_LOGDOMAIN, "Reading line %d", lines);
393  GWEN_Buffer_Reset(lbuffer);
394  err=GWEN_FastBuffer_ReadLineToBuffer(fb, lbuffer);
395  if (err<0) {
396  if (err==GWEN_ERROR_EOF) {
397  DBG_VERBOUS(GWEN_LOGDOMAIN, "EOF met");
398  break;
399  }
400  else {
402  GWEN_Buffer_free(lbuffer);
404  return err;
405  }
406  }
407 
408  if (lines<ignoreLines) {
409  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ignoring line %d", lines);
410  }
411  else {
412  GWEN_STRINGLIST *sl;
413 
414  s=GWEN_Buffer_GetStart(lbuffer);
415  if (fixedWidth)
416  sl=_splitFixedWithStringIntoStringlist(s, condense, cfg);
417  else
418  sl=GWEN_StringList_fromString2(s, delimiters, 0,
423  if (sl) {
424  GWEN_DB_NODE *n;
425 
426  /* store columns to db */
427  n=GWEN_DB_Group_new(groupName);
428  _stringListToDb(sl, colgr, n);
429  GWEN_DB_AddGroup(data, n); /* add data */
431  }
432  else {
433  DBG_INFO(GWEN_LOGDOMAIN, "Line contains no strings");
434  }
435  } /* if this is not the title line */
436  lines++;
437  } /* for */
438 
439  GWEN_Buffer_free(lbuffer);
441 
442  return 0;
443 }
444 
445 
446 
448 {
449  int i;
450  int rv;
451  GWEN_SYNCIO *sio;
452  GWEN_STRINGLIST *sl;
453  GWEN_FAST_BUFFER *fb;
454 
457  rv=GWEN_SyncIo_Connect(sio);
458  if (rv<0) {
459  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
460  GWEN_SyncIo_free(sio);
461  return rv;
462  }
463 
464  fb=GWEN_FastBuffer_new(512, sio);
465 
466  /* read line into string list */
467  sl=GWEN_StringList_new();
468  if (_readCsvLine(fb, sl)) {
469  DBG_INFO(GWEN_LOGDOMAIN, "Error reading a line");
472  GWEN_SyncIo_free(sio);
474  }
475 
476  /* first column: number */
477  i=GWEN_StringList_Count(sl);
479  if (i) {
481  "Found %d columns, file might be supported", i);
484  GWEN_SyncIo_free(sio);
485  /*return GWEN_DBIO_CheckFileResultOk; */
487  }
488  else {
490  "Found no columns, file might not be supported");
493  GWEN_SyncIo_free(sio);
495  }
496 }
497 
498 
499 
501 {
502  GWEN_STRINGLIST *sl;
503  int i;
504  unsigned int llength;
505  unsigned int lpos=0;
506 
507  sl=GWEN_StringList_new();
508 
509  llength=strlen(s);
510  for (i=0; ; i++) {
511  int w;
512  char *t=0;
513  int left;
514 
515  left=llength-lpos;
516  w=GWEN_DB_GetIntValue(cfg, "width", i, -1);
517  if (w<1)
518  break;
519  if (w>left)
520  w=left;
521  if (w<1)
522  break;
523  t=(char *)malloc(w+1);
524  memmove(t, s, w);
525  t[w]=0;
526  if (condense) {
527  int j;
528 
529  for (j=w-1; j>=0; j--) {
530  if ((unsigned char)(t[j])>32) {
531  break;
532  }
533  t[j]=0;
534  }
535  }
536  /* take over new string */
537  GWEN_StringList_AppendString(sl, t, 1, 0);
538  s+=w;
539  lpos+=w;
540  }
541 
542  if (GWEN_StringList_Count(sl)==0) {
544  return NULL;
545  }
546 
547  return sl;
548 }
549 
550 
551 
553 {
555  int col;
556 
557  /* store columns to db */
559  col=1;
560  while (se) {
561  char nbuff[16];
562  const char *vcol;
563  const char *sColumn;
564 
565  DBG_DEBUG(GWEN_LOGDOMAIN, "Handling column %d", col);
566  nbuff[0]=0;
567  snprintf(nbuff, sizeof(nbuff)-1, "%i", col);
568  nbuff[sizeof(nbuff)-1]=0;
569  sColumn=GWEN_StringListEntry_Data(se);
570 
571  vcol=GWEN_DB_GetCharValue(colgr, nbuff, 0, 0);
572  if (vcol) {
573  const char *bracket;
574  GWEN_BUFFER *vname;
575 
576  bracket=strchr(vcol, '[');
577  if (bracket) {
578  /* copy column name without index */
579  vname=GWEN_Buffer_new(0, bracket-vcol+1, 0, 1);
580  GWEN_Buffer_AppendBytes(vname, vcol, bracket-vcol);
581  vcol=GWEN_Buffer_GetStart(vname);
582  }
583  else
584  vname=0;
585  GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_DEFAULT, vcol, sColumn);
586  GWEN_Buffer_free(vname);
587  }
588  else {
589  GWEN_DB_NODE *dbSubFields;
590 
591  dbSubFields=GWEN_DB_GetGroup(colgr, GWEN_PATH_FLAGS_NAMEMUSTEXIST, nbuff);
592  if (dbSubFields) {
593  GWEN_STRINGLIST *slSubFields;
594  const char *delimiter;
595 
596  delimiter=GWEN_DB_GetCharValue(dbSubFields, "delimiter", 0, "/");
597  slSubFields=GWEN_StringList_fromString2(sColumn,
598  delimiter, 0,
603  if (slSubFields) {
604  _stringListToDb(slSubFields, dbSubFields, dbData); /* recursion */
605  GWEN_StringList_free(slSubFields);
606  }
607  }
608  }
609 
611  col++;
612  } /* while */
613 }
614 
615 
616 
617 /* only used by _csvCheckFile(), not for actual import! */
619 {
620  int err;
621  const char *delimiters=";\t,";
622  GWEN_BUFFER *lbuffer;
623  GWEN_BUFFER *wbuffer;
624  int rv;
625  const char *s;
626 
627  assert(fb);
628 
629  /* read line */
630  lbuffer=GWEN_Buffer_new(0, 256, 0, 1);
631  GWEN_Buffer_Reset(lbuffer);
632  err=GWEN_FastBuffer_ReadLineToBuffer(fb, lbuffer);
633  if (err<0) {
635  GWEN_Buffer_free(lbuffer);
636  return err;
637  }
638 
639  /* read columns */
640  wbuffer=GWEN_Buffer_new(0, 256, 0, 1);
641 
642  s=GWEN_Buffer_GetStart(lbuffer);
643  while (*s) {
644  rv=GWEN_Text_GetWordToBuffer(s, delimiters, wbuffer,
649  &s);
650  if (rv<0) {
651  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
652  GWEN_Buffer_free(wbuffer);
653  GWEN_Buffer_free(lbuffer);
654  return rv;
655  }
656 
658  GWEN_Buffer_Reset(wbuffer);
659  if (*s) {
660  if (strchr(delimiters, *s))
661  s++;
662  }
663  } /* while */
664  GWEN_Buffer_free(wbuffer);
665  GWEN_Buffer_free(lbuffer);
666 
667  return 0;
668 }
669 
670 
671 
672 int _getNameAndIndex(const char *name, char *buffer, unsigned int size)
673 {
674  unsigned int i;
675  int rv;
676 
677  i=0;
678  rv=0;
679  /* read and copy name */
680  while (name[i] && name[i]!='[' && i<size) {
681  buffer[i]=name[i];
682  i++;
683  } /* while */
684 
685  if (i>=size) {
686  DBG_INFO(0, "Name too long (%d>=%d)", i, size);
687  return -1;
688  }
689  buffer[i]=0;
690 
691  /* read and copy index, if any */
692  if (name[i]=='[') {
693  char numbuffer[16];
694  unsigned int j;
695 
696  j=0;
697  i++;
698  while (name[i] && name[i]!=']' && j<sizeof(numbuffer)) {
699  numbuffer[j]=name[i];
700  i++;
701  j++;
702  } /* while */
703  if (j>=sizeof(numbuffer)) {
704  DBG_INFO(0, "Index number too long (%u>=%d)", j,
705  (int)(sizeof(numbuffer)));
706  return -1;
707  }
708  numbuffer[j]=0;
709  rv=atoi(numbuffer);
710  }
711 
712  return rv;
713 }
714 
715 
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
Definition: stringlist.c:801
struct GWEN_PLUGIN_MANAGER GWEN_PLUGIN_MANAGER
Definition: plugin.h:40
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
#define GWEN_TEXT_FLAGS_DEL_TRAILING_BLANKS
Definition: text.h:45
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:97
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
struct GWEN_PLUGIN GWEN_PLUGIN
Definition: plugin.h:39
GWEN_DBIO * GWEN_DBIO_new(const char *name, const char *descr)
Definition: dbio.c:207
#define GWEN_ERROR_INVALID
Definition: error.h:67
#define GWEN_SYNCIO_FILE_FLAGS_READ
Definition: syncio_file.h:53
#define NULL
Definition: binreloc.c:300
int GWEN_FastBuffer_ReadLineToBuffer(GWEN_FAST_BUFFER *fb, GWEN_BUFFER *buf)
Definition: fastbuffer.c:95
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
void GWEN_DBIO_SetCheckFileFn(GWEN_DBIO *dbio, GWEN_DBIO_CHECKFILEFN f)
Definition: dbio.c:344
static GWEN_DBIO * _csvFactory(GWEN_PLUGIN *pl)
static int _getNameAndIndex(const char *name, char *buffer, unsigned int size)
Definition: csv.c:672
void GWEN_FastBuffer_free(GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:46
#define DBG_ERROR_ERR(dbg_logger, dbg_err)
Definition: debug.h:113
#define GWEN_LOGDOMAIN
Definition: logger.h:35
static void _stringListToDb(GWEN_STRINGLIST *sl, GWEN_DB_NODE *colgr, GWEN_DB_NODE *dbData)
Definition: csv.c:552
void GWEN_DBIO_SetImportFn(GWEN_DBIO *dbio, GWEN_DBIO_IMPORTFN f)
Definition: dbio.c:329
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
#define GWEN_FASTBUFFER_FLUSH(fb, var)
Definition: fastbuffer.h:162
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
static GWEN_STRINGLIST * _splitFixedWithStringIntoStringlist(const char *s, int condense, GWEN_DB_NODE *cfg)
Definition: csv.c:500
static int _csvExport(GWEN_DBIO *dbio, GWEN_SYNCIO *sio, GWEN_DB_NODE *data, GWEN_DB_NODE *cfg, uint32_t flags)
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition: db.c:1482
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
#define GWEN_TEXT_FLAGS_NULL_IS_DELIMITER
Definition: text.h:48
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
const char * GWEN_DB_GroupName(GWEN_DB_NODE *n)
Definition: db.c:1408
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
#define GWEN_ERROR_GENERIC
Definition: error.h:62
GWEN_DB_NODE * GWEN_DB_GetNextGroup(GWEN_DB_NODE *n)
Definition: db.c:461
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
Definition: db.c:1565
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1381
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:78
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:179
int GWEN_Text_NumToString(int num, char *buffer, unsigned int bufsize, int fillchar)
Definition: text.c:1243
#define GWENHYWFAR_EXPORT
Definition: gwenhywfarapi.h:75
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:427
void GWEN_DBIO_Plugin_SetFactoryFn(GWEN_PLUGIN *pl, GWEN_DBIO_PLUGIN_FACTORYFN f)
Definition: dbio.c:188
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_EOF
Definition: error.h:96
struct GWEN_DBIO GWEN_DBIO
Definition: dbio.h:43
#define GWEN_FASTBUFFER_WRITEFORCED(fb, var, p, len)
Definition: fastbuffer.h:377
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:109
void GWEN_DBIO_SetExportFn(GWEN_DBIO *dbio, GWEN_DBIO_EXPORTFN f)
Definition: dbio.c:337
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
#define GWEN_FASTBUFFER_WRITEBYTE(fb, var, chr)
Definition: fastbuffer.h:134
GWEN_DBIO_CHECKFILE_RESULT
Definition: dbio.h:79
GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n, const char *path, unsigned int i)
Definition: db.c:1612
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define GWEN_TEXT_FLAGS_DEL_QUOTES
Definition: text.h:49
static int _readCsvLine(GWEN_FAST_BUFFER *fb, GWEN_STRINGLIST *sl)
Definition: csv.c:618
int GWEN_Text_GetWordToBuffer(const char *src, const char *delims, GWEN_BUFFER *buf, uint32_t flags, const char **next)
Definition: text.c:226
GWEN_DB_NODE_TYPE
Definition: db.h:233
#define GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS
Definition: text.h:44
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1163
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:361
GWENHYWFAR_API GWEN_SYNCIO * GWEN_SyncIo_File_new(const char *path, GWEN_SYNCIO_FILE_CREATIONMODE cm)
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
#define GWEN_FASTBUFFER_WRITELINE(fb, var, p)
Definition: fastbuffer.h:407
GWEN_DB_NODE * GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n)
Definition: db.c:440
GWENHYWFAR_EXPORT GWEN_PLUGIN * dbio_csv_factory(GWEN_PLUGIN_MANAGER *pm, const char *modName, const char *fileName)
Definition: csv.c:88
GWEN_FAST_BUFFER * GWEN_FastBuffer_new(uint32_t bsize, GWEN_SYNCIO *io)
Definition: fastbuffer.c:27
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
Definition: path.h:84
static GWEN_DBIO_CHECKFILE_RESULT _csvCheckFile(GWEN_DBIO *dbio, const char *fname)
#define GWEN_UNUSED
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
GWEN_PLUGIN * GWEN_DBIO_Plugin_new(GWEN_PLUGIN_MANAGER *pm, const char *name, const char *fileName)
Definition: dbio.c:147
static int _csvImport(GWEN_DBIO *dbio, GWEN_SYNCIO *sio, GWEN_DB_NODE *data, GWEN_DB_NODE *cfg, uint32_t flags)