1 // © 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
;