[vConnect/trunk/stand2.0] modified: TextReader, TextWriter, EncodingConverter; 改行コードをCRLFに変更
@@ -1,272 +1,272 @@ | ||
1 | -/* | |
2 | - * TextReader.h | |
3 | - * Copyright © 2012 kbinani | |
4 | - * | |
5 | - * This file is part of vConnect-STAND. | |
6 | - * | |
7 | - * vConnect-STAND is free software; you can redistribute it and/or | |
8 | - * modify it under the terms of the GPL License. | |
9 | - * | |
10 | - * vConnect-STAND is distributed in the hope that it will be useful, | |
11 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
13 | - */ | |
14 | -#ifndef __TextReader_h__ | |
15 | -#define __TextReader_h__ | |
16 | - | |
17 | -#include <stdio.h> | |
18 | -#include "EncodingConverter.h" | |
19 | - | |
20 | -namespace vconnect | |
21 | -{ | |
22 | - /** | |
23 | - * テキストファイルを読み込むためのクラス | |
24 | - * @todo 1 行が BUFFER_SIZE を超えるテキストを読む場合動作がデタラメ | |
25 | - */ | |
26 | - class TextReader | |
27 | - { | |
28 | - private: | |
29 | - /** | |
30 | - * 1行の最大文字数 | |
31 | - */ | |
32 | - static const int BUFFER_SIZE = 1024; | |
33 | - | |
34 | - /** | |
35 | - * テキストエンコーディングのコンバータ | |
36 | - */ | |
37 | - EncodingConverter *converter; | |
38 | - | |
39 | - /** | |
40 | - * ファイルハンドル | |
41 | - */ | |
42 | - FILE *fileHandle; | |
43 | - | |
44 | - /** | |
45 | - * 指定されたエンコーディングの読み込み単位バイト数 | |
46 | - * たとえば UTF8 なら 1 バイト、UTF16 なら 2 バイト単位で読み込む | |
47 | - */ | |
48 | - int bytesPerWord; | |
49 | - | |
50 | - /** | |
51 | - * bytesPerWord バイト分のバッファー | |
52 | - */ | |
53 | - char *unitBuffer; | |
54 | - | |
55 | - /** | |
56 | - * ファイルからデータを読み込むときに使うバッファー | |
57 | - */ | |
58 | - char *buffer; | |
59 | - | |
60 | - public: | |
61 | - /** | |
62 | - * テキストエンコーディングを指定して、テキストファイルを開く | |
63 | - * @param path 開くファイルのパス | |
64 | - * @param encoding テキストエンコーディング | |
65 | - */ | |
66 | - TextReader( string path, string encoding ) | |
67 | - { | |
68 | - this->converter = new EncodingConverter( encoding, EncodingConverter::getInternalEncoding() ); | |
69 | - this->fileHandle = fopen( path.c_str(), "rb" ); | |
70 | - this->bytesPerWord = EncodingConverter::getBytesPerWord( encoding ); | |
71 | - this->unitBuffer = new char[this->bytesPerWord]; | |
72 | - | |
73 | - int bufferBytes = this->bytesPerWord * BUFFER_SIZE; | |
74 | - this->buffer = new char[bufferBytes]; | |
75 | - } | |
76 | - | |
77 | - /** | |
78 | - * デストラクタ | |
79 | - */ | |
80 | - ~TextReader() | |
81 | - { | |
82 | - this->close(); | |
83 | - } | |
84 | - | |
85 | - /** | |
86 | - * テキストファイルから 1 行読み込む | |
87 | - * @return 行データ | |
88 | - */ | |
89 | - string readLine() | |
90 | - { | |
91 | - FILE *fp = this->fileHandle; | |
92 | - int unit_buflen = this->bytesPerWord; | |
93 | - int unit_bufbytes = sizeof( char ) * unit_buflen; | |
94 | - int i; | |
95 | - int bufbytes = this->bytesPerWord * BUFFER_SIZE; | |
96 | - | |
97 | - string result = ""; | |
98 | - bool isEndOfLine = false; | |
99 | - while( false == isEndOfLine ){ | |
100 | - memset( this->buffer, 0, bufbytes ); | |
101 | - int offset = -unit_buflen; | |
102 | - for( i = 0; i < bufbytes - 1; i++ ){ | |
103 | - // このループ中でbuf[offset]からbuf[offset+buflen]までを埋めます | |
104 | - offset += unit_buflen; | |
105 | - int j; | |
106 | - | |
107 | - // 1文字分読み込む | |
108 | - int len = fillUnitBuffer( this->unitBuffer, unit_buflen, fp ); | |
109 | - | |
110 | - if( len != unit_buflen ){ | |
111 | - // EOFまで読んだ場合 | |
112 | - for( j = 0; j < unit_buflen; j++ ){ | |
113 | - this->buffer[j + offset] = '\0'; | |
114 | - } | |
115 | - isEndOfLine = true; | |
116 | - break; | |
117 | - }else if( isCR( this->unitBuffer, unit_buflen ) ){ | |
118 | - // 読んだのがCRだった場合 | |
119 | - // 次の文字がLFかどうかを調べる | |
120 | - len = fillUnitBuffer( this->unitBuffer, unit_buflen, fp ); | |
121 | - if( len == unit_buflen ){ | |
122 | - if( isLF( this->unitBuffer, unit_buflen ) ){ | |
123 | - // LFのようだ | |
124 | - }else{ | |
125 | - // LFでないので、ファイルポインタを戻す | |
126 | - fseek( fp, -unit_bufbytes, SEEK_CUR ); | |
127 | - } | |
128 | - } | |
129 | - isEndOfLine = true; | |
130 | - break; | |
131 | - }else if( isLF( this->unitBuffer, unit_buflen ) ){ | |
132 | - // 読んだのがLFだった場合 | |
133 | - // 次の文字がCRかどうかを調べる | |
134 | - len = fillUnitBuffer( this->unitBuffer, unit_buflen, fp ); | |
135 | - if( len == unit_buflen ){ | |
136 | - if( isCR( this->unitBuffer, unit_buflen ) ){ | |
137 | - // CRのようだ | |
138 | - // LF-CRという改行方法があるかどうかは知らないけれどサポートしとこう | |
139 | - }else{ | |
140 | - // CRでないので、ファイルポインタを戻す | |
141 | - fseek( fp, -unit_bufbytes, SEEK_CUR ); | |
142 | - } | |
143 | - } | |
144 | - isEndOfLine = true; | |
145 | - break; | |
146 | - }else{ | |
147 | - // 通常の処理 | |
148 | - for( j = 0; j < unit_buflen; j++ ){ | |
149 | - this->buffer[offset + j] = this->unitBuffer[j]; | |
150 | - } | |
151 | - } | |
152 | - } | |
153 | - | |
154 | - string source = this->buffer; | |
155 | - result += this->converter->convert( source ); | |
156 | - } | |
157 | - | |
158 | - return result; | |
159 | - } | |
160 | - | |
161 | - /** | |
162 | - * ファイル読み込みがファイル末尾に達したかどうか | |
163 | - * @return ファイル末尾に達している場合 true を、そうでなければ false を返す。 | |
164 | - */ | |
165 | - bool isEOF() | |
166 | - { | |
167 | - return feof( this->fileHandle ) ? true : false; | |
168 | - } | |
169 | - | |
170 | - /** | |
171 | - * ファイルを閉じる | |
172 | - */ | |
173 | - void close() | |
174 | - { | |
175 | - fclose( this->fileHandle ); | |
176 | - delete this->converter; | |
177 | - delete [] this->unitBuffer; | |
178 | - delete [] this->buffer; | |
179 | - } | |
180 | - | |
181 | - private: | |
182 | - TextReader() | |
183 | - { | |
184 | - } | |
185 | - | |
186 | - /** | |
187 | - * マルチバイトの一文字分のデータをファイルから読み込む | |
188 | - * @param buffer 読み込んだデータの格納先 | |
189 | - * @param length buffer のバイト数 | |
190 | - * @param fileHandle 読み込み対象のファイル | |
191 | - * @return 読み込んだデータのバイト数 | |
192 | - */ | |
193 | - static int fillUnitBuffer( char *buffer, int length, FILE *fileHandle ) | |
194 | - { | |
195 | - int ret = 0; | |
196 | - memset( buffer, 0, length * sizeof( char ) ); | |
197 | - for( int i = 0; i < length; i++ ){ | |
198 | - int c = fgetc( fileHandle ); | |
199 | - if( c == EOF ){ | |
200 | - return ret; | |
201 | - } | |
202 | - buffer[i] = (char)c; | |
203 | - ret++; | |
204 | - } | |
205 | - return ret; | |
206 | - } | |
207 | - | |
208 | - /** | |
209 | - * 指定したマルチバイトの一文字が、指定した制御文字を表すかどうかを調べる | |
210 | - * @param buffer マルチバイトの一文字 | |
211 | - * @param length buffer のバイト数 | |
212 | - * @param expected 期待値 | |
213 | - * @return 一致したら ture を、そうでなければ false を返す | |
214 | - */ | |
215 | - static bool isExpectedCode( char *buffer, int length, char expected ) | |
216 | - { | |
217 | - if( length < 1 ){ | |
218 | - return false; | |
219 | - } | |
220 | - int i; | |
221 | - | |
222 | - // LEを仮定 | |
223 | - if( buffer[0] == expected ){ | |
224 | - for( i = 1; i < length; i++ ){ | |
225 | - if( buffer[i] != 0x00 ){ | |
226 | - return false; | |
227 | - } | |
228 | - } | |
229 | - return true; | |
230 | - } | |
231 | - | |
232 | - // BEを仮定 | |
233 | - if( buffer[length - 1] == expected ){ | |
234 | - for( i = 0; i < length - 1; i++ ){ | |
235 | - if( buffer[i] != 0x00 ){ | |
236 | - return false; | |
237 | - } | |
238 | - } | |
239 | - return true; | |
240 | - } | |
241 | - | |
242 | - return false; | |
243 | - } | |
244 | - | |
245 | - /** | |
246 | - * マルチバイト文字列が、改行制御文字(キャリッジリターン, CR)を表すかどうかを調べます | |
247 | - * @param buf 調査対象のマルチバイト文字列のバッファ | |
248 | - * @param len バッファbufの長さ | |
249 | - * @param check_char チェックする制御文字コード | |
250 | - * @return バッファの文字列がLFを表すならtrue、そうでなければfalse | |
251 | - */ | |
252 | - static bool isCR( char *buffer, int length ) | |
253 | - { | |
254 | - return isExpectedCode( buffer, length, 0x0D ); | |
255 | - } | |
256 | - | |
257 | - /** | |
258 | - * マルチバイト文字列が、改行制御文字(ラインフィード, LF)を表すかどうかを調べます | |
259 | - * @param buf 調査対象のマルチバイト文字列のバッファ | |
260 | - * @param len バッファbufの長さ | |
261 | - * @param check_char チェックする制御文字コード | |
262 | - * @return バッファの文字列がLFを表すならtrue、そうでなければfalse | |
263 | - */ | |
264 | - static bool isLF( char *buffer, int length ) | |
265 | - { | |
266 | - return isExpectedCode( buffer, length, 0x0A ); | |
267 | - } | |
268 | - }; | |
269 | -} | |
270 | - | |
271 | -#endif | |
272 | - | |
1 | +/* | |
2 | + * TextReader.h | |
3 | + * Copyright © 2012 kbinani | |
4 | + * | |
5 | + * This file is part of vConnect-STAND. | |
6 | + * | |
7 | + * vConnect-STAND is free software; you can redistribute it and/or | |
8 | + * modify it under the terms of the GPL License. | |
9 | + * | |
10 | + * vConnect-STAND is distributed in the hope that it will be useful, | |
11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
13 | + */ | |
14 | +#ifndef __TextReader_h__ | |
15 | +#define __TextReader_h__ | |
16 | + | |
17 | +#include <stdio.h> | |
18 | +#include "EncodingConverter.h" | |
19 | + | |
20 | +namespace vconnect | |
21 | +{ | |
22 | + /** | |
23 | + * テキストファイルを読み込むためのクラス | |
24 | + * @todo 1 行が BUFFER_SIZE を超えるテキストを読む場合動作がデタラメ | |
25 | + */ | |
26 | + class TextReader | |
27 | + { | |
28 | + private: | |
29 | + /** | |
30 | + * 1行の最大文字数 | |
31 | + */ | |
32 | + static const int BUFFER_SIZE = 1024; | |
33 | + | |
34 | + /** | |
35 | + * テキストエンコーディングのコンバータ | |
36 | + */ | |
37 | + EncodingConverter *converter; | |
38 | + | |
39 | + /** | |
40 | + * ファイルハンドル | |
41 | + */ | |
42 | + FILE *fileHandle; | |
43 | + | |
44 | + /** | |
45 | + * 指定されたエンコーディングの読み込み単位バイト数 | |
46 | + * たとえば UTF8 なら 1 バイト、UTF16 なら 2 バイト単位で読み込む | |
47 | + */ | |
48 | + int bytesPerWord; | |
49 | + | |
50 | + /** | |
51 | + * bytesPerWord バイト分のバッファー | |
52 | + */ | |
53 | + char *unitBuffer; | |
54 | + | |
55 | + /** | |
56 | + * ファイルからデータを読み込むときに使うバッファー | |
57 | + */ | |
58 | + char *buffer; | |
59 | + | |
60 | + public: | |
61 | + /** | |
62 | + * テキストエンコーディングを指定して、テキストファイルを開く | |
63 | + * @param path 開くファイルのパス | |
64 | + * @param encoding テキストエンコーディング | |
65 | + */ | |
66 | + TextReader( string path, string encoding ) | |
67 | + { | |
68 | + this->converter = new EncodingConverter( encoding, EncodingConverter::getInternalEncoding() ); | |
69 | + this->fileHandle = fopen( path.c_str(), "rb" ); | |
70 | + this->bytesPerWord = EncodingConverter::getBytesPerWord( encoding ); | |
71 | + this->unitBuffer = new char[this->bytesPerWord]; | |
72 | + | |
73 | + int bufferBytes = this->bytesPerWord * BUFFER_SIZE; | |
74 | + this->buffer = new char[bufferBytes]; | |
75 | + } | |
76 | + | |
77 | + /** | |
78 | + * デストラクタ | |
79 | + */ | |
80 | + ~TextReader() | |
81 | + { | |
82 | + this->close(); | |
83 | + } | |
84 | + | |
85 | + /** | |
86 | + * テキストファイルから 1 行読み込む | |
87 | + * @return 行データ | |
88 | + */ | |
89 | + string readLine() | |
90 | + { | |
91 | + FILE *fp = this->fileHandle; | |
92 | + int unit_buflen = this->bytesPerWord; | |
93 | + int unit_bufbytes = sizeof( char ) * unit_buflen; | |
94 | + int i; | |
95 | + int bufbytes = this->bytesPerWord * BUFFER_SIZE; | |
96 | + | |
97 | + string result = ""; | |
98 | + bool isEndOfLine = false; | |
99 | + while( false == isEndOfLine ){ | |
100 | + memset( this->buffer, 0, bufbytes ); | |
101 | + int offset = -unit_buflen; | |
102 | + for( i = 0; i < bufbytes - 1; i++ ){ | |
103 | + // このループ中でbuf[offset]からbuf[offset+buflen]までを埋めます | |
104 | + offset += unit_buflen; | |
105 | + int j; | |
106 | + | |
107 | + // 1文字分読み込む | |
108 | + int len = fillUnitBuffer( this->unitBuffer, unit_buflen, fp ); | |
109 | + | |
110 | + if( len != unit_buflen ){ | |
111 | + // EOFまで読んだ場合 | |
112 | + for( j = 0; j < unit_buflen; j++ ){ | |
113 | + this->buffer[j + offset] = '\0'; | |
114 | + } | |
115 | + isEndOfLine = true; | |
116 | + break; | |
117 | + }else if( isCR( this->unitBuffer, unit_buflen ) ){ | |
118 | + // 読んだのがCRだった場合 | |
119 | + // 次の文字がLFかどうかを調べる | |
120 | + len = fillUnitBuffer( this->unitBuffer, unit_buflen, fp ); | |
121 | + if( len == unit_buflen ){ | |
122 | + if( isLF( this->unitBuffer, unit_buflen ) ){ | |
123 | + // LFのようだ | |
124 | + }else{ | |
125 | + // LFでないので、ファイルポインタを戻す | |
126 | + fseek( fp, -unit_bufbytes, SEEK_CUR ); | |
127 | + } | |
128 | + } | |
129 | + isEndOfLine = true; | |
130 | + break; | |
131 | + }else if( isLF( this->unitBuffer, unit_buflen ) ){ | |
132 | + // 読んだのがLFだった場合 | |
133 | + // 次の文字がCRかどうかを調べる | |
134 | + len = fillUnitBuffer( this->unitBuffer, unit_buflen, fp ); | |
135 | + if( len == unit_buflen ){ | |
136 | + if( isCR( this->unitBuffer, unit_buflen ) ){ | |
137 | + // CRのようだ | |
138 | + // LF-CRという改行方法があるかどうかは知らないけれどサポートしとこう | |
139 | + }else{ | |
140 | + // CRでないので、ファイルポインタを戻す | |
141 | + fseek( fp, -unit_bufbytes, SEEK_CUR ); | |
142 | + } | |
143 | + } | |
144 | + isEndOfLine = true; | |
145 | + break; | |
146 | + }else{ | |
147 | + // 通常の処理 | |
148 | + for( j = 0; j < unit_buflen; j++ ){ | |
149 | + this->buffer[offset + j] = this->unitBuffer[j]; | |
150 | + } | |
151 | + } | |
152 | + } | |
153 | + | |
154 | + string source = this->buffer; | |
155 | + result += this->converter->convert( source ); | |
156 | + } | |
157 | + | |
158 | + return result; | |
159 | + } | |
160 | + | |
161 | + /** | |
162 | + * ファイル読み込みがファイル末尾に達したかどうか | |
163 | + * @return ファイル末尾に達している場合 true を、そうでなければ false を返す。 | |
164 | + */ | |
165 | + bool isEOF() | |
166 | + { | |
167 | + return feof( this->fileHandle ) ? true : false; | |
168 | + } | |
169 | + | |
170 | + /** | |
171 | + * ファイルを閉じる | |
172 | + */ | |
173 | + void close() | |
174 | + { | |
175 | + fclose( this->fileHandle ); | |
176 | + delete this->converter; | |
177 | + delete [] this->unitBuffer; | |
178 | + delete [] this->buffer; | |
179 | + } | |
180 | + | |
181 | + private: | |
182 | + TextReader() | |
183 | + { | |
184 | + } | |
185 | + | |
186 | + /** | |
187 | + * マルチバイトの一文字分のデータをファイルから読み込む | |
188 | + * @param buffer 読み込んだデータの格納先 | |
189 | + * @param length buffer のバイト数 | |
190 | + * @param fileHandle 読み込み対象のファイル | |
191 | + * @return 読み込んだデータのバイト数 | |
192 | + */ | |
193 | + static int fillUnitBuffer( char *buffer, int length, FILE *fileHandle ) | |
194 | + { | |
195 | + int ret = 0; | |
196 | + memset( buffer, 0, length * sizeof( char ) ); | |
197 | + for( int i = 0; i < length; i++ ){ | |
198 | + int c = fgetc( fileHandle ); | |
199 | + if( c == EOF ){ | |
200 | + return ret; | |
201 | + } | |
202 | + buffer[i] = (char)c; | |
203 | + ret++; | |
204 | + } | |
205 | + return ret; | |
206 | + } | |
207 | + | |
208 | + /** | |
209 | + * 指定したマルチバイトの一文字が、指定した制御文字を表すかどうかを調べる | |
210 | + * @param buffer マルチバイトの一文字 | |
211 | + * @param length buffer のバイト数 | |
212 | + * @param expected 期待値 | |
213 | + * @return 一致したら ture を、そうでなければ false を返す | |
214 | + */ | |
215 | + static bool isExpectedCode( char *buffer, int length, char expected ) | |
216 | + { | |
217 | + if( length < 1 ){ | |
218 | + return false; | |
219 | + } | |
220 | + int i; | |
221 | + | |
222 | + // LEを仮定 | |
223 | + if( buffer[0] == expected ){ | |
224 | + for( i = 1; i < length; i++ ){ | |
225 | + if( buffer[i] != 0x00 ){ | |
226 | + return false; | |
227 | + } | |
228 | + } | |
229 | + return true; | |
230 | + } | |
231 | + | |
232 | + // BEを仮定 | |
233 | + if( buffer[length - 1] == expected ){ | |
234 | + for( i = 0; i < length - 1; i++ ){ | |
235 | + if( buffer[i] != 0x00 ){ | |
236 | + return false; | |
237 | + } | |
238 | + } | |
239 | + return true; | |
240 | + } | |
241 | + | |
242 | + return false; | |
243 | + } | |
244 | + | |
245 | + /** | |
246 | + * マルチバイト文字列が、改行制御文字(キャリッジリターン, CR)を表すかどうかを調べます | |
247 | + * @param buf 調査対象のマルチバイト文字列のバッファ | |
248 | + * @param len バッファbufの長さ | |
249 | + * @param check_char チェックする制御文字コード | |
250 | + * @return バッファの文字列がLFを表すならtrue、そうでなければfalse | |
251 | + */ | |
252 | + static bool isCR( char *buffer, int length ) | |
253 | + { | |
254 | + return isExpectedCode( buffer, length, 0x0D ); | |
255 | + } | |
256 | + | |
257 | + /** | |
258 | + * マルチバイト文字列が、改行制御文字(ラインフィード, LF)を表すかどうかを調べます | |
259 | + * @param buf 調査対象のマルチバイト文字列のバッファ | |
260 | + * @param len バッファbufの長さ | |
261 | + * @param check_char チェックする制御文字コード | |
262 | + * @return バッファの文字列がLFを表すならtrue、そうでなければfalse | |
263 | + */ | |
264 | + static bool isLF( char *buffer, int length ) | |
265 | + { | |
266 | + return isExpectedCode( buffer, length, 0x0A ); | |
267 | + } | |
268 | + }; | |
269 | +} | |
270 | + | |
271 | +#endif | |
272 | + |
@@ -1,323 +1,324 @@ | ||
1 | -#ifndef __EncodingConverter_h__ | |
2 | -#define __EncodingConverter_h__ | |
3 | - | |
4 | -#include <iconv.h> | |
5 | - | |
6 | -using namespace std; | |
7 | - | |
8 | -namespace vconnect | |
9 | -{ | |
10 | - /** | |
11 | - * マルチバイト文字列のテキストエンコーディングを変換するためのコンバータ | |
12 | - */ | |
13 | - class EncodingConverter | |
14 | - { | |
15 | - private: | |
16 | - /** | |
17 | - * システム内部のマルチバイト文字列が使用しているテキストエンコーディング名 | |
18 | - */ | |
19 | - string internalEncoding; | |
20 | - | |
21 | - /** | |
22 | - * libiconv のコンバータ | |
23 | - */ | |
24 | - iconv_t converter; | |
25 | - | |
26 | - public: | |
27 | - /** | |
28 | - * 変換元と変換先のエンコーディングを指定し、コンバータを初期化する | |
29 | - * @param from 変換前のエンコーディング名 | |
30 | - * @param to 変換後のエンコーディング名 | |
31 | - */ | |
32 | - EncodingConverter( string from, string to ) | |
33 | - { | |
34 | - this->converter = iconv_open( to.c_str(), from.c_str() ); | |
35 | - this->internalEncoding = getInternalEncoding(); | |
36 | - } | |
37 | - | |
38 | - ~EncodingConverter() | |
39 | - { | |
40 | - iconv_close( this->converter ); | |
41 | - } | |
42 | - | |
43 | - /** | |
44 | - * 文字列のテキストエンコーディングを変換する | |
45 | - * @param source 変換する文字列 | |
46 | - * @return エンコーディングを変換した文字列 | |
47 | - */ | |
48 | - string convert( string source ) | |
49 | - { | |
50 | - string result; | |
51 | - char *input = const_cast<char *>( source.c_str() ); | |
52 | - size_t remainingInputBytes = source.size(); | |
53 | - | |
54 | - char *buffer = new char[remainingInputBytes + 1]; | |
55 | - char *output = buffer; | |
56 | - size_t remainingOutputBytes = remainingInputBytes; | |
57 | - size_t outputBytes = remainingInputBytes; | |
58 | - | |
59 | - while( remainingInputBytes > 0 ){ | |
60 | - char *originalInput = input; | |
61 | - size_t n = iconv( this->converter, &input, &remainingInputBytes, &output, &remainingOutputBytes ); | |
62 | - if( (n != (size_t) - 1 && remainingInputBytes == 0) || (errno == EINVAL) ){ | |
63 | - remainingInputBytes = 0; | |
64 | - result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
65 | - }else{ | |
66 | - switch( errno ){ | |
67 | - case E2BIG:{ | |
68 | - result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
69 | - output = buffer; | |
70 | - remainingOutputBytes = outputBytes; | |
71 | - break; | |
72 | - } | |
73 | - case EILSEQ:{ | |
74 | - result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
75 | - result.append( input, 0, 1 ); | |
76 | - input++; | |
77 | - remainingInputBytes--; | |
78 | - output = buffer; | |
79 | - remainingOutputBytes = outputBytes; | |
80 | - break; | |
81 | - } | |
82 | - default:{ | |
83 | - result.append( originalInput ); | |
84 | - remainingInputBytes = 0; | |
85 | - break; | |
86 | - } | |
87 | - } | |
88 | - } | |
89 | - } | |
90 | - output = buffer; | |
91 | - remainingOutputBytes = outputBytes; | |
92 | - if( iconv( this->converter , NULL, NULL, &output, &remainingOutputBytes ) != (size_t) - 1 ){ | |
93 | - result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
94 | - } | |
95 | - delete [] buffer; | |
96 | - return result; | |
97 | - } | |
98 | - | |
99 | - /** | |
100 | - * char の内部のエンコーディングを調べる | |
101 | - * @return | |
102 | - */ | |
103 | - static string getInternalEncoding() | |
104 | - { | |
105 | - unsigned int result = 0; | |
106 | - char *localeNameRaw = std::setlocale( LC_CTYPE, "" ); | |
107 | -#ifdef __APPLE__ | |
108 | - // Macは決め打ち | |
109 | - result = 1208; | |
110 | -#else | |
111 | - if( NULL != localeNameRaw ){ | |
112 | - // localeName = "ja_JP.UTF-8" (openSUSE, g++) | |
113 | - // localeName = "Japanese_Japan.932" (Windows XP, g++) | |
114 | - string localeName = localeNameRaw; | |
115 | - int index = localeName.rfind( "." ); | |
116 | - if( index != string::npos ){ | |
117 | - string encodingName = localeName.substr( index + 1 ); | |
118 | - // snum部分が数値に変換できるかどうかを調べる | |
119 | - if( encodingName.size() == 0 ){ | |
120 | - result = 1208; | |
121 | - }else{ | |
122 | - bool allnum = true; | |
123 | - for( int i = 0; i < encodingName.size(); i++ ){ | |
124 | - char c = encodingName[i]; | |
125 | - if( isdigit( c ) == 0 ){ | |
126 | - allnum = false; | |
127 | - break; | |
128 | - } | |
129 | - } | |
130 | - if( allnum ){ | |
131 | - int encodingNumber = atoi( encodingName.c_str() ); | |
132 | - result = encodingNumber; | |
133 | - }else{ | |
134 | - result = 1208; | |
135 | - } | |
136 | - } | |
137 | - }else{ | |
138 | - result = 1208; | |
139 | - } | |
140 | - }else{ | |
141 | - result = 1208; | |
142 | - } | |
143 | -#endif | |
144 | - return getCharsetFromCodepage( result ); | |
145 | - } | |
146 | - | |
147 | - /** | |
148 | - * コードページの名称から、読込み時の読込単位(バイト)を調べます | |
149 | - * @return テキストファイルからの読み込み単位 | |
150 | - */ | |
151 | - static int getBytesPerWord( string encoding ){ | |
152 | - encoding = toLower( encoding ); | |
153 | - if( encoding.compare( "shift_jis" ) == 0 ){ | |
154 | - return 1; | |
155 | - }else if( encoding.compare( "euc-jp" ) == 0 ){ | |
156 | - return 1; | |
157 | - }else if( encoding.compare( "iso-2022-jp" ) == 0 ){ | |
158 | - return 1; | |
159 | - }else if( encoding.compare( "utf-8" ) == 0 ){ | |
160 | - return 1; | |
161 | - }else if( encoding.compare( "utf-16le" ) == 0 ){ | |
162 | - return 2; | |
163 | - }else if( encoding.compare( "utf-16be" ) == 0 ){ | |
164 | - return 2; | |
165 | - }else if( encoding.compare( "utf-16" ) == 0 ){ | |
166 | - return 2; | |
167 | - }else if( encoding.compare( "utf-32le" ) == 0 ){ | |
168 | - return 4; | |
169 | - }else if( encoding.compare( "utf-32be" ) == 0 ){ | |
170 | - return 4; | |
171 | - }else if( encoding.compare( "utf-32" ) == 0 ){ | |
172 | - return 4; | |
173 | - }else{ | |
174 | - return 1; | |
175 | - } | |
176 | - } | |
177 | - | |
178 | - private: | |
179 | - EncodingConverter(); | |
180 | - | |
181 | - /** | |
182 | - * 小文字に変換する | |
183 | - * @param text 変換元の文字列 | |
184 | - * @return 小文字に変換後の文字列 | |
185 | - */ | |
186 | - static string toLower( string text ) | |
187 | - { | |
188 | - int length = text.length(); | |
189 | - int i; | |
190 | - for( i = 0; i < length; i++ ){ | |
191 | - text[i] = tolower( text[i] ); | |
192 | - } | |
193 | - return text; | |
194 | - } | |
195 | - | |
196 | - /** | |
197 | - * コードページ番号から、エンコーディング名を取得する | |
198 | - * @param codepage 調べるコードページ番号 | |
199 | - * @return エンコーディング名 | |
200 | - */ | |
201 | - static string getCharsetFromCodepage( unsigned int codepage ) | |
202 | - { | |
203 | - switch( codepage ){ | |
204 | - case 932:{ | |
205 | - return "Shift_JIS"; | |
206 | - } | |
207 | - case 51932: { | |
208 | - return "euc-jp"; | |
209 | - } | |
210 | - case 50220: { | |
211 | - return "iso-2022-jp"; | |
212 | - } | |
213 | - case 1208: | |
214 | - case 1209: { | |
215 | - return "UTF-8"; | |
216 | - } | |
217 | - case 1202: | |
218 | - case 1203: { | |
219 | - return "UTF-16LE"; | |
220 | - } | |
221 | - case 1200: | |
222 | - case 1201: { | |
223 | - return "UTF-16BE"; | |
224 | - } | |
225 | - case 1204: | |
226 | - case 1205: { | |
227 | - return "UTF-16"; | |
228 | - } | |
229 | - case 1234: | |
230 | - case 1235: { | |
231 | - return "UTF-32LE"; | |
232 | - } | |
233 | - case 1232: | |
234 | - case 1233: { | |
235 | - return "UTF-32BE"; | |
236 | - } | |
237 | - case 1236: | |
238 | - case 1237: { | |
239 | - return "UTF-32"; | |
240 | - } | |
241 | - } | |
242 | - return ""; | |
243 | - } | |
244 | - | |
245 | - /** | |
246 | - * コードページの名称から、コードページ番号を取得する | |
247 | - * @param name コードページ名称 | |
248 | - * @return コードページ番号 | |
249 | - */ | |
250 | - static unsigned int getCodepageFromCharset( string sname ) | |
251 | - { | |
252 | - sname = toLower( sname ); | |
253 | - if( sname.compare( "shift_jis") == 0 ){ | |
254 | - return 932; | |
255 | - }else if( sname.compare( "euc-jp" ) == 0 ){ | |
256 | - return 51932; | |
257 | - }else if( sname.compare( "iso-2022-jp" ) == 0 ){ | |
258 | - return 50220; | |
259 | - }else if( sname.compare( "utf-8" ) == 0 || sname.compare( "utf8" ) == 0 ){ | |
260 | - return 1208; | |
261 | - }else if( sname.compare( "utf-16le" ) == 0 || sname.compare( "utf16le" ) == 0 ){ | |
262 | - return 1202; | |
263 | - }else if( sname.compare( "utf-16be" ) == 0 || sname.compare( "utf16be" ) == 0 ){ | |
264 | - return 1200; | |
265 | - }else if( sname.compare( "utf-16" ) == 0 || sname.compare( "utf16" ) == 0 ){ | |
266 | - return 1204; | |
267 | - }else if( sname.compare( "utf-32le" ) == 0 || sname.compare( "utf32le" ) == 0 ){ | |
268 | - return 1234; | |
269 | - }else if( sname.compare( "utf-32be" ) == 0 || sname.compare( "utf32be" ) == 0 ){ | |
270 | - return 1232; | |
271 | - }else if( sname.compare( "utf-32" ) == 0 || sname.compare( "utf32" ) == 0 ){ | |
272 | - return 1236; | |
273 | - }else{ | |
274 | - return 0; | |
275 | - } | |
276 | - } | |
277 | - | |
278 | - /** | |
279 | - * 有効なコンバータかどうかを調べる | |
280 | - * @param converter 調べる対象のコンバータ | |
281 | - * @return コンバータが有効であれば true を、そうでなければ false を返す | |
282 | - */ | |
283 | - static bool isValidConverter( iconv_t converter ) | |
284 | - { | |
285 | - iconv_t invalid = (iconv_t) - 1; | |
286 | - return (converter == invalid) ? false : true; | |
287 | - } | |
288 | - | |
289 | - /** | |
290 | - * 有効なエンコーディングかどうかを取得する | |
291 | - * @param codepage エンコーディング番号 | |
292 | - * @return 有効なエンコーディングであれば true を、そうでなければ false を返す | |
293 | - */ | |
294 | - static bool isValidEncoding( unsigned int codepage ) | |
295 | - { | |
296 | - // まずUTF-8が有効かどうか | |
297 | - iconv_t cnv = iconv_open( "UTF-8", "UTF-8" ); | |
298 | - if( false == isValidConverter( cnv ) ){ | |
299 | - iconv_close( cnv ); | |
300 | - return false; | |
301 | - } | |
302 | - iconv_close( cnv ); | |
303 | - | |
304 | - string charset_name = getCharsetFromCodepage( codepage ); | |
305 | - iconv_t cnv2 = iconv_open( "UTF-8", charset_name.c_str() ); | |
306 | - if( false == isValidConverter( cnv2 ) ){ | |
307 | - iconv_close( cnv2 ); | |
308 | - return false; | |
309 | - } | |
310 | - iconv_close( cnv2 ); | |
311 | - | |
312 | - iconv_t cnv3 = iconv_open( charset_name.c_str(), "UTF-8" ); | |
313 | - if( false == isValidConverter( cnv3 ) ){ | |
314 | - iconv_close( cnv3 ); | |
315 | - return false; | |
316 | - } | |
317 | - iconv_close( cnv3 ); | |
318 | - return true; | |
319 | - } | |
320 | - }; | |
321 | -} | |
322 | - | |
323 | -#endif | |
1 | +#ifndef __EncodingConverter_h__ | |
2 | +#define __EncodingConverter_h__ | |
3 | + | |
4 | +#include <iconv.h> | |
5 | + | |
6 | +using namespace std; | |
7 | + | |
8 | +namespace vconnect | |
9 | +{ | |
10 | + /** | |
11 | + * マルチバイト文字列のテキストエンコーディングを変換するためのコンバータ | |
12 | + */ | |
13 | + class EncodingConverter | |
14 | + { | |
15 | + private: | |
16 | + /** | |
17 | + * システム内部のマルチバイト文字列が使用しているテキストエンコーディング名 | |
18 | + */ | |
19 | + string internalEncoding; | |
20 | + | |
21 | + /** | |
22 | + * libiconv のコンバータ | |
23 | + */ | |
24 | + iconv_t converter; | |
25 | + | |
26 | + public: | |
27 | + /** | |
28 | + * 変換元と変換先のエンコーディングを指定し、コンバータを初期化する | |
29 | + * @param from 変換前のエンコーディング名 | |
30 | + * @param to 変換後のエンコーディング名 | |
31 | + */ | |
32 | + EncodingConverter( string from, string to ) | |
33 | + { | |
34 | + this->converter = iconv_open( to.c_str(), from.c_str() ); | |
35 | + this->internalEncoding = getInternalEncoding(); | |
36 | + } | |
37 | + | |
38 | + ~EncodingConverter() | |
39 | + { | |
40 | + iconv_close( this->converter ); | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * 文字列のテキストエンコーディングを変換する | |
45 | + * @param source 変換する文字列 | |
46 | + * @return エンコーディングを変換した文字列 | |
47 | + */ | |
48 | + string convert( string source ) | |
49 | + { | |
50 | + string result; | |
51 | + char *input = const_cast<char *>( source.c_str() ); | |
52 | + size_t remainingInputBytes = source.size(); | |
53 | + | |
54 | + char *buffer = new char[remainingInputBytes + 1]; | |
55 | + char *output = buffer; | |
56 | + size_t remainingOutputBytes = remainingInputBytes; | |
57 | + size_t outputBytes = remainingInputBytes; | |
58 | + | |
59 | + while( remainingInputBytes > 0 ){ | |
60 | + char *originalInput = input; | |
61 | + size_t n = iconv( this->converter, &input, &remainingInputBytes, &output, &remainingOutputBytes ); | |
62 | + if( (n != (size_t) - 1 && remainingInputBytes == 0) || (errno == EINVAL) ){ | |
63 | + remainingInputBytes = 0; | |
64 | + result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
65 | + }else{ | |
66 | + switch( errno ){ | |
67 | + case E2BIG:{ | |
68 | + result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
69 | + output = buffer; | |
70 | + remainingOutputBytes = outputBytes; | |
71 | + break; | |
72 | + } | |
73 | + case EILSEQ:{ | |
74 | + result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
75 | + result.append( input, 0, 1 ); | |
76 | + input++; | |
77 | + remainingInputBytes--; | |
78 | + output = buffer; | |
79 | + remainingOutputBytes = outputBytes; | |
80 | + break; | |
81 | + } | |
82 | + default:{ | |
83 | + result.append( originalInput ); | |
84 | + remainingInputBytes = 0; | |
85 | + break; | |
86 | + } | |
87 | + } | |
88 | + } | |
89 | + } | |
90 | + output = buffer; | |
91 | + remainingOutputBytes = outputBytes; | |
92 | + if( iconv( this->converter , NULL, NULL, &output, &remainingOutputBytes ) != (size_t) - 1 ){ | |
93 | + result.append( buffer, 0, outputBytes - remainingOutputBytes ); | |
94 | + } | |
95 | + delete [] buffer; | |
96 | + return result; | |
97 | + } | |
98 | + | |
99 | + /** | |
100 | + * char の内部のエンコーディングを調べる | |
101 | + * @return | |
102 | + */ | |
103 | + static string getInternalEncoding() | |
104 | + { | |
105 | + unsigned int result = 0; | |
106 | + char *localeNameRaw = std::setlocale( LC_CTYPE, "" ); | |
107 | +#ifdef __APPLE__ | |
108 | + // Macは決め打ち | |
109 | + result = 1208; | |
110 | +#else | |
111 | + if( NULL != localeNameRaw ){ | |
112 | + // localeName = "ja_JP.UTF-8" (openSUSE, g++) | |
113 | + // localeName = "Japanese_Japan.932" (Windows XP, g++) | |
114 | + string localeName = localeNameRaw; | |
115 | + int index = localeName.rfind( "." ); | |
116 | + if( index != string::npos ){ | |
117 | + string encodingName = localeName.substr( index + 1 ); | |
118 | + // snum部分が数値に変換できるかどうかを調べる | |
119 | + if( encodingName.size() == 0 ){ | |
120 | + result = 1208; | |
121 | + }else{ | |
122 | + bool allnum = true; | |
123 | + for( int i = 0; i < encodingName.size(); i++ ){ | |
124 | + char c = encodingName[i]; | |
125 | + if( isdigit( c ) == 0 ){ | |
126 | + allnum = false; | |
127 | + break; | |
128 | + } | |
129 | + } | |
130 | + if( allnum ){ | |
131 | + int encodingNumber = atoi( encodingName.c_str() ); | |
132 | + result = encodingNumber; | |
133 | + }else{ | |
134 | + result = 1208; | |
135 | + } | |
136 | + } | |
137 | + }else{ | |
138 | + result = 1208; | |
139 | + } | |
140 | + }else{ | |
141 | + result = 1208; | |
142 | + } | |
143 | +#endif | |
144 | + return getCharsetFromCodepage( result ); | |
145 | + } | |
146 | + | |
147 | + /** | |
148 | + * コードページの名称から、読込み時の読込単位(バイト)を調べます | |
149 | + * @return テキストファイルからの読み込み単位 | |
150 | + */ | |
151 | + static int getBytesPerWord( string encoding ) | |
152 | + { | |
153 | + encoding = toLower( encoding ); | |
154 | + if( encoding.compare( "shift_jis" ) == 0 ){ | |
155 | + return 1; | |
156 | + }else if( encoding.compare( "euc-jp" ) == 0 ){ | |
157 | + return 1; | |
158 | + }else if( encoding.compare( "iso-2022-jp" ) == 0 ){ | |
159 | + return 1; | |
160 | + }else if( encoding.compare( "utf-8" ) == 0 ){ | |
161 | + return 1; | |
162 | + }else if( encoding.compare( "utf-16le" ) == 0 ){ | |
163 | + return 2; | |
164 | + }else if( encoding.compare( "utf-16be" ) == 0 ){ | |
165 | + return 2; | |
166 | + }else if( encoding.compare( "utf-16" ) == 0 ){ | |
167 | + return 2; | |
168 | + }else if( encoding.compare( "utf-32le" ) == 0 ){ | |
169 | + return 4; | |
170 | + }else if( encoding.compare( "utf-32be" ) == 0 ){ | |
171 | + return 4; | |
172 | + }else if( encoding.compare( "utf-32" ) == 0 ){ | |
173 | + return 4; | |
174 | + }else{ | |
175 | + return 1; | |
176 | + } | |
177 | + } | |
178 | + | |
179 | + private: | |
180 | + EncodingConverter(); | |
181 | + | |
182 | + /** | |
183 | + * 小文字に変換する | |
184 | + * @param text 変換元の文字列 | |
185 | + * @return 小文字に変換後の文字列 | |
186 | + */ | |
187 | + static string toLower( string text ) | |
188 | + { | |
189 | + int length = text.length(); | |
190 | + int i; | |
191 | + for( i = 0; i < length; i++ ){ | |
192 | + text[i] = tolower( text[i] ); | |
193 | + } | |
194 | + return text; | |
195 | + } | |
196 | + | |
197 | + /** | |
198 | + * コードページ番号から、エンコーディング名を取得する | |
199 | + * @param codepage 調べるコードページ番号 | |
200 | + * @return エンコーディング名 | |
201 | + */ | |
202 | + static string getCharsetFromCodepage( unsigned int codepage ) | |
203 | + { | |
204 | + switch( codepage ){ | |
205 | + case 932:{ | |
206 | + return "Shift_JIS"; | |
207 | + } | |
208 | + case 51932: { | |
209 | + return "euc-jp"; | |
210 | + } | |
211 | + case 50220: { | |
212 | + return "iso-2022-jp"; | |
213 | + } | |
214 | + case 1208: | |
215 | + case 1209: { | |
216 | + return "UTF-8"; | |
217 | + } | |
218 | + case 1202: | |
219 | + case 1203: { | |
220 | + return "UTF-16LE"; | |
221 | + } | |
222 | + case 1200: | |
223 | + case 1201: { | |
224 | + return "UTF-16BE"; | |
225 | + } | |
226 | + case 1204: | |
227 | + case 1205: { | |
228 | + return "UTF-16"; | |
229 | + } | |
230 | + case 1234: | |
231 | + case 1235: { | |
232 | + return "UTF-32LE"; | |
233 | + } | |
234 | + case 1232: | |
235 | + case 1233: { | |
236 | + return "UTF-32BE"; | |
237 | + } | |
238 | + case 1236: | |
239 | + case 1237: { | |
240 | + return "UTF-32"; | |
241 | + } | |
242 | + } | |
243 | + return ""; | |
244 | + } | |
245 | + | |
246 | + /** | |
247 | + * コードページの名称から、コードページ番号を取得する | |
248 | + * @param name コードページ名称 | |
249 | + * @return コードページ番号 | |
250 | + */ | |
251 | + static unsigned int getCodepageFromCharset( string sname ) | |
252 | + { | |
253 | + sname = toLower( sname ); | |
254 | + if( sname.compare( "shift_jis") == 0 ){ | |
255 | + return 932; | |
256 | + }else if( sname.compare( "euc-jp" ) == 0 ){ | |
257 | + return 51932; | |
258 | + }else if( sname.compare( "iso-2022-jp" ) == 0 ){ | |
259 | + return 50220; | |
260 | + }else if( sname.compare( "utf-8" ) == 0 || sname.compare( "utf8" ) == 0 ){ | |
261 | + return 1208; | |
262 | + }else if( sname.compare( "utf-16le" ) == 0 || sname.compare( "utf16le" ) == 0 ){ | |
263 | + return 1202; | |
264 | + }else if( sname.compare( "utf-16be" ) == 0 || sname.compare( "utf16be" ) == 0 ){ | |
265 | + return 1200; | |
266 | + }else if( sname.compare( "utf-16" ) == 0 || sname.compare( "utf16" ) == 0 ){ | |
267 | + return 1204; | |
268 | + }else if( sname.compare( "utf-32le" ) == 0 || sname.compare( "utf32le" ) == 0 ){ | |
269 | + return 1234; | |
270 | + }else if( sname.compare( "utf-32be" ) == 0 || sname.compare( "utf32be" ) == 0 ){ | |
271 | + return 1232; | |
272 | + }else if( sname.compare( "utf-32" ) == 0 || sname.compare( "utf32" ) == 0 ){ | |
273 | + return 1236; | |
274 | + }else{ | |
275 | + return 0; | |
276 | + } | |
277 | + } | |
278 | + | |
279 | + /** | |
280 | + * 有効なコンバータかどうかを調べる | |
281 | + * @param converter 調べる対象のコンバータ | |
282 | + * @return コンバータが有効であれば true を、そうでなければ false を返す | |
283 | + */ | |
284 | + static bool isValidConverter( iconv_t converter ) | |
285 | + { | |
286 | + iconv_t invalid = (iconv_t) - 1; | |
287 | + return (converter == invalid) ? false : true; | |
288 | + } | |
289 | + | |
290 | + /** | |
291 | + * 有効なエンコーディングかどうかを取得する | |
292 | + * @param codepage エンコーディング番号 | |
293 | + * @return 有効なエンコーディングであれば true を、そうでなければ false を返す | |
294 | + */ | |
295 | + static bool isValidEncoding( unsigned int codepage ) | |
296 | + { | |
297 | + // まずUTF-8が有効かどうか | |
298 | + iconv_t cnv = iconv_open( "UTF-8", "UTF-8" ); | |
299 | + if( false == isValidConverter( cnv ) ){ | |
300 | + iconv_close( cnv ); | |
301 | + return false; | |
302 | + } | |
303 | + iconv_close( cnv ); | |
304 | + | |
305 | + string charset_name = getCharsetFromCodepage( codepage ); | |
306 | + iconv_t cnv2 = iconv_open( "UTF-8", charset_name.c_str() ); | |
307 | + if( false == isValidConverter( cnv2 ) ){ | |
308 | + iconv_close( cnv2 ); | |
309 | + return false; | |
310 | + } | |
311 | + iconv_close( cnv2 ); | |
312 | + | |
313 | + iconv_t cnv3 = iconv_open( charset_name.c_str(), "UTF-8" ); | |
314 | + if( false == isValidConverter( cnv3 ) ){ | |
315 | + iconv_close( cnv3 ); | |
316 | + return false; | |
317 | + } | |
318 | + iconv_close( cnv3 ); | |
319 | + return true; | |
320 | + } | |
321 | + }; | |
322 | +} | |
323 | + | |
324 | +#endif |
@@ -1,92 +1,92 @@ | ||
1 | -/* | |
2 | - * TextWriter.h | |
3 | - * Copyright © 2012 kbinani | |
4 | - * | |
5 | - * This file is part of vConnect-STAND. | |
6 | - * | |
7 | - * vConnect-STAND is free software; you can redistribute it and/or | |
8 | - * modify it under the terms of the GPL License. | |
9 | - * | |
10 | - * vConnect-STAND is distributed in the hope that it will be useful, | |
11 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
13 | - */ | |
14 | -#ifndef __TextWriter_h__ | |
15 | -#define __TextWriter_h__ | |
16 | - | |
17 | -#include "EncodingConverter.h" | |
18 | - | |
19 | -using namespace std; | |
20 | - | |
21 | -namespace vconnect | |
22 | -{ | |
23 | - | |
24 | - /** | |
25 | - * テキストファイルへの書き込みを行うためのクラス | |
26 | - */ | |
27 | - class TextWriter | |
28 | - { | |
29 | - private: | |
30 | - EncodingConverter *converter; | |
31 | - FILE *fileHandle; | |
32 | - string newLine; | |
33 | - | |
34 | - public: | |
35 | - /** | |
36 | - * テキストエンコーディング、ファイルパス、改行文字を指定してファイルを開く | |
37 | - * @param path ファイルパス | |
38 | - * @param encoding 書きこむテキストのエンコーディング | |
39 | - * @param newLine 改行文字列 | |
40 | - */ | |
41 | - TextWriter( string path, string encoding, string newLine ) | |
42 | - { | |
43 | - this->fileHandle = fopen( path.c_str(), "wb" ); | |
44 | - this->converter = new EncodingConverter( EncodingConverter::getInternalEncoding(), encoding ); | |
45 | - this->newLine = newLine; | |
46 | - } | |
47 | - | |
48 | - /** | |
49 | - * デストラクタ | |
50 | - */ | |
51 | - ~TextWriter() | |
52 | - { | |
53 | - this->close(); | |
54 | - } | |
55 | - | |
56 | - /** | |
57 | - * バッファをフラッシュしファイルを閉じる | |
58 | - */ | |
59 | - void close() | |
60 | - { | |
61 | - if( this->fileHandle ){ | |
62 | - fflush( this->fileHandle ); | |
63 | - fclose( this->fileHandle ); | |
64 | - } | |
65 | - if( this->converter ){ | |
66 | - delete this->converter; | |
67 | - } | |
68 | - this->fileHandle = NULL; | |
69 | - this->converter = NULL; | |
70 | - } | |
71 | - | |
72 | - /** | |
73 | - * 新しい行を書き込む | |
74 | - * @param line 書きこむ行データ | |
75 | - */ | |
76 | - void writeLine( string line ) | |
77 | - { | |
78 | - string converted; | |
79 | - converted = this->converter->convert( line ); | |
80 | - converted += this->newLine; | |
81 | - fprintf( this->fileHandle, "%s", converted.c_str() ); | |
82 | - } | |
83 | - | |
84 | - private: | |
85 | - TextWriter() | |
86 | - { | |
87 | - }; | |
88 | - }; | |
89 | - | |
90 | -} | |
91 | - | |
92 | -#endif | |
1 | +/* | |
2 | + * TextWriter.h | |
3 | + * Copyright © 2012 kbinani | |
4 | + * | |
5 | + * This file is part of vConnect-STAND. | |
6 | + * | |
7 | + * vConnect-STAND is free software; you can redistribute it and/or | |
8 | + * modify it under the terms of the GPL License. | |
9 | + * | |
10 | + * vConnect-STAND is distributed in the hope that it will be useful, | |
11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
13 | + */ | |
14 | +#ifndef __TextWriter_h__ | |
15 | +#define __TextWriter_h__ | |
16 | + | |
17 | +#include "EncodingConverter.h" | |
18 | + | |
19 | +using namespace std; | |
20 | + | |
21 | +namespace vconnect | |
22 | +{ | |
23 | + | |
24 | + /** | |
25 | + * テキストファイルへの書き込みを行うためのクラス | |
26 | + */ | |
27 | + class TextWriter | |
28 | + { | |
29 | + private: | |
30 | + EncodingConverter *converter; | |
31 | + FILE *fileHandle; | |
32 | + string newLine; | |
33 | + | |
34 | + public: | |
35 | + /** | |
36 | + * テキストエンコーディング、ファイルパス、改行文字を指定してファイルを開く | |
37 | + * @param path ファイルパス | |
38 | + * @param encoding 書きこむテキストのエンコーディング | |
39 | + * @param newLine 改行文字列 | |
40 | + */ | |
41 | + TextWriter( string path, string encoding, string newLine ) | |
42 | + { | |
43 | + this->fileHandle = fopen( path.c_str(), "wb" ); | |
44 | + this->converter = new EncodingConverter( EncodingConverter::getInternalEncoding(), encoding ); | |
45 | + this->newLine = newLine; | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * デストラクタ | |
50 | + */ | |
51 | + ~TextWriter() | |
52 | + { | |
53 | + this->close(); | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * バッファをフラッシュしファイルを閉じる | |
58 | + */ | |
59 | + void close() | |
60 | + { | |
61 | + if( this->fileHandle ){ | |
62 | + fflush( this->fileHandle ); | |
63 | + fclose( this->fileHandle ); | |
64 | + } | |
65 | + if( this->converter ){ | |
66 | + delete this->converter; | |
67 | + } | |
68 | + this->fileHandle = NULL; | |
69 | + this->converter = NULL; | |
70 | + } | |
71 | + | |
72 | + /** | |
73 | + * 新しい行を書き込む | |
74 | + * @param line 書きこむ行データ | |
75 | + */ | |
76 | + void writeLine( string line ) | |
77 | + { | |
78 | + string converted; | |
79 | + converted = this->converter->convert( line ); | |
80 | + converted += this->newLine; | |
81 | + fprintf( this->fileHandle, "%s", converted.c_str() ); | |
82 | + } | |
83 | + | |
84 | + private: | |
85 | + TextWriter() | |
86 | + { | |
87 | + }; | |
88 | + }; | |
89 | + | |
90 | +} | |
91 | + | |
92 | +#endif |