~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/xpinstall/wizard/os2/uninstall/nsINIParser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/*
 
3
 * The contents of this file are subject to the Netscape Public
 
4
 * License Version 1.1 (the "License"); you may not use this file
 
5
 * except in compliance with the License. You may obtain a copy of
 
6
 * the License at http://www.mozilla.org/NPL/
 
7
 *
 
8
 * Software distributed under the License is distributed on an "AS
 
9
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
 * implied. See the License for the specific language governing
 
11
 * rights and limitations under the License.
 
12
 *
 
13
 * The Original Code is Mozilla Communicator client code, 
 
14
 * released March 31, 1998. 
 
15
 *
 
16
 * The Initial Developer of the Original Code is Netscape Communications 
 
17
 * Corporation.  Portions created by Netscape are
 
18
 * Copyright (C) 1998 Netscape Communications Corporation. All
 
19
 * Rights Reserved.
 
20
 *
 
21
 * Contributor(s): 
 
22
 *     Samir Gehani <sgehani@netscape.com>
 
23
 */
 
24
 
 
25
 
 
26
#include "nsINIParser.h"
 
27
 
 
28
#ifdef __cplusplus
 
29
extern "C" {
 
30
#endif
 
31
unsigned long GetPrivateProfileString(const char* szAppName,
 
32
                                      const char* szKeyName,
 
33
                                      const char* szDefault,
 
34
                                      char* szReturnedString,
 
35
                                      int nSize,
 
36
                                      const char* szFileName)
 
37
{
 
38
   nsINIParser parser((char*)szFileName);
 
39
   if (parser.GetString((char*)szAppName, (char*)szKeyName, szReturnedString, &nSize) != nsINIParser::OK) {
 
40
      if (szDefault) {
 
41
         strcpy(szReturnedString, szDefault);
 
42
      }
 
43
   }
 
44
   return strlen(szReturnedString);
 
45
}
 
46
 
 
47
unsigned long WritePrivateProfileString(const char* szAppName,
 
48
                                        const char* szKeyName,
 
49
                                        const char* szValue,
 
50
                                        const char* szFileName)
 
51
{
 
52
   nsINIParser parser((char*)szFileName);
 
53
   if (parser.WriteString((char*)szAppName, (char*)szKeyName, (char*)szValue) != nsINIParser::OK) {
 
54
      return 0;
 
55
   }
 
56
   return 1;
 
57
}
 
58
#ifdef __cplusplus
 
59
}
 
60
#endif
 
61
 
 
62
nsINIParser::nsINIParser(char *aFilename)
 
63
{
 
64
    FILE    *fd = NULL;
 
65
    long    eofpos = 0;
 
66
    int     rd = 0;
 
67
 
 
68
    mfWrite = 0;
 
69
    mFileBuf = NULL;
 
70
    mFilename = (char*)malloc(strlen(aFilename)+1);
 
71
    strcpy(mFilename, aFilename);
 
72
    mFileBufSize = 0;
 
73
    mError = OK;
 
74
 
 
75
    /* param check */
 
76
    if (!aFilename)
 
77
    {
 
78
        mError = E_PARAM;
 
79
        return;
 
80
    }
 
81
 
 
82
    /* open the file */
 
83
    fd = fopen(aFilename, "r");
 
84
    if (!fd)
 
85
        goto bail;
 
86
    
 
87
    /* get file size */
 
88
    if (fseek(fd, 0, SEEK_END) != 0)
 
89
        goto bail;
 
90
    eofpos = ftell(fd);
 
91
    if (eofpos == 0)
 
92
        goto bail;
 
93
 
 
94
    /* malloc an internal buf the size of the file */
 
95
    mFileBuf = (char *) calloc(1, eofpos * sizeof(char));
 
96
    if (!mFileBuf)
 
97
    {
 
98
        mError = E_MEM;
 
99
        return;
 
100
    }
 
101
    mFileBufSize = eofpos;
 
102
 
 
103
    /* read the file in one swoop */
 
104
    if (fseek(fd, 0, SEEK_SET) != 0)
 
105
        goto bail;
 
106
    rd = fread((void *)mFileBuf, 1, eofpos, fd);
 
107
    if (!rd)
 
108
        goto bail;
 
109
 
 
110
    /* actual number of bytes read is less than the size of the file */
 
111
    /* due to /r/n -> /n conversion */
 
112
    if (rd < eofpos) {
 
113
      mFileBufSize = rd;
 
114
    } else {
 
115
      mFileBufSize = eofpos;
 
116
    }
 
117
 
 
118
    /* close file */
 
119
    fclose(fd);
 
120
 
 
121
    return;
 
122
 
 
123
bail:
 
124
    mError = E_READ;
 
125
    return;
 
126
}
 
