DCL 4.0
Loading...
Searching...
No Matches
BufferedInputStream.cpp
Go to the documentation of this file.
1#include <stdlib.h> // malloc, realloc, free
2#include <string.h> // memset, memcpy
3
5#include <dcl/size_t.h>
6
7#if __DCL_DEBUG
8#undef __THIS_FILE__
9static const char_t __THIS_FILE__[] = __T("dcl/BufferedInputStream.cpp");
10#endif
11
12__DCL_BEGIN_NAMESPACE
13
15
17{
18 StringBuilder r = className();
19 if (__input)
20 r += __T("(") + __input->toString() + __T(")");
21 else
22 r += __T(" closed");
23 return r;
24}
25
26BufferedInputStream::BufferedInputStream(InputStream& __noclose__ _input, size_t _bufSize)
27{
28 __DCL_ASSERT_PARAM(_bufSize > 0);
29
30 __input = &_input;
31 __closeDestroy = false;
32
33 __buf = NULL;
34 __bufSize = _bufSize;
35 __begin = __end = NULL;
36 __endLine = false;
37}
38
39BufferedInputStream::BufferedInputStream(InputStream* __destroy__ _pInput, size_t _bufSize)
41{
42 __DCL_ASSERT_PARAM(_pInput != NULL);
43 __DCL_ASSERT_PARAM(_bufSize > 0);
44
45 __input = _pInput;
46 __closeDestroy = true;
47
48 __buf = NULL;
49 __bufSize = _bufSize;
50 __begin = __end = NULL;
51 __endLine = false;
52}
53
54BufferedInputStream::~BufferedInputStream()
55{
56 if (__input)
57 {
58 try
59 {
60 close();
61 }
62 catch (Exception* e)
63 {
64 __DCL_TRACE1(__T("Warning! %ls\n"), e->toString().data());
65 e->destroy();
66 }
67 }
68}
69
70void BufferedInputStream::close()
72{
73 __DCL_ASSERT_HANDLE(__input != NULL);
74
75 if (__buf)
76 {
77 free(__buf);
78 __buf = NULL;
79 __begin = __end = NULL;
80 }
81 __bufSize = 0;
82
83 InputStream* reader = __input;
84 __input = NULL;
85 if (__closeDestroy)
86 {
87 Exception* e = NULL;
88 try
89 {
90 reader->close();
91 }
92 catch (Exception* cause)
93 {
94 e = cause;
95 }
96 reader->destroy();
97 if (e)
98 throw e;
99 }
100}
101
102size_t BufferedInputStream::read(void* _buf, size_t _n)
104{
105 __DCL_ASSERT_HANDLE(__input != NULL);
106 __DCL_ASSERT_PARAM(_buf != NULL);
107
108 if (__endLine)
109 {
110 __endLine = false;
111 // 이전에 CR 또는 LF 직전까지 읽었다. CRLF를 건너뛴다.
112 // 이전의 CL, LF 또는 CRLF는 이전에 읽은 것이다.
113 if (*__begin == '\r')
114 __begin++;
115 if (*__begin == '\n')
116 __begin++;
117 }
118
119 size_t n = 0;
120 if (__begin < __end)
121 {
122 __DCL_ASSERT(__buf != NULL);
123
124 size_t nCopy = __MIN(__end - __begin, _n);
125 memcpy(_buf, __begin, nCopy * sizeof(char));
126 __begin += nCopy;
127 n += nCopy;
128 _n -= nCopy;
129 }
130
131 while (_n)
132 {
133 size_t nRead = __input->read((char*)_buf + n, _n);
134 if (!nRead)
135 break; // EOF
136 n += nRead;
137 _n -= nRead;
138 }
139
140 return n;
141}
142
143bool BufferedInputStream::readLine(ByteString& _r)
145{
146 __DCL_ASSERT_HANDLE(__input != NULL);
147
148 ByteStringBuilder sb((size_t) 0);
149 bool assigned = false;
150 if (__endLine) {
151 __endLine = false;
152 // 이전에 CR 또는 LF 직전까지 읽었다. CRLF를 건너뛴다.
153 // 이전의 CL, LF 또는 CRLF는 이전에 읽은 것이다.
154 if (*__begin == '\r')
155 __begin++;
156 if (*__begin == '\n')
157 __begin++;
158 }
159
160 if (__begin < __end) {
161 for (const char* cur = __begin; cur < __end; cur++) {
162 if (*cur == '\r' || *cur == '\n') {
163 __endLine = true;
164 sb.assign(__begin, cur - __begin);
165 __begin = cur;
166
167 assigned = true;
168 goto __done;
169 }
170 }
171 sb.assign(__begin, __end - __begin);
172 __begin = __end;
173 assigned = true;
174 }
175
176 if (!__buf) {
177 __buf = (char*)malloc(__bufSize * sizeof(char));
178 if (!__buf) {
179 throw new IOException(className(), IOException::NOMEM);
180 }
181 }
182
183 size_t nRead;
184 // 버퍼만큼 읽는다. 여기서 Block 될 수 있다.
185 while ((nRead = __input->read(__buf, __bufSize)) > 0) {
186 __begin = __buf;
187 __end = __buf + nRead;
188 for (const char* cur = __begin; cur < __end; cur++) {
189 if (*cur == '\r' || *cur == '\n') {
190 __endLine = true;
191 if (assigned)
192 sb.append(__begin, cur - __begin);
193 else {
194 sb.assign(__begin, cur - __begin);
195 assigned = true;
196 }
197 __begin = cur;
198
199 assigned = true;
200 goto __done;
201 }
202 }
203 // __bufSize 개수안에 CR, LF를 찾을 수 없다.
204 if (assigned)
205 sb.append(__begin, __end - __begin);
206 else {
207 sb.assign(__begin, __end - __begin);
208 assigned = true;
209 }
210 __begin = __end;
211 }
212
213__done:
214 _r = sb.toByteString();
215 return assigned;
216}
217
218__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
#define __destroy__
Definition Config.h:363
wchar_t char_t
Definition Config.h:275
#define __noclose__
Definition Config.h:360
#define __DCL_THROWS1(e)
Definition Config.h:167
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:376
#define __DCL_ASSERT_PARAM(expr)
Definition Object.h:384
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
#define __DCL_ASSERT_HANDLE(expr)
Definition Object.h:383
ByteString r
_r
Definition SQLField.cpp:260
void CharsetConvertException *size_t n
Definition SQLField.cpp:253
virtual String toString() const
Definition Exception.cpp:40
virtual void destroy()
Definition Exception.cpp:74
virtual String toString() const
Definition Object.cpp:187
virtual void destroy()
Definition Object.cpp:192
String className() const
Definition Object.cpp:163
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27