fork download
  1.  
  2. #ifndef _WSTRING_BUILDER_9bf1541fdf7efd41b7b39543fd870ac4_
  3. #define _WSTRING_BUILDER_9bf1541fdf7efd41b7b39543fd870ac4_
  4.  
  5. #include <memory.h>
  6. #include "WString.h"
  7.  
  8. // 스트링의 m_ptr이 불변임을 확신하는 경우
  9. // capacity보다 높은 자원에 한해서
  10. // 해당 포인터를 그대로 불러와 복사에 낭비되는 자원을 회수합니다.
  11. //#define STRING_BUILDER_COPY_NATIVE
  12.  
  13. namespace Utility {
  14.  
  15. using namespace Inherit;
  16.  
  17. //
  18. // 길이에 상관없이 긴 일련의 문자열 집합을 매우 빠르게 생성하는 알고리즘입니다.
  19. //
  20. class WStringBuilder
  21. {
  22. size_t capacity = 1024;
  23. size_t m_offset;
  24. size_t m_length;
  25. bool m_top;
  26. bool m_nodispose;
  27. wchar_t *m_ptr;
  28. WStringBuilder *m_prev;
  29.  
  30. // 복사 생성자
  31. WStringBuilder(WStringBuilder& th)
  32. {
  33. m_offset = th.m_offset;
  34. m_length = th.m_length;
  35. m_ptr = th.m_ptr;
  36. m_prev = th.m_prev;
  37. m_nodispose = th.m_nodispose;
  38. }
  39.  
  40. public:
  41.  
  42. WStringBuilder()
  43. : m_offset(0)
  44. , m_length(0)
  45. , m_ptr(nullptr)
  46. , m_prev(nullptr)
  47. , m_top(false)
  48. , m_nodispose(false)
  49. {
  50. }
  51.  
  52. WStringBuilder(size_t capacity)
  53. : WStringBuilder()
  54. {
  55. this->capacity = capacity;
  56. }
  57.  
  58. WStringBuilder(WString& refer)
  59. : WStringBuilder()
  60. {
  61. Append(refer);
  62. }
  63.  
  64. WStringBuilder(WString& refer, size_t capacity)
  65. : WStringBuilder(capacity)
  66. {
  67. Append(refer);
  68. }
  69.  
  70. ~WStringBuilder()
  71. {
  72. // 사용자가 알아서 Dispose를 호출하게함
  73. }
  74.  
  75. void Append(const WString& refer)
  76. {
  77. if (!refer.Empty())
  78. {
  79. if (capacity > refer.Length() + m_length)
  80. {
  81. __Ensure();
  82.  
  83. wmemcpy_s(m_ptr + m_length, refer.Length(), refer.Reference(), refer.Length());
  84.  
  85. m_length += refer.Length();
  86. }
  87. else
  88. {
  89. __Expand();
  90.  
  91. if (capacity <= refer.Length())
  92. {
  93. #ifdef STRING_BUILDER_COPY_NATIVE
  94. m_ptr = (wchar_t *)refer.Reference();
  95. m_nodispose = true;
  96. #else
  97. m_ptr = (wchar_t *)refer.ToArray();
  98. #endif
  99. m_length = refer.Length();
  100. }
  101. else
  102. {
  103. Append(refer);
  104. return;
  105. }
  106.  
  107. __LinkTo();
  108. }
  109. }
  110. }
  111.  
  112. void Append(const wchar_t *str, size_t len)
  113. {
  114. if (len > 0)
  115. {
  116. if (capacity > len + m_length)
  117. {
  118. __Ensure();
  119.  
  120. wmemcpy_s(m_ptr + m_length, len, str, len);
  121.  
  122. m_length += len;
  123. }
  124. else
  125. {
  126. __Expand();
  127.  
  128. m_length = len;
  129. m_ptr = new wchar_t[len];
  130. wmemcpy_s(m_ptr, len, str, len);
  131.  
  132. __LinkTo();
  133. }
  134. }
  135. }
  136.  
  137. void Append(const wchar_t *str)
  138. {
  139. size_t len = wcslen(str);
  140. Append(str, len);
  141. }
  142.  
  143. // 입력되는 스트링이 매우 클 경우를 확신하는 경우
  144. // 해당 포인터를 그래로 불러와 복사에 낭비되는 자원을 회수합니다.
  145. // 많은 __LinkTo 호출은 많은 할당을 필요함으로, 작은 스트링에선
  146. // 적절하지 않습니다.
  147. // 이 함수는 Append와 같이 사용되어선 안됩니다.
  148. /*void AppendVeryLarge(WString& refer)
  149. {
  150. m_ptr = (wchar_t *)refer.Reference();
  151. m_length = refer.Length();
  152. __LinkTo();
  153. }*/
  154.  
  155. size_t Length() const
  156. {
  157. return m_offset;
  158. }
  159.  
  160. WString ToString()
  161. {
  162. size_t len = m_offset + m_length + 1;
  163. wchar_t *newString = new wchar_t[len];
  164.  
  165. WStringBuilder *iter = this;
  166. for ( ; iter != nullptr; iter = iter->m_prev )
  167. {
  168. wmemcpy_s(newString + iter->m_offset, iter->m_length, iter->m_ptr, iter->m_length);
  169. }
  170.  
  171. newString[m_offset + m_length] = 0;
  172.  
  173. StringReferencePutWith with;
  174. return *new WString(newString, m_offset + m_length, with);
  175. }
  176.  
  177. void Dispose()
  178. {
  179. WStringBuilder *iter = this;
  180.  
  181. for ( ; iter != nullptr; iter = iter->m_prev )
  182. {
  183. delete[] iter->m_ptr;
  184. iter->m_ptr = nullptr;
  185. }
  186.  
  187. for ( iter = this; iter->m_prev != nullptr; )
  188. {
  189. WStringBuilder *tmp = iter->m_prev;
  190. iter->m_prev = iter->m_prev->m_prev;
  191. delete tmp;
  192. }
  193.  
  194. }
  195.  
  196. private:
  197.  
  198. void __Ensure()
  199. {
  200. if (m_ptr == nullptr)
  201. {
  202. m_ptr = new wchar_t[capacity];
  203. }
  204. }
  205.  
  206. bool __Expand()
  207. {
  208. if (m_length > 0)
  209. {
  210. __LinkTo();
  211. return true;
  212. }
  213. return false;
  214. }
  215.  
  216. // 포인터로 전 StringBuilder와 링크합니다.
  217. void __LinkTo()
  218. {
  219. m_top = false;
  220. m_prev = new WStringBuilder(*this);
  221. m_offset += m_length;
  222. m_ptr = nullptr;
  223. m_length = 0;
  224. m_top = true;
  225. m_nodispose = false;
  226. }
  227.  
  228. };
  229. }
  230.  
  231. #endif
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:6:21: fatal error: WString.h: No such file or directory
compilation terminated.
stdout
Standard output is empty