127
 
 
128
nsINIParser::~nsINIParser()
 
129
{
 
130
    if (mfWrite) {
 
131
      FILE* hFile = fopen(mFilename, "w+");
 
132
      fwrite(mFileBuf, mFileBufSize, 1, (FILE *)hFile);
 
133
      fclose(hFile);
 
134
    }
 
135
    free(mFileBuf);
 
136
    free(mFilename);
 
137
}
 
138
 
 
139
int
 
140
nsINIParser::GetString( char *aSection, char *aKey, 
 
141
                        char *aValBuf, int *aIOValBufSize )
 
142
{
 
143
    char *secPtr = NULL;
 
144
    mError = OK;
 
145
    DUMP("GetString");
 
146
 
 
147
    /* param check */
 
148
    if ( !aSection || !aValBuf || 
 
149
         !aIOValBufSize || (*aIOValBufSize <= 0) )
 
150
        return E_PARAM;
 
151
 
 
152
    /* find the section if it exists */
 
153
    mError = FindSection(aSection, &secPtr);
 
154
    if (mError != OK)
 
155
        return mError;
 
156
 
 
157
    if (aKey) {
 
158
        /* find the key if it exists in the valid section we found */
 
159
        mError = GetValue(secPtr, aKey, aValBuf, aIOValBufSize);
 
160
    } else {
 
161
        mError = GetAllKeys(secPtr, aValBuf, aIOValBufSize);
 
162
    }
 
163
 
 
164
 
 
165
    return mError;
 
166
}
 
167
 
 
168
int
 
169
nsINIParser::GetStringAlloc( char *aSection, char *aKey,
 
170
                             char **aOutBuf, int *aOutBufSize )
 
171
{
 
172
    char buf[MAX_VAL_SIZE];
 
173
    int bufsize = MAX_VAL_SIZE;
 
174
    mError = OK;
 
175
    DUMP("GetStringAlloc");
 
176
 
 
177
    mError = GetString(aSection, aKey, buf, &bufsize);
 
178
    if (mError != OK)
 
179
        return mError;
 
180
 
 
181
    *aOutBuf = (char *) malloc(bufsize + 1);
 
182
    strncpy(*aOutBuf, buf, bufsize);
 
183
    *(*aOutBuf + bufsize) = 0;
 
184
    *aOutBufSize = bufsize + 1;
 
185
 
 
186
    return mError;
 
187
}
 
188
 
 
189
int
 
190
nsINIParser::GetError()
 
191
{
 
192
    DUMP("GetError");
 
193
    return mError;
 
194
}
 
195
 
 
196
char *
 
197
nsINIParser::ResolveName(char *aINIRoot)
 
198
{
 
199
    char *resolved = NULL;
 
200
    char *locale = NULL;
 
201
    struct stat st_exists;
 
202
 
 
203
    /* param check */
 
204
    if (!aINIRoot)
 
205
        return NULL;
 
206
 
 
207
    locale = setlocale(LC_CTYPE, NULL);
 
208
    if (!locale) 
 
209
        return NULL;
 
210
 
 
211
    /* resolved string: "<root>.ini.<locale>\0" */
 
212
    resolved = (char *) malloc(strlen(aINIRoot) + 5 + strlen(locale) + 1);
 
213
    if (!resolved)
 
214
        return NULL;
 
215
 
 
216
    /* locale specific ini file name */
 
217
    sprintf(resolved, "%s.ini.%s", aINIRoot, locale);
 
218
    if (0 == stat(resolved, &st_exists))
 
219
        return resolved;
 
220
 
 
221
    /* fallback to general ini file name */
 
222
    sprintf(resolved, "%s.ini", aINIRoot);
 
223
    if (0 == stat(resolved, &st_exists))
 
224
        return resolved;
 
225
    
 
226
    /* neither existed so error returned */
 
227
    return NULL;
 
228
}
 
229
 
 
230
int
 
231
nsINIParser::WriteString(char *aSection, char *aKey, char *aValBuf)
 
