ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

infput.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:    .inf file parser
00003  * LICENSE:    GPL - See COPYING in the top level directory
00004  * COPYRIGHT:  Copyright 2005 Ge van Geldorp <gvg@reactos.org>
00005  */
00006 
00007 /* INCLUDES *****************************************************************/
00008 
00009 #include "inflib.h"
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 #define EOL      _T("\r\n")
00015 #define SIZE_INC 1024
00016 
00017 typedef struct _OUTPUTBUFFER
00018 {
00019   PCHAR Buffer;
00020   PCHAR Current;
00021   ULONG TotalSize;
00022   ULONG FreeSize;
00023   INFSTATUS Status;
00024 } OUTPUTBUFFER, *POUTPUTBUFFER;
00025 
00026 static void
00027 Output(POUTPUTBUFFER OutBuf, PCTSTR Text)
00028 {
00029   ULONG Length;
00030   PCHAR NewBuf;
00031   ULONG NewSize;
00032 
00033   /* Skip mode? */
00034   if (! INF_SUCCESS(OutBuf->Status))
00035     {
00036       return;
00037     }
00038 
00039   /* Doesn't fit? */
00040   Length = (ULONG)_tcslen(Text);
00041   if (OutBuf->FreeSize < Length + 1 && INF_SUCCESS(OutBuf->Status))
00042     {
00043       DPRINT("Out of free space. TotalSize %u FreeSize %u Length %u\n",
00044              (UINT)OutBuf->TotalSize, (UINT)OutBuf->FreeSize, (UINT)Length);
00045       /* Round up to next SIZE_INC */
00046       NewSize = OutBuf->TotalSize +
00047                 (((Length + 1) - OutBuf->FreeSize + (SIZE_INC - 1)) /
00048                  SIZE_INC) * SIZE_INC;
00049       DPRINT("NewSize %u\n", (UINT)NewSize);
00050       NewBuf = MALLOC(NewSize);
00051       /* Abort if failed */
00052       if (NULL == NewBuf)
00053         {
00054           DPRINT1("MALLOC() failed\n");
00055           OutBuf->Status = INF_STATUS_NO_MEMORY;
00056           return;
00057         }
00058       
00059       /* Need to copy old contents? */
00060       if (NULL != OutBuf->Buffer)
00061         {
00062           DPRINT("Copying %u bytes from old content\n",
00063                  (UINT)(OutBuf->TotalSize - OutBuf->FreeSize));
00064           MEMCPY(NewBuf, OutBuf->Buffer, OutBuf->TotalSize - OutBuf->FreeSize);
00065           OutBuf->Current = NewBuf + (OutBuf->Current - OutBuf->Buffer);
00066           FREE(OutBuf->Buffer);
00067         }
00068       else
00069         {
00070           OutBuf->Current = NewBuf;
00071         }
00072       OutBuf->Buffer = NewBuf;
00073       OutBuf->FreeSize += NewSize - OutBuf->TotalSize;
00074       OutBuf->TotalSize = NewSize;
00075       DPRINT("After reallocation TotalSize %u FreeSize %u\n",
00076              (UINT)OutBuf->TotalSize, (UINT)OutBuf->FreeSize);
00077     }
00078 
00079   /* We're guaranteed to have enough room now. Copy char by char because of
00080      possible "conversion" from Unicode to Ansi */
00081   while (Length--)
00082     {
00083       *OutBuf->Current++ = (char) *Text++;
00084       OutBuf->FreeSize--;
00085     }
00086   *OutBuf->Current = '\0';
00087 }
00088 
00089 INFSTATUS
00090 InfpBuildFileBuffer(PINFCACHE Cache,
00091                     PCHAR *Buffer,
00092                     PULONG BufferSize)
00093 {
00094   OUTPUTBUFFER OutBuf;
00095   PINFCACHESECTION CacheSection;
00096   PINFCACHELINE CacheLine;
00097   PINFCACHEFIELD CacheField;
00098   PTCHAR p;
00099   BOOLEAN NeedQuotes;
00100 
00101   OutBuf.Buffer = NULL;
00102   OutBuf.Current = NULL;
00103   OutBuf.FreeSize = 0;
00104   OutBuf.TotalSize = 0;
00105   OutBuf.Status = INF_STATUS_SUCCESS;
00106 
00107   /* Iterate through list of sections */
00108   CacheSection = Cache->FirstSection;
00109   while (CacheSection != NULL)
00110     {
00111       DPRINT("Processing section " STRFMT "\n", CacheSection->Name);
00112       if (CacheSection != Cache->FirstSection)
00113         {
00114           Output(&OutBuf, EOL);
00115         }
00116       Output(&OutBuf, _T("["));
00117       Output(&OutBuf, CacheSection->Name);
00118       Output(&OutBuf, _T("]"));
00119       Output(&OutBuf, EOL);
00120 
00121       /* Iterate through list of lines */
00122       CacheLine = CacheSection->FirstLine;
00123       while (CacheLine != NULL)
00124         {
00125           if (NULL != CacheLine->Key)
00126             {
00127               DPRINT("Line with key " STRFMT "\n", CacheLine->Key);
00128               Output(&OutBuf, CacheLine->Key);
00129               Output(&OutBuf, _T(" = "));
00130             }
00131           else
00132             {
00133               DPRINT("Line without key\n");
00134             }
00135 
00136           /* Iterate through list of lines */
00137           CacheField = CacheLine->FirstField;
00138           while (CacheField != NULL)
00139             {
00140               if (CacheField != CacheLine->FirstField)
00141                 {
00142                   Output(&OutBuf, _T(","));
00143                 }
00144               p = CacheField->Data;
00145               NeedQuotes = FALSE;
00146               while (_T('\0') != *p && ! NeedQuotes)
00147                 {
00148                   NeedQuotes = (BOOLEAN)(_T(',') == *p || _T(';') == *p ||
00149                                          _T('\\') == *p);
00150                   p++;
00151                 }
00152               if (NeedQuotes)
00153                 {
00154                   Output(&OutBuf, _T("\""));
00155                   Output(&OutBuf, CacheField->Data);
00156                   Output(&OutBuf, _T("\""));
00157                 }
00158               else
00159                 {
00160                   Output(&OutBuf, CacheField->Data);
00161                 }
00162 
00163               /* Get the next field */
00164               CacheField = CacheField->Next;
00165             }
00166 
00167           Output(&OutBuf, EOL);
00168           /* Get the next line */
00169           CacheLine = CacheLine->Next;
00170         }
00171 
00172       /* Get the next section */
00173       CacheSection = CacheSection->Next;
00174     }
00175 
00176   if (INF_SUCCESS(OutBuf.Status))
00177     {
00178       *Buffer = OutBuf.Buffer;
00179       *BufferSize = OutBuf.TotalSize - OutBuf.FreeSize;
00180     }
00181   else if (NULL != OutBuf.Buffer)
00182     {
00183       FREE(OutBuf.Buffer);
00184     }
00185 
00186   return INF_STATUS_SUCCESS;
00187 }
00188 
00189 INFSTATUS
00190 InfpFindOrAddSection(PINFCACHE Cache,
00191                      PCTSTR Section,
00192                      PINFCONTEXT *Context)
00193 {
00194   DPRINT("InfpFindOrAddSection section " STRFMT "\n", Section);
00195 
00196   *Context = MALLOC(sizeof(INFCONTEXT));
00197   if (NULL == *Context)
00198     {
00199       DPRINT1("MALLOC() failed\n");
00200       return INF_STATUS_NO_MEMORY;
00201     }
00202 
00203   (*Context)->Inf = Cache;
00204   (*Context)->Section = InfpFindSection(Cache, Section);
00205   (*Context)->Line = NULL;
00206   if (NULL == (*Context)->Section)
00207     {
00208       DPRINT("Section not found, creating it\n");
00209       (*Context)->Section = InfpAddSection(Cache, Section);
00210       if (NULL == (*Context)->Section)
00211         {
00212           DPRINT("Failed to create section\n");
00213           FREE(*Context);
00214           return INF_STATUS_NO_MEMORY;
00215         }
00216     }
00217 
00218   return INF_STATUS_SUCCESS;
00219 }
00220 
00221 INFSTATUS
00222 InfpAddLineWithKey(PINFCONTEXT Context, PCTSTR Key)
00223 {
00224   if (NULL == Context)
00225     {
00226       DPRINT1("Invalid parameter\n");
00227       return INF_STATUS_INVALID_PARAMETER;
00228     }
00229 
00230   Context->Line = InfpAddLine(Context->Section);
00231   if (NULL == Context->Line)
00232     {
00233       DPRINT("Failed to create line\n");
00234       return INF_STATUS_NO_MEMORY;
00235     }
00236 
00237   if (NULL != Key && NULL == InfpAddKeyToLine(Context->Line, Key))
00238     {
00239       DPRINT("Failed to add key\n");
00240       return INF_STATUS_NO_MEMORY;
00241     }
00242 
00243   return INF_STATUS_SUCCESS;
00244 }
00245 
00246 INFSTATUS
00247 InfpAddField(PINFCONTEXT Context, PCTSTR Data)
00248 {
00249   if (NULL == Context || NULL == Context->Line)
00250     {
00251       DPRINT1("Invalid parameter\n");
00252       return INF_STATUS_INVALID_PARAMETER;
00253     }
00254 
00255   if (NULL == InfpAddFieldToLine(Context->Line, Data))
00256     {
00257       DPRINT("Failed to add field\n");
00258       return INF_STATUS_NO_MEMORY;
00259     }
00260 
00261   return INF_STATUS_SUCCESS;
00262 }
00263 
00264 /* EOF */

Generated on Wed May 23 2012 04:34:04 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.