stringbuffer.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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_STRINGBUFFER_H_
  19. #define RAPIDJSON_STRINGBUFFER_H_
  20. #include "internal/stack.h"
  21. #include "stream.h"
  22. #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
  23. #include <utility> // std::move
  24. #endif
  25. #include "internal/stack.h"
  26. #if defined(__clang__)
  27. RAPIDJSON_DIAG_PUSH
  28. RAPIDJSON_DIAG_OFF(c++ 98 - compat)
  29. #endif
  30. RAPIDJSON_NAMESPACE_BEGIN
  31. //! Represents an in-memory output stream.
  32. /*!
  33. \tparam Encoding Encoding of the stream.
  34. \tparam Allocator type for allocating memory buffer.
  35. \note implements Stream concept
  36. */
  37. template <typename Encoding, typename Allocator = CrtAllocator>
  38. class GenericStringBuffer {
  39. public:
  40. typedef typename Encoding::Ch Ch;
  41. GenericStringBuffer(Allocator *allocator = 0,
  42. size_t capacity = kDefaultCapacity)
  43. : stack_(allocator, capacity) {}
  44. #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
  45. GenericStringBuffer(GenericStringBuffer &&rhs)
  46. : stack_(std::move(rhs.stack_)) {}
  47. GenericStringBuffer &operator=(GenericStringBuffer &&rhs) {
  48. if (&rhs != this) stack_ = std::move(rhs.stack_);
  49. return *this;
  50. }
  51. #endif
  52. void Put(Ch c) { *stack_.template Push<Ch>() = c; }
  53. void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }
  54. void Flush() {}
  55. void Clear() { stack_.Clear(); }
  56. void ShrinkToFit() {
  57. // Push and pop a null terminator. This is safe.
  58. *stack_.template Push<Ch>() = '\0';
  59. stack_.ShrinkToFit();
  60. stack_.template Pop<Ch>(1);
  61. }
  62. void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
  63. Ch *Push(size_t count) { return stack_.template Push<Ch>(count); }
  64. Ch *PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }
  65. void Pop(size_t count) { stack_.template Pop<Ch>(count); }
  66. const Ch *GetString() const {
  67. // Push and pop a null terminator. This is safe.
  68. *stack_.template Push<Ch>() = '\0';
  69. stack_.template Pop<Ch>(1);
  70. return stack_.template Bottom<Ch>();
  71. }
  72. //! Get the size of string in bytes in the string buffer.
  73. size_t GetSize() const { return stack_.GetSize(); }
  74. //! Get the length of string in Ch in the string buffer.
  75. size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }
  76. static const size_t kDefaultCapacity = 256;
  77. mutable internal::Stack<Allocator> stack_;
  78. private:
  79. // Prohibit copy constructor & assignment operator.
  80. GenericStringBuffer(const GenericStringBuffer &);
  81. GenericStringBuffer &operator=(const GenericStringBuffer &);
  82. };
  83. //! String buffer with UTF8 encoding
  84. typedef GenericStringBuffer<UTF8<>> StringBuffer;
  85. template <typename Encoding, typename Allocator>
  86. inline void PutReserve(GenericStringBuffer<Encoding, Allocator> &stream,
  87. size_t count) {
  88. stream.Reserve(count);
  89. }
  90. template <typename Encoding, typename Allocator>
  91. inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator> &stream,
  92. typename Encoding::Ch c) {
  93. stream.PutUnsafe(c);
  94. }
  95. //! Implement specialized version of PutN() with memset() for better
  96. //! performance.
  97. template <>
  98. inline void PutN(GenericStringBuffer<UTF8<>> &stream, char c, size_t n) {
  99. std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
  100. }
  101. RAPIDJSON_NAMESPACE_END
  102. #if defined(__clang__)
  103. RAPIDJSON_DIAG_POP
  104. #endif
  105. #endif // RAPIDJSON_STRINGBUFFER_H_