232
{
 
233
    mfWrite = 1;
 
234
    char *secPtr = NULL;
 
235
    char *keyPtr = NULL;
 
236
    mError = OK;
 
237
    DUMP("GetString");
 
238
 
 
239
    /* param check */
 
240
    if ( !aSection || !aKey || !aValBuf )
 
241
        return E_PARAM;
 
242
 
 
243
    /* find the section if it exists */
 
244
    mError = FindSection(aSection, &secPtr);
 
245
    if (mError != OK) {
 
246
      /* if the seciont doesn't exist, add it to the END of the buffer */
 
247
      char szNewSection[MAX_VAL_SIZE];
 
248
      strcpy(szNewSection, "[");
 
249
      strcat(szNewSection, aSection);
 
250
      strcat(szNewSection, "]");
 
251
      strcat(szNewSection, NLSTRING);
 
252
      mFileBuf = (char*)realloc(mFileBuf, mFileBufSize+strlen(szNewSection));
 
253
      memcpy(&mFileBuf[mFileBufSize], szNewSection, strlen(szNewSection));
 
254
      secPtr = &mFileBuf[mFileBufSize];
 
255
      mFileBufSize+= strlen(szNewSection);
 
256
      mError = OK;
 
257
    }
 
258
 
 
259
    /* find the key if it exists in the valid section we found */
 
260
    mError = FindKey(secPtr, aKey, &keyPtr);
 
261
    if (mError != OK) {
 
262
      char szNewKeyValue[MAX_VAL_SIZE];
 
263
      strcpy(szNewKeyValue, aKey);
 
264
      strcat(szNewKeyValue, "=");
 
265
      strcat(szNewKeyValue, aValBuf);
 
266
      strcat(szNewKeyValue, NLSTRING);
 
267
      char *mNewFileBuf = (char*)calloc(1, mFileBufSize+strlen(szNewKeyValue));
 
268
      memcpy(mNewFileBuf, mFileBuf, mFileBufSize);
 
269
      /* Set the section pointer to the location of the rest of the buffer */
 
270
      while (*secPtr != NL) {
 
271
         secPtr++;
 
272
      }
 
273
      secPtr++;
 
274
      /* Use sectionptr to compte where in the new buf we are going to insert */
 
275
      memcpy(mNewFileBuf+(secPtr-mFileBuf), szNewKeyValue, strlen(szNewKeyValue));
 
276
      memcpy(mNewFileBuf+(secPtr-mFileBuf)+strlen(szNewKeyValue), secPtr, mFileBufSize-(secPtr-mFileBuf));
 
277
      mFileBufSize += strlen(szNewKeyValue);
 
278
      free(mFileBuf);
 
279
      mFileBuf = mNewFileBuf;
 
280
      mError = OK;
 
281
    } else {
 
282
      while (*keyPtr != '=') {
 
283
         keyPtr++;
 
284
      }
 
285
      keyPtr++;
 
286
      int length = 0;
 
287
      char* lenPtr = keyPtr;
 
288
      while (*lenPtr != NL) {
 
289
         lenPtr++;
 
290
         length++;
 
291
      }
 
292
      int difference;
 
293
      difference = strlen(aValBuf)- length;
 
294
      char *mNewFileBuf = (char*)calloc(1, mFileBufSize+difference);
 
295
      memcpy(mNewFileBuf, mFileBuf, mFileBufSize);
 
296
      /* Use keyptr to compte where in the new buf we are going to insert */
 
297
      memcpy(mNewFileBuf+(keyPtr-mFileBuf), aValBuf, strlen(aValBuf));
 
298
 
 
299
 
 
300
      memcpy(mNewFileBuf+(keyPtr-mFileBuf)+strlen(aValBuf), lenPtr, mFileBufSize-(lenPtr-mFileBuf));
 
301
      mFileBufSize += difference;
 
302
      free(mFileBuf);
 
303
      mFileBuf = mNewFileBuf;
 
304
      mError = OK;
 
305
 
 
306
 
 
307
    }
 
308
 
 
309
    return mError;
 
310
}
 
311
 
 
312
int
 
313
nsINIParser::FindSection(char *aSection, char **aOutSecPtr)
 
314
{
 
315
    char *currChar = mFileBuf;
 
316
    char *nextSec = NULL;
 
317
    char *secClose = NULL;
 
318
    char *nextNL = NULL;
 
319
    mError = E_NO_SEC;
 
320
    DUMP("FindSection");
 
321
 
 
322
    // param check
 
323
    if (!aSection || !aOutSecPtr)
 
324
    {
 
325
        mError = E_PARAM;
 
326
        return mError;
 
327
    }
 
328
 
 
329
    while (currChar < (mFileBuf + mFileBufSize))
 
330
    {
 
331
        // look for first '['
 
332
        nextSec = NULL;
 
333
        nextSec = strchr(currChar, '[');
 
334
        if (!nextSec)
 
335
            break;
 
336
            
 
337
        currChar = nextSec + 1;
 
338
 
 
339
        // extract section name till first ']'
 
340
        secClose = NULL; nextNL = NULL;
 
341
        secClose = strchr(currChar, ']');
 
342
        nextNL = strchr(currChar, NL);
 
343
        if ((!nextNL) || (nextNL < secClose))
 
344
        {
 
345
            currChar = nextNL;
 
346
            continue;
 
347
        }
 
348
 
 
349
        // if section name matches we succeeded
 
350
        if (strnicmp(aSection, currChar, strlen(aSection)) == 0)
 
351
        {
 
352
            *aOutSecPtr = secClose + 1;
 
353
            mError = OK;
 
354
            break;
 
355
        }
 
356
    }
 
357
 
 
358
    return mError;
 
359
}
 
