string.inl 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #ifndef BX_STRING_H_HEADER_GUARD
  6. # error "Must be included from bx/string.h!"
  7. #endif // BX_STRING_H_HEADER_GUARD
  8. #if BX_CRT_MSVC && !defined(va_copy)
  9. # define va_copy(_a, _b) (_a) = (_b)
  10. #endif // BX_CRT_MSVC && !defined(va_copy)
  11. namespace bx
  12. {
  13. template <typename Ty>
  14. inline void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList)
  15. {
  16. char temp[2048];
  17. char* out = temp;
  18. int32_t len = vsnprintf(out, sizeof(temp), _format, _argList);
  19. if (int32_t(sizeof(temp) ) < len)
  20. {
  21. out = (char*)alloca(len);
  22. len = vsnprintf(out, len, _format, _argList);
  23. }
  24. _out.append(out, out+len);
  25. }
  26. template <typename Ty>
  27. inline void stringPrintf(Ty& _out, const char* _format, ...)
  28. {
  29. va_list argList;
  30. va_start(argList, _format);
  31. stringPrintfVargs(_out, _format, argList);
  32. va_end(argList);
  33. }
  34. template <typename Ty>
  35. inline Ty replaceAll(const Ty& _str, const char* _from, const char* _to)
  36. {
  37. Ty str = _str;
  38. typename Ty::size_type startPos = 0;
  39. const typename Ty::size_type fromLen = strLen(_from);
  40. const typename Ty::size_type toLen = strLen(_to);
  41. while ( (startPos = str.find(_from, startPos) ) != Ty::npos)
  42. {
  43. str.replace(startPos, fromLen, _to);
  44. startPos += toLen;
  45. }
  46. return str;
  47. }
  48. inline StringView::StringView()
  49. {
  50. clear();
  51. }
  52. inline StringView::StringView(const StringView& _rhs, int32_t _start, int32_t _len)
  53. {
  54. set(_rhs, _start, _len);
  55. }
  56. inline StringView& StringView::operator=(const char* _rhs)
  57. {
  58. set(_rhs);
  59. return *this;
  60. }
  61. inline StringView& StringView::operator=(const StringView& _rhs)
  62. {
  63. set(_rhs);
  64. return *this;
  65. }
  66. inline StringView::StringView(char* _ptr)
  67. {
  68. set(_ptr, INT32_MAX);
  69. }
  70. inline StringView::StringView(const char* _ptr)
  71. {
  72. set(_ptr, INT32_MAX);
  73. }
  74. inline StringView::StringView(char* _ptr, int32_t _len)
  75. {
  76. set(_ptr, _len);
  77. }
  78. inline StringView::StringView(const char* _ptr, int32_t _len)
  79. {
  80. set(_ptr, _len);
  81. }
  82. inline StringView::StringView(const char* _ptr, const char* _term)
  83. {
  84. set(_ptr, _term);
  85. }
  86. template<typename Ty>
  87. inline StringView::StringView(const Ty& _container)
  88. {
  89. set(_container);
  90. }
  91. inline void StringView::set(char* _ptr)
  92. {
  93. set(_ptr, INT32_MAX);
  94. }
  95. inline void StringView::set(const char* _ptr)
  96. {
  97. set(_ptr, INT32_MAX);
  98. }
  99. inline void StringView::set(const char* _ptr, int32_t _len)
  100. {
  101. clear();
  102. if (NULL != _ptr)
  103. {
  104. m_len = INT32_MAX == _len ? strLen(_ptr) : _len;
  105. m_ptr = _ptr;
  106. }
  107. }
  108. inline void StringView::set(const char* _ptr, const char* _term)
  109. {
  110. set(_ptr, int32_t(_term-_ptr) );
  111. }
  112. template<typename Ty>
  113. inline void StringView::set(const Ty& _container)
  114. {
  115. set(_container.data(), int32_t(_container.length() ) );
  116. }
  117. inline void StringView::set(const StringView& _str, int32_t _start, int32_t _len)
  118. {
  119. const int32_t start = min(_start, _str.m_len);
  120. const int32_t len = clamp(_str.m_len - start, 0, min(_len, _str.m_len) );
  121. set(_str.m_ptr + start, len);
  122. }
  123. inline void StringView::clear()
  124. {
  125. m_ptr = "";
  126. m_len = 0;
  127. }
  128. inline const char* StringView::getPtr() const
  129. {
  130. return m_ptr;
  131. }
  132. inline const char* StringView::getTerm() const
  133. {
  134. return m_ptr + m_len;
  135. }
  136. inline bool StringView::isEmpty() const
  137. {
  138. return 0 == m_len;
  139. }
  140. inline int32_t StringView::getLength() const
  141. {
  142. return m_len;
  143. }
  144. template<bx::AllocatorI** AllocatorT>
  145. inline StringT<AllocatorT>::StringT()
  146. : StringView()
  147. {
  148. }
  149. template<bx::AllocatorI** AllocatorT>
  150. inline StringT<AllocatorT>::StringT(const StringT<AllocatorT>& _rhs)
  151. : StringView()
  152. {
  153. set(_rhs);
  154. }
  155. template<bx::AllocatorI** AllocatorT>
  156. inline StringT<AllocatorT>& StringT<AllocatorT>::operator=(const StringT<AllocatorT>& _rhs)
  157. {
  158. set(_rhs);
  159. return *this;
  160. }
  161. template<bx::AllocatorI** AllocatorT>
  162. inline StringT<AllocatorT>::StringT(const StringView& _rhs)
  163. {
  164. set(_rhs);
  165. }
  166. template<bx::AllocatorI** AllocatorT>
  167. inline StringT<AllocatorT>::~StringT()
  168. {
  169. clear();
  170. }
  171. template<bx::AllocatorI** AllocatorT>
  172. inline void StringT<AllocatorT>::set(const StringView& _str)
  173. {
  174. clear();
  175. append(_str);
  176. }
  177. template<bx::AllocatorI** AllocatorT>
  178. inline void StringT<AllocatorT>::append(const StringView& _str)
  179. {
  180. if (0 != _str.getLength() )
  181. {
  182. int32_t old = m_len;
  183. int32_t len = m_len + strLen(_str);
  184. char* ptr = (char*)BX_REALLOC(*AllocatorT, 0 != m_len ? const_cast<char*>(m_ptr) : NULL, len+1);
  185. m_len = len;
  186. strCopy(ptr + old, len-old+1, _str);
  187. *const_cast<char**>(&m_ptr) = ptr;
  188. }
  189. }
  190. template<bx::AllocatorI** AllocatorT>
  191. inline void StringT<AllocatorT>::append(const char* _ptr, const char* _term)
  192. {
  193. append(StringView(_ptr, _term) );
  194. }
  195. template<bx::AllocatorI** AllocatorT>
  196. inline void StringT<AllocatorT>::clear()
  197. {
  198. if (0 != m_len)
  199. {
  200. BX_FREE(*AllocatorT, const_cast<char*>(m_ptr) );
  201. StringView::clear();
  202. }
  203. }
  204. template<bx::AllocatorI** AllocatorT>
  205. inline const char* StringT<AllocatorT>::getCPtr() const
  206. {
  207. return getPtr();
  208. }
  209. inline StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len)
  210. {
  211. return StringView(_str, _start, _len);
  212. }
  213. inline LineReader::LineReader(const bx::StringView& _str)
  214. : m_str(_str)
  215. {
  216. reset();
  217. }
  218. inline void LineReader::reset()
  219. {
  220. m_curr = m_str;
  221. m_line = 0;
  222. }
  223. inline StringView LineReader::next()
  224. {
  225. if (m_curr.getPtr() != m_str.getTerm() )
  226. {
  227. ++m_line;
  228. StringView curr(m_curr);
  229. m_curr = bx::strFindNl(m_curr);
  230. StringView line(curr.getPtr(), m_curr.getPtr() );
  231. return strRTrim(line, "\n\r");
  232. }
  233. return m_curr;
  234. }
  235. inline bool LineReader::isDone() const
  236. {
  237. return m_curr.getPtr() == m_str.getTerm();
  238. }
  239. inline uint32_t LineReader::getLine() const
  240. {
  241. return m_line;
  242. }
  243. } // namespace bx