stringbuffer.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. All rights reserved.
  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 "rapidjson.h"
  17. #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
  18. #include <utility> // std::move
  19. #endif
  20. #include "internal/stack.h"
  21. RAPIDJSON_NAMESPACE_BEGIN
  22. //! Represents an in-memory output stream.
  23. /*!
  24. \tparam Encoding Encoding of the stream.
  25. \tparam Allocator type for allocating memory buffer.
  26. \note implements Stream concept
  27. */
  28. template <typename Encoding, typename Allocator = CrtAllocator>
  29. class GenericStringBuffer {
  30. public:
  31. typedef typename Encoding::Ch Ch;
  32. GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
  33. #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
  34. GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
  35. GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
  36. if (&rhs != this)
  37. stack_ = std::move(rhs.stack_);
  38. return *this;
  39. }
  40. #endif
  41. void Put(Ch c) { *stack_.template Push<Ch>() = c; }
  42. void Flush() {}
  43. void Clear() { stack_.Clear(); }
  44. void ShrinkToFit() {
  45. // Push and pop a null terminator. This is safe.
  46. *stack_.template Push<Ch>() = '\0';
  47. stack_.ShrinkToFit();
  48. stack_.template Pop<Ch>(1);
  49. }
  50. Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
  51. void Pop(size_t count) { stack_.template Pop<Ch>(count); }
  52. const Ch* GetString() const {
  53. // Push and pop a null terminator. This is safe.
  54. *stack_.template Push<Ch>() = '\0';
  55. stack_.template Pop<Ch>(1);
  56. return stack_.template Bottom<Ch>();
  57. }
  58. size_t GetSize() const { return stack_.GetSize(); }
  59. static const size_t kDefaultCapacity = 256;
  60. mutable internal::Stack<Allocator> stack_;
  61. private:
  62. // Prohibit copy constructor & assignment operator.
  63. GenericStringBuffer(const GenericStringBuffer&);
  64. GenericStringBuffer& operator=(const GenericStringBuffer&);
  65. };
  66. //! String buffer with UTF8 encoding
  67. typedef GenericStringBuffer<UTF8<> > StringBuffer;
  68. //! Implement specialized version of PutN() with memset() for better performance.
  69. template<>
  70. inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
  71. std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
  72. }
  73. RAPIDJSON_NAMESPACE_END
  74. #endif // RAPIDJSON_STRINGBUFFER_H_