360
 
 
361
int
 
362
nsINIParser::GetValue(char *aSecPtr, char *aKey, char *aVal, int *aIOValSize)
 
363
{
 
364
    char *nextNL = NULL;
 
365
    char *secEnd = NULL;
 
366
    char *currLine = aSecPtr;
 
367
    char *nextEq = NULL;
 
368
    mError = E_NO_KEY;
 
369
    DUMP("FindKey");
 
370
 
 
371
    // param check
 
372
    if (!aSecPtr || !aKey || !aVal || !aIOValSize || (*aIOValSize <= 0))
 
373
    {
 
374
        mError = E_PARAM;
 
375
        return mError;
 
376
    }
 
377
 
 
378
    // determine the section end
 
379
    secEnd = aSecPtr;
 
380
find_end:
 
381
    if (secEnd)
 
382
        secEnd = strchr(secEnd, '['); // search for next sec start
 
383
    if (!secEnd)
 
384
    {
 
385
        secEnd = strchr(aSecPtr, '\0'); // else search for file end
 
386
        if (!secEnd)
 
387
        {
 
388
            mError = E_SEC_CORRUPT; // else this data is corrupt
 
389
            return mError;
 
390
        }
 
391
    }
 
392
 
 
393
    // handle start section token ('[') in values for i18n
 
394
    if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == NL))
 
395
    {
 
396
        secEnd++;
 
397
        goto find_end;
 
398
    }
 
399
 
 
400
    while (currLine < secEnd)
 
401
    {
 
402
        nextNL = NULL;
 
403
        nextNL = strchr(currLine, NL);
 
404
        if (!nextNL)
 
405
            nextNL = mFileBuf + mFileBufSize;
 
406
 
 
407
        // ignore commented lines (starting with ;)
 
408
        if (currLine == strchr(currLine, ';'))
 
409
        {
 
410
            currLine = nextNL + 1;
 
411
            continue;
 
412
        }
 
413
 
 
414
        // extract key before '='
 
415
        nextEq = NULL;
 
416
        nextEq = strchr(currLine, '=');
 
417
        if (!nextEq || nextEq > nextNL) 
 
418
        {
 
419
            currLine = nextNL + 1;
 
420
            continue;
 
421
        }
 
422
 
 
423
        // if key matches we succeeded
 
424
        if (strnicmp(currLine, aKey, strlen(aKey)) == 0)
 
425
        {
 
426
            // extract the value and return
 
427
            if (*aIOValSize < nextNL - nextEq)
 
428
            {
 
429
                mError = E_SMALL_BUF;
 
430
                *aVal = '\0';
 
431
                *aIOValSize = 0;
 
432
                return mError;
 
433
            }
 
434
                
 
435
            *aIOValSize = nextNL - (nextEq + 1); 
 
436
            strncpy(aVal, (nextEq + 1), *aIOValSize);
 
437
            *(aVal + *aIOValSize) = 0; // null terminate
 
438
            mError = OK;
 
439
            return mError;
 
440
        }
 
441
        else
 
442
        {
 
443
            currLine = nextNL + 1;
 
444
        }
 
445
    }
 
446
 
 
447
    return mError;
 
448
}
 
449
 
 
450
int
 
451
nsINIParser::GetAllKeys(char *aSecPtr, char *aVal, int *aIOValSize)
 
452
{
 
453
    char *nextNL = NULL;
 
454
    char *secEnd = NULL;
 
455
    char *currLine = aSecPtr;
 
456
    char *nextEq = NULL;
 
457
    char *outPtr = NULL;
 
458
    mError = E_NO_KEY;
 
459
    DUMP("FindKey");
 
460
 
 
461
    // param check
 
462
    if (!aSecPtr || !aVal || !aIOValSize || (*aIOValSize <= 0))
 
463
    {
 
464
        mError = E_PARAM;
 
465
        return mError;
 
466
    }
 
467
 
 
468
    // determine the section end
 
469
    secEnd = aSecPtr;
 
470
find_end:
 
471
    if (secEnd)
 
472
        secEnd = strchr(secEnd, '['); // search for next sec start
 
473
    if (!secEnd)
 
474
    {
 
475
        secEnd = strchr(aSecPtr, '\0'); // else search for file end
 
476
        if (!secEnd)
 
477
        {
 
478
            mError = E_SEC_CORRUPT; // else this data is corrupt
 
479
            return mError;
 
480
        }
 
481
    }
 
482
 
 
483
    // handle start section token ('[') in values for i18n
 
484
    if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == NL))
 
