dbrw.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003  -------------------
00004  cvs         : $Id: db.c 1231 2007-06-12 01:54:15Z martin $
00005  begin       : Tue Sep 09 2003
00006  copyright   : (C) 2003 by Martin Preuss
00007  email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 
00029 /* This file is included from db.c */
00030 
00031 
00032 
00033 int GWEN_DB_ReadFileAs(GWEN_DB_NODE *db,
00034                        const char *fname,
00035                        const char *type,
00036                        GWEN_DB_NODE *params,
00037                        uint32_t dbflags,
00038                        uint32_t guiid,
00039                        int msecs){
00040   GWEN_IO_LAYER *io;
00041   GWEN_DBIO *dbio;
00042   int fd;
00043   int rv;
00044 
00045   dbio=GWEN_DBIO_GetPlugin(type);
00046   if (!dbio) {
00047     DBG_ERROR(GWEN_LOGDOMAIN, "Plugin \"%s\" is not supported", type);
00048     return GWEN_ERROR_NOT_SUPPORTED;
00049   }
00050 
00051   fd=open(fname, O_RDONLY);
00052   if (fd==-1) {
00053     DBG_ERROR(GWEN_LOGDOMAIN, "open(%s, O_RDONLY): %s", fname, strerror(errno));
00054     return GWEN_ERROR_IO;
00055   }
00056 
00057   /* create io layer for this file (readonly) */
00058   io=GWEN_Io_LayerFile_new(fd, -1);
00059   assert(io);
00060 
00061   rv=GWEN_Io_Manager_RegisterLayer(io);
00062   if (rv) {
00063     DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: Could not register io layer (%d)", rv);
00064     GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
00065     GWEN_Io_Layer_free(io);
00066     return rv;
00067   }
00068 
00069   rv=GWEN_DBIO_Import(dbio, io, db, params, dbflags, guiid, msecs);
00070   if (rv) {
00071     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00072   }
00073   GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
00074   GWEN_Io_Layer_free(io);
00075 
00076   return rv;
00077 }
00078 
00079 
00080 
00081 int GWEN_DB_WriteFileAs(GWEN_DB_NODE *db,
00082                         const char *fname,
00083                         const char *type,
00084                         GWEN_DB_NODE *params,
00085                         uint32_t dbflags,
00086                         uint32_t guiid,
00087                         int msecs){
00088   int rv;
00089   GWEN_DBIO *dbio;
00090 
00091   dbio=GWEN_DBIO_GetPlugin(type);
00092   if (!dbio) {
00093     DBG_ERROR(GWEN_LOGDOMAIN, "Plugin \"%s\" is not supported", type);
00094     return GWEN_ERROR_NOT_SUPPORTED;
00095   }
00096 
00097   rv=GWEN_DBIO_ExportToFile(dbio, fname, db, params, dbflags, guiid, msecs);
00098   if (rv) {
00099     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00100     return rv;
00101   }
00102 
00103   return 0;
00104 }
00105 
00106 
00107 
00108 int GWEN_DB_WriteGroupToIoLayer(GWEN_DB_NODE *node,
00109                                 GWEN_FAST_BUFFER *fb,
00110                                 uint32_t dbflags,
00111                                 int insert) {
00112   GWEN_DB_NODE *n;
00113   GWEN_DB_NODE *cn;
00114   int i;
00115   int err;
00116   int lastWasVar;
00117 
00118   lastWasVar=0;
00119 
00120   n=GWEN_DB_Node_List_First(node->children);
00121   while(n) {
00122     if (!(n->nodeFlags & GWEN_DB_NODE_FLAGS_VOLATILE)) {
00123       DBG_VERBOUS(GWEN_LOGDOMAIN, "Writing node");
00124       switch(n->typ) {
00125       case GWEN_DB_NodeType_Group:
00126         if (dbflags & GWEN_DB_FLAGS_WRITE_SUBGROUPS) {
00127           if (dbflags & GWEN_DB_FLAGS_ADD_GROUP_NEWLINES) {
00128             if (lastWasVar) {
00129               /* only insert newline if the last one before this group was a
00130                * variable */
00131               GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00132               if (err<0) {
00133                 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00134                 return err;
00135               }
00136             }
00137           }
00138 
00139           /* indend */
00140           if (dbflags & GWEN_DB_FLAGS_INDEND) {
00141             for (i=0; i<insert; i++) {
00142               GWEN_FASTBUFFER_WRITEBYTE(fb, err, ' ');
00143               if (err<0) {
00144                 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00145                 return err;
00146               }
00147             } /* for */
00148           } /* if indend */
00149           GWEN_FASTBUFFER_WRITEFORCED(fb, err, n->data.dataName, -1);
00150           if (err<0) {
00151             DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00152             return err;
00153           }
00154           GWEN_FASTBUFFER_WRITELINE(fb, err, " {");
00155           if (err<0) {
00156             DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00157             return err;
00158           }
00159           err=GWEN_DB_WriteGroupToIoLayer(n, fb, dbflags, insert+2);
00160           if (err<0)
00161             return err;
00162 
00163           /* indend */
00164           if (dbflags & GWEN_DB_FLAGS_INDEND) {
00165             for (i=0; i<insert; i++) {
00166               GWEN_FASTBUFFER_WRITEBYTE(fb, err, ' ');
00167               if (err<0) {
00168                 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00169                 return err;
00170               }
00171             } /* for */
00172           } /* if indend */
00173 
00174           if (dbflags & GWEN_DB_FLAGS_DETAILED_GROUPS) {
00175             GWEN_FASTBUFFER_WRITEFORCED(fb, err, "} #", -1);
00176             if (err<0) {
00177               DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00178               return err;
00179             }
00180             GWEN_FASTBUFFER_WRITELINE(fb, err, n->data.dataName);
00181             if (err<0) {
00182               DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00183               return err;
00184             }
00185           } /* if detailed groups */
00186           else {
00187             GWEN_FASTBUFFER_WRITELINE(fb, err, "}");
00188             if (err<0) {
00189               DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00190               return err;
00191             }
00192           }
00193           if (dbflags & GWEN_DB_FLAGS_ADD_GROUP_NEWLINES) {
00194             if (GWEN_DB_Node_List_Next(n)) {
00195               /* only insert newline if something
00196                * is following on the same level */
00197               GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00198               if (err<0) {
00199                 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00200                 return err;
00201               }
00202             }
00203           }
00204         }
00205         lastWasVar=0;
00206         break;
00207 
00208       case GWEN_DB_NodeType_Var:
00209         cn=GWEN_DB_Node_List_First(n->children);
00210         if (cn) {
00211           char *typname;
00212           int namewritten;
00213           int values;
00214 
00215           typname=0;
00216           namewritten=0;
00217           values=0;
00218           while(cn) {
00219             char numbuffer[32];
00220             char *binbuffer=NULL;
00221             unsigned int bbsize;
00222             const char *pvalue=NULL;
00223             GWEN_BUFFER *vbuf=NULL;
00224 
00225             switch(cn->typ) {
00226             case GWEN_DB_NodeType_ValueChar:
00227               typname="char ";
00228               pvalue=cn->data.dataChar;
00229               if (dbflags & GWEN_DB_FLAGS_ESCAPE_CHARVALUES) {
00230                 vbuf=GWEN_Buffer_new(0, strlen(pvalue)+32, 0, 1);
00231                 if (GWEN_Text_EscapeToBufferTolerant(pvalue, vbuf)) {
00232                   DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00233                   GWEN_Buffer_free(vbuf);
00234                   return 1;
00235                 }
00236                 pvalue=GWEN_Buffer_GetStart(vbuf);
00237               }
00238               break;
00239 
00240             case GWEN_DB_NodeType_ValueInt:
00241               typname="int  ";
00242               if (GWEN_Text_NumToString(cn->data.dataInt,
00243                                         numbuffer,
00244                                         sizeof(numbuffer)-1,
00245                                         0)<1) {
00246                 DBG_ERROR(GWEN_LOGDOMAIN, "Error writing numeric value");
00247                 return GWEN_ERROR_GENERIC;
00248               }
00249               pvalue=numbuffer;
00250               break;
00251 
00252             case GWEN_DB_NodeType_ValueBin:
00253               bbsize=cn->dataSize*2+1;
00254               binbuffer=(char*)GWEN_Memory_malloc(bbsize);
00255               assert(binbuffer);
00256               typname="bin  ";
00257               if (!GWEN_Text_ToHex(cn->data.dataBin,
00258                                    cn->dataSize,
00259                                    binbuffer,
00260                                    bbsize)) {
00261                 DBG_ERROR(GWEN_LOGDOMAIN, "Error writing binary value");
00262                 return GWEN_ERROR_GENERIC;
00263               }
00264               pvalue=binbuffer;
00265               break;
00266 
00267             case GWEN_DB_NodeType_ValuePtr:
00268               DBG_DEBUG(GWEN_LOGDOMAIN, "Not writing ptr type");
00269               break;
00270 
00271             default:
00272               DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled type [%d]", cn->type);
00273               break;
00274             }
00275 
00276             if (pvalue) {
00277               if (!namewritten) {
00278                 /* write name */
00279                 /* indend */
00280                 if (dbflags & GWEN_DB_FLAGS_INDEND) {
00281                   for (i=0; i<insert; i++) {
00282                     GWEN_FASTBUFFER_WRITEBYTE(fb, err, ' ');
00283                     if (err<0) {
00284                       DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00285                       GWEN_Memory_dealloc(binbuffer);
00286                       GWEN_Buffer_free(vbuf);
00287                       return 1;
00288                     }
00289                   } /* for */
00290                 } /* if indend */
00291                 if (!(dbflags & GWEN_DB_FLAGS_OMIT_TYPES)) {
00292                   GWEN_FASTBUFFER_WRITEFORCED(fb, err, typname, -1);
00293                   if (err<0) {
00294                     DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00295                     GWEN_Memory_dealloc(binbuffer);
00296                     GWEN_Buffer_free(vbuf);
00297                     return 1;
00298                   }
00299                 }
00300                 if (dbflags & GWEN_DB_FLAGS_QUOTE_VARNAMES) {
00301                   GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00302                   if (err<0) {
00303                     DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00304                     GWEN_Memory_dealloc(binbuffer);
00305                     GWEN_Buffer_free(vbuf);
00306                     return 1;
00307                   }
00308                 }
00309                 GWEN_FASTBUFFER_WRITEFORCED(fb, err, n->data.dataName, -1);
00310                 if (err<0) {
00311                   DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00312                   GWEN_Memory_dealloc(binbuffer);
00313                   GWEN_Buffer_free(vbuf);
00314                   return 1;
00315                 }
00316                 if (dbflags & GWEN_DB_FLAGS_QUOTE_VARNAMES) {
00317                   GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00318                   if (err<0) {
00319                     DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00320                     GWEN_Memory_dealloc(binbuffer);
00321                     GWEN_Buffer_free(vbuf);
00322                     return 1;
00323                   }
00324                 }
00325                 GWEN_FASTBUFFER_WRITEFORCED(fb, err, ((dbflags & GWEN_DB_FLAGS_USE_COLON)?": ":"="), -1);
00326                 if (err<0) {
00327                   DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00328                   GWEN_Memory_dealloc(binbuffer);
00329                   GWEN_Buffer_free(vbuf);
00330                   return 1;
00331                 }
00332                 namewritten=1;
00333               } /* if !namewritten */
00334 
00335               if (values) {
00336                 GWEN_FASTBUFFER_WRITEFORCED(fb, err, ", ", -1);
00337                 if (err<0) {
00338                   DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00339                   GWEN_Memory_dealloc(binbuffer);
00340                   GWEN_Buffer_free(vbuf);
00341                   return 1;
00342                 }
00343               }
00344               values++;
00345               if (dbflags & GWEN_DB_FLAGS_QUOTE_VALUES) {
00346                 GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00347                 if (err<0) {
00348                   DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00349                   GWEN_Memory_dealloc(binbuffer);
00350                   GWEN_Buffer_free(vbuf);
00351                   return 1;
00352                 }
00353               }
00354 
00355               GWEN_FASTBUFFER_WRITEFORCED(fb, err, pvalue, -1);
00356               if (err<0) {
00357                 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00358                 GWEN_Memory_dealloc(binbuffer);
00359                 GWEN_Buffer_free(vbuf);
00360                 return 1;
00361               }
00362 
00363               if (dbflags & GWEN_DB_FLAGS_QUOTE_VALUES) {
00364                 GWEN_FASTBUFFER_WRITEBYTE(fb, err, '\"');
00365                 if (err<0) {
00366                   DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00367                   GWEN_Memory_dealloc(binbuffer);
00368                   GWEN_Buffer_free(vbuf);
00369                   return 1;
00370                 }
00371               }
00372             } /* if pvalue */
00373 
00374             GWEN_Memory_dealloc(binbuffer);
00375             GWEN_Buffer_free(vbuf);
00376             cn=GWEN_DB_Node_List_Next(cn);
00377           } /* while cn */
00378 
00379           if (namewritten) {
00380             GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00381             if (err<0) {
00382               DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00383               return GWEN_ERROR_GENERIC;
00384             }
00385           }
00386         } /* if children */
00387         lastWasVar=1;
00388         break;
00389 
00390       default:
00391         DBG_WARN(GWEN_LOGDOMAIN, "[unhandled node type %d]", n->typ);
00392       } /* switch */
00393     } /* if not volatile */
00394     else {
00395       DBG_DEBUG(GWEN_LOGDOMAIN, "Node is volatile, not writing it");
00396     }
00397     n=GWEN_DB_Node_List_Next(n);
00398   } /* while */
00399 
00400   return 0;
00401 }
00402 
00403 
00404 
00405 int GWEN_DB_WriteToFastBuffer(GWEN_DB_NODE *node,
00406                               GWEN_FAST_BUFFER *fb,
00407                               uint32_t dbflags) {
00408   int rv;
00409 
00410   rv=GWEN_DB_WriteGroupToIoLayer(node, fb, dbflags, 0);
00411   if (rv<0) {
00412     return rv;
00413   }
00414   GWEN_FASTBUFFER_FLUSH(fb, rv);
00415   return rv;
00416 }
00417 
00418 
00419 
00420 int GWEN_DB_WriteToIo(GWEN_DB_NODE *node,
00421                       GWEN_IO_LAYER *io,
00422                       uint32_t dbflags,
00423                       uint32_t guiid,
00424                       int msecs) {
00425   int rv;
00426   GWEN_FAST_BUFFER *fb;
00427 
00428   fb=GWEN_FastBuffer_new(512, io, guiid, msecs);
00429   if (dbflags & GWEN_DB_FLAGS_DOSMODE)
00430     GWEN_FastBuffer_AddFlags(fb, GWEN_FAST_BUFFER_FLAGS_DOSMODE);
00431   rv=GWEN_DB_WriteGroupToIoLayer(node, fb, dbflags, 0);
00432   if (rv<0) {
00433     GWEN_FastBuffer_free(fb);
00434     return rv;
00435   }
00436   GWEN_FASTBUFFER_FLUSH(fb, rv);
00437   GWEN_FastBuffer_free(fb);
00438   return rv;
00439 }
00440 
00441 
00442 
00443 int GWEN_DB_WriteToFd(GWEN_DB_NODE *n, int fd, uint32_t dbflags, uint32_t guiid, int msecs){
00444   GWEN_IO_LAYER *io;
00445   int rv;
00446 
00447   /* create io layer for this file */
00448   io=GWEN_Io_LayerFile_new(-1, fd);
00449   assert(io);
00450   GWEN_Io_Layer_AddFlags(io, GWEN_IO_LAYER_FLAGS_DONTCLOSE);
00451 
00452   rv=GWEN_Io_Manager_RegisterLayer(io);
00453   if (rv) {
00454     DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: Could not register io layer (%d)", rv);
00455     GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
00456     GWEN_Io_Layer_free(io);
00457     return rv;
00458   }
00459 
00460   /* write to file */
00461   rv=GWEN_DB_WriteToIo(n, io, dbflags, guiid, msecs);
00462   if (rv<0) {
00463     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00464     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, 1000);
00465     GWEN_Io_Layer_free(io);
00466     return rv;
00467   }
00468 
00469   /* close io layer */
00470   rv=GWEN_Io_Layer_DisconnectRecursively(io, NULL, 0, guiid, 30000);
00471   if (rv<0) {
00472     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00473     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, 1000);
00474     GWEN_Io_Layer_free(io);
00475     return rv;
00476   }
00477 
00478   GWEN_Io_Layer_free(io);
00479 
00480   return 0;
00481 }
00482 
00483 
00484 
00485 int GWEN_DB_WriteFile(GWEN_DB_NODE *n, const char *fname, uint32_t dbflags, uint32_t guiid, int msecs){
00486   int fd;
00487   int rv;
00488   GWEN_FSLOCK *lck=0;
00489 
00490   /* if locking requested */
00491   if (dbflags & GWEN_DB_FLAGS_LOCKFILE) {
00492     GWEN_FSLOCK_RESULT res;
00493 
00494     lck=GWEN_FSLock_new(fname, GWEN_FSLock_TypeFile);
00495     assert(lck);
00496     res=GWEN_FSLock_Lock(lck, GWEN_DB_DEFAULT_LOCK_TIMEOUT, 0);
00497     if (res!=GWEN_FSLock_ResultOk) {
00498       DBG_ERROR(GWEN_LOGDOMAIN,
00499                 "Could not apply lock to file \"%s\" (%d)",
00500                 fname, res);
00501       GWEN_FSLock_free(lck);
00502       return -1;
00503     }
00504   }
00505 
00506   /* open file */
00507   if (dbflags & GWEN_DB_FLAGS_APPEND_FILE)
00508     fd=open(fname, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
00509   else
00510     fd=open(fname, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
00511   if (fd==-1) {
00512     DBG_ERROR(GWEN_LOGDOMAIN, "Error opening file \"%s\": %s",
00513               fname,
00514               strerror(errno));
00515     if (lck) {
00516       GWEN_FSLock_Unlock(lck);
00517       GWEN_FSLock_free(lck);
00518     }
00519     return GWEN_ERROR_IO;
00520   }
00521 
00522   rv=GWEN_DB_WriteToFd(n, fd, dbflags, guiid, msecs);
00523   if (rv<0) {
00524     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00525     close(fd);
00526     if (lck) {
00527       GWEN_FSLock_Unlock(lck);
00528       GWEN_FSLock_free(lck);
00529     }
00530     return rv;
00531   }
00532 
00533   if (close(fd)) {
00534     DBG_ERROR(GWEN_LOGDOMAIN, "Error closing file \"%s\": %s",
00535               fname,
00536               strerror(errno));
00537     if (lck) {
00538       GWEN_FSLock_Unlock(lck);
00539       GWEN_FSLock_free(lck);
00540     }
00541     return GWEN_ERROR_IO;
00542   }
00543 
00544   /* remove lock, if any */
00545   if (lck) {
00546     GWEN_FSLOCK_RESULT res;
00547 
00548     res=GWEN_FSLock_Unlock(lck);
00549     if (res!=GWEN_FSLock_ResultOk) {
00550       DBG_WARN(GWEN_LOGDOMAIN,
00551                "Could not remove lock on file \"%s\" (%d)",
00552                fname, res);
00553     }
00554     GWEN_FSLock_free(lck);
00555   }
00556 
00557   return 0;
00558 }
00559 
00560 
00561 
00562 int GWEN_DB__ReadValues(GWEN_DB_NODE *n,
00563                         uint32_t dbflags,
00564                         const char *typeName,
00565                         const char *varName,
00566                         uint8_t *p) {
00567   GWEN_DB_NODE_TYPE nodeType=GWEN_DB_NodeType_ValueChar;
00568   GWEN_DB_NODE *dbVar;
00569   GWEN_BUFFER *wbuf;
00570   uint8_t *pDebug;
00571 
00572   pDebug=p;
00573 
00574   if (typeName==NULL)
00575     typeName="char";
00576   if (strcasecmp(typeName, "int")==0)
00577     nodeType=GWEN_DB_NodeType_ValueInt;
00578   else if (strcasecmp(typeName, "char")==0)
00579     nodeType=GWEN_DB_NodeType_ValueChar;
00580   else if (strcasecmp(typeName, "bin")==0)
00581     nodeType=GWEN_DB_NodeType_ValueBin;
00582   else {
00583     DBG_ERROR(GWEN_LOGDOMAIN, "Unknown type \"%s\"", typeName);
00584     return GWEN_ERROR_BAD_DATA;
00585   }
00586 
00587   dbVar=GWEN_DB_GetNode(n, varName, dbflags | GWEN_PATH_FLAGS_VARIABLE);
00588   if (dbVar==NULL) {
00589     DBG_INFO(GWEN_LOGDOMAIN, "Variable [%s] is not available", varName);
00590     return GWEN_ERROR_GENERIC;
00591   }
00592 
00593   wbuf=GWEN_Buffer_new(0, 32, 0, 1);
00594   for (;;) {
00595     int quotes=0;
00596     GWEN_DB_NODE *dbVal=NULL;
00597     const char *v;
00598 
00599     while(*p && isspace(*p))
00600       p++;
00601     if (!*p) {
00602       DBG_INFO(GWEN_LOGDOMAIN, "Missing value");
00603       GWEN_Buffer_free(wbuf);
00604       return GWEN_ERROR_BAD_DATA;
00605     }
00606 
00607     if (*p=='"') {
00608       quotes=1;
00609       p++;
00610     }
00611 
00612     while(*p) {
00613       if (*p=='%') {
00614         uint8_t c;
00615         uint8_t cHex;
00616 
00617         /* get first nibble */
00618         p++;
00619         if (!*p) {
00620           DBG_INFO(GWEN_LOGDOMAIN, "Incomplete escape sequence");
00621           GWEN_Buffer_free(wbuf);
00622           return GWEN_ERROR_BAD_DATA;
00623         }
00624         c=toupper(*p)-'0';
00625         if (c>9) c-=7;
00626         cHex=c<<4;
00627 
00628         p++;
00629         if (!*p) {
00630           DBG_INFO(GWEN_LOGDOMAIN, "Incomplete escape sequence");
00631           GWEN_Buffer_free(wbuf);
00632           return GWEN_ERROR_BAD_DATA;
00633         }
00634         c=toupper(*p)-'0';
00635         if (c>9) c-=7;
00636         cHex|=c;
00637         GWEN_Buffer_AppendByte(wbuf, cHex);
00638       }
00639       else
00640         if (quotes) {
00641           if (*p=='"') {
00642             p++;
00643             break;
00644           }
00645           else
00646             GWEN_Buffer_AppendByte(wbuf, *p);
00647         }
00648         else {
00649           if (*p==',' || *p==';' || *p=='#')
00650             break;
00651           else if (*p=='"') {
00652             DBG_INFO(GWEN_LOGDOMAIN, "Unexpected quotation mark (Line: [%s], parsed: [%s]",
00653                      pDebug, GWEN_Buffer_GetStart(wbuf));
00654             GWEN_Buffer_free(wbuf);
00655             return GWEN_ERROR_BAD_DATA;
00656           }
00657           else
00658             GWEN_Buffer_AppendByte(wbuf, *p);
00659         }
00660       p++;
00661     }
00662 
00663     v=GWEN_Buffer_GetStart(wbuf);
00664     if (nodeType==GWEN_DB_NodeType_ValueInt) {
00665       int i;
00666 
00667       if (1!=sscanf(v, "%d", &i)) {
00668         DBG_INFO(GWEN_LOGDOMAIN, "Not an integer value [%s]", v);
00669         GWEN_Buffer_free(wbuf);
00670         return GWEN_ERROR_BAD_DATA;
00671       }
00672       dbVal=GWEN_DB_ValueInt_new(i);
00673     }
00674     else if (nodeType==GWEN_DB_NodeType_ValueChar)
00675       dbVal=GWEN_DB_ValueChar_new(v);
00676     else if (nodeType==GWEN_DB_NodeType_ValueBin) {
00677       GWEN_BUFFER *bbuf;
00678       int rv;
00679 
00680       bbuf=GWEN_Buffer_new(0, (GWEN_Buffer_GetUsedBytes(wbuf)/2)+1, 0, 1);
00681       rv=GWEN_Text_FromHexBuffer(v, bbuf);
00682       if (rv) {
00683         DBG_INFO(GWEN_LOGDOMAIN, "Bad bin value [%s]", v);
00684         GWEN_Buffer_free(bbuf);
00685         GWEN_Buffer_free(wbuf);
00686         return GWEN_ERROR_BAD_DATA;
00687       }
00688       dbVal=GWEN_DB_ValueBin_new(GWEN_Buffer_GetStart(bbuf),
00689                                  GWEN_Buffer_GetUsedBytes(bbuf));
00690       GWEN_Buffer_free(bbuf);
00691     }
00692     else {
00693       /* should never reach this point */
00694       assert(0);
00695     }
00696     GWEN_DB_Node_Append(dbVar, dbVal);
00697 
00698     /* skip blanks if any */
00699     while(*p && isspace(*p))
00700       p++;
00701     if (!*p || *p==';' || *p=='#')
00702       break;
00703     else if (*p!=',') {
00704       DBG_INFO(GWEN_LOGDOMAIN, "Unexpected character [%s]", p);
00705       GWEN_Buffer_free(wbuf);
00706       return GWEN_ERROR_BAD_DATA;
00707     }
00708     p++;
00709     GWEN_Buffer_Reset(wbuf);
00710   }
00711 
00712   GWEN_Buffer_free(wbuf);
00713   return 0;
00714 }
00715 
00716 
00717 
00718 int GWEN_DB_ReadFromFastBuffer(GWEN_DB_NODE *n,
00719                                GWEN_FAST_BUFFER *fb,
00720                                uint32_t dbflags) {
00721   GWEN_BUFFER *lbuf;
00722   int level=0;
00723   int someLinesRead=0;
00724 
00725   lbuf=GWEN_Buffer_new(0, 128, 0, 1);
00726 
00727   for (;;) {
00728     int rv;
00729     uint8_t *p;
00730 
00731     rv=GWEN_FastBuffer_ReadLineToBuffer(fb, lbuf);
00732     if (rv<0) {
00733       if (rv==GWEN_ERROR_EOF) {
00734         if (!someLinesRead) {
00735           DBG_INFO(GWEN_LOGDOMAIN, "Unexpected EOF (%d)", rv);
00736           GWEN_Buffer_free(lbuf);
00737           return rv;
00738         }
00739         break;
00740       }
00741       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00742       GWEN_Buffer_free(lbuf);
00743       return rv;
00744     }
00745 
00746     if (GWEN_Buffer_GetUsedBytes(lbuf)==0) {
00747       if (dbflags & GWEN_DB_FLAGS_UNTIL_EMPTY_LINE) {
00748         break;
00749       }
00750     }
00751     else {
00752       someLinesRead=1;
00753       p=(uint8_t*)GWEN_Buffer_GetStart(lbuf);
00754       while(*p && isspace(*p))
00755         p++;
00756       if (*p) {
00757         uint8_t *p1begin=NULL, *p1end=NULL;
00758         uint8_t *p2begin=NULL, *p2end=NULL;
00759   
00760         /* non-empty line */
00761         if (*p=='}') {
00762           /* found end of current group */
00763           if (level<1) {
00764             DBG_INFO(GWEN_LOGDOMAIN, "Unbalanced number of curly bracket");
00765             GWEN_Buffer_free(lbuf);
00766             return GWEN_ERROR_BAD_DATA;
00767           }
00768           n=n->parent;
00769           assert(n); /* internal error if parent not found */
00770           assert(n->typ==GWEN_DB_NodeType_Group); /* internal error if parent is not a group */
00771           level--;
00772         }
00773         else if (*p=='#') {
00774           /* comment only line */
00775         }
00776         else {
00777           p1begin=p;
00778           /* read first token */
00779           while(*p && !isspace(*p) &&
00780                 *p!='{' &&
00781                 *p!=((dbflags & GWEN_DB_FLAGS_USE_COLON)?':':'=') &&
00782                 *p!='}' &&
00783                 *p!=',' &&
00784                 *p!=';')
00785             p++;
00786           if (!*p) {
00787             DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token");
00788             GWEN_Buffer_Dump(lbuf, stderr, 2);
00789             GWEN_Buffer_free(lbuf);
00790             return GWEN_ERROR_BAD_DATA;
00791           }
00792           p1end=p;
00793 
00794           /* get to start of 2nd token */
00795           while(*p && isspace(*p))
00796             p++;
00797           if (!*p) {
00798             DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token");
00799             GWEN_Buffer_free(lbuf);
00800             return GWEN_ERROR_BAD_DATA;
00801           }
00802   
00803           if (*p=='{') {
00804             GWEN_DB_NODE *newGr;
00805   
00806             /* found start of group */
00807             *p1end=0;
00808             newGr=GWEN_DB_GetGroup(n, dbflags, (const char*)p1begin);
00809             if (newGr==NULL) {
00810               DBG_INFO(GWEN_LOGDOMAIN, "Could not create group [%s]", p1begin);
00811               GWEN_Buffer_free(lbuf);
00812               return GWEN_ERROR_GENERIC;
00813             }
00814             n=newGr;
00815             level++;
00816           }
00817           else if (*p=='=' || *p==':') {
00818             /* found short variable definition */
00819             *p1end=0;
00820             p++;
00821             rv=GWEN_DB__ReadValues(n, dbflags, NULL, (const char*)p1begin, p);
00822             if (rv) {
00823               DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00824               GWEN_Buffer_free(lbuf);
00825               return rv;
00826             }
00827           }
00828           else if (*p==',' || *p==';') {
00829             DBG_INFO(GWEN_LOGDOMAIN, "Unexpected delimiter found");
00830             GWEN_Buffer_free(lbuf);
00831             return GWEN_ERROR_BAD_DATA;
00832           }
00833           else {
00834             /* 2nd token, so this should be a standard variable definition */
00835             p2begin=p;
00836             while(*p &&
00837                   !isspace(*p) &&
00838                   *p!='{' &&
00839                   *p!=((dbflags & GWEN_DB_FLAGS_USE_COLON)?':':'=') &&
00840                   *p!='}' &&
00841                   *p!=',' &&
00842                   *p!=';')
00843               p++;
00844             if (!*p) {
00845               DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token [%s], [%s]", p1begin, p2begin);
00846               GWEN_Buffer_free(lbuf);
00847               return GWEN_ERROR_BAD_DATA;
00848             }
00849             p2end=p;
00850             if (isspace(*p)) {
00851               while(*p && isspace(*p))
00852                 p++;
00853               if (!*p) {
00854                 DBG_INFO(GWEN_LOGDOMAIN, "Missing 2nd token");
00855                 GWEN_Buffer_free(lbuf);
00856                 return GWEN_ERROR_BAD_DATA;
00857               }
00858             }
00859             if (*p!='=' && *p!=':') {
00860               DBG_INFO(GWEN_LOGDOMAIN, "Equation mark expected");
00861               GWEN_Buffer_free(lbuf);
00862               return GWEN_ERROR_BAD_DATA;
00863             }
00864             p++;
00865   
00866             *p1end=0;
00867             *p2end=0;
00868             rv=GWEN_DB__ReadValues(n, dbflags, (const char*)p1begin, (const char*)p2begin, p);
00869             if (rv) {
00870               DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00871               GWEN_Buffer_free(lbuf);
00872               return rv;
00873             }
00874           }
00875         }
00876       }
00877     }
00878     GWEN_Buffer_Reset(lbuf);
00879   }
00880 
00881   if (level) {
00882     DBG_INFO(GWEN_LOGDOMAIN, "Unbalanced number of curly bracket (too few)");
00883     GWEN_Buffer_free(lbuf);
00884     return GWEN_ERROR_BAD_DATA;
00885   }
00886 
00887   GWEN_Buffer_free(lbuf);
00888 
00889   return 0;
00890 }
00891 
00892 
00893 
00894 int GWEN_DB_ReadFromIo(GWEN_DB_NODE *n,
00895                        GWEN_IO_LAYER *io,
00896                        uint32_t dbflags,
00897                        uint32_t guiid,
00898                        int msecs) {
00899   GWEN_FAST_BUFFER *fb;
00900   int rv;
00901 
00902   /* prepare fast buffer */
00903   fb=GWEN_FastBuffer_new(1024, io, guiid, msecs);
00904   if (dbflags & GWEN_DB_FLAGS_DOSMODE)
00905     GWEN_FastBuffer_AddFlags(fb, GWEN_FAST_BUFFER_FLAGS_DOSMODE);
00906 
00907   /* read from it */
00908   rv=GWEN_DB_ReadFromFastBuffer(n, fb, dbflags);
00909   if (rv) {
00910     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00911     GWEN_FastBuffer_free(fb);
00912     return rv;
00913   }
00914 
00915   GWEN_FastBuffer_free(fb);
00916   return 0;
00917 }
00918 
00919 
00920 
00921 int GWEN_DB_ReadFromFd(GWEN_DB_NODE *n,
00922                        int fd,
00923                        uint32_t dbflags,
00924                        uint32_t guiid,
00925                        int msecs) {
00926   GWEN_IO_LAYER *io;
00927   int rv;
00928 
00929   /* create io layer for this file (readonly) */
00930   io=GWEN_Io_LayerFile_new(fd, -1);
00931   assert(io);
00932   GWEN_Io_Layer_AddFlags(io, GWEN_IO_LAYER_FLAGS_DONTCLOSE);
00933 
00934   rv=GWEN_Io_Manager_RegisterLayer(io);
00935   if (rv) {
00936     DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: Could not register io layer (%d)", rv);
00937     GWEN_Io_Layer_free(io);
00938     return rv;
00939   }
00940 
00941   rv=GWEN_DB_ReadFromIo(n, io, dbflags, guiid, msecs);
00942   if (rv) {
00943     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00944   }
00945   GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
00946   GWEN_Io_Layer_free(io);
00947 
00948   return rv;
00949 }
00950 
00951 
00952 
00953 int GWEN_DB_ReadFile(GWEN_DB_NODE *n,
00954                      const char *fname,
00955                      uint32_t dbflags,
00956                      uint32_t guiid,
00957                      int msecs) {
00958   int fd;
00959   int rv;
00960 
00961   fd=open(fname, O_RDONLY);
00962   if (fd==-1) {
00963     DBG_ERROR(GWEN_LOGDOMAIN, "open(%s, O_RDONLY): %s", fname, strerror(errno));
00964     return GWEN_ERROR_IO;
00965   }
00966 
00967   rv=GWEN_DB_ReadFromFd(n, fd, dbflags, guiid, msecs);
00968   close(fd);
00969 
00970   return rv;
00971 }
00972 
00973 
00974 
00975 int GWEN_DB_ReadFromString(GWEN_DB_NODE *n,
00976                            const char *str,
00977                            int len,
00978                            uint32_t dbflags,
00979                            uint32_t guiid,
00980                            int msecs) {
00981   GWEN_IO_LAYER *io;
00982   int rv;
00983 
00984   if (len==0)
00985     len=strlen(str);
00986 
00987   /* create io layer */
00988   io=GWEN_Io_LayerMemory_fromString((const uint8_t*)str, len);
00989   assert(io);
00990 
00991   rv=GWEN_Io_Manager_RegisterLayer(io);
00992   if (rv) {
00993     DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: Could not register io layer (%d)", rv);
00994     GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
00995     GWEN_Io_Layer_free(io);
00996     return rv;
00997   }
00998 
00999   rv=GWEN_DB_ReadFromIo(n, io, dbflags, guiid, msecs);
01000   if (rv) {
01001     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01002   }
01003   GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
01004   GWEN_Io_Layer_free(io);
01005 
01006   return rv;
01007 }
01008 
01009 
01010 
01011 int GWEN_DB_WriteToBuffer(GWEN_DB_NODE *n,
01012                           GWEN_BUFFER *buf,
01013                           uint32_t dbflags,
01014                           uint32_t guiid,
01015                           int msecs) {
01016   GWEN_IO_LAYER *io;
01017   int rv;
01018 
01019   /* create io layer */
01020   io=GWEN_Io_LayerMemory_new(buf);
01021   assert(io);
01022 
01023   rv=GWEN_Io_Manager_RegisterLayer(io);
01024   if (rv) {
01025     DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: Could not register io layer (%d)", rv);
01026     GWEN_Io_Layer_DisconnectRecursively(io, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, msecs);
01027     GWEN_Io_Layer_free(io);
01028     return rv;
01029   }
01030 
01031   rv=GWEN_DB_WriteToIo(n, io, dbflags, guiid, msecs);
01032   if (rv<0) {
01033     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01034     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
01035     GWEN_Io_Layer_free(io);
01036     return rv;
01037   }
01038 
01039   /* flush data */
01040   rv=GWEN_Io_Layer_WriteString(io, "",
01041                                GWEN_IO_REQUEST_FLAGS_FLUSH,
01042                                guiid,
01043                                30000);
01044   if (rv<0) {
01045     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01046     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
01047     GWEN_Io_Layer_free(io);
01048     return rv;
01049   }
01050 
01051   /* close io layer */
01052   rv=GWEN_Io_Layer_DisconnectRecursively(io, NULL, 0, guiid, 30000);
01053   if (rv<0) {
01054     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01055     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, guiid, 1000);
01056     GWEN_Io_Layer_free(io);
01057     return rv;
01058   }
01059 
01060   GWEN_Io_Layer_free(io);
01061 
01062   return 0;
01063 }
01064 
01065 
01066 
01067 
01068 
01069 
01070 
01071 
01072 
01073 
01074 
01075 

Generated on Fri Apr 11 01:53:46 2008 for gwenhywfar by  doxygen 1.5.5