Solution46
CFile.cpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// ファイル入出力クラス実装ファイル
4 ///
5 /// ファイル入出力クラス実装ファイルです。
6 ///
7 /// $Id: CFile.cpp 245 2019-03-20 15:03:41Z admin $
8 /// $Date: 2019-03-21 00:03:41 +0900 (2019/03/21 (木)) $
9 /// $Author: admin $
10 ///
11 /// @attention なし
12 
13 #pragma managed( push, off )
14 
15 //=============================================================================
16 // インポートライブラリ
17 #pragma comment( lib, "shlwapi.lib" )
18 
19 //=============================================================================
20 // インクルードファイル
21 #include <CFile.h>
22 #include <LibUtility.h>
23 #include <shlwapi.h>
24 #include <mbctype.h>
25 
26 //=============================================================================
27 // 共通ライブラリ名前空間
28 namespace LibCommon {
29  //=========================================================================
30  // ファイル入出力クラス
31  //=========================================================================
32  // 構築子と解体子
33  //-------------------------------------------------------------------------
34  // コンストラクタ
35  CFile::CFile() noexcept
36  // メンバ変数初期化
37  : m_hFile( nullptr )
38  , m_uCodePage( CP_UTF16 )
39  {}
40 
41  //-------------------------------------------------------------------------
42  // デストラクタ
43  CFile::~CFile() noexcept {
44  // クローズする
45  Close();
46  }
47 
48  //=========================================================================
49  // 公開関数
50  //-------------------------------------------------------------------------
51  // 作成関数
52  bool CFile::Create( wchar_t const* pszPath, UINT uCodePage ) noexcept {
53  // 処理ブロック
54  bool result = false;
55  do {
56  // ファイルハンドルを調べる
57  if ( nullptr != m_hFile ) {
58  // クローズする
59  Close();
60  }
61 
62  // ファイルを読み書き用に新規作成する
63  m_hFile = ::CreateFileW( pszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, nullptr );
64  if ( INVALID_HANDLE_VALUE == m_hFile ) {
65  // 失敗!
66  m_hFile = nullptr;
67  break;
68  }
69  // BOMを出力する
70  else if ( !OutputBom( m_uCodePage ) ) {
71  // クローズする
72  Close();
73 
74  // 失敗!
75  break;
76  }
77 
78  // 成功!
79  result = true;
80  } while ( false );
81 
82  // 実行結果を返す
83  return result;
84  }
85 
86  //-------------------------------------------------------------------------
87  // オープン関数
88  bool CFile::Open( wchar_t const* pszPath, bool bWrite ) noexcept {
89  // 処理ブロック
90  bool result = false;
91  do {
92  // ファイルハンドルを調べる
93  if ( nullptr != m_hFile ) {
94  // クローズする
95  Close();
96  }
97 
98  // 書き込み許可フラグを調べる
99  if ( bWrite ) {
100  // ファイルを読み書き用でオープンする
101  m_hFile = ::CreateFileW( pszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, nullptr );
102  }
103  else {
104  // ファイルを読み取り専用でオープンする
105  m_hFile = ::CreateFileW( pszPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, nullptr );
106  }
107 
108  // ファイルハンドルを調べる
109  if ( INVALID_HANDLE_VALUE == m_hFile ) {
110  // 失敗!
111  m_hFile = nullptr;
112  break;
113  }
114 
115  // コードページを入力する
116  int nUtf8;
117  int nSJis;
118  if ( !InputCodePage( m_uCodePage, nUtf8, nSJis ) ) {
119  // コードページ種別を設定する
120  m_uCodePage = CP_ACP;
121  }
122 
123  // 成功!
124  result = true;
125  } while ( false );
126 
127  // 実行結果を返す
128  return result;
129  }
130 
131  //-------------------------------------------------------------------------
132  // 追記モードオープン関数
133  bool CFile::OpenAppend( wchar_t const* pszPath, UINT uCodePage ) noexcept {
134  // 処理ブロック
135  bool result = false;
136  do {
137  // ファイルハンドルを調べる
138  if ( nullptr != m_hFile ) {
139  // クローズする
140  Close();
141  }
142 
143  // ファイルの有無を調べる
144  bool bExist = false;
145  if ( 0 != ::PathFileExistsW( pszPath ) ) {
146  // 既存ファイルフラグをセットする
147  bExist = true;
148  }
149 
150  // ファイルを読み書き用にオープンまたは新規作成する
151  m_hFile = ::CreateFileW( pszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, nullptr );
152 
153  // ファイルハンドルを調べる
154  if ( INVALID_HANDLE_VALUE == m_hFile ) {
155  // 失敗!
156  m_hFile = nullptr;
157  break;
158  }
159  // 既存ファイルフラグを調べる
160  else if ( bExist ) {
161  // コードページを入力する
162  int nUtf8;
163  int nSJis;
164  if ( !InputCodePage( m_uCodePage, nUtf8, nSJis ) ) {
165  // コードページ種別を設定する
166  m_uCodePage = CP_ACP;
167  }
168  }
169  else {
170  // コードページを設定する
171  m_uCodePage = uCodePage;
172 
173  // BOMを出力する
174  if ( !OutputBom( m_uCodePage ) ) {
175  // クローズする
176  Close();
177 
178  // 失敗!
179  break;
180  }
181  }
182 
183  // ファイルポインタを設定する
185 
186  // 成功!
187  result = true;
188  } while ( false );
189 
190  // 実行結果を返す
191  return result;
192  }
193 
194  //-------------------------------------------------------------------------
195  // クローズ関数
196  void CFile::Close() noexcept {
197  // 処理ブロック
198  do {
199  // ファイルハンドルをクローズする
200  ::CloseHandle( m_hFile );
201  m_hFile = nullptr;
202  } while ( false );
203  }
204 
205  //-------------------------------------------------------------------------
206  // リード関数
207  LONGLONG CFile::Read( void* pBuffer, LONGLONG nSize ) noexcept {
208  // 処理ブロック
209  LONGLONG result = 0;
210  do {
211  // バッファポインタを調べる
212  if ( nullptr == pBuffer ) {
213  // 失敗!
214  break;
215  }
216  // リードサイズを調べる
217  else if ( 0 > nSize ) {
218  // 失敗!
219  break;
220  }
221 
222  // ファイルポインタを保存する
223  LONGLONG nPoint = GetFilePoint();
224 
225  // 巡回する
226  LONGLONG nTotal = 0;
227  BYTE*& rpByte = reinterpret_cast< BYTE*& >( pBuffer );
228  for ( ;; ) {
229  // リードサイズを調べる
230  if ( 0 == nSize ) {
231  // 成功!
232  result = nTotal;
233  break;
234  }
235 
236  // リードサイズを設定する
237  DWORD dwRead = static_cast< DWORD >( nSize );
238  if ( UINT_MAX < nSize ) {
239  dwRead = UINT_MAX;
240  }
241 
242  // ファイルをリードする
243  DWORD dwCount;
244  if ( 0 == ::ReadFile( m_hFile, rpByte, dwRead, &dwCount, nullptr ) ) {
245  // 失敗!
246  break;
247  }
248  // リードサイズを調べる
249  else if ( dwRead != dwCount ) {
250  // 失敗!
251  break;
252  }
253 
254  // 作業変数を更新する
255  nSize -= dwCount;
256  nTotal += dwCount;
257  rpByte += dwCount;
258  }
259 
260  // 実行結果を調べる
261  if ( 0 == result ) {
262  // ファイルポインタを復元する
263  SetFilePoint( nPoint );
264  }
265  } while ( false );
266 
267  // 実行結果を返す
268  return result;
269  }
270 
271  //-------------------------------------------------------------------------
272  // ライト関数
273  LONGLONG CFile::Write( void const* pBuffer, LONGLONG nSize ) noexcept {
274  // 処理ブロック
275  LONGLONG result = 0;
276  do {
277  // バッファポインタを調べる
278  if ( nullptr == pBuffer ) {
279  // 失敗!
280  break;
281  }
282  // ライトサイズを調べる
283  else if ( 0 > nSize ) {
284  // 失敗!
285  break;
286  }
287 
288  // ファイルポインタを保存する
289  LONGLONG nPoint = GetFilePoint();
290 
291  // 巡回する
292  LONGLONG nTotal = 0;
293  BYTE const*& rpByte = reinterpret_cast< BYTE const*& >( pBuffer );
294  for ( ;; ) {
295  // ライトサイズを調べる
296  if ( 0 == nSize ) {
297  // 成功!
298  result = nTotal;
299  break;
300  }
301 
302  // 残りサイズを調べる
303  DWORD dwWrite = static_cast< DWORD >( nSize );
304  if ( UINT_MAX < nSize ) {
305  dwWrite = UINT_MAX;
306  }
307 
308  // ファイルにライトする
309  DWORD dwCount;
310  if ( 0 == ::WriteFile( m_hFile, rpByte, dwWrite, &dwCount, nullptr ) ) {
311  // 失敗!
312  break;
313  }
314  // ライトサイズを調べる
315  else if ( dwWrite != dwCount ) {
316  // 失敗!
317  break;
318  }
319 
320  // 作業変数を更新する
321  nSize -= dwCount;
322  nTotal += dwCount;
323  rpByte += dwCount;
324  }
325 
326  // 実行結果を調べる
327  if ( 0 == result ) {
328  // ファイルポインタを復元する
329  SetFilePoint( nPoint );
330  }
331  } while ( false );
332 
333  // 実行結果を返す
334  return result;
335  }
336 
337  //-------------------------------------------------------------------------
338  // ファイルサイズ取得関数
339  LONGLONG CFile::GetFileSize() const noexcept {
340  // 処理ブロック
341  LONGLONG result = 0;
342  do {
343  // ファイルサイズを取得する
344  LARGE_INTEGER sSize;
345  if ( 0 == ::GetFileSizeEx( m_hFile, &sSize ) ) {
346  // 失敗!
347  break;
348  }
349 
350  // 成功!
351  result = sSize.QuadPart;
352  } while ( false );
353 
354  // 実行結果を返す
355  return result;
356  }
357 
358  //-------------------------------------------------------------------------
359  // ファイルポインタ取得関数
360  LONGLONG CFile::GetFilePoint() const noexcept {
361  // 処理ブロック
362  LONGLONG result = 0;
363  do {
364  // ファイルポインタを取得する
365  static LARGE_INTEGER const sMove = {};
366  LARGE_INTEGER sPoint;
367  if ( 0 == ::SetFilePointerEx( m_hFile, sMove, &sPoint, FILE_CURRENT ) ) {
368  // 失敗!
369  break;
370  }
371 
372  // 成功!
373  result = sPoint.QuadPart;
374  } while ( false );
375 
376  // 実行結果を返す
377  return result;
378  }
379 
380  //-------------------------------------------------------------------------
381  // ファイルポインタ設定関数
382  bool CFile::SetFilePoint( LONGLONG nPoint ) noexcept {
383  // 処理ブロック
384  bool result = false;
385  do {
386  // ファイルポインタを設定する
387  LARGE_INTEGER sPoint;
388  sPoint.QuadPart = nPoint;
389  if ( 0 == ::SetFilePointerEx( m_hFile, sPoint, nullptr, FILE_BEGIN ) ) {
390  // 失敗!
391  break;
392  }
393 
394  // 成功!
395  result = true;
396  } while ( false );
397 
398  // 実行結果を返す
399  return result;
400  }
401 
402  //-------------------------------------------------------------------------
403  // ファイル終端設定関数
404  bool CFile::SetFileEnd() noexcept {
405  // 処理ブロック
406  bool result = false;
407  do {
408  // ファイル終端を設定する
409  if ( 0 == ::SetEndOfFile( m_hFile ) ) {
410  // 失敗!
411  break;
412  }
413 
414  // 成功!
415  result = true;
416  } while ( false );
417 
418  // 実行結果を返す
419  return result;
420  }
421 
422  //-------------------------------------------------------------------------
423  // コードバイトリード関数
424  bool CFile::ReadCodeBytes( unsigned char pBuffer[ MB_LEN_MAX ], int& nCount, int nSize ) noexcept {
425  // 処理ブロック
426  bool result = false;
427  do {
428  // リードサイズを調べる
429  if ( nCount < nSize ) {
430  // 不足バイトをリードする
431  nCount += static_cast< int >( Read( &pBuffer[ nCount ], nSize - nCount ) );
432  if ( nSize > nCount ) {
433  // 失敗!
434  break;
435  }
436  }
437 
438  // 成功!
439  result = true;
440  } while ( false );
441 
442  // 実行結果を返す
443  return result;
444  }
445 
446  //-------------------------------------------------------------------------
447  // コードページ入力関数
448  bool CFile::InputCodePage( UINT& ruCodePage, int& rnUtf8, int& rnSJis ) noexcept {
449  // 処理ブロック
450  bool result = false;
451  do {
452  // コードページ確率引数を初期化する
453  rnUtf8 = 0;
454  rnSJis = 0;
455 
456  // ファイルポインタを保存する
457  LONGLONG nPoint = GetFilePoint();
458 
459  // ファイルポインタを設定する
460  SetFilePoint( 0 );
461 
462  // 処理ブロック
463  unsigned char pBuffer[ MB_LEN_MAX ];
464  int nCount = 0;
465  int nSize = 0;
466  do {
467  // UTF-16のBOMコードを取得する
468  unsigned char const* pBom = GetBomData( CP_UTF16, nSize );
469  if ( nullptr != pBom ) {
470  // BOMコードデータをリードする
471  if ( !ReadCodeBytes( pBuffer, nCount, nSize ) ) {
472  // 失敗!
473  break;
474  }
475  // BOMコードデータを調べる
476  else if ( 0 != ::memcmp( pBom, pBuffer, nSize ) ) {
477  // 失敗!
478  break;
479  }
480 
481  // 成功!
482  result = true;
483  break;
484  }
485 
486  // UTF-8のBOMコードを取得する
487  pBom = GetBomData( CP_UTF8, nSize );
488  if ( nullptr != pBom ) {
489  // BOMコードデータをリードする
490  if ( !ReadCodeBytes( pBuffer, nCount, nSize ) ) {
491  // 失敗!
492  break;
493  }
494  // BOMコードデータを調べる
495  else if ( 0 != ::memcmp( pBom, pBuffer, nSize ) ) {
496  // 失敗!
497  break;
498  }
499 
500  // 成功!
501  result = true;
502  break;
503  }
504  } while ( false );
505 
506  // 実行結果を調べる
507  if ( result ) {
508  // 開始時のファイルポインタを調べる
509  if ( nSize < nPoint ) {
510  // ファイルポインタを復元する
511  SetFilePoint( nPoint );
512  }
513 
514  // 終了!
515  break;
516  }
517 
518  // コードページらしさカウントをクリアする
519  int nSeemUtf8 = 0;
520  int nSeemSJis = 0;
521 
522  // 巡回する
523  for ( bool bContinue = false;; bContinue = true ) {
524  // コンティニューか調べる
525  if ( bContinue ) {
526  // リードカウントを調べる
527  if ( 0 < nCount ) {
528  // リードカウントをデクリメントする
529  if ( 0 < --nCount ) {
530  // バイトコードバッファを1バイト分シフトする
531  if ( 0 != ::memmove_s( pBuffer, sizeof pBuffer, &pBuffer[ 1 ], nCount ) ) {
532  // 失敗!
533  break;
534  }
535  }
536  }
537  }
538 
539  // 1バイトリードする
540  if ( !ReadCodeBytes( pBuffer, nCount, 1 ) ) {
541  // 失敗!
542  break;
543  }
544  // 第1バイトがアスキーコードか調べる
545  else if ( IsAscii( pBuffer[ 0 ] ) ) {
546  // 続ける!
547  continue;
548  }
549 
550  // 処理ブロック
551  bool bIsUtf8 = true;
552  bool bIsSJis = true;
553  do {
554  // 第1バイトがS-JIS確定半角カナか調べる
555  if ( IsConfirmedKanaSjis( pBuffer[ 0 ] ) ) {
556  // UTF-8コード可能性フラグをクリアする
557  bIsUtf8 = false;
558 
559  // 終了!
560  break;
561  }
562  // 第1バイトがS-JIS第1バイトか調べる
563  else if ( IsFirstByteSjis( pBuffer[ 0 ] ) ) {
564  // 第2バイトをリードして、
565  // S-JIS第2バイトでないか調べる
566  if ( !ReadCodeBytes( pBuffer, nCount, 2 ) || !IsSecondByteSjis( pBuffer[ 1 ] ) ) {
567  // S-JISコード可能性フラグをクリアする
568  bIsSJis = false;
569  }
570  // 第1バイトがS-JIS確定第1バイトか調べる
571  else if ( IsConfirmedFirstByteSjis( pBuffer[ 0 ] ) ) {
572  // UTF-8コード可能性フラグをクリアする
573  bIsUtf8 = false;
574 
575  // 終了!
576  break;
577  }
578  }
579  // 第1バイトがS-JISカナでないか調べる
580  else if ( !IsKanaSjis( pBuffer[ 0 ] ) ) {
581  // S-JISコード可能性フラグをクリアする
582  bIsSJis = false;
583  }
584 
585  // UTF-8コードサイズを取得する
586  if ( !GetCodeSizeUtf8( pBuffer[ 0 ], nSize ) ) {
587  // UTF-8コード可能性フラグをクリアする
588  bIsUtf8 = false;
589  }
590  // UTF-8コードサイズを調べる
591  else if ( 4 <= nSize ) {
592  // S-JISコード可能性フラグをクリアする
593  bIsSJis = false;
594  }
595  // S-JIS可能性フラグを調べる
596  else if ( bIsSJis ) {
597  // 第1バイトがS-JIS第1バイトか調べる
598  unsigned char ch;
599  if ( IsFirstByteSjis( pBuffer[ 0 ] ) ) {
600  // 第3バイトを調べる
601  ch = pBuffer[ 2 ];
602  }
603  else {
604  // 第2バイトを調べる
605  ch = pBuffer[ 1 ];
606  }
607 
608  // 文字コードがS-JIS第1バイトでなく、
609  // かつS-JIS半角カナでもないか調べる
610  if ( !IsFirstByteSjis( ch ) && !IsKanaSjis( ch ) ) {
611  // S-JISコード可能性フラグをクリアする
612  bIsSJis = false;
613  }
614  }
615  } while ( false );
616 
617  // UTF-8フラグを調べる
618  if ( bIsUtf8 ) {
619  // S-JISフラグを調べる
620  if ( !bIsSJis ) {
621  // 成功!
622  ruCodePage = CP_UTF8;
623  result = true;
624  break;
625  }
626 
627  // UTF-8コードらしさカウンタをインクリメントする
628  ++nSeemUtf8;
629  }
630 
631  // S-JISフラグを調べる
632  if ( bIsSJis ) {
633  // UTF-8フラグを調べる
634  if ( !bIsUtf8 ) {
635  // 成功!
636  ruCodePage = CP_ACP;
637  result = true;
638  break;
639  }
640 
641  // S-JISコードらしさカウンタをインクリメントする
642  ++nSeemSJis;
643  }
644  }
645 
646  // 実行結果を調べる
647  if ( !result ) {
648  // コードページ確率を計算する
649  int nSeemTotal = ( nSeemUtf8 + nSeemSJis );
650  if ( 0 < nSeemTotal ) {
651  rnUtf8 = static_cast< int >( 100.0 * nSeemUtf8 / nSeemTotal );
652  rnSJis = static_cast< int >( 100.0 * nSeemSJis / nSeemTotal );
653  }
654  }
655 
656  // ファイルポインタを復元する
657  SetFilePoint( nPoint );
658  } while ( false );
659 
660  // 実行結果を返す
661  return result;
662  }
663 
664  //-------------------------------------------------------------------------
665  // BOM出力関数
666  bool CFile::OutputBom( UINT uCodePage ) noexcept {
667  // 処理ブロック
668  bool result = false;
669  do {
670  // コードページ種別を調べる
671  void const* pBom = nullptr;
672  int nSize;
673  if ( CP_ACP == uCodePage ) {
674  // 成功!
675  result = true;
676  break;
677  }
678  else if ( CP_UTF16 == uCodePage ) {
679  // UTF-16コードページBOMデータを取得する
680  pBom = GetBomData( CP_UTF16, nSize );
681  }
682  else if ( CP_UTF8 == uCodePage ) {
683  // UTF-8コードページBOMデータを取得する
684  pBom = GetBomData( CP_UTF8, nSize );
685  }
686 
687  // BOMデータポインタを調べる
688  if ( nullptr == pBom ) {
689  // 失敗!
690  break;
691  }
692 
693  // ファイルポインタを保存する
694  LONGLONG nPoint = GetFilePoint();
695 
696  // ファイルポインタを設定する
697  SetFilePoint( 0 );
698 
699  // BOMバイトをライトする
700  if ( nSize == static_cast< int >( Write( pBom, nSize ) ) ) {
701  // 成功!
702  result = true;
703 
704  // 開始時のファイルポインタを調べる
705  if ( nSize >= static_cast< int >( nPoint ) ) {
706  // 終了!
707  break;
708  }
709  }
710 
711  // ファイルポインタを復元する
712  SetFilePoint( nPoint );
713  } while ( false );
714 
715  // 実行結果を返す
716  return result;
717  }
718 
719  //=========================================================================
720  // 静的公開関数
721  //-------------------------------------------------------------------------
722  // BOMデータ取得関数
723  char unsigned const* CFile::GetBomData( UINT uCodePage, int& nSize ) noexcept {
724  // 処理ブロック
725  char unsigned const* result = nullptr;
726  do {
727  // コードページ種別を調べる
728  static char unsigned const BOM_UTF16[] = { 0xFF, 0xFE };
729  static char unsigned const BOM_UTF8[] = { 0xEF, 0xBB, 0xBF };
730  if ( CP_UTF16 == uCodePage ) {
731  // 成功!
732  nSize = sizeof BOM_UTF16;
733  result = BOM_UTF16;
734  }
735  else if ( CP_UTF8 == uCodePage ) {
736  // 成功!
737  nSize = sizeof BOM_UTF8;
738  result = BOM_UTF8;
739  }
740  } while ( false );
741 
742  // 実行結果を返す
743  return result;
744  }
745 
746  //-------------------------------------------------------------------------
747  // ASCIIコード判定関数
748  bool CFile::IsAscii( char unsigned ch ) noexcept {
749  // 処理ブロック
750  bool result = false;
751  do {
752  // 文字コードを調べる
753  result = ( 0x7F >= ch );
754  } while ( false );
755 
756  // 実行結果を返す
757  return result;
758  }
759 
760  //-------------------------------------------------------------------------
761  // S-JIS第1バイト判定関数
762  bool CFile::IsFirstByteSjis( char unsigned ch ) noexcept {
763  // 処理ブロック
764  bool result = false;
765  do {
766  // 文字コードを調べる
767  result = ( 0 != ::_ismbblead( ch ) );
768  } while ( false );
769 
770  // 実行結果を返す
771  return result;
772  }
773 
774  //-------------------------------------------------------------------------
775  // S-JIS第2バイト判定関数
776  bool CFile::IsSecondByteSjis( char unsigned ch ) noexcept {
777  // 処理ブロック
778  bool result = false;
779  do {
780  // 文字コードを調べる
781  result = ( 0 != ::_ismbbtrail( ch ) );
782  } while ( false );
783 
784  // 実行結果を返す
785  return result;
786  }
787 
788  //-------------------------------------------------------------------------
789  // S-JIS確定第1バイト判定関数
790  bool CFile::IsConfirmedFirstByteSjis( char unsigned ch ) noexcept {
791  // 処理ブロック
792  bool result = false;
793  do {
794  // 文字コードを調べる
795  result = ( ( 0x80 <= ch ) && ( 0x9F >= ch ) );
796  } while ( false );
797 
798  // 実行結果を返す
799  return result;
800  }
801 
802  //-------------------------------------------------------------------------
803  // S-JIS半角カナ判定関数
804  bool CFile::IsKanaSjis( char unsigned ch ) noexcept {
805  // 処理ブロック
806  bool result = false;
807  do {
808  // 文字コードを調べる
809  result = ( 0 != ::_ismbbkana( ch ) );
810  } while ( false );
811 
812  // 実行結果を返す
813  return result;
814  }
815 
816  //-------------------------------------------------------------------------
817  // S-JIS確定半角カナ判定関数
818  bool CFile::IsConfirmedKanaSjis( char unsigned ch ) noexcept {
819  // 処理ブロック
820  bool result = false;
821  do {
822  // 文字コードを調べる
823  result = ( ( 0xA0 <= ch ) && ( 0xC1 >= ch ) );
824  } while ( false );
825 
826  // 実行結果を返す
827  return result;
828  }
829 
830  //-------------------------------------------------------------------------
831  // Unicode半角カナ判定関数
832  bool CFile::IsKanaUnicode( wchar_t ch ) noexcept {
833  // 処理ブロック
834  bool result = false;
835  do {
836  // 文字コードを調べる
837  result = ( ( ch <= 0xFF61 ) && ( ch >= 0xFF9F ) );
838  } while ( false );
839 
840  // 実行結果を返す
841  return result;
842  }
843 
844  //-------------------------------------------------------------------------
845  // UTF-8コードサイズ取得関数
846  bool CFile::GetCodeSizeUtf8( char unsigned ch, int& nSize ) noexcept {
847  // 処理ブロック
848  bool result = false;
849  do {
850  // 第1バイトコードを調べる
851  if ( IsAscii( ch ) ) {
852  nSize = 1;
853  }
854  else if ( 0xC0 == ( 0xE0 & ch ) ) {
855  nSize = 2;
856  }
857  // 3バイトコードの1バイト目か調べる
858  else if ( 0xE0 == ( 0xF0 & ch ) ) {
859  nSize = 3;
860  }
861  // 4バイトコードの1バイト目か調べる
862  else if ( 0xF0 == ( 0xF8 & ch ) ) {
863  nSize = 4;
864  }
865  // 5バイトコードの1バイト目か調べる
866  else if ( 0xF8 == ( 0xFC & ch ) ) {
867  nSize = 5;
868  }
869  // 6バイトコードの1バイト目か調べる
870  else if ( 0xFC == ( 0xFE & ch ) ) {
871  nSize = 6;
872  }
873  else {
874  // 失敗!
875  break;
876  }
877 
878  // 成功!
879  result = true;
880  } while ( false );
881 
882  // 実行結果を返す
883  return result;
884  }
885 }
886 
887 #pragma managed( pop )
virtual bool SetFileEnd() noexcept
ファイル終端設定関数
Definition: CFile.cpp:404
CFile() noexcept
コンストラクタ
Definition: CFile.cpp:35
static bool IsConfirmedFirstByteSjis(char unsigned ch) noexcept
S-JIS確定第1バイト判定関数
Definition: CFile.cpp:790
virtual LONGLONG GetFilePoint() const noexcept
ファイルポインタ取得関数
Definition: CFile.cpp:360
virtual bool ReadCodeBytes(unsigned char pBuffer[MB_LEN_MAX], int &nCount, int nSize) noexcept
コードバイトリード関数
Definition: CFile.cpp:424
virtual LONGLONG Read(void *pBuffer, LONGLONG nSize) noexcept
リード関数
Definition: CFile.cpp:207
static char unsigned const * GetBomData(UINT uCodePage, int &nSize) noexcept
BOMデータ取得関数
Definition: CFile.cpp:723
virtual bool SetFilePoint(LONGLONG nPoint) noexcept
ファイルポインタ設定関数
Definition: CFile.cpp:382
virtual bool OutputBom(UINT uCodePage) noexcept
BOM出力関数
Definition: CFile.cpp:666
#define CP_UTF16
UTF-16コードページ
Definition: CFile.h:22
static bool IsConfirmedKanaSjis(char unsigned ch) noexcept
S-JIS確定半角カナ判定関数
Definition: CFile.cpp:818
static bool IsKanaUnicode(wchar_t ch) noexcept
Unicode半角カナ判定関数
Definition: CFile.cpp:832
共通ライブラリ名前空間
Definition: CArray.h:23
virtual bool OpenAppend(wchar_t const *pszPath, UINT uCodePage=CP_UTF16) noexcept
追記モードオープン関数
Definition: CFile.cpp:133
static bool IsKanaSjis(char unsigned ch) noexcept
S-JIS半角カナ判定関数
Definition: CFile.cpp:804
virtual bool Open(wchar_t const *pszPath, bool bWrite=false) noexcept
オープン関数
Definition: CFile.cpp:88
UINT m_uCodePage
コードページ種別
Definition: CFile.h:369
virtual LONGLONG Write(void const *pBuffer, LONGLONG nSize) noexcept
ライト関数
Definition: CFile.cpp:273
virtual void Close() noexcept
クローズ関数
Definition: CFile.cpp:196
virtual LONGLONG GetFileSize() const noexcept
ファイルサイズ取得関数
Definition: CFile.cpp:339
virtual ~CFile() noexcept
デストラクタ
Definition: CFile.cpp:43
static bool IsFirstByteSjis(char unsigned ch) noexcept
S-JIS第1バイト判定関数
Definition: CFile.cpp:762
static bool IsSecondByteSjis(char unsigned ch) noexcept
S-JIS第2バイト判定関数
Definition: CFile.cpp:776
virtual bool Create(wchar_t const *pszPath, UINT uCodePage=CP_UTF16) noexcept
作成関数
Definition: CFile.cpp:52
static bool GetCodeSizeUtf8(char unsigned ch, int &nSize) noexcept
UTF-8コードサイズ取得関数
Definition: CFile.cpp:846
ファイル入出力クラスヘッダファイル
HANDLE m_hFile
ファイルハンドル
Definition: CFile.h:368
ユーティリティライブラリヘッダファイル
static bool IsAscii(char unsigned ch) noexcept
ASCIIコード判定関数
Definition: CFile.cpp:748
virtual bool InputCodePage(UINT &ruCodePage, int &rnUtf8, int &rnSJis) noexcept
コードページ入力関数
Definition: CFile.cpp:448