cplusStr.cpp
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* cplusStr.cpp - simple string class for C++ demangler */
  2. /* Copyright 1993 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01e,17oct00,sn   backed out __cplusStr_o removal
  8. 01d,22jul99,mrs  Rewrite in C++.
  9. 01d,12may99,jku  removed __cplusStr_o
  10. 01c,03jun93,srh  doc cleanup
  11. 01b,23apr93,srh  implemented new force-link/initialization scheme
  12. 01a,31jan93,srh  written.
  13. */
  14. /*
  15. DESCRIPTION
  16. This module provides a very simple, ring-buffer based string class.
  17. It was written, in the absence of a more general (and more useful)
  18. string class to support the demangler. It values speed over most
  19. everything else. It contains no user-callable routines.
  20. NOMANUAL
  21. */
  22. /* globals */
  23. char __cplusStr_o;
  24. /* includes */
  25. #include "vxWorks.h"
  26. #include "cplusLib.h"
  27. #include "string.h"
  28. /*******************************************************************************
  29. *
  30. * RBStringIterator_T :: RBStringIterator_T - initialize an RBStringIterator
  31. *
  32. * RETURNS:
  33. * nothing
  34. *
  35. * NOMANUAL
  36. */
  37. RBStringIterator_T :: RBStringIterator_T (const RBString_T &anRBString)
  38.     {
  39.     theRBString = &anRBString;
  40.     nc = anRBString.head;
  41.     }
  42. /*******************************************************************************
  43. *
  44. * RBStringIterator_T :: nextChar - advance iterator by one character
  45. *
  46. * RETURNS:
  47. * next character, or EOS if end-of-string
  48. *
  49. * NOMANUAL
  50. */
  51. char RBStringIterator_T :: nextChar ()
  52.     {
  53.     char returnValue = *nc;
  54.     // If nc already points to the terminating EOS, return it (possible
  55.     // for a second time).
  56.     // Otherwise increment nc and see if it is still within bounds.
  57.     // If not, wrap nc around to the beginning of the string and return
  58.     // the first character (of the array).
  59.     // Otherwise, dereference the pointer and return the character.
  60.     if (*nc)
  61. {
  62. nc += 1;
  63. if (nc == &theRBString->data [ sizeof (theRBString->data) ])
  64.     {
  65.     nc = theRBString->data;
  66.     }
  67. }
  68.     
  69.     return returnValue;
  70.     }
  71. /*******************************************************************************
  72. *
  73. * RBString_T :: RBString_T - create a zero-length RBString
  74. *
  75. * RETURNS:
  76. * nothing
  77. *
  78. * NOMANUAL
  79. */
  80. RBString_T :: RBString_T ()
  81.     {
  82.     // String is initially empty. Start head and tail in the middle of
  83.     // the array to minimize wraparound occasions. I do not know if this
  84.     // affects performance one way or the other, but whenever the string
  85.     // is contiguous in memory, i.e. not wrapped, the contents can be
  86.     // more easily viewed when debugging client code.
  87.     // head = tail = data + sizeof (data) / 2;
  88.     
  89.     head = tail = data;
  90.     data [0] = 0;
  91.     nChars = 0;
  92.     }
  93. /******************************************************************************
  94.  *
  95.  * RBString :: clear - reinitialize
  96.  *
  97.  * RETURNS: N/A
  98.  *
  99.  * NOMANUAL
  100.  */
  101. void RBString_T :: clear ()
  102.     {
  103.     head = tail = data;
  104.     data [0] = 0;
  105.     nChars = 0;
  106.     }
  107. /*******************************************************************************
  108. *
  109. * RBString_T :: RBString_T - clone an RBString
  110. *
  111. * RETURNS:
  112. * nothing
  113. *
  114. * NOMANUAL
  115. */
  116. RBString_T :: RBString_T (RBString_T & anRBString)
  117.     {
  118.     nChars = anRBString.nChars;
  119.     memcpy (data, anRBString.data, sizeof (data));
  120.     head = data + (anRBString.head - anRBString.data);
  121.     tail = data + (anRBString.tail - anRBString.data);
  122.     }
  123. /*******************************************************************************
  124. *
  125. * RBString_T :: RBString_T - make an RBString out of a C string
  126. *
  127. * RETURNS:
  128. * nothing
  129. *
  130. * NOMANUAL
  131. */
  132. RBString_T :: RBString_T (const char * aCString)
  133.     {
  134.     // For most strings, which are relatively short, strlen followed
  135.     // by memcpy should be faster than strncpy.
  136.     nChars = min ((sizeof (data) - 1), strlen (aCString));
  137.     memcpy (data, aCString, nChars);
  138.     data [ nChars ] = 0;
  139.     head = data;
  140.     tail = & data [ nChars ];
  141.     }
  142. /*******************************************************************************
  143. *
  144. * RBString_T & RBString_T :: operator =
  145. *
  146. * RETURNS:
  147. * Reference to updated RBString
  148. *
  149. * NOMANUAL
  150. */
  151. RBString_T & RBString_T :: operator = (RBString_T & anRBString)
  152.     {
  153.     if (data != anRBString.data)
  154. {
  155. nChars = anRBString.nChars;
  156. memcpy (data, anRBString.data, sizeof (data));
  157. head = data + (anRBString.head - anRBString.data);
  158. tail = data + (anRBString.tail - anRBString.data);
  159. }
  160.     return *this;
  161.     }
  162. /*******************************************************************************
  163. *
  164. * RBString_T :: operator ==
  165. *
  166. * RETURNS:
  167. * TRUE if operands contain the same characters, otherwise FALSE
  168. *
  169. * NOMANUAL
  170. */
  171. BOOL RBString_T :: operator == (RBString_T & anRBString) const
  172.     {
  173.     if (nChars != anRBString.nChars)
  174. {
  175. return FALSE;
  176. }
  177.     else
  178. {
  179. int i;
  180. RBStringIterator_T s1 (*this);
  181. RBStringIterator_T s2 (anRBString);
  182. for (i = 0; i < nChars; i++)
  183.     {
  184.     if (s1.nextChar () != s2.nextChar ())
  185. {
  186. break;
  187. }
  188.     }
  189. return (i == nChars) ? TRUE : FALSE;
  190. }
  191.     }
  192. /*******************************************************************************
  193. *
  194. * RBString_T :: extractCString - extract demangled internal representation,
  195. *                                copy to C string
  196. *
  197. * RETURNS:
  198. * 0, if demangling failed, otherwise pChar
  199. *
  200. * NOMANUAL
  201. */
  202. char * RBString_T :: extractCString
  203.     (
  204.      char * pChar,  // buffer in which to save
  205.        // extracted string
  206.      int   length  // size of buffer
  207.     )
  208.     {
  209.     RBStringIterator_T si (*this);
  210.     int i;
  211.     int limit;
  212.     char *s;
  213.     
  214.     for (i = 0, s = pChar, limit = min (length - 1, nChars);
  215.  i < limit;
  216.  i++, s++)
  217. {
  218. *s = si.nextChar ();
  219. }
  220.     *s = 0;
  221.     return pChar;
  222.     }
  223. /*******************************************************************************
  224. *
  225. * RBString_T :: operator != 
  226. *
  227. * RETURNS:
  228. * TRUE if operands do not contain the same characters, otherwise FALSE
  229. *
  230. * NOMANUAL
  231. */
  232. inline BOOL RBString_T :: operator != (RBString_T & anRBString ) const
  233.     {
  234.     return ! (*this == anRBString);
  235.     }
  236. /*******************************************************************************
  237. *
  238. * RBString_T :: appendChar - append a character
  239. *
  240. * RETURNS:
  241. * EOS if character cannot be added, otherwise the appended character
  242. *
  243. * NOMANUAL
  244. */
  245. inline char RBString_T :: appendChar (char c)
  246.     {
  247.     if ((nChars + 2) >= sizeof (data))
  248. {
  249. c = 0;
  250. }
  251.     if (c != 0)
  252. {
  253. *tail = c;
  254. tail = (++tail == &data [ sizeof (data) ]) ? data : tail;
  255. *tail = 0;
  256. nChars++;
  257. }
  258.     return c;
  259.     }
  260. /*******************************************************************************
  261. *
  262. * RBString_T :: prependChar - prepend a character
  263. *
  264. * RETURNS:
  265. * EOS if character cannot be added, otherwise the prepended character
  266. *
  267. * NOMANUAL
  268. */
  269. inline char RBString_T :: prependChar (char c)
  270.     {
  271.     if ((nChars + 2) >= sizeof (data))
  272. {
  273. c = 0;
  274. }
  275.     else
  276. {
  277. head = (--head < data)  ?  &data [ sizeof (data) - 1 ] : head;
  278. *head = c;
  279. nChars++;
  280. }
  281.     return c;
  282.     }
  283. /*******************************************************************************
  284. *
  285. * RBString_T :: append  - append contents of an RBString to this RBString
  286. *
  287. * RETURNS:
  288. * Reference to updated RBString
  289. *
  290. * NOMANUAL
  291. */
  292. RBString_T & RBString_T :: append (RBString_T & anRBString)
  293.     {
  294.     RBStringIterator_T sourceString (anRBString);
  295.     char c;
  296.     
  297.     if (anRBString.nChars > 0)
  298. {
  299. while ((c = sourceString.nextChar ()))
  300.     {
  301.     appendChar (c);
  302.     }
  303. }
  304.     return *this;
  305.     }
  306. /*******************************************************************************
  307. *
  308. * RBString_T :: append  - append contents of a C string to this RBString
  309. *
  310. * This function will append up to INT_MAX characters, or through the end of
  311. * the C string. The operation terminates at the earlier of these conditions.
  312. *
  313. * RETURNS:
  314. * Reference to updated RBString
  315. *
  316. * NOMANUAL
  317. */
  318. RBString_T & RBString_T :: append (const char *aCString, int length)
  319.     {
  320.     for ( ; (length > 0) && (*aCString != 0); aCString++, length--)
  321. {
  322. appendChar (*aCString);
  323. }
  324.     return *this;
  325.     }
  326. /*******************************************************************************
  327. *
  328. * RBString_T :: append - append a character to this RBString
  329. *
  330. * RETURNS:
  331. * Reference to updated RBString
  332. *
  333. * NOMANUAL
  334. */
  335. RBString_T & RBString_T :: append (char c)
  336.     {
  337.     appendChar (c);
  338.     return *this;
  339.     }
  340. /*******************************************************************************
  341. *
  342. * RBString_T :: prepend - prepend a character to this RBString
  343. *
  344. * RETURNS:
  345. * Reference to updated RBString
  346. *
  347. * NOMANUAL
  348. */
  349. RBString_T & RBString_T :: prepend (char c)
  350.     {
  351.     prependChar (c);
  352.     return *this;
  353.     }
  354. /*******************************************************************************
  355. *
  356. * RBString_T :: prepend - prepend contents of an RBString to this RBString
  357. *
  358. * RETURNS:
  359. * Reference to updated RBString
  360. *
  361. * NOMANUAL
  362. */
  363. RBString_T & RBString_T :: prepend (RBString_T & anRBString)
  364.     {
  365.     RBString_T tmp (anRBString);
  366.     tmp.append (*this);
  367.     *this = tmp;
  368.     return *this;
  369.     }
  370. /*******************************************************************************
  371. *
  372. * RBString_T :: prepend - prepend contents of a C string to this RBString
  373. *
  374. * RETURNS:
  375. * Reference to updated RBString
  376. *
  377. * NOMANUAL
  378. */
  379. RBString_T & RBString_T :: prepend (const char *aCString, int length)
  380.     {
  381.     RBString_T tmp;
  382.     tmp.append (aCString, length);
  383.     tmp.append (*this);
  384.     *this = tmp;
  385.     return *this;
  386.     }