stringbuffer.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Tencent is pleased to support the open source community by making RapidJSON available.
  2. //
  3. // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
  4. //
  5. // Licensed under the MIT License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://opensource.org/licenses/MIT
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #ifndef RAPIDJSON_STRINGBUFFER_H_
  15. #define RAPIDJSON_STRINGBUFFER_H_
  16. #include "stream.h"
  17. #include "internal/stack.h"
  18. #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
  19. #include <utility> // std::move
  20. #endif
  21. #include "internal/stack.h"
  22. #if defined(__clang__)
  23. RAPIDJSON_DIAG_PUSH
  24. RAPIDJSON_DIAG_OFF(c++98-compat)
  25. #endif
  26. RAPIDJSON_NAMESPACE_BEGIN
  27. //! Represents an in-memory output stream.
  28. /*!
  29. \tparam Encoding Encoding of the stream.
  30. \tparam Allocator type for allocating memory buffer.
  31. \note implements Stream concept
  32. */
  33. template <typename Encoding, typename Allocator = CrtAllocator>
  34. class GenericStringBuffer {
  35. public:
  36. typedef typename Encoding::Ch Ch;
  37. GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
  38. #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
  39. GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
  40. GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
  41. if (&rhs != this)
  42. stack_ = std::move(rhs.stack_);
  43. return *this;
  44. }
  45. #endif
  46. void Put(Ch c) {
  47. *stack_.template Push<Ch>() = c;
  48. }
  49. void PutUnsafe(Ch c) {
  50. *stack_.template PushUnsafe<Ch>() = c;
  51. }
  52. void Flush() {}
  53. void Clear() { stack_.Clear(); }
  54. void ShrinkToFit() {
  55. // Push and pop a null terminator. This is safe.
  56. *stack_.template Push<Ch>() = '\0';
  57. stack_.ShrinkToFit();
  58. stack_.template Pop<Ch>(1);
  59. }
  60. void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
  61. Ch* Push(size_t count) {
  62. return stack_.template Push<Ch>(count);
  63. }
  64. Ch* PushUnsafe(size_t count) {
  65. return stack_.template PushUnsafe<Ch>(count);
  66. }
  67. void Pop(size_t count) { stack_.template Pop<Ch>(count); }
  68. const Ch* GetString() const {
  69. // Push and pop a null terminator. This is safe.
  70. *stack_.template Push<Ch>() = '\0';
  71. stack_.template Pop<Ch>(1);
  72. return stack_.template Bottom<Ch>();
  73. }
  74. //! Get the size of string in bytes in the string buffer.
  75. size_t GetSize() const { return stack_.GetSize(); }
  76. //! Get the length of string in Ch in the string buffer.
  77. size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }
  78. static const size_t kDefaultCapacity = 256;
  79. mutable internal::Stack<Allocator> stack_;
  80. private:
  81. // Prohibit copy constructor & assignment operator.
  82. GenericStringBuffer(const GenericStringBuffer&);
  83. GenericStringBuffer& operator=(const GenericStringBuffer&);
  84. };
  85. //! String buffer with UTF8 encoding
  86. typedef GenericStringBuffer<UTF8<> > StringBuffer;
  87. template<typename Encoding, typename Allocator>
  88. inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {
  89. stream.Reserve(count);
  90. }
  91. template<typename Encoding, typename Allocator>
  92. inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {
  93. stream.PutUnsafe(c);
  94. }
  95. //! Implement specialized version of PutN() with memset() for better performance.
  96. template<>
  97. inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
  98. std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
  99. }
  100. RAPIDJSON_NAMESPACE_END
  101. #if defined(__clang__)
  102. RAPIDJSON_DIAG_POP
  103. #endif
  104. #endif // RAPIDJSON_STRINGBUFFER_H_