1e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Tencent is pleased to support the open source community by making RapidJSON available. 2e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 3e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 5e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Licensed under the MIT License (the "License"); you may not use this file except 6e462795ff5d4c7359f9e8637c10544bb2de70107tturney// in compliance with the License. You may obtain a copy of the License at 7e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 8e462795ff5d4c7359f9e8637c10544bb2de70107tturney// http://opensource.org/licenses/MIT 9e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 10e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Unless required by applicable law or agreed to in writing, software distributed 11e462795ff5d4c7359f9e8637c10544bb2de70107tturney// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12e462795ff5d4c7359f9e8637c10544bb2de70107tturney// CONDITIONS OF ANY KIND, either express or implied. See the License for the 13e462795ff5d4c7359f9e8637c10544bb2de70107tturney// specific language governing permissions and limitations under the License. 14e462795ff5d4c7359f9e8637c10544bb2de70107tturney 15e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifndef RAPIDJSON_FILEWRITESTREAM_H_ 16e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_FILEWRITESTREAM_H_ 17e462795ff5d4c7359f9e8637c10544bb2de70107tturney 18e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "rapidjson.h" 19e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include <cstdio> 20e462795ff5d4c7359f9e8637c10544bb2de70107tturney 21e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_NAMESPACE_BEGIN 22e462795ff5d4c7359f9e8637c10544bb2de70107tturney 23e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Wrapper of C file stream for input using fread(). 24e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! 25e462795ff5d4c7359f9e8637c10544bb2de70107tturney \note implements Stream concept 26e462795ff5d4c7359f9e8637c10544bb2de70107tturney*/ 27e462795ff5d4c7359f9e8637c10544bb2de70107tturneyclass FileWriteStream { 28e462795ff5d4c7359f9e8637c10544bb2de70107tturneypublic: 29e462795ff5d4c7359f9e8637c10544bb2de70107tturney typedef char Ch; //!< Character type. Only support char. 30e462795ff5d4c7359f9e8637c10544bb2de70107tturney 31e462795ff5d4c7359f9e8637c10544bb2de70107tturney FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 32e462795ff5d4c7359f9e8637c10544bb2de70107tturney RAPIDJSON_ASSERT(fp_ != 0); 33e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 34e462795ff5d4c7359f9e8637c10544bb2de70107tturney 35e462795ff5d4c7359f9e8637c10544bb2de70107tturney void Put(char c) { 36e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (current_ >= bufferEnd_) 37e462795ff5d4c7359f9e8637c10544bb2de70107tturney Flush(); 38e462795ff5d4c7359f9e8637c10544bb2de70107tturney 39e462795ff5d4c7359f9e8637c10544bb2de70107tturney *current_++ = c; 40e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 41e462795ff5d4c7359f9e8637c10544bb2de70107tturney 42e462795ff5d4c7359f9e8637c10544bb2de70107tturney void PutN(char c, size_t n) { 43e462795ff5d4c7359f9e8637c10544bb2de70107tturney size_t avail = static_cast<size_t>(bufferEnd_ - current_); 44e462795ff5d4c7359f9e8637c10544bb2de70107tturney while (n > avail) { 45e462795ff5d4c7359f9e8637c10544bb2de70107tturney std::memset(current_, c, avail); 46e462795ff5d4c7359f9e8637c10544bb2de70107tturney current_ += avail; 47e462795ff5d4c7359f9e8637c10544bb2de70107tturney Flush(); 48e462795ff5d4c7359f9e8637c10544bb2de70107tturney n -= avail; 49e462795ff5d4c7359f9e8637c10544bb2de70107tturney avail = static_cast<size_t>(bufferEnd_ - current_); 50e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 51e462795ff5d4c7359f9e8637c10544bb2de70107tturney 52e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (n > 0) { 53e462795ff5d4c7359f9e8637c10544bb2de70107tturney std::memset(current_, c, n); 54e462795ff5d4c7359f9e8637c10544bb2de70107tturney current_ += n; 55e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 56e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 57e462795ff5d4c7359f9e8637c10544bb2de70107tturney 58e462795ff5d4c7359f9e8637c10544bb2de70107tturney void Flush() { 59e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (current_ != buffer_) { 60e462795ff5d4c7359f9e8637c10544bb2de70107tturney size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_); 61e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (result < static_cast<size_t>(current_ - buffer_)) { 62e462795ff5d4c7359f9e8637c10544bb2de70107tturney // failure deliberately ignored at this time 63e462795ff5d4c7359f9e8637c10544bb2de70107tturney // added to avoid warn_unused_result build errors 64e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 65e462795ff5d4c7359f9e8637c10544bb2de70107tturney current_ = buffer_; 66e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 67e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 68e462795ff5d4c7359f9e8637c10544bb2de70107tturney 69e462795ff5d4c7359f9e8637c10544bb2de70107tturney // Not implemented 70e462795ff5d4c7359f9e8637c10544bb2de70107tturney char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 71e462795ff5d4c7359f9e8637c10544bb2de70107tturney char Take() { RAPIDJSON_ASSERT(false); return 0; } 72e462795ff5d4c7359f9e8637c10544bb2de70107tturney size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 73e462795ff5d4c7359f9e8637c10544bb2de70107tturney char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 74e462795ff5d4c7359f9e8637c10544bb2de70107tturney size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 75e462795ff5d4c7359f9e8637c10544bb2de70107tturney 76e462795ff5d4c7359f9e8637c10544bb2de70107tturneyprivate: 77e462795ff5d4c7359f9e8637c10544bb2de70107tturney // Prohibit copy constructor & assignment operator. 78e462795ff5d4c7359f9e8637c10544bb2de70107tturney FileWriteStream(const FileWriteStream&); 79e462795ff5d4c7359f9e8637c10544bb2de70107tturney FileWriteStream& operator=(const FileWriteStream&); 80e462795ff5d4c7359f9e8637c10544bb2de70107tturney 81e462795ff5d4c7359f9e8637c10544bb2de70107tturney std::FILE* fp_; 82e462795ff5d4c7359f9e8637c10544bb2de70107tturney char *buffer_; 83e462795ff5d4c7359f9e8637c10544bb2de70107tturney char *bufferEnd_; 84e462795ff5d4c7359f9e8637c10544bb2de70107tturney char *current_; 85e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; 86e462795ff5d4c7359f9e8637c10544bb2de70107tturney 87e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Implement specialized version of PutN() with memset() for better performance. 88e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<> 89e462795ff5d4c7359f9e8637c10544bb2de70107tturneyinline void PutN(FileWriteStream& stream, char c, size_t n) { 90e462795ff5d4c7359f9e8637c10544bb2de70107tturney stream.PutN(c, n); 91e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 92e462795ff5d4c7359f9e8637c10544bb2de70107tturney 93e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_NAMESPACE_END 94e462795ff5d4c7359f9e8637c10544bb2de70107tturney 95e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif // RAPIDJSON_FILESTREAM_H_ 96