Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninfput.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
1.7.6.1
|