filewritestream.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. #ifndef RAPIDJSON_FILEWRITESTREAM_H_
  19. #define RAPIDJSON_FILEWRITESTREAM_H_
  20. #include <cstdio>
  21. #include "stream.h"
  22. #ifdef __clang__
  23. RAPIDJSON_DIAG_PUSH
  24. RAPIDJSON_DIAG_OFF(unreachable - code)
  25. #endif
  26. RAPIDJSON_NAMESPACE_BEGIN
  27. //! Wrapper of C file stream for output using fwrite().
  28. /*!
  29. \note implements Stream concept
  30. */
  31. class FileWriteStream {
  32. public:
  33. typedef char Ch; //!< Character type. Only support char.
  34. FileWriteStream(std::FILE *fp, char *buffer, size_t bufferSize)
  35. : fp_(fp),
  36. buffer_(buffer),
  37. bufferEnd_(buffer + bufferSize),
  38. current_(buffer_) {
  39. RAPIDJSON_ASSERT(fp_ != 0);
  40. }
  41. void Put(char c) {
  42. if (current_ >= bufferEnd_) Flush();
  43. *current_++ = c;
  44. }
  45. void PutN(char c, size_t n) {
  46. size_t avail = static_cast<size_t>(bufferEnd_ - current_);
  47. while (n > avail) {
  48. std::memset(current_, c, avail);
  49. current_ += avail;
  50. Flush();
  51. n -= avail;
  52. avail = static_cast<size_t>(bufferEnd_ - current_);
  53. }
  54. if (n > 0) {
  55. std::memset(current_, c, n);
  56. current_ += n;
  57. }
  58. }
  59. void Flush() {
  60. if (current_ != buffer_) {
  61. size_t result =
  62. std::fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
  63. if (result < static_cast<size_t>(current_ - buffer_)) {
  64. // failure deliberately ignored at this time
  65. // added to avoid warn_unused_result build errors
  66. }
  67. current_ = buffer_;
  68. }
  69. }
  70. // Not implemented
  71. char Peek() const {
  72. RAPIDJSON_ASSERT(false);
  73. return 0;
  74. }
  75. char Take() {
  76. RAPIDJSON_ASSERT(false);
  77. return 0;
  78. }
  79. size_t Tell() const {
  80. RAPIDJSON_ASSERT(false);
  81. return 0;
  82. }
  83. char *PutBegin() {
  84. RAPIDJSON_ASSERT(false);
  85. return 0;
  86. }
  87. size_t PutEnd(char *) {
  88. RAPIDJSON_ASSERT(false);
  89. return 0;
  90. }
  91. private:
  92. // Prohibit copy constructor & assignment operator.
  93. FileWriteStream(const FileWriteStream &);
  94. FileWriteStream &operator=(const FileWriteStream &);
  95. std::FILE *fp_;
  96. char *buffer_;
  97. char *bufferEnd_;
  98. char *current_;
  99. };
  100. //! Implement specialized version of PutN() with memset() for better
  101. //! performance.
  102. template <>
  103. inline void PutN(FileWriteStream &stream, char c, size_t n) {
  104. stream.PutN(c, n);
  105. }
  106. RAPIDJSON_NAMESPACE_END
  107. #ifdef __clang__
  108. RAPIDJSON_DIAG_POP
  109. #endif
  110. #endif // RAPIDJSON_FILESTREAM_H_