root/trunk/CConfigFile.cpp

Revision 14, 14.3 kB (checked in by sagrer, 4 months ago)

Поковырял код на предмет понять "где что есть". Заодно добавил везде шапку и вбил дополнительно в конфиг проекта те модули, которые вбиты не были - чтобы можно было быстро открыть любой файл через окно менеджера проекта.

Line 
1 ///////////////////////////////////////////////////////////
2 //                        TexGen                         //
3 //          утилита для подготовки текстур рельефа       //
4 //               для игры Проклятые Земли                //
5 //           Copyright (C) 2007-2008 Gipat Group         //
6 //              Распространяется на условиях             //
7 //    Gipat Group's opened EI-editor-utility license     //
8 //                      версии 1.0                       //
9 //                                                       //
10 //                  www.gipatgroup.org                   //
11 ///////////////////////////////////////////////////////////
12
13 //К работе над данным файлом приложили руки, ноги.... короче аффтары:
14 // 1) Снайпер (sniper-rifle@rambler.ru)
15
16 ////////////////////////////////////////////////////////////////////////
17
18 #include <vcl.h>
19 #include "CConfigFile.h"
20 //-------------------------------------------
21 //По всему файлу
22 void CConfigFile::LoadConfig(AnsiString FileName)
23 {
24 //Загружаем всю инфу из файла
25   if(FileExists(FileName))  //Если есть чего открывать
26   {
27     AnsiString FILE, TempStr, ClearStr, Val, CurrSect;
28     int Hnd, Len;
29     Hnd = FileOpen(FileName,fmOpenRead);
30     if(Hnd > 0)              //Если удалось открыть
31     {
32       Len = FileSeek(Hnd,0,SEEK_END);       //
33       FileSeek(Hnd,0,SEEK_SET);             //
34       FILE.SetLength(Len);                  //   Считали файл в переменную и закрыли его.
35       FileRead(Hnd,&FILE[1],Len);           //
36       FileClose(Hnd);                       //
37       ////////////////////////////////////////
38       RemoveAllSect();                      //   Очистили объект от старой инфы
39       FILE += "\r\n";                       //Ибо нефиг.
40       while(AnsiContainsText(FILE,"\r\n"))
41       {
42         TempStr = Trim(LeftStr(FILE,AnsiPos("\r\n",FILE)-1));                // Выделили очередную строку
43         FILE = RightStr(FILE,FILE.Length() - AnsiPos("\r\n",FILE)-1);  // И убрали её из файла
44
45         //1) проверяем - не является ли параметр комментарием
46         if(LeftStr(TempStr,2) == "//")
47         {
48           IniComment += TempStr+"\r\n";
49         }
50         else         //2) или нет - и это секция
51           if( (LeftStr(TempStr,1)=="[")&&(RightStr(TempStr,1)=="]") )
52           {
53             ClearStr = Trim(MidStr(TempStr,2,TempStr.Length() - 2));
54             if(!SectionExists(ClearStr))AddSection(ClearStr);
55             CurrSect = ClearStr;
56           }
57           else
58             if(AnsiContainsStr(TempStr,"="))
59             {
60               ClearStr = Trim(LeftStr(TempStr,AnsiPos("=",TempStr)-1));
61               Val = Trim(RightStr(TempStr,TempStr.Length() - AnsiPos("=",TempStr)));
62               AddValue(CurrSect, ClearStr, Val);
63             }
64       }
65     }
66   }
67 }
68 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
69 void CConfigFile::SaveConfig(AnsiString FileName)
70 {
71 //Савим данные в файл
72   int Hnd;
73   if(!FileExists(FileName))
74   {
75     Hnd=FileCreate(FileName,fmOpenWrite);
76   }
77   else
78   {
79     DeleteFile(FileName);
80     Hnd=FileCreate(FileName,fmOpenWrite);
81   }
82   if(Hnd>0)
83   {
84     AnsiString Rez=IniComment+"\r\n";
85     for(SectionsChain *TMP=DataStart; TMP != NULL; TMP = TMP->Next)
86     {
87       Rez += "["+TMP->Name+"]\r\n";
88       for(ValueChain *VTMP=TMP->Start; VTMP != NULL; VTMP = VTMP->Next)
89       {
90         Rez += VTMP->Name + "=" + VTMP->Value + "\r\n";
91       }
92       Rez += "\r\n";
93     }
94
95     while(AnsiContainsText(Rez,"\n\n"))
96     {
97       Rez = AnsiReplaceText(Rez,"\n\n","\n");
98     }
99
100     while(AnsiContainsText(Rez,"\r\r"))
101     {
102       Rez = AnsiReplaceText(Rez,"\r\r","\r");
103     }
104
105     while(AnsiContainsText(Rez,"\r\n\r\n"))
106     {
107       Rez = AnsiReplaceText(Rez,"\r\n\r\n","\r\n");
108     }
109
110    
111     FileWrite(Hnd,&Rez[1],Rez.Length());
112     FileClose(Hnd);
113   }
114 }
115 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
116
117 //По секциям
118 bool CConfigFile::SectionExists(AnsiString SName)
119 {
120 //Проверяем существование секции (раздела)
121
122   SectionsChain *Sect;
123   bool found = false;
124   for(Sect = DataStart; (Sect != NULL) && (!found); Sect = Sect->Next)
125   {
126     if(Sect->Name.LowerCase() == SName.LowerCase() )
127     {
128       found = true;
129     }
130   }
131   return found;
132 }
133 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
134 void CConfigFile::AddSection(AnsiString Name)
135 {
136 //Добавляем запись о новой секции в список
137   SectionsChain *NewSect = new SectionsChain(), *Temp; //Создаём новую секцию
138   NewSect->Name = Name;
139   NewSect->Start = NULL;
140   NewSect->Next = NULL;
141   //Теперь узнаём, куда эту секцию лепить
142   if(DataStart == NULL)
143   {
144     DataStart = NewSect;  //Начало пустое - просто пихаем туда новую секцию
145   }
146   else
147   {
148     for(Temp = DataStart;Temp->Next != NULL; Temp = Temp->Next); //Перебираем все
149     Temp->Next = NewSect;                                        //Дошли до конца и пихаем туда.
150   }
151 }
152 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
153 void CConfigFile::DelSection(AnsiString Name)
154 {
155 //Удаляем секцию, а так же всю её информацию...
156   SectionsChain *Old=NULL, *New;//Сохраним ссылку на предыдущую и новую секции, чтобы соединить цепь на месте вырванного звена
157
158   New = DataStart;
159   while(New != NULL)
160   {
161     if(New->Name.LowerCase() == Name.LowerCase())
162     {
163       if(Old != NULL)
164         Old->Next = New->Next;
165       else
166         DataStart = New->Next;
167
168       RemoveValues(New->Start);
169       delete New;
170
171       New = NULL;
172     }
173     else
174     {
175       Old = New;//Мля, ппц... как оно вылетало, пока не было условия... %)
176       New = New->Next;
177     }
178   }
179 }
180 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
181
182 void CConfigFile::RemoveValues(ValueChain *Start)
183 {
184 //Нужно удалить все значения, которые были у раздела, при его удалении.
185   //Start - начальный элемент списка, после которого удаляются все, включая его.
186   ValueChain *VNext;
187   for(; Start != NULL;  Start = VNext)
188   {
189     VNext = Start->Next;
190     delete Start;
191   }
192 }
193 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
194
195 void CConfigFile::RemoveAllSect()
196 {
197 //Нужно очистить объект от данных
198   //DataStart - первая секция. Может не существовать.
199   SectionsChain *SNext;
200   for(; DataStart != NULL; DataStart = SNext)
201   {
202     SNext = DataStart->Next;
203     DelSection(DataStart->Name);
204   }
205 }
206 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
207
208 void CConfigFile::RenameSection(AnsiString Name, AnsiString NewName)
209 {
210 //Меняем имя раздела. Всё просто.
211   bool found_s=false;
212   for(SectionsChain *Sect = DataStart; (!found_s)&&(Sect != NULL); Sect = Sect->Next)
213   {
214     if(Sect->Name.LowerCase() == Name.LowerCase())
215     {
216       found_s =true;
217       Sect->Name = NewName;
218     }
219   }
220 }
221 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
222
223 //По значениям
224 bool CConfigFile::ValueExists(AnsiString Section, AnsiString ValueName)
225 {
226 //Проверяем, существует ли значение с заданным именем
227   bool found = false;
228   bool ExitLoopS = false, ExitLoopV = false;
229   if(SectionExists(Section))
230   {
231     ValueChain *Val;
232     SectionsChain *Sect;
233     for(Sect = DataStart; (Sect != NULL)&&(!ExitLoopS); Sect = Sect->Next)   //Перебираем секции... тупо...
234     {
235       if(Sect->Name.LowerCase() == Section.LowerCase())
236       {
237         for(Val = Sect->Start; (Val != NULL)&&(!ExitLoopV); Val = Val->Next) //Перебираем параметры... но можно себе позволить %)
238         {
239           if(Val->Name.LowerCase() == ValueName.LowerCase())
240           {
241             found = true;
242             ExitLoopV = true;
243           }
244         }
245         ExitLoopS = true;
246       }
247     }
248   }
249   return found;
250 }
251 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
252
253 void CConfigFile::AddValue(AnsiString Section, AnsiString ValueName, AnsiString Value)
254 {
255 //Добавляет параметр в секцию. Весьма удобно...
256   if(SectionExists(Section))
257   {
258     ValueChain *Val, *Pre = NULL;                            //Переменные для выбора последнего параметра
259     SectionsChain *Sect;
260     bool ExitLoop = false;
261     for(Sect = DataStart; (Sect != NULL) && (!ExitLoop); Sect = Sect->Next)   //Перебираем секции... тупо...
262     {
263       if(Sect->Name.LowerCase() == Section.LowerCase())     //Совпало имя - заходим...
264       {
265         for(Val = Sect->Start; Val != NULL; Val = Val->Next) //Перебираем все параметры до конца
266         {
267           Pre = Val;
268         }
269         Val = new ValueChain();                              //Создать новый элемент списка
270         Val->Name = ValueName;
271         Val->Value = Value;
272         Val->Next = NULL;
273
274         if(Pre==NULL)                                        //Либо в начало его
275         {
276           Sect->Start = Val;
277         }
278         else                                                 //Либо примазать толком :)
279         {
280           Pre->Next = Val;
281         }
282         ExitLoop = true;                                     //Стоп, цикл!
283       }
284     }
285   }
286 }
287 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
288
289 void CConfigFile::DelValue(AnsiString Section, AnsiString ValueName)
290 {
291 //Удаляет из секции первое вхождение параметра, хотя предполагается что их не будет >1
292   bool found_s=false, found_v = false;
293   for(SectionsChain *S = DataStart; (S != NULL)&&(!found_s); S = S->Next) //Перебираем секции
294   {
295     if(S->Name.LowerCase() == Section.LowerCase()) //Нашли нужную секцию
296     {
297       found_s = true; //Пометим секцию найденной
298       if(S->Start->Name.LowerCase() == ValueName.LowerCase()) //Если нужный элемент - первый
299       {
300         found_v = true;
301         ValueChain *Tmp = S->Start->Next;
302         S->Start->Next = NULL;
303         delete S->Start;
304         S->Start = Tmp;
305       }
306       else
307       {
308         ValueChain *Pre=NULL;
309         for(ValueChain *V = S->Start->Next; (V != NULL) && (!found_v); V = V->Next) //Перебираем все значения
310         {
311           if(V->Name.LowerCase() == ValueName.LowerCase()) //Если найден нужный параметр
312           {
313             found_v = true; //Нашли параметр
314             if(Pre != NULL)
315             {
316               Pre->Next = V->Next;
317             }
318             else
319             {
320               S->Start->Next = V->Next;
321             }
322             V->Next = NULL;
323             delete V;
324           }
325           else
326           {
327             Pre = V;
328           }
329         }
330       }
331     }
332   }
333 }
334 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
335
336 void CConfigFile::RenameValue(AnsiString Section, AnsiString OldName, AnsiString NewName)
337 {
338 //Переименовывает параметр
339   if(ValueExists(Section,OldName))
340   {
341     bool found_s = false, found_v = false; //Нашли ли мы секцию и параметр
342     for(SectionsChain *S = DataStart; (!found_s)&&(S != NULL); S = S->Next)// Perebor po sektsijam
343     {
344       if(S->Name.LowerCase() == Section.LowerCase()) //Ura! Nashli!
345       {
346         found_s = true;
347         for(ValueChain *V = S->Start; (!found_v)&&(V != NULL); V = V->Next)// Perebor po parametram
348         {
349           if(V->Name.LowerCase() == OldName.LowerCase())
350           {
351             found_v = true;
352             V->Name = NewName;
353           }
354         }
355       }
356     }
357   }
358 }
359 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
360
361 void CConfigFile::SetValue(AnsiString Section, AnsiString ValueName, AnsiString NewVal)
362 {
363 //Задаёт значение параметра
364   if(ValueExists(Section,ValueName))
365   {
366     ValueChain *Val, *ToSet=NULL;                                            //Переменные для выбора последнего параметра
367     SectionsChain *Sect;
368     bool ExitLoopS = false, ExitLoopV = false;
369     for(Sect = DataStart; (Sect != NULL)&&(!ExitLoopS); Sect = Sect->Next)   //Перебираем секции... тупо...
370     {
371       if(Sect->Name.LowerCase() == Section.LowerCase())                     //Совпало имя - заходим...
372       {
373         for(Val = Sect->Start; (Val != NULL)&&(!ExitLoopV); Val = Val->Next) //Перебираем все параметры до нужного
374         {
375           if(Val->Name.LowerCase() == ValueName.LowerCase())                //Нашли нужное
376           {
377             ToSet = Val;
378             ExitLoopV = true;
379           }
380         }
381
382         if(ToSet != NULL)ToSet->Value = NewVal;                              //Собстно, задаём
383
384         ExitLoopS = true;                                                     //Стоп, цикл!
385       }
386     }
387   }
388   else
389   {
390     if(!SectionExists(Section))
391       AddSection(Section);
392     AddValue(Section,ValueName,NewVal);
393   }
394 }
395 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
396
397 AnsiString CConfigFile::GetValue(AnsiString Section, AnsiString ValueName)
398 {
399 //Возвращает значение параметра. При ошибке возвращает пустую строку.
400
401   AnsiString Rez = "";
402   if(ValueExists(Section,ValueName))
403   {
404     ValueChain *Val, *ToGet=NULL;                            //Переменные для выбора последнего параметра
405     SectionsChain *Sect = DataStart;
406     while(Sect != NULL)                                      //Перебираем секции... тупо...
407     {
408       if(Sect->Name.LowerCase() == Section.LowerCase())     //Совпало имя - заходим...
409       {
410         Val = Sect->Start;
411         while(Val != NULL)                                   //Перебираем все параметры до нужного
412         {
413           if(Val->Name.LowerCase() == ValueName.LowerCase())//Нашли нужное
414           {
415             ToGet = Val;
416             Val = NULL;
417           }
418           else
419           {
420             Val = Val->Next;
421           }
422         }
423
424         if(ToGet != NULL)Rez = ToGet->Value;                 //Собстно, берём возвращаемое значение
425
426         Sect = NULL;                                         //Стоп, цикл!
427       }
428       else
429       {
430         Sect = Sect->Next;
431       }
432     }
433   }
434   return Rez;
435 }
436 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
437
438 void CConfigFile::Debug()
439 {
440 //Test!!!
441
442 }
443 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
444
445 AnsiString CConfigFile::GetValueEx(AnsiString Section, AnsiString ValueName, AnsiString Default)
446 {
447   AnsiString Rez=Default;
448   if(ValueExists(Section,ValueName))
449     Rez = GetValue(Section,ValueName);
450   return Rez;
451 }
452 //ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖопа
Note: See TracBrowser for help on using the browser.