2 **********************************************************************
3 * Copyright (c) 2004,2011 International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
7 * Created: March 19 2004
9 **********************************************************************
17 // If the symbol CCP is defined, then the 'name' and 'encoding'
18 // constructor parameters are copied. Otherwise they are aliased.
21 TextFile::TextFile(const char* _name
, const char* _encoding
, UErrorCode
& ec
) :
28 if (U_FAILURE(ec
) || _name
== 0 || _encoding
== 0) {
30 ec
= U_ILLEGAL_ARGUMENT_ERROR
;
36 name
= uprv_malloc(uprv_strlen(_name
) + 1);
37 encoding
= uprv_malloc(uprv_strlen(_encoding
) + 1);
38 if (name
== 0 || encoding
== 0) {
39 ec
= U_MEMORY_ALLOCATION_ERROR
;
42 uprv_strcpy(name
, _name
);
43 uprv_strcpy(encoding
, _encoding
);
46 encoding
= (char*) _encoding
;
49 const char* testDir
= IntlTest::getSourceTestData(ec
);
53 if (!ensureCapacity((int32_t)(uprv_strlen(testDir
) + uprv_strlen(name
) + 1))) {
54 ec
= U_MEMORY_ALLOCATION_ERROR
;
57 uprv_strcpy(buffer
, testDir
);
58 uprv_strcat(buffer
, name
);
60 file
= T_FileStream_open(buffer
, "rb");
62 ec
= U_ILLEGAL_ARGUMENT_ERROR
;
67 TextFile::~TextFile() {
68 if (file
!= 0) T_FileStream_close(file
);
69 if (buffer
!= 0) uprv_free(buffer
);
76 UBool
TextFile::readLine(UnicodeString
& line
, UErrorCode
& ec
) {
77 if (T_FileStream_eof(file
)) {
80 // Note: 'buffer' may change after ensureCapacity() is called,
87 int c
= T_FileStream_getc(file
); // sic: int, not int32_t
88 if (c
< 0 || c
== 0xD || c
== 0xA) {
89 // consume 0xA following 0xD
91 c
= T_FileStream_getc(file
);
92 if (c
!= 0xA && c
>= 0) {
93 T_FileStream_ungetc(c
, file
);
98 if (!setBuffer(n
++, c
, ec
)) return FALSE
;
100 if (!setBuffer(n
++, 0, ec
)) return FALSE
;
101 UnicodeString
str(buffer
, encoding
);
102 // Remove BOM in first line, if present
103 if (lineNo
== 0 && str
[0] == 0xFEFF) {
107 line
= str
.unescape();
111 UBool
TextFile::readLineSkippingComments(UnicodeString
& line
, UErrorCode
& ec
,
114 if (!readLine(line
, ec
)) return FALSE
;
115 // Skip over white space
117 ICU_Utility::skipWhitespace(line
, pos
, TRUE
);
118 // Ignore blank lines and comment lines
119 if (pos
== line
.length() || line
.charAt(pos
) == 0x23/*'#'*/) {
123 if (trim
) line
.remove(0, pos
);
129 * Set buffer[index] to c, growing buffer if necessary. Return TRUE if
132 UBool
TextFile::setBuffer(int32_t index
, char c
, UErrorCode
& ec
) {
133 if (capacity
<= index
) {
134 if (!ensureCapacity(index
+1)) {
135 ec
= U_MEMORY_ALLOCATION_ERROR
;
144 * Make sure that 'buffer' has at least 'mincapacity' bytes.
145 * Return TRUE upon success. Upon return, 'buffer' may change
146 * value. In any case, previous contents are preserved.
148 #define LOWEST_MIN_CAPACITY 64
149 UBool
TextFile::ensureCapacity(int32_t mincapacity
) {
150 if (capacity
>= mincapacity
) {
154 // Grow by factor of 2 to prevent frequent allocation
155 // Note: 'capacity' may be 0
156 int32_t i
= (capacity
< LOWEST_MIN_CAPACITY
)? LOWEST_MIN_CAPACITY
: capacity
;
157 while (i
< mincapacity
) {
166 // Simple realloc() no good; contents not preserved
167 // Note: 'buffer' may be 0
168 char* newbuffer
= (char*) uprv_malloc(mincapacity
);
169 if (newbuffer
== 0) {
173 uprv_strncpy(newbuffer
, buffer
, capacity
);
177 capacity
= mincapacity
;