1/******************************************************************************
2 *   Copyright (C) 2009, International Business Machines
3 *   Corporation and others.  All Rights Reserved.
4 *******************************************************************************
5 */
6
7#include "flagparser.h"
8#include "filestrm.h"
9
10#define LARGE_BUFFER_MAX_SIZE 2048
11
12static void extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, UErrorCode *status);
13static int32_t getFlagOffset(const char *buffer, int32_t bufferSize);
14
15/*
16 * Opens the given fileName and reads in the information storing the data in flagBuffer.
17 */
18U_CAPI void U_EXPORT2
19parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize, int32_t numOfFlags, UErrorCode *status) {
20    char buffer[LARGE_BUFFER_MAX_SIZE];
21    int32_t i;
22
23    FileStream *f = T_FileStream_open(fileName, "r");
24    if (f == NULL) {
25        *status = U_FILE_ACCESS_ERROR;
26        return;
27    }
28
29    for (i = 0; i < numOfFlags; i++) {
30        if (T_FileStream_readLine(f, buffer, LARGE_BUFFER_MAX_SIZE) == NULL) {
31            *status = U_FILE_ACCESS_ERROR;
32            break;
33        }
34
35        extractFlag(buffer, LARGE_BUFFER_MAX_SIZE, flagBuffer[i], flagBufferSize, status);
36        if (U_FAILURE(*status)) {
37            break;
38        }
39    }
40
41    T_FileStream_close(f);
42}
43
44
45/*
46 * Extract the setting after the '=' and store it in flag excluding the newline character.
47 */
48static void extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, UErrorCode *status) {
49    int32_t i;
50    char *pBuffer;
51    int32_t offset;
52    UBool bufferWritten = FALSE;
53
54    if (buffer[0] != 0) {
55        /* Get the offset (i.e. position after the '=') */
56        offset = getFlagOffset(buffer, bufferSize);
57        pBuffer = buffer+offset;
58        for(i = 0;;i++) {
59            if (i >= flagSize) {
60                *status = U_BUFFER_OVERFLOW_ERROR;
61                return;
62            }
63            if (pBuffer[i+1] == 0) {
64                /* Indicates a new line character. End here. */
65                flag[i] = 0;
66                break;
67            }
68
69            flag[i] = pBuffer[i];
70            if (i == 0) {
71                bufferWritten = TRUE;
72            }
73        }
74    }
75
76    if (!bufferWritten) {
77        flag[0] = 0;
78    }
79}
80
81/*
82 * Get the position after the '=' character.
83 */
84static int32_t getFlagOffset(const char *buffer, int32_t bufferSize) {
85    int32_t offset = 0;
86
87    for (offset = 0; offset < bufferSize;offset++) {
88        if (buffer[offset] == '=') {
89            offset++;
90            break;
91        }
92    }
93
94    if (offset == bufferSize || (offset - 1) == bufferSize) {
95        offset = 0;
96    }
97
98    return offset;
99}
100