DCL 3.7.4
Loading...
Searching...
No Matches
InputStreamReader.cpp
Go to the documentation of this file.
1
2#include <dcl/Config.h>
3
4#ifdef __WINNT__
5#include <windows.h>
6#endif
7
8#include <string.h> // memcpy, memmove
9#include <dcl/size_t.h>
10#include <dcl/Charset.h>
12
13#if __DCL_HAVE_THIS_FILE__
14#undef __THIS_FILE__
15static const char_t __THIS_FILE__[] = __T("dcl/InputStreamReader.cpp");
16#endif
17
18__DCL_BEGIN_NAMESPACE
19
21
22String InputStreamReader::toString() const
23{
24 StringBuilder r = className();
25 if (__input) {
26 r += __T("(") + __input->toString() + __T(",");
27 if (__decoder)
28 r += __decoder->className();
29 else
30 r += __T("null");
31 r += __T(")");
32 }
33 else
34 r += __T(" closed");
35 return r;
36}
37
39{
40 __input = NULL;
42 __closeDestroy = false;
43 __extraBytes = 0;
44}
45
48 CharsetDecoder& _decoder
49)
50{
51 __input = &_input;
52 __decoder = &_decoder;
53 __closeDestroy = false;
54 __extraBytes = 0;
55}
56
58 InputStream* __destroy__ _pInput , // new InputStream
59 CharsetDecoder* __destroy__ _pDecoder // new CharsetDecoder
61{
62 __DCL_ASSERT_PARAM(_pInput != NULL);
63
64 __input = _pInput;
65 __decoder = _pDecoder;
66 __closeDestroy = true;
67 __extraBytes = 0;
68}
69
71{
72 if (__input) {
73 try {
74 close();
75 }
76 catch (Exception* e) {
77 __DCL_TRACE1(L"%ls\n", e->toString().data());
78 e->destroy();
79 }
80 }
81}
82
85{
87
88 Exception* e = NULL;
89 InputStream* input = __input;
90 CharsetDecoder* decoder = __decoder;
91 __input = NULL;
93 __extraBytes = 0;
94
95 if (__closeDestroy) {
96 if (decoder)
97 decoder->destroy();
98
99 try {
100 input->close();
101 }
102 catch (Exception* cause) {
103 e = cause;
104 }
105 input->destroy();
106 }
107
108 if (e)
109 throw e;
110}
111
112size_t InputStreamReader::read(wchar_t* _buf, size_t _n)
114{
116 __DCL_ASSERT_PARAM(_buf != NULL);
117
118 if (!_n)
119 return 0;
120
121 if (!__decoder) {
122 char bom[4];
123 if (__input->available() >= sizeof(bom)) {
124 size_t readCount = __input->read(bom, sizeof(bom));
125 if ((readCount == 4) && IS_UTF32(bom))
126 __decoder = new UTF32Decoder();
127 else if ((readCount >= 3) && IS_UTF8(bom))
128 __decoder = new UTF8Decoder();
129 else if ((readCount >= 2) && IS_UTF16(bom))
130 __decoder = new UTF16Decoder();
131
132 memcpy(__extra, bom, readCount);
133 __extraBytes = readCount;
134 }
135
136 if (!__decoder)
137 __decoder = new LocaleDecoder();
138 }
139
140 wchar_t* outCur = _buf;
141 wchar_t* outEnd = _buf + _n;
142
143#define __BUFFER_SIZE__ 1024
145 size_t extraCount = __extraBytes;
146
147 // Non-Block이 가능한 양 만큼
148 size_t availCount = __input->available();
149 memcpy(inBuf, __extra, extraCount);
150
151 size_t outCount;
152 while ((outCount = outEnd - outCur) && availCount) {
153 size_t readCount = __MIN(__MAX(outCount, __EXTRA_MAX), availCount, __BUFFER_SIZE__);
154 readCount = __input->read(inBuf + extraCount, readCount);
155 availCount -= readCount;
156
157 size_t inCount = readCount + extraCount;
158 if (!inCount)
159 break;
160
161 size_t inCountSave = inCount;
162 int r = __decoder->decode(inBuf, inCount, outCur, outCount);
163 /*__DCL_TRACE4(__T("%ls read[%d], extra[%d], out[%d]\n"),
164 __decoder->className(), readCount, extraCount, outCount);*/
165 extraCount = inCountSave - inCount;
166 switch (r) {
167 case CS_SOURCE_FEW: {
168 __DCL_ASSERT(extraCount <= __EXTRA_MAX);
169 if (inCount > 0)
170 memmove(inBuf, inBuf + inCount, extraCount);
171 break;
172 }
173 case CS_NOERROR: {
174 __DCL_ASSERT(extraCount == 0);
175 break;
176 }
177 default: {
178 throw(new IOException(toString(), new CharsetConvertException(r)));
179 }
180 }
181 outCur += outCount;
182 }
183
184 // 이곳에서 Block 될 수 있다.
185 if ((outCount = outEnd - outCur) > 0) {
186 size_t readCount = __MIN(__MAX(outCount, __EXTRA_MAX), __BUFFER_SIZE__);
187 readCount = __input->read(inBuf + extraCount, readCount);
188 size_t inCount = readCount + extraCount;
189
190 if (inCount) {
191 size_t inCountSave = inCount;
192 int r = __decoder->decode(inBuf, inCount, outCur, outCount);
193 /*__DCL_TRACE4(__T("%ls read[%d], extra[%d], out[%d]\n"),
194 __decoder->className(), readCount, extraCount, outCount);*/
195 extraCount = inCountSave - inCount;
196 switch (r) {
197 case CS_SOURCE_FEW: {
198 __DCL_ASSERT(extraCount <= __EXTRA_MAX);
199 if (inCount > 0)
200 memmove(inBuf, inBuf + inCount, extraCount);
201 break;
202 }
203 case CS_NOERROR: {
204 __DCL_ASSERT(extraCount == 0);
205 break;
206 }
207 default: {
209 }
210 }
211 outCur += outCount;
212 }
213 }
214
215 memcpy(__extra, inBuf, extraCount);
216 __extraBytes = extraCount;
217
218 return outCur - _buf;
219}
220
221__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define IS_UTF16(bom)
Definition Charset.h:41
#define IS_UTF8(bom)
Definition Charset.h:37
#define IS_UTF32(bom)
Definition Charset.h:46
@ CS_SOURCE_FEW
Definition Charset.h:70
@ CS_NOERROR
Definition Charset.h:66
#define NULL
Definition Config.h:312
#define __destroy__
Definition Config.h:334
wchar_t char_t
Definition Config.h:247
unsigned char byte_t
Definition Config.h:246
#define __noclose__
Definition Config.h:331
#define __DCL_THROWS1(e)
Definition Config.h:152
#define __BUFFER_SIZE__
#define __EXTRA_MAX
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_ASSERT_PARAM(expr)
Definition Object.h:409
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __DCL_ASSERT_HANDLE(expr)
Definition Object.h:408
virtual String toString() const
Definition Exception.cpp:40
virtual void destroy()
Definition Exception.cpp:74
virtual void close() __DCL_THROWS1(IOException *)
CharsetDecoder * __decoder
virtual String toString() const
InputStreamReader(InputStream &__noclose__ _input, CharsetDecoder &_decoder)
virtual size_t read(wchar_t *_buf, size_t _n) __DCL_THROWS1(IOException *)
InputStream * __input
virtual String toString() const
Definition Object.cpp:187
virtual void destroy()
Definition Object.cpp:192
String className() const
Definition Object.cpp:163
size_t __MAX(size_t x, size_t y)
Definition size_t.h:43
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27