encodedstream.h (rapidjson-1.0.2) | : | encodedstream.h (rapidjson-1.1.0) | ||
---|---|---|---|---|
skipping to change at line 18 | skipping to change at line 18 | |||
// http://opensource.org/licenses/MIT | // http://opensource.org/licenses/MIT | |||
// | // | |||
// Unless required by applicable law or agreed to in writing, software distribut ed | // Unless required by applicable law or agreed to in writing, software distribut ed | |||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | // CONDITIONS OF ANY KIND, either express or implied. See the License for the | |||
// specific language governing permissions and limitations under the License. | // specific language governing permissions and limitations under the License. | |||
#ifndef RAPIDJSON_ENCODEDSTREAM_H_ | #ifndef RAPIDJSON_ENCODEDSTREAM_H_ | |||
#define RAPIDJSON_ENCODEDSTREAM_H_ | #define RAPIDJSON_ENCODEDSTREAM_H_ | |||
#include "rapidjson.h" | #include "stream.h" | |||
#include "memorystream.h" | ||||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
RAPIDJSON_DIAG_PUSH | RAPIDJSON_DIAG_PUSH | |||
RAPIDJSON_DIAG_OFF(effc++) | RAPIDJSON_DIAG_OFF(effc++) | |||
#endif | #endif | |||
#ifdef __clang__ | ||||
RAPIDJSON_DIAG_PUSH | ||||
RAPIDJSON_DIAG_OFF(padded) | ||||
#endif | ||||
RAPIDJSON_NAMESPACE_BEGIN | RAPIDJSON_NAMESPACE_BEGIN | |||
//! Input byte stream wrapper with a statically bound encoding. | //! Input byte stream wrapper with a statically bound encoding. | |||
/*! | /*! | |||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. | \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. | |||
\tparam InputByteStream Type of input byte stream. For example, FileReadStre am. | \tparam InputByteStream Type of input byte stream. For example, FileReadStre am. | |||
*/ | */ | |||
template <typename Encoding, typename InputByteStream> | template <typename Encoding, typename InputByteStream> | |||
class EncodedInputStream { | class EncodedInputStream { | |||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |||
skipping to change at line 60 | skipping to change at line 66 | |||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } | |||
private: | private: | |||
EncodedInputStream(const EncodedInputStream&); | EncodedInputStream(const EncodedInputStream&); | |||
EncodedInputStream& operator=(const EncodedInputStream&); | EncodedInputStream& operator=(const EncodedInputStream&); | |||
InputByteStream& is_; | InputByteStream& is_; | |||
Ch current_; | Ch current_; | |||
}; | }; | |||
//! Specialized for UTF8 MemoryStream. | ||||
template <> | ||||
class EncodedInputStream<UTF8<>, MemoryStream> { | ||||
public: | ||||
typedef UTF8<>::Ch Ch; | ||||
EncodedInputStream(MemoryStream& is) : is_(is) { | ||||
if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take(); | ||||
if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take(); | ||||
if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take(); | ||||
} | ||||
Ch Peek() const { return is_.Peek(); } | ||||
Ch Take() { return is_.Take(); } | ||||
size_t Tell() const { return is_.Tell(); } | ||||
// Not implemented | ||||
void Put(Ch) {} | ||||
void Flush() {} | ||||
Ch* PutBegin() { return 0; } | ||||
size_t PutEnd(Ch*) { return 0; } | ||||
MemoryStream& is_; | ||||
private: | ||||
EncodedInputStream(const EncodedInputStream&); | ||||
EncodedInputStream& operator=(const EncodedInputStream&); | ||||
}; | ||||
//! Output byte stream wrapper with statically bound encoding. | //! Output byte stream wrapper with statically bound encoding. | |||
/*! | /*! | |||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. | \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. | |||
\tparam InputByteStream Type of input byte stream. For example, FileWriteStr eam. | \tparam OutputByteStream Type of input byte stream. For example, FileWriteSt ream. | |||
*/ | */ | |||
template <typename Encoding, typename OutputByteStream> | template <typename Encoding, typename OutputByteStream> | |||
class EncodedOutputStream { | class EncodedOutputStream { | |||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |||
public: | public: | |||
typedef typename Encoding::Ch Ch; | typedef typename Encoding::Ch Ch; | |||
EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { | EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { | |||
if (putBOM) | if (putBOM) | |||
Encoding::PutBOM(os_); | Encoding::PutBOM(os_); | |||
} | } | |||
void Put(Ch c) { Encoding::Put(os_, c); } | void Put(Ch c) { Encoding::Put(os_, c); } | |||
void Flush() { os_.Flush(); } | void Flush() { os_.Flush(); } | |||
// Not implemented | // Not implemented | |||
Ch Peek() const { RAPIDJSON_ASSERT(false); } | Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} | |||
Ch Take() { RAPIDJSON_ASSERT(false); } | Ch Take() { RAPIDJSON_ASSERT(false); return 0;} | |||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } | |||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } | |||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } | |||
private: | private: | |||
EncodedOutputStream(const EncodedOutputStream&); | EncodedOutputStream(const EncodedOutputStream&); | |||
EncodedOutputStream& operator=(const EncodedOutputStream&); | EncodedOutputStream& operator=(const EncodedOutputStream&); | |||
OutputByteStream& os_; | OutputByteStream& os_; | |||
}; | }; | |||
skipping to change at line 145 | skipping to change at line 179 | |||
// Detect encoding type with BOM or RFC 4627 | // Detect encoding type with BOM or RFC 4627 | |||
void DetectType() { | void DetectType() { | |||
// BOM (Byte Order Mark): | // BOM (Byte Order Mark): | |||
// 00 00 FE FF UTF-32BE | // 00 00 FE FF UTF-32BE | |||
// FF FE 00 00 UTF-32LE | // FF FE 00 00 UTF-32LE | |||
// FE FF UTF-16BE | // FE FF UTF-16BE | |||
// FF FE UTF-16LE | // FF FE UTF-16LE | |||
// EF BB BF UTF-8 | // EF BB BF UTF-8 | |||
const unsigned char* c = (const unsigned char *)is_->Peek4(); | const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Pe ek4()); | |||
if (!c) | if (!c) | |||
return; | return; | |||
unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); | unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); | |||
hasBOM_ = false; | hasBOM_ = false; | |||
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = tr ue; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } | if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = tr ue; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } | |||
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = tr ue; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } | else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = tr ue; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } | |||
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = tr ue; is_->Take(); is_->Take(); } | else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = tr ue; is_->Take(); is_->Take(); } | |||
else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = tr ue; is_->Take(); is_->Take(); } | else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = tr ue; is_->Take(); is_->Take(); } | |||
else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = tr ue; is_->Take(); is_->Take(); is_->Take(); } | else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = tr ue; is_->Take(); is_->Take(); is_->Take(); } | |||
// RFC 4627: Section 3 | // RFC 4627: Section 3 | |||
// "Since the first two characters of a JSON text will always be ASCII | // "Since the first two characters of a JSON text will always be ASCII | |||
// characters [RFC0020], it is possible to determine whether an octet | // characters [RFC0020], it is possible to determine whether an octet | |||
skipping to change at line 196 | skipping to change at line 230 | |||
InputByteStream* is_; | InputByteStream* is_; | |||
UTFType type_; | UTFType type_; | |||
Ch current_; | Ch current_; | |||
TakeFunc takeFunc_; | TakeFunc takeFunc_; | |||
bool hasBOM_; | bool hasBOM_; | |||
}; | }; | |||
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. | //! Output stream wrapper with dynamically bound encoding and automatic encoding detection. | |||
/*! | /*! | |||
\tparam CharType Type of character for writing. | \tparam CharType Type of character for writing. | |||
\tparam InputByteStream type of output byte stream to be wrapped. | \tparam OutputByteStream type of output byte stream to be wrapped. | |||
*/ | */ | |||
template <typename CharType, typename OutputByteStream> | template <typename CharType, typename OutputByteStream> | |||
class AutoUTFOutputStream { | class AutoUTFOutputStream { | |||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |||
public: | public: | |||
typedef CharType Ch; | typedef CharType Ch; | |||
//! Constructor. | //! Constructor. | |||
/*! | /*! | |||
\param os output stream to be wrapped. | \param os output stream to be wrapped. | |||
skipping to change at line 230 | skipping to change at line 264 | |||
if (putBOM) | if (putBOM) | |||
PutBOM(); | PutBOM(); | |||
} | } | |||
UTFType GetType() const { return type_; } | UTFType GetType() const { return type_; } | |||
void Put(Ch c) { putFunc_(*os_, c); } | void Put(Ch c) { putFunc_(*os_, c); } | |||
void Flush() { os_->Flush(); } | void Flush() { os_->Flush(); } | |||
// Not implemented | // Not implemented | |||
Ch Peek() const { RAPIDJSON_ASSERT(false); } | Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} | |||
Ch Take() { RAPIDJSON_ASSERT(false); } | Ch Take() { RAPIDJSON_ASSERT(false); return 0;} | |||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } | |||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } | |||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } | |||
private: | private: | |||
AutoUTFOutputStream(const AutoUTFOutputStream&); | AutoUTFOutputStream(const AutoUTFOutputStream&); | |||
AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); | AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); | |||
void PutBOM() { | void PutBOM() { | |||
typedef void (*PutBOMFunc)(OutputByteStream&); | typedef void (*PutBOMFunc)(OutputByteStream&); | |||
skipping to change at line 257 | skipping to change at line 291 | |||
OutputByteStream* os_; | OutputByteStream* os_; | |||
UTFType type_; | UTFType type_; | |||
PutFunc putFunc_; | PutFunc putFunc_; | |||
}; | }; | |||
#undef RAPIDJSON_ENCODINGS_FUNC | #undef RAPIDJSON_ENCODINGS_FUNC | |||
RAPIDJSON_NAMESPACE_END | RAPIDJSON_NAMESPACE_END | |||
#ifdef __clang__ | ||||
RAPIDJSON_DIAG_POP | ||||
#endif | ||||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
RAPIDJSON_DIAG_POP | RAPIDJSON_DIAG_POP | |||
#endif | #endif | |||
#endif // RAPIDJSON_FILESTREAM_H_ | #endif // RAPIDJSON_FILESTREAM_H_ | |||
End of changes. 10 change blocks. | ||||
9 lines changed or deleted | 47 lines changed or added |