485
    {
 
486
        secEnd++;
 
487
        goto find_end;
 
488
    }
 
489
 
 
490
    outPtr = aVal;
 
491
 
 
492
    while (currLine < secEnd)
 
493
    {
 
494
        nextNL = NULL;
 
495
        nextNL = strchr(currLine, NL);
 
496
        if (!nextNL)
 
497
            nextNL = mFileBuf + mFileBufSize;
 
498
 
 
499
        // ignore commented lines (starting with ;)
 
500
        if (currLine == strchr(currLine, ';'))
 
501
        {
 
502
            currLine = nextNL + 1;
 
503
            continue;
 
504
        }
 
505
 
 
506
        // extract key before '='
 
507
        nextEq = NULL;
 
508
        nextEq = strchr(currLine, '=');
 
509
        if (!nextEq || nextEq > nextNL) 
 
510
        {
 
511
            currLine = nextNL + 1;
 
512
            continue;
 
513
        }
 
514
 
 
515
        strncpy(aVal, currLine, nextEq-currLine);
 
516
        aVal+= nextEq-currLine;
 
517
        *aVal = '\0';
 
518
        aVal++;
 
519
 
 
520
        currLine = nextNL + 1;
 
521
    }
 
522
 
 
523
    return OK;
 
524
}
 
525
 
 
526
int
 
527
nsINIParser::FindKey(char *aSecPtr, char *aKey, char **aOutKeyPtr)
 
528
{
 
529
    char *nextNL = NULL;
 
530
    char *secEnd = NULL;
 
531
    char *currLine = aSecPtr;
 
532
    char *nextEq = NULL;
 
533
    mError = E_NO_KEY;
 
534
    DUMP("FindKey");
 
535
 
 
536
    // param check
 
537
    if (!aSecPtr || !aKey || !aOutKeyPtr)
 
538
    {
 
539
        mError = E_PARAM;
 
540
        return mError;
 
541
    }
 
542
 
 
543
    // determine the section end
 
544
    secEnd = aSecPtr;
 
545
find_end:
 
546
    if (secEnd)
 
547
        secEnd = strchr(secEnd, '['); // search for next sec start
 
548
    if (!secEnd)
 
549
    {
 
550
        secEnd = strchr(aSecPtr, '\0'); // else search for file end
 
551
        if (!secEnd)
 
552
        {
 
553
            mError = E_SEC_CORRUPT; // else this data is corrupt
 
554
            return mError;
 
555
        }
 
556
    }
 
557
 
 
558
    // handle start section token ('[') in values for i18n
 
559
    if (*secEnd == '[' && !(secEnd == aSecPtr || *(secEnd-1) == NL))
 
560
    {
 
561
        secEnd++;
 
562
        goto find_end;
 
563
    }
 
564
 
 
565
    while (currLine < secEnd)
 
566
    {
 
567
        nextNL = NULL;
 
568
        nextNL = strchr(currLine, NL);
 
569
        if (!nextNL)
 
570
            nextNL = mFileBuf + mFileBufSize;
 
571
 
 
572
        // ignore commented lines (starting with ;)
 
573
        if (currLine == strchr(currLine, ';'))
 
574
        {
 
575
            currLine = nextNL + 1;
 
576
            continue;
 
577
        }
 
578
 
 
579
        // extract key before '='
 
580
        nextEq = NULL;
 
581
        nextEq = strchr(currLine, '=');
 
582
        if (!nextEq || nextEq > nextNL) 
 
583
        {
 
584
            currLine = nextNL + 1;
 
585
            continue;
 
586
        }
 
587
 
 
588
        // if key matches we succeeded
 
589
        if (strnicmp(currLine, aKey, strlen(aKey)) == 0)
 
590
        {
 
591
            *aOutKeyPtr = currLine;
 
592
            mError = OK;
 
593
            return mError;
 
594
        }
 
595
        else
 
596
        {
 
597
            currLine = nextNL + 1;
 
598
        }
 
599
    }
 
600
 
 
601
    return mError;
 
602
}