encodedstream.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON
2 // available.
3 //
4 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All
5 // rights reserved.
6 //
7 // Licensed under the MIT License (the "License"); you may not use this file
8 // except in compliance with the License. You may obtain a copy of the License
9 // at
10 //
11 // http://opensource.org/licenses/MIT
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 // License for the specific language governing permissions and limitations under
17 // the License.
18 
19 #ifndef RAPIDJSON_ENCODEDSTREAM_H_
20 #define RAPIDJSON_ENCODEDSTREAM_H_
21 
22 #include "memorystream.h"
23 #include "stream.h"
24 
25 #ifdef __GNUC__
26 RAPIDJSON_DIAG_PUSH
27 RAPIDJSON_DIAG_OFF(effc++)
28 #endif
29 
30 #ifdef __clang__
31 RAPIDJSON_DIAG_PUSH
32 RAPIDJSON_DIAG_OFF(padded)
33 #endif
34 
36 
38 
43 template <typename Encoding, typename InputByteStream>
45  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
46 
47  public:
48  typedef typename Encoding::Ch Ch;
49 
50  EncodedInputStream(InputByteStream &is) : is_(is) {
51  current_ = Encoding::TakeBOM(is_);
52  }
53 
54  Ch Peek() const { return current_; }
55  Ch Take() {
56  Ch c = current_;
57  current_ = Encoding::Take(is_);
58  return c;
59  }
60  size_t Tell() const { return is_.Tell(); }
61 
62  // Not implemented
63  void Put(Ch) { RAPIDJSON_ASSERT(false); }
64  void Flush() { RAPIDJSON_ASSERT(false); }
65  Ch *PutBegin() {
66  RAPIDJSON_ASSERT(false);
67  return 0;
68  }
69  size_t PutEnd(Ch *) {
70  RAPIDJSON_ASSERT(false);
71  return 0;
72  }
73 
74  private:
77 
78  InputByteStream &is_;
80 };
81 
83 template <>
85  public:
86  typedef UTF8<>::Ch Ch;
87 
89  if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take();
90  if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take();
91  if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take();
92  }
93  Ch Peek() const { return is_.Peek(); }
94  Ch Take() { return is_.Take(); }
95  size_t Tell() const { return is_.Tell(); }
96 
97  // Not implemented
98  void Put(Ch) {}
99  void Flush() {}
100  Ch *PutBegin() { return 0; }
101  size_t PutEnd(Ch *) { return 0; }
102 
104 
105  private:
108 };
109 
111 
116 template <typename Encoding, typename OutputByteStream>
118  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
119 
120  public:
121  typedef typename Encoding::Ch Ch;
122 
123  EncodedOutputStream(OutputByteStream &os, bool putBOM = true) : os_(os) {
124  if (putBOM) Encoding::PutBOM(os_);
125  }
126 
127  void Put(Ch c) { Encoding::Put(os_, c); }
128  void Flush() { os_.Flush(); }
129 
130  // Not implemented
131  Ch Peek() const {
132  RAPIDJSON_ASSERT(false);
133  return 0;
134  }
135  Ch Take() {
136  RAPIDJSON_ASSERT(false);
137  return 0;
138  }
139  size_t Tell() const {
140  RAPIDJSON_ASSERT(false);
141  return 0;
142  }
143  Ch *PutBegin() {
144  RAPIDJSON_ASSERT(false);
145  return 0;
146  }
147  size_t PutEnd(Ch *) {
148  RAPIDJSON_ASSERT(false);
149  return 0;
150  }
151 
152  private:
155 
156  OutputByteStream &os_;
157 };
158 
159 #define RAPIDJSON_ENCODINGS_FUNC(x) \
160  UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
161 
164 
168 template <typename CharType, typename InputByteStream>
170  RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
171 
172  public:
173  typedef CharType Ch;
174 
176 
180  AutoUTFInputStream(InputByteStream &is, UTFType type = kUTF8)
181  : is_(&is), type_(type), hasBOM_(false) {
182  RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
183  DetectType();
184  static const TakeFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(Take)};
185  takeFunc_ = f[type_];
186  current_ = takeFunc_(*is_);
187  }
188 
189  UTFType GetType() const { return type_; }
190  bool HasBOM() const { return hasBOM_; }
191 
192  Ch Peek() const { return current_; }
193  Ch Take() {
194  Ch c = current_;
195  current_ = takeFunc_(*is_);
196  return c;
197  }
198  size_t Tell() const { return is_->Tell(); }
199 
200  // Not implemented
201  void Put(Ch) { RAPIDJSON_ASSERT(false); }
202  void Flush() { RAPIDJSON_ASSERT(false); }
203  Ch *PutBegin() {
204  RAPIDJSON_ASSERT(false);
205  return 0;
206  }
207  size_t PutEnd(Ch *) {
208  RAPIDJSON_ASSERT(false);
209  return 0;
210  }
211 
212  private:
215 
216  // Detect encoding type with BOM or RFC 4627
217  void DetectType() {
218  // BOM (Byte Order Mark):
219  // 00 00 FE FF UTF-32BE
220  // FF FE 00 00 UTF-32LE
221  // FE FF UTF-16BE
222  // FF FE UTF-16LE
223  // EF BB BF UTF-8
224 
225  const unsigned char *c =
226  reinterpret_cast<const unsigned char *>(is_->Peek4());
227  if (!c) return;
228 
229  unsigned bom =
230  static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
231  hasBOM_ = false;
232  if (bom == 0xFFFE0000) {
233  type_ = kUTF32BE;
234  hasBOM_ = true;
235  is_->Take();
236  is_->Take();
237  is_->Take();
238  is_->Take();
239  } else if (bom == 0x0000FEFF) {
240  type_ = kUTF32LE;
241  hasBOM_ = true;
242  is_->Take();
243  is_->Take();
244  is_->Take();
245  is_->Take();
246  } else if ((bom & 0xFFFF) == 0xFFFE) {
247  type_ = kUTF16BE;
248  hasBOM_ = true;
249  is_->Take();
250  is_->Take();
251  } else if ((bom & 0xFFFF) == 0xFEFF) {
252  type_ = kUTF16LE;
253  hasBOM_ = true;
254  is_->Take();
255  is_->Take();
256  } else if ((bom & 0xFFFFFF) == 0xBFBBEF) {
257  type_ = kUTF8;
258  hasBOM_ = true;
259  is_->Take();
260  is_->Take();
261  is_->Take();
262  }
263 
264  // RFC 4627: Section 3
265  // "Since the first two characters of a JSON text will always be ASCII
266  // characters [RFC0020], it is possible to determine whether an octet
267  // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
268  // at the pattern of nulls in the first four octets."
269  // 00 00 00 xx UTF-32BE
270  // 00 xx 00 xx UTF-16BE
271  // xx 00 00 00 UTF-32LE
272  // xx 00 xx 00 UTF-16LE
273  // xx xx xx xx UTF-8
274 
275  if (!hasBOM_) {
276  int pattern =
277  (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
278  switch (pattern) {
279  case 0x08:
280  type_ = kUTF32BE;
281  break;
282  case 0x0A:
283  type_ = kUTF16BE;
284  break;
285  case 0x01:
286  type_ = kUTF32LE;
287  break;
288  case 0x05:
289  type_ = kUTF16LE;
290  break;
291  case 0x0F:
292  type_ = kUTF8;
293  break;
294  default:
295  break; // Use type defined by user.
296  }
297  }
298 
299  // Runtime check whether the size of character type is sufficient. It only
300  // perform checks with assertion.
301  if (type_ == kUTF16LE || type_ == kUTF16BE)
302  RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
303  if (type_ == kUTF32LE || type_ == kUTF32BE)
304  RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
305  }
306 
307  typedef Ch (*TakeFunc)(InputByteStream &is);
308  InputByteStream *is_;
311  TakeFunc takeFunc_;
312  bool hasBOM_;
313 };
314 
317 
321 template <typename CharType, typename OutputByteStream>
323  RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
324 
325  public:
326  typedef CharType Ch;
327 
329 
334  AutoUTFOutputStream(OutputByteStream &os, UTFType type, bool putBOM)
335  : os_(&os), type_(type) {
336  RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
337 
338  // Runtime check whether the size of character type is sufficient. It only
339  // perform checks with assertion.
340  if (type_ == kUTF16LE || type_ == kUTF16BE)
341  RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
342  if (type_ == kUTF32LE || type_ == kUTF32BE)
343  RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
344 
345  static const PutFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(Put)};
346  putFunc_ = f[type_];
347 
348  if (putBOM) PutBOM();
349  }
350 
351  UTFType GetType() const { return type_; }
352 
353  void Put(Ch c) { putFunc_(*os_, c); }
354  void Flush() { os_->Flush(); }
355 
356  // Not implemented
357  Ch Peek() const {
358  RAPIDJSON_ASSERT(false);
359  return 0;
360  }
361  Ch Take() {
362  RAPIDJSON_ASSERT(false);
363  return 0;
364  }
365  size_t Tell() const {
366  RAPIDJSON_ASSERT(false);
367  return 0;
368  }
369  Ch *PutBegin() {
370  RAPIDJSON_ASSERT(false);
371  return 0;
372  }
373  size_t PutEnd(Ch *) {
374  RAPIDJSON_ASSERT(false);
375  return 0;
376  }
377 
378  private:
381 
382  void PutBOM() {
383  typedef void (*PutBOMFunc)(OutputByteStream &);
384  static const PutBOMFunc f[] = {RAPIDJSON_ENCODINGS_FUNC(PutBOM)};
385  f[type_](*os_);
386  }
387 
388  typedef void (*PutFunc)(OutputByteStream &, Ch);
389 
390  OutputByteStream *os_;
392  PutFunc putFunc_;
393 };
394 
395 #undef RAPIDJSON_ENCODINGS_FUNC
396 
398 
399 #ifdef __clang__
400 RAPIDJSON_DIAG_POP
401 #endif
402 
403 #ifdef __GNUC__
404 RAPIDJSON_DIAG_POP
405 #endif
406 
407 #endif // RAPIDJSON_FILESTREAM_H_
#define RAPIDJSON_ENCODINGS_FUNC(x)
UTFType
Runtime-specified UTF encoding type of a stream.
Definition: encodings.h:688
bool HasBOM() const
Represents an in-memory input byte stream.
Definition: memorystream.h:48
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:433
f
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:131
OutputByteStream * os_
CharType Ch
Definition: encodings.h:103
UTF-32 big endian.
Definition: encodings.h:693
UTFType GetType() const
UTF-16 little endian.
Definition: encodings.h:690
EncodedInputStream & operator=(const EncodedInputStream &)
Output byte stream wrapper with statically bound encoding.
UTF-8.
Definition: encodings.h:689
AutoUTFOutputStream(OutputByteStream &os, UTFType type, bool putBOM)
Constructor.
size_t PutEnd(Ch *)
Encoding::Ch Ch
Definition: encodedstream.h:48
UTF-16 big endian.
Definition: encodings.h:691
EncodedOutputStream(OutputByteStream &os, bool putBOM=true)
size_t Tell() const
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:128
size_t PutEnd(Ch *)
Definition: encodedstream.h:69
EncodedInputStream(InputByteStream &is)
Definition: encodedstream.h:50
UTF-8 encoding.
Definition: encodings.h:102
InputByteStream * is_
Ch Peek() const
Definition: encodedstream.h:54
AutoUTFInputStream(InputByteStream &is, UTFType type=kUTF8)
Constructor.
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:44
size_t Tell() const
size_t Tell() const
Definition: encodedstream.h:60
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch)==1)
UTFType GetType() const
size_t PutEnd(Ch *)
UTF-32 little endian.
Definition: encodings.h:692
InputByteStream & is_
Definition: encodedstream.h:78
OutputByteStream & os_
size_t Tell() const
size_t PutEnd(Ch *)


livox_ros_driver
Author(s): Livox Dev Team
autogenerated on Mon Mar 15 2021 02:40:46