nlib
TextReader.h
[詳解]
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_TEXTREADER_H_
17 #define INCLUDE_NN_NLIB_TEXTREADER_H_
18 
19 #include "nn/nlib/Config.h"
20 
21 NLIB_NAMESPACE_BEGIN
22 
23 class InputStream;
24 
25 // code snippets:
26 // TextReader reader;
27 // if (reader.Init() != 0 || reader.Open(&stream) != 0) { error }
28 // while ((c = reader.Read()) >= 0)
29 // c is a codepoint
30 // if (!reader) { stream error if !stream, otherwise UTF-8 may be malformed }
31 // reader.Close();
32 // (stream.Close();)
34  public:
36  virtual ~TextReader() NLIB_NOEXCEPT;
37  errno_t Init() NLIB_NOEXCEPT;
38  errno_t Open(InputStream* stream) NLIB_NOEXCEPT;
39  size_t Read(nlib_utf8_t* buf, size_t n) NLIB_NOEXCEPT;
40  int Read() NLIB_NOEXCEPT;
41  int Peek() NLIB_NOEXCEPT;
43  // skip ' ' \t \n (\r)
44  if (cur_ + 1 < bufend_) {
45  unsigned char c = *reinterpret_cast<unsigned char*>(cur_);
46  if (c > ' ') return 0;
47  if (c == ' ') {
48  ++cur_;
49  c = *reinterpret_cast<unsigned char*>(cur_);
50  if (c > ' ') {
51  utf32_cache_ = 0;
52  return 1;
53  }
54  return this->SkipWs_(1);
55  }
56  }
57  return this->SkipWs_(0);
58  }
59  bool ReadUntil(size_t* len, nlib_utf8_t* buf, size_t n, char delim) NLIB_NOEXCEPT NLIB_NONNULL;
60  template<size_t N>
61  bool ReadUntil(size_t* len, nlib_utf8_t (&buf)[N], char delim) NLIB_NOEXCEPT {
62  return this->ReadUntil(len, &buf[0], N, delim);
63  }
64  // deprecated
65  template<class T>
66  bool ReadUntil(size_t* len, nlib_utf8_t* buf, size_t n, T pred) NLIB_NOEXCEPT;
67  template<class T, size_t N>
68  NLIB_DEPRECATED bool ReadUntil(size_t* len, nlib_utf8_t (&buf)[N], T pred) NLIB_NOEXCEPT {
69  return this->ReadUntil(len, buf, N, pred);
70  }
71  size_t ReadDecimalString(char* buf, size_t n) NLIB_NOEXCEPT NLIB_NONNULL;
72  template<size_t N>
73  size_t ReadDecimalString(char (&buf)[N]) NLIB_NOEXCEPT {
74  return this->ReadDecimalString(buf, N);
75  }
76  bool Proceed(const nlib_utf8_t* str, size_t n) NLIB_NOEXCEPT NLIB_NONNULL;
77  bool Proceed(char c) NLIB_NOEXCEPT {
78  NLIB_ASSERT(!(c & 0x80) && c != 0x0A);
79  if (cur_ == bufend_) {
80  this->FillBuffer();
81  if (cur_ == bufend_) return false;
82  }
83  if (*cur_ != c) return false;
84  ++cur_;
85  return true;
86  }
87  bool ProceedEx(const nlib_utf8_t* str) NLIB_NOEXCEPT;
88  bool Close() NLIB_NOEXCEPT;
89  void SetError(errno_t e) const NLIB_NOEXCEPT {
90  if (errno_ == 0) errno_ = e;
91  }
92  errno_t GetErrorValue() const NLIB_NOEXCEPT { return errno_; }
93  InputStream* GetStream() NLIB_NOEXCEPT { return stream_; }
94  int GetLine() const NLIB_NOEXCEPT { return line_; }
95  int GetColumn() const NLIB_NOEXCEPT {
96  return static_cast<int>((cur_ - &buf_[0]) + 1 + pos_of_buf_ - pos_of_line_);
97  }
98  NLIB_SAFE_BOOL(TextReader, GetErrorValue() == 0)
99 
100  protected:
101  char* GetCur() NLIB_NOEXCEPT { return cur_; }
102  char* GetBufEnd() NLIB_NOEXCEPT { return bufend_; }
103  void SetBufEnd(char* p) NLIB_NOEXCEPT { bufend_ = p; }
104 
105  // checks UTF-8 validity, converts CRLF to LF, and convert CR to LF
106  virtual void FillBuffer_() NLIB_NOEXCEPT;
107 
108  private:
109  void FillBuffer() NLIB_NOEXCEPT { this->FillBuffer_(); }
110  void ConstructUtf32Cache() NLIB_NOEXCEPT;
111  int SkipWs_(int base) NLIB_NOEXCEPT;
112 
113  private:
114  char buf_[512 + 3 + 1];
115  nlib_utf32_t utf32_cache_;
116  char* cur_;
117  char* bufend_;
118  size_t utf8_bytecount_;
119  InputStream* stream_;
120  mutable ErrnoT errno_;
121  int line_;
122  size_t pos_of_line_;
123  size_t pos_of_buf_;
124 
125  NLIB_DISALLOW_COPY_AND_ASSIGN(TextReader);
126 };
127 
128 template<class T>
129 bool TextReader::ReadUntil(size_t* len, nlib_utf8_t* buf, size_t n, T pred) NLIB_NOEXCEPT {
130  // NOTICE: not NULL terminated
131  if (!buf) {
132  *len = 0;
133  return false;
134  }
135  utf32_cache_ = 0;
136  char* p = buf;
137  char* pend = buf + n;
138  for (;;) {
139  if (cur_ == bufend_) {
140  this->FillBuffer();
141  if (cur_ == bufend_) {
142  *len = p - buf;
143  return false;
144  }
145  }
146  // T::operator()(const char* ptr);
147  while (p != pend && cur_ != bufend_) {
148  if ((*reinterpret_cast<unsigned char*>(cur_) & 0xC0) != 0x80 &&
149  pred((const char*)cur_)) {
150  *len = p - buf;
151  return true;
152  }
153  *p = *cur_;
154  ++p;
155  ++cur_;
156  }
157  if (p == pend) {
158  if (cur_ != bufend_ && (*reinterpret_cast<unsigned char*>(cur_) & 0xC0) == 0x80) {
159  do {
160  --p;
161  --cur_;
162  } while ((*reinterpret_cast<unsigned char*>(cur_) & 0xC0) == 0x80);
163  }
164  *len = p - buf;
165  return false;
166  }
167  }
168 }
169 
170 NLIB_NAMESPACE_END
171 
172 #endif // INCLUDE_NN_NLIB_TEXTREADER_H_
bool ReadUntil(size_t *len, nlib_utf8_t(&buf)[N], T pred) noexcept
上記関数のテンプレートオーバーロードです。
Definition: TextReader.h:68
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:183
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
Definition: Config.h:199
InputStream * GetStream() noexcept
テキストリーダーが書き込みを行うストリームを取得します。
Definition: TextReader.h:93
#define NLIB_DEPRECATED
関数等がdeprecatedになったことを示します。
Definition: Config.h:113
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:87
int GetColumn() const noexcept
現在の桁を取得します。
Definition: TextReader.h:95
errno_t GetErrorValue() const noexcept
読み込みが失敗した際に、エラーの原因を取得できます。
Definition: TextReader.h:92
uint32_t nlib_utf32_t
char32_tが利用できる場合はchar32_tに、そうでない場合はuint32_tにtypedefされます。 ...
Definition: Platform.h:289
size_t ReadDecimalString(char(&buf)[N]) noexcept
上記関数のテンプレートオーバーロードです。
Definition: TextReader.h:73
bool Proceed(char c) noexcept
文字c の分だけストリームを進めます。
Definition: TextReader.h:77
bool ReadUntil(size_t *len, nlib_utf8_t(&buf)[N], char delim) noexcept
上記関数のテンプレートオーバーロードです。
Definition: TextReader.h:61
ストリームからテキストを読み込むクラスです。
Definition: TextReader.h:33
入力ストリームの基底クラスです。このクラスを実体化することはできません。
Definition: InputStream.h:29
int GetLine() const noexcept
現在の行番号を取得します。
Definition: TextReader.h:94
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Config.h:109
開発環境別の設定が書かれるファイルです。
bool Proceed(StringView &str, const StringView &prefix) noexcept
strがprefixで始まっていればその文字列長だけ進めます。
Definition: StringView.h:353
int SkipWs() noexcept
ストリーム内の空白(スペース,改行,タブ,復帰)文字を読み飛ばして、読み飛ばした空白の数を返します。 ...
Definition: TextReader.h:42
bool Read(BinaryReader *r, T *x)
この関数テンプレートを特殊化することで、ユーザー定義クラスに読み込むことができます。 ...
Definition: BinaryReader.h:161
#define NLIB_NONNULL
全ての引数にNULLを指定することができないことを示します。
char nlib_utf8_t
charのtypedefです。文字列がUTF-8であることを示します。
Definition: Platform.h:303
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:37