TNB Library
TnbJisStr.h
[詳解]
1#pragma once
11#include "TnbStr.h"
12
13
14
15//T-TestCaseコードカバレッジDisable
16#pragma comment(user,"T-Coverage Disable")
17
18
19
20//TNB Library
21namespace TNB
22{
23
24
25
42class CJisStr : public IComparableT<TNB::CJisStr>
43{
44 CAscii m_vtcText;
45 enum { ESC = 0x1B };
47 static bool IsKanji(int c)
48 {
49 return ((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xFC));
50 }
52 static bool IsHankaku(int c)
53 {
54 return (c >= 0xa0 && c <= 0xdf);
55 }
56 /*
57 * [変換] 半角カナを全角カナに変換.
58 * @param[out] _zenkaku 変換後の全角を格納
59 * @param[in] P 半角カナのポインタ。次の文字も確認します。
60 * @retval 1 濁点、半濁点無し変換
61 * @retval 2 濁点、半濁点あり変換
62 */
63 static int ms_HanToZen(WORD& _zenkaku, const BYTE* P)
64 {
65 const static WORD z[64] =
66 {
67 0x2121, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, 0x2521,
68 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, 0x2543,
69 0x213c, 0x2522, 0x2524, 0x2526, 0x2528, 0x252a, 0x252b, 0x252d,
70 0x252f, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253b, 0x253d,
71 0x253f, 0x2541, 0x2544, 0x2546, 0x2548, 0x254a, 0x254b, 0x254c,
72 0x254d, 0x254e, 0x254f, 0x2552, 0x2555, 0x2558, 0x255b, 0x255e,
73 0x255f, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, 0x2569,
74 0x256a, 0x256b, 0x256c, 0x256d, 0x256f, 0x2573, 0x212b, 0x212c
75 };
77 struct TMark
78 {
79 BYTE han;
80 WCHAR zen;
81 };
83 const static TMark marks1[] =
84 {
85 {0xb3, 0x2574}, {0xb6, 0x252c}, {0xb7, 0x252e}, {0xb8, 0x2530},
86 {0xb9, 0x2532}, {0xba, 0x2534}, {0xbb, 0x2536}, {0xbc, 0x2538},
87 {0xbd, 0x253a}, {0xbe, 0x253c}, {0xbf, 0x253e}, {0xc0, 0x2540},
88 {0xc1, 0x2542}, {0xc2, 0x2545}, {0xc3, 0x2547}, {0xc4, 0x2549},
89 {0xca, 0x2550}, {0xcb, 0x2553}, {0xcc, 0x2556}, {0xcd, 0x2559},
90 {0xce, 0x255c}, {0, 0}
91 };
93 const static TMark marks2[] =
94 {
95 {0xca, 0x2551}, {0xcb, 0x2554}, {0xcc, 0x2557}, {0xcd, 0x255a},
96 {0xce, 0x255d}, {0, 0}
97 };
98 if ( P[1] == 0xde/*濁音符*/ )
99 {
100 loop ( i, countof(marks1) )
101 {
102 if ( P[0] == marks1[i].han )
103 {
104 _zenkaku = marks1[i].zen;
105 return 2;
106 }
107 }
108 }
109 else if ( P[1] == 0xdf/*半濁音符*/ )
110 {
111 loop ( i, countof(marks2) )
112 {
113 if ( P[0] == marks2[i].han )
114 {
115 _zenkaku = marks2[i].zen;
116 return 2;
117 }
118 }
119 }
120 int r = P[0] - 0xa0;
121 ASSERT( r >= 0 && r < countof(z) );
122 _zenkaku = z[r];
123 return 1;
124 }
125 /*
126 * [変換] SJISの2バイトをJISに変換
127 * @param[in,out] ph 上位BYTE
128 * @param[in,out] pl 下位BYTE
129 */
130 static void ms_SjisToJis(UINT *ph, UINT *pl)
131 {
132 *ph = *ph & 0xff;
133 *pl = *pl & 0xff;
134 if ( *ph <= 0x9F )
135 {
136 if ( *pl < 0x9F )
137 {
138 *ph = (*ph << 1) - 0xE1;
139 }
140 else
141 {
142 *ph = (*ph << 1) - 0xE0;
143 }
144 }
145 else
146 {
147 if ( *pl < 0x9F )
148 {
149 *ph = (*ph << 1) - 0x161;
150 }
151 else
152 {
153 *ph = (*ph << 1) - 0x160;
154 }
155 }
156 if ( *pl < 0x7F )
157 {
158 *pl -= 0x1F;
159 }
160 else if ( *pl < 0x9F )
161 {
162 *pl -= 0x20;
163 }
164 else
165 {
166 *pl -= 0x7E;
167 }
168 }
169 /*
170 * [変換] SJIS→ISO2022JP.
171 * sjis_iso2022jp - SJISをISO-2022-JP(JIS)に変換 (RFC 1468)
172 * @param[in] pSjis 元のSJIS文字列。
173 * @param[out] pIso2022 変換したISO2022JP文字列。バッファは元の文字列の4倍必要。
174 * @return 変換後の文字数。
175 */
176 static INT_PTR ms_SjisToIso2022jp(LPCSTR pSjis, LPSTR pIso2022)
177 {
178 const BYTE* p = reinterpret_cast<const BYTE*>(pSjis);
179 BYTE* r = reinterpret_cast<BYTE*>(pIso2022);
180 bool isKanji = false;
181 UINT c = 0;
182 while ( (c = *(p++)) != '\0')
183 {
184 if ( ! isKanji )
185 {
186 if ( IsKanji(c) || IsHankaku(c) )
187 {
188 *(r++) = ESC;
189 *(r++) = '$';
190 *(r++) = 'B';
191 if ( IsKanji(c) )
192 {
193 UINT d = *(p++);
194 ms_SjisToJis(&c, &d);
195 *(r++) = static_cast<BYTE>(c);
196 *(r++) = static_cast<BYTE>(d);
197 }
198 else
199 {
200 WORD e;
201 int rc = ms_HanToZen(e, p - 1);
202 if ( rc != 1 )
203 {
204 p++;
205 }
206 *(r++) = static_cast<BYTE>((e >> 8) & 0xff);
207 *(r++) = static_cast<BYTE>(e & 0xff);
208 }
209 isKanji = true;
210 }
211 else
212 {
213 *(r++) = static_cast<BYTE>(c);
214 }
215 }
216 else
217 {
218 if ( ! IsKanji(c) && ! IsHankaku(c) )
219 {
220 *(r++) = ESC;
221 *(r++) = '(';
222 *(r++) = 'B';
223 *(r++) = static_cast<BYTE>(c);
224 isKanji = false;
225 }
226 else
227 {
228 if ( IsKanji(c) )
229 {
230 UINT d = *(p++);
231 ms_SjisToJis(&c, &d);
232 *(r++) = static_cast<BYTE>(c);
233 *(r++) = static_cast<BYTE>(d);
234 }
235 else
236 {
237 WORD e;
238 int rc = ms_HanToZen(e, p - 1);
239 if (rc != 1)
240 {
241 p++;
242 }
243 *(r++) = static_cast<BYTE>((e >> 8) & 0xff);
244 *(r++) = static_cast<BYTE>(e & 0xff);
245 }
246 }
247 }
248 }
249 if ( isKanji )
250 {
251 *(r++) = ESC;
252 *(r++) = '(';
253 *(r++) = 'B';
254 }
255 *r = '\0';
256 return r - reinterpret_cast<BYTE*>(pIso2022);
257 }
258 /*
259 * [変換] JISの2バイトをSJISに変換
260 * @param[in,out] ph 上位BYTE
261 * @param[in,out] pl 下位BYTE
262 */
263 static void ms_JisToSjis(UINT* ph, UINT* pl)
264 {
265 if ( (*ph & 1) != 0 )
266 {
267 if ( *pl < 0x60 )
268 {
269 *pl += 0x1F;
270 }
271 else
272 {
273 *pl += 0x20;
274 }
275 }
276 else
277 {
278 *pl += 0x7E;
279 }
280 if ( *ph < 0x5F )
281 {
282 *ph = (*ph + 0xE1) >> 1;
283 }
284 else
285 {
286 *ph = (*ph + 0x161) >> 1;
287 }
288 }
295 static INT_PTR ms_Iso2022jpToSjis(LPCSTR pIso2022, LPSTR pSjis)
296 {
297 LPCSTR p = pIso2022;
298 LPSTR r = pSjis;
299 int j = 0;
300 bool jiskanji = false;
301 bool hankaku = false;
302 while ( *p != '\0')
303 {
304 j++;
305 UINT c = *(p++);
306 UINT d;
307 if ( c == ESC )
308 {
309 if ( *p == '\0' )
310 {
311 break;
312 }
313 if ( (c = *(p++)) == '$' )
314 {
315 if ( (c = *(p++)) == '@' || c == 'B' )
316 {
317 jiskanji = true;
318 }
319 else
320 {
321 *(r++) = ESC;
322 *(r++) = '$';
323 if ( c != '\0' )
324 {
325 *(r++) = static_cast<BYTE>(c);
326 }
327 }
328 }
329 else if ( c == '(' )
330 {
331 if ( (c = *(p++)) == 'H' || c == 'J' || c == 'B' )
332 {
333 jiskanji = false;
334 }
335 else
336 {
337 jiskanji = false;
338 *(r++) = ESC;
339 *(r++) = '(';
340 if ( c != '\0' )
341 {
342 *(r++) = static_cast<BYTE>(c);
343 }
344 }
345 }
346 else if ( c == '*' )
347 {
348 if ( (c = *(p++)) == 'B' )
349 {
350 hankaku = false;
351 }
352 else if ( c == 'I' )
353 {
354 hankaku = false;
355 }
356 }
357 else if ( hankaku && c == 'N' )
358 {
359 c = *(p++);
360 *(r++) = static_cast<BYTE>(c + 0x80);
361 }
362 else if ( c == 'K' )
363 {
364 jiskanji = true;
365 }
366 else if ( c == 'H' )
367 {
368 jiskanji = false;
369 }
370 else
371 {
372 *(r++) = ESC;
373 if ( c != '\0' )
374 {
375 *(r++) = static_cast<BYTE>(c);
376 }
377 }
378 }
379 else if ( jiskanji && (c == '\r' || c == '\n') )
380 {
381 jiskanji = false;
382 *(r++) = static_cast<BYTE>(c);
383 }
384 else if ( jiskanji && c >= 0x21 && c <= 0x7E )
385 {
386 if ( *p == '\0' )
387 {
388 break;
389 }
390 if ( (d = *(p++)) >= 0x21 && d <= 0x7E )
391 {
392 ms_JisToSjis(&c, &d);
393 }
394 *(r++) = static_cast<BYTE>(c);
395 if ( d != '\0' )
396 {
397 *(r++) = static_cast<BYTE>(d);
398 }
399 }
400 else if ( c >= 0xA1 && c <= 0xFE )
401 {
402 if ( *p == '\0' )
403 {
404 break;
405 }
406 if ( (d = *(p++)) >= 0xA1 && d <= 0xFE )
407 {
408 d &= 0x7E;
409 c &= 0x7E;
410 ms_JisToSjis(&c, &d);
411 }
412 *(r++) = static_cast<BYTE>(c);
413 if ( d != '\0' )
414 {
415 *(r++) = static_cast<BYTE>(d);
416 }
417 }
418 else if ( c == 0x0E )
419 {
420 while ( *p != '\0' && *p != 0x0F && *p != '\r' && *p != '\n' && *p != ESC )
421 {
422 *(r++) = static_cast<BYTE>(*(p++) + 0x80);
423 }
424 if ( *p == 0x0F )
425 {
426 p++;
427 }
428 }
429 else
430 {
431 *(r++) = static_cast<BYTE>(c);
432 }
433 }
434 *r = '\0';
435 return r - pSjis;
436 }
437public:
438
441 {
442 }
443
448 CJisStr(const CJisStr& other) : m_vtcText(other.m_vtcText)
449 {
450 }
451
456 CJisStr(LPCSTR lpszJis)
457 {
458 SetOfJis(lpszJis);
459 }
460
465 CJisStr(const CAscii& ascii)
466 {
467 SetOfAscii(ascii);
468 }
469
474 CJisStr(const CUnicode& unicode)
475 {
476 SetOfUnicode(unicode);
477 }
478
484 CJisStr& operator=(const CJisStr& other)
485 {
486 m_vtcText = other.m_vtcText;
487 return *this;
488 }
489
497 virtual INT_PTR Compare(const CJisStr& t) const
498 {
500 }
501
505 void Empty(void)
506 {
507 m_vtcText.Empty();
508 }
509
515 bool IsEmpty(void) const
516 {
517 return GetLength() == 0;
518 }
519
524 void SetOfJis(LPCSTR lpszJis)
525 {
526 if ( lpszJis == NULL )
527 {
528 Empty();
529 }
530 else
531 {
532 size_t iSize = STRLIB::GetLen(lpszJis);
533 MemCopy(m_vtcText.GetBuffer(iSize + 1), lpszJis, iSize + 1);
534 m_vtcText.ReleaseBuffer();
535 }
536 }
537
542 void SetOfUnicode(LPCWSTR lpszUnicode)
543 {
544 SetOfAscii(CAscii(lpszUnicode));
545 }
546
551 void SetOfAscii(LPCSTR lpszAscii)
552 {
553 TTRACE0("SJIS 文字列を JIS 文字列に変換\n");
554 if ( lpszAscii != NULL )
555 {
556 size_t len = STRLIB::GetLen(lpszAscii);
557 if ( len > 0 )
558 {
559 INT_PTR r = ms_SjisToIso2022jp(lpszAscii, m_vtcText.GetBuffer(len * 4 + 1));
560 ASSERT( r < static_cast<INT_PTR>(len * 4 + 1));
561 m_vtcText.ReleaseBuffer();
562 return;
563 }
564 }
565 Empty();
566 }
567
575 {
576 m_vtcText += j.m_vtcText;
577 return *this;
578 }
579
586 CJisStr operator+(const CJisStr& j) const
587 {
588 CJisStr newJis = *this;
589 newJis += j;
590 return newJis;
591 }
592
597 size_t GetLength(void) const
598 {
599 return STRLIB::GetLen(ReferBuffer());
600 }
601
606 CUnicode ToUnicode(void) const { return CUnicode(ToAscii()); }
607
612 CAscii ToAscii(void) const
613 {
614 TTRACE0("Jis 文字列を S-JIS文字列に変換\n");
615 CAscii asc;
616 size_t len = m_vtcText.GetLength();
617 size_t r = ms_Iso2022jpToSjis(m_vtcText, asc.GetBuffer(len));
618 ASSERT( r < len );
619 asc.ReleaseBuffer();
620 return asc;
621 }
622
627 CStr ToStr(void) const { return CStr(ToAscii()); }
628
633 LPCSTR ReferBuffer(void) const
634 {
635 return m_vtcText;
636 }
637
642 operator LPCSTR (void) const
643 {
644 return ReferBuffer();
645 }
646
655 LPSTR GetBuffer(int iLength)
656 {
657 return m_vtcText.GetBuffer(iLength);
658 }
659
665 void ReleaseBuffer(void)
666 {
667 m_vtcText.ReleaseBuffer();
668 CJisStr s;
669 s.SetOfJis(m_vtcText);
670 m_vtcText = s.m_vtcText;
671 }
672
678 static CJisStr ToJis(LPCSTR lpszAscii)
679 {
680 CJisStr j;
681 j.SetOfAscii(lpszAscii);
682 return j;
683 }
684};
685
686
687
688}; // TNB
689
690
691
692//T-TestCaseコードカバレッジEnable
693#pragma comment(user,"T-Coverage Enable")
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
文字列管理関係のヘッダ
JIS型文字列管理
Definition: TnbJisStr.h:43
virtual INT_PTR Compare(const CJisStr &t) const
[確認] 比較
Definition: TnbJisStr.h:497
CJisStr(const CJisStr &other)
コピーコンストラクタ
Definition: TnbJisStr.h:448
void SetOfUnicode(LPCWSTR lpszUnicode)
[設定] 代入(UNICODE用)
Definition: TnbJisStr.h:542
bool IsEmpty(void) const
[確認] 空か
Definition: TnbJisStr.h:515
CJisStr(const CUnicode &unicode)
代入コンストラクタ(UNICODE用)
Definition: TnbJisStr.h:474
CJisStr(const CAscii &ascii)
代入コンストラクタ(ASCII用)
Definition: TnbJisStr.h:465
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbJisStr.h:665
CJisStr & operator+=(const CJisStr &j)
[追加] 追加オペレータ
Definition: TnbJisStr.h:574
size_t GetLength(void) const
[取得] JIS文字列長さ
Definition: TnbJisStr.h:597
CJisStr(void)
コンストラクタ
Definition: TnbJisStr.h:440
CUnicode ToUnicode(void) const
[取得] UNICODE文字列取得
Definition: TnbJisStr.h:606
CJisStr & operator=(const CJisStr &other)
[代入] コピーオペレータ
Definition: TnbJisStr.h:484
static CJisStr ToJis(LPCSTR lpszAscii)
[変換] JISに変換
Definition: TnbJisStr.h:678
void SetOfJis(LPCSTR lpszJis)
[設定] 代入(JIS用)
Definition: TnbJisStr.h:524
CStr ToStr(void) const
[取得] 文字列取得
Definition: TnbJisStr.h:627
void SetOfAscii(LPCSTR lpszAscii)
[設定] 代入(ASCII用)
Definition: TnbJisStr.h:551
void Empty(void)
[設定] 空化
Definition: TnbJisStr.h:505
CAscii ToAscii(void) const
[取得] ASCII文字列取得
Definition: TnbJisStr.h:612
CJisStr(LPCSTR lpszJis)
代入コンストラクタ(JIS用)
Definition: TnbJisStr.h:456
LPSTR GetBuffer(int iLength)
[操作] 書き込みバッファ要求
Definition: TnbJisStr.h:655
LPCSTR ReferBuffer(void) const
[取得] JIS文字列参照取得
Definition: TnbJisStr.h:633
CJisStr operator+(const CJisStr &j) const
[作成] 加算オペレータ
Definition: TnbJisStr.h:586
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbStr.h:954
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
void Empty(void)
[削除] 空化
Definition: TnbStr.h:197
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
Definition: TnbStr.h:914
int Compare(LPCSTR P1, LPCSTR P2, INT_PTR len=-1, DWORD dwCmpFlags=0)
[比較] 文字列比較(ASCII/SJIS用)
Definition: TnbStrLib.h:135
size_t GetLen(LPCSTR lpsz)
[計算] 文字列長計算(ASCII/SJIS用)
Definition: TnbStrLib.h:44
TNB::CStrT< char > CAscii
ASCII文字列クラス
Definition: TnbStr.h:1758
TNB::CStrT< WCHAR > CUnicode
UNICODE文字列クラス
Definition: TnbStr.h:1771
TNB::CStrT< TCHAR > CStr
文字列クラス
Definition: TnbStr.h:1785
TNB Library
Definition: TnbDoxyTitle.txt:2
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
Definition: TnbDef.h:376
比較機能インターフェース.
Definition: TnbComparable.h:54