string_vs.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. ////////////////////////////////////////////////////////////////////////////////////////
  2. // RAVEN STANDARD TEMPLATE LIBRARY
  3. // (c) 2002 Activision
  4. //
  5. //
  6. // String
  7. // ------
  8. // Simple wrapper around a char[SIZE] array.
  9. //
  10. //
  11. //
  12. // NOTES:
  13. //
  14. //
  15. //
  16. ////////////////////////////////////////////////////////////////////////////////////////
  17. #if !defined(RATL_STRING_VS_INC)
  18. #define RATL_STRING_VS_INC
  19. ////////////////////////////////////////////////////////////////////////////////////////
  20. // Includes
  21. ////////////////////////////////////////////////////////////////////////////////////////
  22. #if !defined(RATL_COMMON_INC)
  23. #include "ratl_common.h"
  24. #endif
  25. namespace ratl
  26. {
  27. ////////////////////////////////////////////////////////////////////////////////////////
  28. // The String Class
  29. ////////////////////////////////////////////////////////////////////////////////////////
  30. template<int ARG_CAPACITY>
  31. class string_vs : public ratl_base
  32. {
  33. public:
  34. ////////////////////////////////////////////////////////////////////////////////////
  35. // Capacity Enum
  36. ////////////////////////////////////////////////////////////////////////////////////
  37. enum
  38. {
  39. CAPACITY = ARG_CAPACITY,
  40. };
  41. private:
  42. ////////////////////////////////////////////////////////////////////////////////////
  43. // Data
  44. ////////////////////////////////////////////////////////////////////////////////////
  45. #ifdef _DEBUG
  46. char mData[CAPACITY+4];
  47. #else
  48. char mData[CAPACITY];
  49. #endif
  50. void FillTerminator()
  51. {
  52. #ifdef _DEBUG
  53. mData[CAPACITY]='e';
  54. mData[CAPACITY+1]='n';
  55. mData[CAPACITY+2]='d';
  56. mData[CAPACITY+3]=0;
  57. #endif
  58. }
  59. public:
  60. ////////////////////////////////////////////////////////////////////////////////////
  61. // Constructor
  62. ////////////////////////////////////////////////////////////////////////////////////
  63. string_vs()
  64. {
  65. mData[0]=0;
  66. FillTerminator();
  67. }
  68. #ifdef _DEBUG
  69. ~string_vs()
  70. {
  71. //if you hit the below asserts, the end of the string was overwritten
  72. assert(mData[CAPACITY]=='e');
  73. assert(mData[CAPACITY+1]=='n');
  74. assert(mData[CAPACITY+2]=='d');
  75. assert(mData[CAPACITY+3]==0);
  76. }
  77. #endif
  78. ////////////////////////////////////////////////////////////////////////////////////
  79. // Copy Constructor
  80. ////////////////////////////////////////////////////////////////////////////////////
  81. string_vs(const string_vs<CAPACITY> &o)
  82. {
  83. assert(str::len(o.mData)<CAPACITY);
  84. str::ncpy(mData, o.mData, CAPACITY); // Safe String Copy
  85. mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
  86. FillTerminator();
  87. }
  88. ////////////////////////////////////////////////////////////////////////////////////
  89. // Copy Constructor
  90. ////////////////////////////////////////////////////////////////////////////////////
  91. string_vs(const char *s)
  92. {
  93. assert(str::len(s)<CAPACITY);
  94. str::ncpy(mData, s, CAPACITY); // Safe String Copy
  95. mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
  96. FillTerminator();
  97. }
  98. ////////////////////////////////////////////////////////////////////////////////////
  99. //
  100. ////////////////////////////////////////////////////////////////////////////////////
  101. string_vs& operator=(const char *s)
  102. {
  103. assert(str::len(s)<CAPACITY);
  104. str::ncpy(mData, s, CAPACITY); // Safe String Copy
  105. mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
  106. FillTerminator();
  107. return *this;
  108. }
  109. ////////////////////////////////////////////////////////////////////////////////////
  110. // Access To Raw Array
  111. ////////////////////////////////////////////////////////////////////////////////////
  112. char* c_str()
  113. {
  114. return mData;
  115. }
  116. ////////////////////////////////////////////////////////////////////////////////////
  117. // Access To Raw Array
  118. ////////////////////////////////////////////////////////////////////////////////////
  119. const char* c_str() const
  120. {
  121. return mData;
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////////
  124. // Access To Raw Array
  125. ////////////////////////////////////////////////////////////////////////////////////
  126. operator const char *()
  127. {
  128. return mData;
  129. }
  130. ////////////////////////////////////////////////////////////////////////////////////
  131. // Access To Raw Array
  132. ////////////////////////////////////////////////////////////////////////////////////
  133. const char* operator*()
  134. {
  135. return mData;
  136. }
  137. ////////////////////////////////////////////////////////////////////////////////////
  138. // How Many Characters Can This Hold
  139. ////////////////////////////////////////////////////////////////////////////////////
  140. int capacity() const
  141. {
  142. return CAPACITY;
  143. }
  144. ////////////////////////////////////////////////////////////////////////////////////
  145. // Length
  146. ////////////////////////////////////////////////////////////////////////////////////
  147. int length() const
  148. {
  149. assert(str::len(mData)<CAPACITY-1);
  150. return str::len(mData);
  151. }
  152. ////////////////////////////////////////////////////////////////////////////////////
  153. // Character Bracket Operator
  154. ////////////////////////////////////////////////////////////////////////////////////
  155. char operator[](int index)
  156. {
  157. assert(index<CAPACITY);
  158. return mData[index];
  159. }
  160. ////////////////////////////////////////////////////////////////////////////////////
  161. // Equality Operator
  162. ////////////////////////////////////////////////////////////////////////////////////
  163. bool operator==(const string_vs &o) const
  164. {
  165. if (!stricmp(mData,o.mData))
  166. {
  167. return true;
  168. }
  169. return false;
  170. }
  171. ////////////////////////////////////////////////////////////////////////////////////
  172. // InEquality Operator
  173. ////////////////////////////////////////////////////////////////////////////////////
  174. bool operator!=(const string_vs &o) const
  175. {
  176. if (str::icmp(mData,o.mData)!=0)
  177. {
  178. return true;
  179. }
  180. return false;
  181. }
  182. ////////////////////////////////////////////////////////////////////////////////////
  183. // Compare Less Than
  184. ////////////////////////////////////////////////////////////////////////////////////
  185. bool operator<(const string_vs &o) const
  186. {
  187. if (str::icmp(mData,o.mData)<0)
  188. {
  189. return true;
  190. }
  191. return false;
  192. }
  193. ////////////////////////////////////////////////////////////////////////////////////
  194. // Compare Greater Than
  195. ////////////////////////////////////////////////////////////////////////////////////
  196. bool operator>(const string_vs &o) const
  197. {
  198. if (str::icmp(mData,o.mData)>0)
  199. {
  200. return true;
  201. }
  202. return false;
  203. }
  204. ////////////////////////////////////////////////////////////////////////////////////
  205. //
  206. ////////////////////////////////////////////////////////////////////////////////////
  207. void operator+=(const string_vs &o)
  208. {
  209. if ( (str::len(mData)+o.length())<CAPACITY ) // Only If It Is Safe
  210. {
  211. str::cat(mData, o.c_str());
  212. }
  213. else
  214. {
  215. assert(!"string_vs overflow\n");
  216. }
  217. }
  218. ////////////////////////////////////////////////////////////////////////////////////
  219. //
  220. ////////////////////////////////////////////////////////////////////////////////////
  221. void operator+=(const char *s)
  222. {
  223. if ( (str::len(mData)+str::len(s))<CAPACITY ) // Only If It Is Safe
  224. {
  225. str::cat(mData, s);
  226. }
  227. else
  228. {
  229. assert(!"string_vs overflow\n");
  230. }
  231. }
  232. ////////////////////////////////////////////////////////////////////////////////////
  233. // Tokenizer
  234. //
  235. // The string tokenizer class is similar to an iterator in that it essentially
  236. // iterates over all the tokens in the string seperated by a common series of
  237. // delinating sequences. For example: " ,\t\n" would seperate tokens on spaces
  238. // commas, tabs and linefeeds.
  239. //
  240. // Iterating over string tokens is just like normal iteration:
  241. //
  242. // for (string_vs<CAPACITY>::tokenizer it=MyString.begin(" ,\t\n"); it!=MyString.end(); it++)
  243. // {
  244. // const char* token = *it;
  245. // }
  246. //
  247. //
  248. // NOTE: This class is built upon the c library function strtok() which uses a
  249. // static working area, so having multiple tokenizers in multiple threads or just
  250. // plain at the same time is not safe.
  251. //
  252. ////////////////////////////////////////////////////////////////////////////////////
  253. class tokenizer
  254. {
  255. enum
  256. {
  257. TOKEN_GAP_LEN = 15,
  258. };
  259. public:
  260. // Constructors
  261. //--------------
  262. tokenizer() : mLoc(0)
  263. {}
  264. tokenizer(const char* t, const char* gap)
  265. {
  266. strncpy(mGap, gap, TOKEN_GAP_LEN); // Safe String Copy
  267. mGap[TOKEN_GAP_LEN-1] = 0; // Make Sure We Have A Null Terminated Str
  268. char* temp = (char*)t;
  269. mLoc = str::tok(temp, mGap);
  270. }
  271. // Assignment Operator
  272. //---------------------
  273. void operator= (const tokenizer &t)
  274. {
  275. mLoc = t.mLoc;
  276. str::cpy(mGap, t.mGap);
  277. }
  278. // Equality Operators
  279. //--------------------
  280. bool operator==(const tokenizer &t) {return (mLoc==t.mLoc);}
  281. bool operator!=(const tokenizer &t) {return !(operator==(t));}
  282. // DeReference Operator
  283. //----------------------
  284. const char* operator*()
  285. {
  286. assert(mLoc);
  287. return mLoc;
  288. }
  289. // Inc & Dec Operators
  290. //--------------------
  291. void operator++(int)
  292. {
  293. assert(mLoc && mGap[0]);
  294. mLoc = str::tok(NULL, mGap);
  295. }
  296. // Data
  297. //------
  298. private:
  299. char* mLoc;
  300. char mGap[TOKEN_GAP_LEN];
  301. };
  302. ////////////////////////////////////////////////////////////////////////////////////
  303. // Get An Iterator To The First Token Seperated By Gap
  304. ////////////////////////////////////////////////////////////////////////////////////
  305. tokenizer begin(const char* gap)
  306. {
  307. return tokenizer(mData, gap);
  308. }
  309. ////////////////////////////////////////////////////////////////////////////////////
  310. // The Invalid Iterator, Use As A Stop Condition In Your For Loops
  311. ////////////////////////////////////////////////////////////////////////////////////
  312. tokenizer end()
  313. {
  314. return tokenizer();
  315. }
  316. };
  317. }
  318. //fixme get rid of these
  319. typedef ratl::string_vs<256> TString_vs;
  320. typedef ratl::string_vs<128> TUIString_vs;
  321. #endif