Solution46
CJsonToken.cpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// JSONトークンクラス実装ファイル
4 ///
5 /// JSONトークンクラス実装ファイルです。
6 ///
7 /// $Id: CJsonToken.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 #include <CJsonToken.h>
18 #include <LibUtility.h>
19 
20 //=============================================================================
21 // JSONライブラリ名前空間
22 namespace LibJson {
23  //=========================================================================
24  // JSONトークンクラス
25  //=========================================================================
26  // 構築子と解体子
27  //-------------------------------------------------------------------------
28  // コンストラクタ
29  CJsonToken::CJsonToken( CJson* pcParent, wchar_t const* pszString ) noexcept
30  // 基底クラスコンストラクタ
31  : CJsonValue( pcParent )
32  , CStringStream( pszString )
33  // メンバ変数初期化
34  , m_pcStringPointerList( nullptr )
35  {
36  // 処理ブロック
37  do {
38  // 文字列ストリームポインタリストを作成する
39  m_pcStringPointerList = new CArray< int >;
40  if ( nullptr == m_pcStringPointerList ) {
41  // 致命的エラー!
43  break;
44  }
45  } while ( false );
46  }
47 
48  //-------------------------------------------------------------------------
49  // デストラクタ
51  // 文字列ストリームポインタリストを削除する
52  delete m_pcStringPointerList;
53  }
54 
55  //=========================================================================
56  // 公開関数
57  //-------------------------------------------------------------------------
58  // JSONクラスクリア関数
59  void CJsonToken::ClearJson() noexcept {
60  // JSONバリュー基底クラスをクリアする
62 
63  // 文字列ストリーム基底クラスをクリアする
65 
66  // 文字列ストリームポインタリストをクリアする
68  }
69 
70  //-------------------------------------------------------------------------
71  // JSONクラスコンパクト化関数
72  bool CJsonToken::CompactJson() noexcept {
73  // 処理ブロック
74  bool result = false;
75  do {
76  // JSONバリュー基底クラスをコンパクト化する
77  if ( !CJsonValue::CompactJson() ) {
78  // 失敗!
79  break;
80  }
81  // 文字列ストリーム基底クラスの文字列バッファサイズをコンパクト化する
82  else if ( !CStringStream::CompactBuffer() ) {
83  // 失敗!
84  break;
85  }
86  // 文字列ストリームポインタリストバッファサイズをコンパクト化する
87  else if ( !m_pcStringPointerList->CompactBuffer() ) {
88  // 失敗!
89  break;
90  }
91 
92  // 成功!
93  result = true;
94  } while ( false );
95 
96  // 実行結果を返す
97  return result;
98  }
99 
100  //-------------------------------------------------------------------------
101  // JSONクラス出力関数
102  bool CJsonToken::OutputJson( CStreamOut& rcStreamOut ) noexcept {
103  // 処理ブロック
104  bool result = false;
105  do {
106  // 文字列バッファポインタを調べる
107  if ( nullptr == GetBuffer() ) {
108  // 失敗!
109  break;
110  }
111  // 文字列を出力する
112  else if ( !rcStreamOut.OutputString( GetBuffer() ) ) {
113  // 失敗!
114  break;
115  }
116 
117  // 成功!
118  result = true;
119  } while ( false );
120 
121  // 実行結果を返す
122  return result;
123  }
124 
125  //-------------------------------------------------------------------------
126  // JSON文字集合入力関数
127  bool CJsonToken::InputJsonChars( CStream& rcStream, wchar_t const* pszNgChars ) noexcept {
128  // 処理ブロック
129  bool result = false;
130  do {
131  // ストリームポインタをプッシュする
132  if ( !PushStreamPoints( rcStream ) ) {
133  // 失敗!
134  break;
135  }
136  // 処理ブロック
137  else do {
138  // 巡回する
139  for ( ;; ) {
140  // JSON文字を入力する
141  if ( !InputJsonChar( rcStream, pszNgChars ) ) {
142  // 終了!
143  break;
144  }
145 
146  // 1文字でも入力すれば成功!
147  result = true;
148  }
149  } while ( false );
150 
151  // ストリームポインタをポップする
152  PopStreamPoints( rcStream, !result );
153  } while ( false );
154 
155  // 実行結果を返す
156  return result;
157  }
158 
159  //-------------------------------------------------------------------------
160  // JSON文字入力関数
161  bool CJsonToken::InputJsonChar( CStream& rcStream, wchar_t const* pszNgChars ) noexcept {
162  // 処理ブロック
163  bool result = false;
164  do {
165  // ストリームポインタをプッシュする
166  if ( !PushStreamPoints( rcStream ) ) {
167  // 失敗!
168  break;
169  }
170  // 処理ブロック
171  else do {
172  // 1文字入力する
173  wchar_t ch;
174  if ( !rcStream.InputChar( ch ) ) {
175  // 失敗!
176  break;
177  }
178  // 入力禁止文字列ポインタを調べる
179  else if ( nullptr != pszNgChars ) {
180  // 文字コードを調べる
181  if ( nullptr != ::wcschr( pszNgChars, ch ) ) {
182  // 失敗!
183  break;
184  }
185  }
186 
187  // 1文字出力する
188  if ( !OutputChar( ch ) ) {
189  // 失敗!
190  break;
191  }
192  // 文字コードを調べる
193  else if ( ( L'\"' == ch ) || ( 0 != ::iswcntrl( ch ) ) ) {
194  // 失敗!
195  break;
196  }
197  // 文字コードを調べる
198  else if ( L'\\' == ch ) {
199  // 1文字入力する
200  if ( !rcStream.InputChar( ch ) ) {
201  // 失敗!
202  break;
203  }
204  // 1文字出力する
205  else if ( !OutputChar( ch ) ) {
206  // 失敗!
207  break;
208  }
209  // 文字コードを調べる
210  else if ( L'u' == ch ) {
211  // 巡回する
212  for ( int nCount = 4; 0 < nCount; --nCount ) {
213  // 1文字入力する
214  if ( !rcStream.InputChar( ch ) ) {
215  // 失敗!
216  break;
217  }
218  // 1文字出力する
219  else if ( !OutputChar( ch ) ) {
220  // 失敗!
221  break;
222  }
223  // 文字コードを調べる
224  else if ( nullptr != ::wcschr( L"0123456789ABCDEF", ::towupper( ch ) ) ) {
225  // 失敗!
226  break;
227  }
228  }
229  }
230  // 文字コードを調べる
231  else if ( nullptr == ::wcschr( L"\"\\/bfnrt", ch ) ) {
232  // 失敗!
233  break;
234  }
235  }
236 
237  // 成功!
238  result = true;
239  } while ( false );
240 
241  // ストリームポインタをポップする
242  PopStreamPoints( rcStream, !result );
243  } while ( false );
244 
245  // 実行結果を返す
246  return result;
247  }
248 
249  //-------------------------------------------------------------------------
250  // JSON整数部入力関数
251  bool CJsonToken::InputJsonInt( CStream& rcStream ) noexcept {
252  // 処理ブロック
253  bool result = false;
254  do {
255  // ストリームポインタをプッシュする
256  if ( !PushStreamPoints( rcStream ) ) {
257  // 失敗!
258  break;
259  }
260  // 処理ブロック
261  else do {
262  // JSON固定文字を入力する
263  InputJsonFixedChar( rcStream, L'-', false );
264 
265  // JSON数字を入力する
266  if ( !InputJsonDigit( rcStream ) ) {
267  // 失敗!
268  break;
269  }
270 
271  // 1文字でも成功!
272  result = true;
273 
274  // 文字コードを調べる
275  if ( L'0' != GetLastChar() ) {
276  // JSON数字集合を入力する
277  InputJsonDigits( rcStream );
278  }
279  } while ( false );
280 
281  // ストリームポインタをポップする
282  PopStreamPoints( rcStream, !result );
283  } while ( false );
284 
285  // 実行結果を返す
286  return result;
287  }
288 
289  //-------------------------------------------------------------------------
290  // JSON小数部入力関数
291  bool CJsonToken::InputJsonFrac( CStream& rcStream ) noexcept {
292  // 処理ブロック
293  bool result = false;
294  do {
295  // ストリームポインタをプッシュする
296  if ( !PushStreamPoints( rcStream ) ) {
297  // 失敗!
298  break;
299  }
300  // 処理ブロック
301  else do {
302  // JSON固定文字を入力する
303  if ( !InputJsonFixedChar( rcStream, L'.', false ) ) {
304  // 失敗!
305  break;
306  }
307  // JSON数字集合を入力する
308  else if ( !InputJsonDigits( rcStream ) ) {
309  // 失敗!
310  break;
311  }
312 
313  // 成功!
314  result = true;
315  } while ( false );
316 
317  // ストリームポインタをポップする
318  PopStreamPoints( rcStream, !result );
319  } while ( false );
320 
321  // 実行結果を返す
322  return result;
323  }
324 
325  //-------------------------------------------------------------------------
326  // JSON指数部入力関数
327  bool CJsonToken::InputJsonExp( CStream& rcStream ) noexcept {
328  // 処理ブロック
329  bool result = false;
330  do {
331  // ストリームポインタをプッシュする
332  if ( !PushStreamPoints( rcStream ) ) {
333  // 失敗!
334  break;
335  }
336  // 処理ブロック
337  else do {
338  // JSON指数部ヘッダを入力する
339  if ( !InputJsonExpHeader( rcStream ) ) {
340  // 失敗!
341  break;
342  }
343  // JSON数字集合を入力する
344  else if ( !InputJsonDigits( rcStream ) ) {
345  // 失敗!
346  break;
347  }
348 
349  // 成功!
350  result = true;
351  } while ( false );
352 
353  // ストリームポインタをポップする
354  PopStreamPoints( rcStream, !result );
355  } while ( false );
356 
357  // 実行結果を返す
358  return result;
359  }
360 
361  //-------------------------------------------------------------------------
362  // JSON指数部ヘッダ入力関数
363  bool CJsonToken::InputJsonExpHeader( CStream& rcStream ) noexcept {
364  // 処理ブロック
365  bool result = false;
366  do {
367  // ストリームポインタをプッシュする
368  if ( !PushStreamPoints( rcStream ) ) {
369  // 失敗!
370  break;
371  }
372  // 処理ブロック
373  else do {
374  // JSON固定文字を入力する
375  if ( !InputJsonFixedChar( rcStream, L'e', true ) ) {
376  // 失敗!
377  break;
378  }
379 
380  // 1文字でも成功!
381  result = true;
382 
383  // JSON固定文字を入力する
384  if ( !InputJsonFixedChar( rcStream, L'+' ) ) {
385  // JSON固定文字を入力する
386  InputJsonFixedChar( rcStream, L'-' );
387  }
388  } while ( false );
389 
390  // ストリームポインタをポップする
391  PopStreamPoints( rcStream, !result );
392  } while ( false );
393 
394  // 実行結果を返す
395  return result;
396  }
397 
398  //-------------------------------------------------------------------------
399  // JSON数字集合入力関数
400  bool CJsonToken::InputJsonDigits( CStream& rcStream ) noexcept {
401  // 処理ブロック
402  bool result = false;
403  do {
404  // ストリームポインタをプッシュする
405  if ( !PushStreamPoints( rcStream ) ) {
406  // 失敗!
407  break;
408  }
409  // 処理ブロック
410  else do {
411  // 巡回する
412  for ( ;; ) {
413  // JSON数字を入力する
414  if ( !InputJsonDigit( rcStream ) ) {
415  // 終了!
416  break;
417  }
418 
419  // 1文字でも入力すれば成功!
420  result = true;
421  }
422  } while ( false );
423 
424  // ストリームポインタをポップする
425  PopStreamPoints( rcStream, !result );
426  } while ( false );
427 
428  // 実行結果を返す
429  return result;
430  }
431 
432  //-------------------------------------------------------------------------
433  // JSON数字入力関数
434  bool CJsonToken::InputJsonDigit( CStream& rcStream ) noexcept {
435  // 処理ブロック
436  bool result = false;
437  do {
438  // ストリームポインタをプッシュする
439  if ( !PushStreamPoints( rcStream ) ) {
440  // 失敗!
441  break;
442  }
443  // 処理ブロック
444  else do {
445  // 1文字入力する
446  wchar_t ch;
447  if ( !rcStream.InputChar( ch ) ) {
448  // 失敗!
449  break;
450  }
451  // 1文字出力する
452  else if ( !OutputChar( ch ) ) {
453  // 失敗!
454  break;
455  }
456  // 文字コードを調べる
457  else if ( nullptr == ::wcschr( L"0123456789", ch ) ) {
458  // 失敗!
459  break;
460  }
461 
462  // 成功!
463  result = true;
464  } while ( false );
465 
466  // ストリームポインタをポップする
467  PopStreamPoints( rcStream, !result );
468  } while ( false );
469 
470  // 実行結果を返す
471  return result;
472  }
473 
474  //-------------------------------------------------------------------------
475  // JSON固定文字入力関数
476  bool CJsonToken::InputJsonFixedChar( CStream& rcStream, wchar_t ch, bool bIgnore ) noexcept {
477  // 処理ブロック
478  bool result = false;
479  do {
480  // ストリームポインタをプッシュする
481  if ( !PushStreamPoints( rcStream ) ) {
482  // 失敗!
483  break;
484  }
485  // 処理ブロック
486  else do {
487  // 1文字入力する
488  wchar_t ch2;
489  if ( !rcStream.InputChar( ch2 ) ) {
490  // 失敗!
491  break;
492  }
493  // 1文字出力する
494  else if ( !OutputChar( ch2 ) ) {
495  // 失敗!
496  break;
497  }
498  // 大小文字無視フラグを調べる
499  else if ( bIgnore ) {
500  // 大文字に統一する
501  ch = ::towupper( ch );
502  ch2 = ::towupper( ch2 );
503  }
504 
505  // 文字コードを調べる
506  if ( ch != ch2 ) {
507  // 失敗!
508  break;
509  }
510 
511  // 成功!
512  result = true;
513  } while ( false );
514 
515  // ストリームポインタをポップする
516  PopStreamPoints( rcStream, !result );
517  } while ( false );
518 
519  // 実行結果を返す
520  return result;
521  }
522 
523  //-------------------------------------------------------------------------
524  // JSON固定文字列入力関数
525  bool CJsonToken::InputJsonFixedString( CStream& rcStream, wchar_t const* pszString ) noexcept {
526  // 処理ブロック
527  bool result = false;
528  do {
529  // 文字列ポインタを調べる
530  if ( nullptr == pszString ) {
531  // 失敗!
532  break;
533  }
534  // ストリームポインタをプッシュする
535  else if ( !PushStreamPoints( rcStream ) ) {
536  // 失敗!
537  break;
538  }
539  // 処理ブロック
540  else do {
541  // 巡回する
542  for ( ;; ++pszString ) {
543  // 文字コードを調べる
544  if ( L'\0' == *pszString ) {
545  // 成功!
546  result = true;
547  break;
548  }
549 
550  // 1文字入力する
551  wchar_t ch;
552  if ( !rcStream.InputChar( ch ) ) {
553  // 失敗!
554  break;
555  }
556  // 1文字出力する
557  else if ( !OutputChar( ch ) ) {
558  // 失敗!
559  break;
560  }
561  // 文字コードを調べる
562  else if ( *pszString != ch ) {
563  // 失敗!
564  break;
565  }
566  }
567  } while ( false );
568 
569  // ストリームポインタをポップする
570  PopStreamPoints( rcStream, !result );
571  } while ( false );
572 
573  // 実行結果を返す
574  return result;
575  }
576 
577  //-------------------------------------------------------------------------
578  // 最後尾文字取得関数
579  wchar_t CJsonToken::GetLastChar() noexcept {
580  // 処理ブロック
581  wchar_t result = L'\0';
582  do {
583  // 文字数を調べる
584  if ( 0 >= GetCount() ) {
585  // 失敗!
586  break;
587  }
588 
589  // 最後尾文字を取得する
590  result = ( *this )[ GetCount() - 1 ];
591  } while ( false );
592 
593  // 実行結果を返す
594  return result;
595  }
596 
597  //-------------------------------------------------------------------------
598  // ストリームポインタプッシュ関数
599  bool CJsonToken::PushStreamPoints( CStream& rcStream ) noexcept {
600  // 処理ブロック
601  bool result = false;
602  do {
603  // 入力ストリームポインタをプッシュする
604  if ( !rcStream.PushStreamPoint( m_pcInputPointerList ) ) {
605  // 失敗!
606  break;
607  }
608  // 文字列ストリームポインタをプッシュする
609  else if ( !PushStreamPoint( m_pcStringPointerList ) ) {
610  // 入力ストリームポインタをポップする
612 
613  // 失敗!
614  break;
615  }
616 
617  // 成功!
618  result = true;
619  } while ( false );
620 
621  // 実行結果を返す
622  return result;
623  }
624 
625  //-------------------------------------------------------------------------
626  // ストリームポインタポップ関数
627  bool CJsonToken::PopStreamPoints( CStream& rcStream, bool bResume ) noexcept {
628  // 処理ブロック
629  bool result = false;
630  do {
631  // 文字列ストリームポインタをポップする
632  if ( !PopStreamPoint( m_pcStringPointerList, bResume ) ) {
633  // 入力ストリームポインタをポップする
634  rcStream.PopStreamPoint( m_pcInputPointerList, bResume );
635 
636  // 失敗!
637  break;
638  }
639  // ポインタ復元フラグを調べる
640  else if ( bResume ) {
641  // 文字列ストリーム終端ポインタを設定する
642  SetStreamEnd();
643  }
644 
645  // 入力ストリームポインタをポップする
646  if ( !rcStream.PopStreamPoint( m_pcInputPointerList, bResume ) ) {
647  // 失敗!
648  break;
649  }
650 
651  // 成功!
652  result = true;
653  } while ( false );
654 
655  // 実行結果を返す
656  return result;
657  }
658 }
659 
660 #pragma managed( pop )
virtual bool InputJsonExp(CStream &rcStream) noexcept
JSON指数部入力関数
Definition: CJsonToken.cpp:327
virtual bool SetStreamEnd() noexcept override
ストリーム終端設定関数
#define NotifyFatalError()
致命的エラー発生通知マクロ
Definition: LibUtility.h:22
virtual wchar_t GetLastChar() noexcept
最後尾文字取得関数
Definition: CJsonToken.cpp:579
JSONトークンクラスヘッダファイル
virtual bool InputJsonDigit(CStream &rcStream) noexcept
JSON数字入力関数
Definition: CJsonToken.cpp:434
virtual bool PushStreamPoints(CStream &rcStream) noexcept
ストリームポインタプッシュ関数
Definition: CJsonToken.cpp:599
virtual void Clear() noexcept
クリア関数
Definition: CArray.hpp:209
JSONライブラリ名前空間
Definition: CJson.h:24
JSONバリュークラス
Definition: CJsonValue.h:30
virtual int GetCount() const noexcept
文字数取得関数
Definition: CString.h:181
CArray< int > * m_pcStringPointerList
文字列ストリームポインタリストポインタ
Definition: CJsonToken.h:312
virtual bool PopStreamPoints(CStream &rcStream, bool bResume) noexcept
ストリームポインタポップ関数
Definition: CJsonToken.cpp:627
virtual void Clear() noexcept override
クリア関数
virtual bool InputJsonFixedChar(CStream &rcStream, wchar_t ch, bool bIgnore=false) noexcept
JSON固定文字入力関数
Definition: CJsonToken.cpp:476
virtual bool PopStreamPoint(CArray< int > *pcPointerList, bool bResume) noexcept
ストリームポインタポップ数
Definition: CStream.cpp:214
virtual bool OutputChar(wchar_t ch) noexcept override
1文字出力関数
ストリームクラス
Definition: CStream.h:31
virtual bool InputJsonChars(CStream &rcStream, wchar_t const *pszNgChars=nullptr) noexcept
JSON文字集合入力関数
Definition: CJsonToken.cpp:127
JSONクラス
Definition: CJson.h:44
ストリーム出力クラス
Definition: CStreamOut.h:30
CArray< int > * m_pcInputPointerList
入力ストリームポインタリストポインタ
Definition: CJson.h:238
virtual bool InputJsonExpHeader(CStream &rcStream) noexcept
JSON指数部ヘッダ入力関数
Definition: CJsonToken.cpp:363
virtual bool CompactBuffer() noexcept
バッファサイズコンパクト化関数
Definition: CString.cpp:348
virtual bool CompactJson() noexcept
JSONクラスコンパクト化関数
Definition: CJson.cpp:93
virtual bool InputJsonInt(CStream &rcStream) noexcept
JSON整数部入力関数
Definition: CJsonToken.cpp:251
文字列ストリームクラス
Definition: CStringStream.h:31
virtual bool InputJsonChar(CStream &rcStream, wchar_t const *pszNgChars=nullptr) noexcept
JSON文字入力関数
Definition: CJsonToken.cpp:161
virtual bool PushStreamPoint(CArray< int > *pcPointerList) noexcept
ストリームポインタプッシュ関数
Definition: CStream.cpp:191
virtual bool CompactBuffer() noexcept
バッファサイズコンパクト化関数
Definition: CArray.hpp:297
virtual bool InputJsonFrac(CStream &rcStream) noexcept
JSON小数部入力関数
Definition: CJsonToken.cpp:291
virtual bool OutputJson(CStreamOut &rcStreamOut) noexcept override
JSONクラス出力関数
Definition: CJsonToken.cpp:102
CJsonToken(CJson *pcParent, wchar_t const *pszString=nullptr) noexcept
コンストラクタ
Definition: CJsonToken.cpp:29
virtual bool CompactJson() noexcept override
JSONクラスコンパクト化関数
Definition: CJsonToken.cpp:72
virtual ~CJsonToken() noexcept
デストラクタ
Definition: CJsonToken.cpp:50
ユーティリティライブラリヘッダファイル
virtual bool InputJsonDigits(CStream &rcStream) noexcept
JSON数字集合入力関数
Definition: CJsonToken.cpp:400
virtual wchar_t const * GetBuffer() const noexcept
文字列バッファ取得関数
Definition: CString.h:159
virtual bool InputJsonFixedString(CStream &rcStream, wchar_t const *pszString) noexcept
JSON固定文字列入力関数
Definition: CJsonToken.cpp:525
virtual void ClearJson() noexcept override
JSONクラスクリア関数
Definition: CJsonToken.cpp:59
virtual void ClearJson() noexcept
JSONクラスクリア関数
Definition: CJson.cpp:86