1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 **********************************************************************
5 * Copyright (c) 2004,2011 International Business Machines
6 * Corporation and others. All Rights Reserved.
7 **********************************************************************
9 * Created: March 19 2004
11 **********************************************************************
19 // If the symbol CCP is defined, then the 'name' and 'encoding'
20 // constructor parameters are copied. Otherwise they are aliased.
23 TextFile::TextFile(const char* _name, const char* _encoding, UErrorCode& ec) :
30 if (U_FAILURE(ec) || _name == 0 || _encoding == 0) {
32 ec = U_ILLEGAL_ARGUMENT_ERROR;
38 name = uprv_malloc(uprv_strlen(_name) + 1);
39 encoding = uprv_malloc(uprv_strlen(_encoding) + 1);
40 if (name == 0 || encoding == 0) {
41 ec = U_MEMORY_ALLOCATION_ERROR;
44 uprv_strcpy(name, _name);
45 uprv_strcpy(encoding, _encoding);
48 encoding = (char*) _encoding;
51 const char* testDir = IntlTest::getSourceTestData(ec);
55 if (!ensureCapacity((int32_t)(uprv_strlen(testDir) + uprv_strlen(name) + 1))) {
56 ec = U_MEMORY_ALLOCATION_ERROR;
59 uprv_strcpy(buffer, testDir);
60 uprv_strcat(buffer, name);
62 file = T_FileStream_open(buffer, "rb");
64 ec = U_ILLEGAL_ARGUMENT_ERROR;
69 TextFile::~TextFile() {
70 if (file != 0) T_FileStream_close(file);
71 if (buffer != 0) uprv_free(buffer);
78 UBool TextFile::readLine(UnicodeString& line, UErrorCode& ec) {
79 if (T_FileStream_eof(file)) {
82 // Note: 'buffer' may change after ensureCapacity() is called,
89 int c = T_FileStream_getc(file); // sic: int, not int32_t
90 if (c < 0 || c == 0xD || c == 0xA) {
91 // consume 0xA following 0xD
93 c = T_FileStream_getc(file);
94 if (c != 0xA && c >= 0) {
95 T_FileStream_ungetc(c, file);
100 if (!setBuffer(n++, c, ec)) return FALSE;
102 if (!setBuffer(n++, 0, ec)) return FALSE;
103 UnicodeString str(buffer, encoding);
104 // Remove BOM in first line, if present
105 if (lineNo == 0 && str[0] == 0xFEFF) {
109 line = str.unescape();
113 UBool TextFile::readLineSkippingComments(UnicodeString& line, UErrorCode& ec,
116 if (!readLine(line, ec)) return FALSE;
117 // Skip over white space
119 ICU_Utility::skipWhitespace(line, pos, TRUE);
120 // Ignore blank lines and comment lines
121 if (pos == line.length() || line.charAt(pos) == 0x23/*'#'*/) {
125 if (trim) line.remove(0, pos);
131 * Set buffer[index] to c, growing buffer if necessary. Return TRUE if
134 UBool TextFile::setBuffer(int32_t index, char c, UErrorCode& ec) {
135 if (capacity <= index) {
136 if (!ensureCapacity(index+1)) {
137 ec = U_MEMORY_ALLOCATION_ERROR;
146 * Make sure that 'buffer' has at least 'mincapacity' bytes.
147 * Return TRUE upon success. Upon return, 'buffer' may change
148 * value. In any case, previous contents are preserved.
150 #define LOWEST_MIN_CAPACITY 64
151 UBool TextFile::ensureCapacity(int32_t mincapacity) {
152 if (capacity >= mincapacity) {
156 // Grow by factor of 2 to prevent frequent allocation
157 // Note: 'capacity' may be 0
158 int32_t i = (capacity < LOWEST_MIN_CAPACITY)? LOWEST_MIN_CAPACITY: capacity;
159 while (i < mincapacity) {
168 // Simple realloc() no good; contents not preserved
169 // Note: 'buffer' may be 0
170 char* newbuffer = (char*) uprv_malloc(mincapacity);
171 if (newbuffer == 0) {
175 uprv_strncpy(newbuffer, buffer, capacity);
179 capacity = mincapacity;