DString.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /***************************************************************************
  2. * E-Com Technology Ltd.
  3. *
  4. * ECOMPACS DICOM Network Transport Libraries * Version 0.1 Beta
  5. ***************************************************************************/
  6. #ifndef _DICOM_DSTRING_
  7. #define _DICOM_DSTRING_
  8. class InBuffer;
  9. class OutBuffer;
  10. #ifndef _OLEAUTO_H_
  11. typedef LPWSTR BSTR;// must (semantically) match typedef in oleauto.h
  12. #endif
  13. struct DStringData
  14. {
  15. long nRefs; // reference count
  16. int nDataLength; // length of data (including terminator)
  17. int nAllocLength; // length of allocation
  18. // char data[nAllocLength]
  19. char * data () // char* to managed data
  20. { return (char*) (this+1); }
  21. };
  22. class DICOM_API DString
  23. {
  24. public:
  25. // Constructors
  26. // constructs empty DString
  27. DString ();
  28. // copy constructor
  29. DString (const DString& stringSrc);
  30. // from a single character
  31. DString (char ch, int nRepeat);
  32. // from an ANSI string (converts to char)
  33. DString (const char * lpsz);
  34. // subset of characters from an ANSI string (converts to char)
  35. DString (const char * lpch, int nLength);
  36. // from unsigned characters
  37. DString (const unsigned char * lpsz) { Init(); *this = (const char *) lpsz; }
  38. // from digital
  39. explicit DString (const int i);
  40. explicit DString (const long i);
  41. explicit DString (const unsigned int u);
  42. explicit DString (const unsigned long u);
  43. explicit DString (const double d);
  44. // construct from digital, using the special format, such as DString (12, "0x%04x") --> "0x000c"
  45. DString (const int i, const char * szFormat);
  46. DString (const long i, const char * szFormat);
  47. DString (const unsigned int ui, const char * szFormat);
  48. DString (const unsigned long ul, const char * szFormat);
  49. DString (const double d, const char * szFormat);
  50. // construct from many of const char *, nbArg is the number of arg,
  51. // if nbArgs is 0, the last arg must be NULL.
  52. // such DString a (3, "a", "bb", "ccc") -> "abbccc";
  53. // or DString a (0, "a", "bb", "ccc", NULL) -> "abbccc";
  54. // construct it from 2 char * to void confuse with other constructors
  55. DString (int nbArgs, const char * lpszFirst, const char * lpszSecond, ...);
  56. DString (const BSTR bstr);
  57. // Attributes & Operations
  58. // get data length
  59. int GetLength () const { return GetData ()->nDataLength; }
  60. // TRUE if zero length
  61. BOOL IsEmpty () const { return (GetData ()->nDataLength == 0); }
  62. // clear contents to empty
  63. void Empty ();
  64. // return single character at zero-based index
  65. char GetAt (int nIndex) const
  66. {
  67. // ASSERT(nIndex >= 0);
  68. // ASSERT(nIndex < GetData()->nDataLength);
  69. return m_pchData[nIndex];
  70. }
  71. // return single character at zero-based index
  72. char operator [] (int nIndex) const { return GetAt (nIndex); }
  73. // set a single character at zero-based index
  74. void SetAt (int nIndex, char ch);
  75. // return pointer to const string
  76. operator const char * () const { return m_pchData; }
  77. const char * constBuffer (void) const { return m_pchData; }
  78. // Number of ch
  79. int Count (char ch) const;
  80. // Number of lpszSub
  81. int Count (const char * lpszSub) const;
  82. // overloaded assignment
  83. // ref-counted copy from another DString
  84. DString & operator = (const DString & stringSrc);
  85. // set string content to single character
  86. DString & operator = (char ch);
  87. // copy string content from ANSI string (converts to char)
  88. DString & operator = (const char * lpsz);
  89. // copy string content from unsigned chars
  90. DString & operator = (const unsigned char * lpsz) { *this = (const char *) lpsz; return *this; }
  91. // copy string content from BSTR
  92. DString & operator = (const BSTR bstr);
  93. // string concatenation
  94. // concatenate from another DString
  95. DString & Append (const DString & string);
  96. // concatenate a single character
  97. DString & Append (char ch);
  98. // concatenate a UNICODE character after converting it to char
  99. DString & Append (const char * lpsz);
  100. // concatenate from another DString
  101. DString & operator += (const DString & string)
  102. {
  103. return Append (string);
  104. }
  105. // concatenate a single character
  106. DString & operator += (char ch)
  107. {
  108. return Append (ch);
  109. }
  110. // concatenate a UNICODE character after converting it to char
  111. DString & operator += (const char * lpsz)
  112. {
  113. return Append (lpsz);
  114. }
  115. DICOM_API friend DString operator + (const DString & string1, const DString & string2);
  116. DICOM_API friend DString operator + (const DString & string, char ch);
  117. DICOM_API friend DString operator + (char ch, const DString & string);
  118. DICOM_API friend DString operator + (const DString & string, const char * lpsz);
  119. DICOM_API friend DString operator + (const char * lpsz, const DString & string);
  120. // string comparison
  121. // straight character comparison
  122. int Compare (const char * lpsz) const;
  123. // compare ignoring case
  124. int CompareNoCase (const char * lpsz) const;
  125. // NLS aware comparison, case sensitive
  126. int Collate (const char * lpsz) const;
  127. // NLS aware comparison, case insensitive
  128. int CollateNoCase (const char * lpsz) const;
  129. // Returns the similarity between 2 strings
  130. float Similar (const char * lpsz) const;
  131. float Similar (const DString & str) const;
  132. // simple sub-string extraction
  133. // return nCount characters starting at zero-based nFirst
  134. DString Mid (int nFirst, int nCount) const;
  135. // return all characters starting at zero-based nFirst
  136. DString Mid (int nFirst) const;
  137. // return first nCount characters in string
  138. DString Left (int nCount) const;
  139. // return nCount characters from end of string
  140. DString Right (int nCount) const;
  141. // characters from beginning that are also in passed string
  142. DString SpanIncluding (const char * lpszCharSet) const;
  143. // characters from beginning that are not also in passed string
  144. DString SpanExcluding (const char * lpszCharSet) const;
  145. // upper/lower/reverse conversion
  146. // NLS aware conversion to uppercase
  147. void MakeUpper ();
  148. // NLS aware conversion to lowercase
  149. void MakeLower ();
  150. // reverse string right-to-left
  151. void MakeReverse ();
  152. // trimming whitespace (either side)
  153. // remove whitespace starting from right edge
  154. void TrimRight ();
  155. // remove whitespace starting from left side
  156. void TrimLeft ();
  157. // remove continuous occurrences of chTarget starting from right
  158. void TrimRight (char chTarget);
  159. // remove continuous occcurrences of characters in passed string,
  160. // starting from right
  161. void TrimRight (const char * lpszTargets);
  162. // remove continuous occurrences of chTarget starting from left
  163. void TrimLeft (char chTarget);
  164. // remove continuous occcurrences of characters in
  165. // passed string, starting from left
  166. void TrimLeft (const char * lpszTargets);
  167. // trimming anything (either side)
  168. DString Trim () const { DString copy = *this; copy.TrimRight (); copy.TrimLeft (); return copy; }
  169. // advanced manipulation
  170. // replace occurrences of chOld with chNew
  171. int Replace (char chOld, char chNew);
  172. // replace occurrences of substring lpszOld with lpszNew;
  173. // empty lpszNew removes instances of lpszOld
  174. int Replace (const char * lpszOld, const char * lpszNew);
  175. // remove occurrences of lpszSub, just same as Replace (lpszSub, NULL);
  176. int Remove (const char * lpszSub);
  177. // remove occurrences of chRemove
  178. int Remove (char chRemove);
  179. // remove space character
  180. int RemoveSpace ();
  181. // remove punctuation character
  182. int RemovePunctuation ();
  183. // remove control character
  184. int RemoveControl ();
  185. // remove occurrences of lpszSub, compare no case
  186. int NCRemove (const char * lpszSub);
  187. // remove occurrences of chRemove, compare no case
  188. int NCRemove (char chRemove);
  189. // replace tabs to space;
  190. int ReplaceTabs (int abstand);
  191. // insert character at zero-based index; concatenates
  192. // if index is past end of string
  193. int Insert (int nIndex, char ch);
  194. // insert substring at zero-based index; concatenates
  195. // if index is past end of string
  196. int Insert (int nIndex, const char * pstr);
  197. // delete nCount characters starting at zero-based index
  198. int Delete (int nIndex, int nCount = 1);
  199. // insert character n times
  200. void Repeat (char ch, int n);
  201. // insert string n times;
  202. void Repeat (const char * lpszStr, int n);
  203. // searching
  204. // find character starting at left, -1 if not found
  205. int Find (char ch) const;
  206. // find character starting at right
  207. int ReverseFind (char ch) const;
  208. // find character starting at zero-based index and going right
  209. int Find (char ch, int nStart) const;
  210. // find first instance of any character in passed string
  211. int FindOneOf (const char * lpszCharSet) const;
  212. // find first instance of substring
  213. int Find (const char * lpszSub) const;
  214. // find first instance of substring starting at zero-based index
  215. int Find (const char * lpszSub, int nStart) const;
  216. int NCFind (char ch) const;
  217. int NCFind (const char * lpszSub) const;
  218. // simple formatting
  219. protected:
  220. // make a guess at the maximum length of the resulting string
  221. static int __cdecl GetFormattedLength (const char * pszFormat, va_list argList);
  222. static int __cdecl VFormat (char * lpzBuffer, const char * pszFormat, va_list argList);
  223. public:
  224. // printf-like formatting using passed string
  225. void Format (const char * lpszFormat, ...);
  226. // printf-like formatting using referenced string resource
  227. void FormatV (const char * lpszFormat, va_list argList);
  228. // append with the formatted string
  229. void AppendFormat (const char * lpszFormat, ...);
  230. void AppendFormatV (const char * lpszFormat, va_list argList);
  231. void FormatMessage (unsigned long errcode, const char * fmt, ...);
  232. // ANSI <-> OEM support (convert string in place)
  233. // convert string from ANSI to OEM in-place
  234. void AnsiToOem ();
  235. // convert string from OEM to ANSI in-place
  236. void OemToAnsi ();
  237. // Access to string implementation buffer as "C" character array
  238. // get pointer to modifiable buffer at least as long as nMinBufLength
  239. char * GetBuffer (int nMinBufLength);
  240. // release buffer, setting length to nNewLength (or to first nul if -1)
  241. void ReleaseBuffer (int nNewLength = -1);
  242. // get pointer to modifiable buffer exactly as long as nNewLength
  243. char * GetBufferSetLength (int nNewLength);
  244. //==============================================================================
  245. // Functions for Element-Strings
  246. //==============================================================================
  247. DString Elements (int start, int stop, char sep) const;
  248. DString Element (int i, char sep) const;
  249. int IndexOfElement (const char * lpszSuch, char sep) const;
  250. int IndexOfElement (double such, char sep) const;
  251. int IndexOfElement (int such, char sep) const;
  252. int IndexOfElement (char such, char sep) const;
  253. int IndexOfElement (bool such, char sep) const;
  254. // release memory allocated to but unused by string
  255. void FreeExtra ();
  256. // Use LockBuffer/UnlockBuffer to turn refcounting off
  257. // turn refcounting back on
  258. char * LockBuffer ();
  259. // turn refcounting off
  260. void UnlockBuffer ();
  261. // input and output
  262. friend InBuffer & operator >> (InBuffer & ib, DString& string);
  263. friend OutBuffer & operator << (OutBuffer & ob, const DString& string);
  264. // Implementation
  265. public:
  266. ~DString ();
  267. int GetAllocLength () const { return GetData ()->nAllocLength; }
  268. // The following code is stealed from CStringEx
  269. public:
  270. DString operator -- ()
  271. {
  272. *this = Left (GetLength () - 1);
  273. return *this;
  274. }
  275. DString operator -- (int)
  276. {
  277. DString copy (*this);
  278. *this = Left (GetLength () - 1);
  279. return copy;
  280. }
  281. double Double () const { return atof (m_pchData); }
  282. int Int () const { int i = atoi (m_pchData); if (i) return i; return strtol (m_pchData, NULL, 16); }
  283. long Long () const { long l = atol (m_pchData); if (l) return l; return strtol (m_pchData, NULL, 16); }
  284. char Char () const { return m_pchData[0]; }
  285. bool Bool () const;
  286. // 判断整个字符串是否是某一类字符组成
  287. bool IsDigit () const;
  288. bool IsAlNum () const;
  289. bool IsAlpha () const;
  290. bool IsUpper () const;
  291. bool IsLower () const;
  292. bool IsSpace () const;
  293. // 判断某个字符是否是某一类字符组成
  294. bool IsDigit (int nPos) const;
  295. bool IsAlNum (int nPos) const;
  296. bool IsAlpha (int nPos) const;
  297. bool IsUpper (int nPos) const;
  298. bool IsLower (int nPos) const;
  299. bool IsSpace (int nPos) const;
  300. // 先把字符串转换成数字,再按照参数中的格式来格式化这个字符串
  301. DString DigitFormat (const char * lpszFormat);
  302. static DString Concat (const char * lpszFirst, ...);
  303. static DString Concat (int nbArgs, const char * lpszFirst, ...);
  304. public:
  305. bool ToCharacterSet (UINT CodePage);
  306. bool FromCharacterSet (UINT CodePage);
  307. bool ToUnicode ();
  308. bool FromUnicode ();
  309. BSTR AllocSysString () const;
  310. BSTR SetSysString (BSTR* pbstr) const;
  311. // End of stealed code
  312. protected:
  313. char * m_pchData; // pointer to ref counted string data
  314. // implementation helpers
  315. DStringData* DString::GetData() const
  316. {
  317. return ((DStringData*)m_pchData)-1;
  318. }
  319. void Init ();
  320. void AllocCopy (DString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
  321. void AllocBuffer (int nLen);
  322. void AssignCopy (int nSrcLen, const char * lpszSrcData);
  323. void ConcatCopy (int nSrc1Len, const char * lpszSrc1Data, int nSrc2Len, const char * lpszSrc2Data);
  324. void ConcatInPlace (int nSrcLen, const char * lpszSrcData);
  325. void CopyBeforeWrite ();
  326. void AllocBeforeWrite (int nLen);
  327. void Release ();
  328. static void Release (DStringData * pData);
  329. static void FreeData (DStringData * pData);
  330. static BSTR __cdecl AllocSysString (const char * pchData, int nDataLength) throw();
  331. static BOOL __cdecl ReAllocSysString (const char * pchData, BSTR * pbstr, int nDataLength) throw();
  332. //-----------------------------------------------------------------------------
  333. // Token类用来对字符串进行标识符切分
  334. //-----------------------------------------------------------------------------
  335. public:
  336. class DICOM_API Token
  337. {
  338. public:
  339. Token (const DString & str, bool bSkipPunctuation = false) :
  340. m_Str (str),
  341. m_bSkipPunctuation (bSkipPunctuation)
  342. {
  343. // 在Restart之前先初始化这个变量,因为Restart之后需要立即调用Next,
  344. // 而Next函数需要这个变量
  345. Restart ();
  346. }
  347. public:
  348. operator bool () const { return m_bContinue; };
  349. operator DString () const { return Current (); };
  350. public:
  351. // 定位到下一个标识符
  352. bool Next (void);
  353. // 定位到下一个标识符,但是以出作为分割符
  354. bool Next (char sep);
  355. // 定位到行尾,Current返回直到行尾的所有字符,但是不包括行尾的回车或换行
  356. bool NextLine (void);
  357. DString Current (void) const; // 获得当前标识符,或者当前行
  358. bool IsValid () const { return (m_nL <= m_nR); };
  359. void Clear (void)
  360. {
  361. m_nL = 0;
  362. m_nR = -1;
  363. m_nNext = 0;
  364. m_bContinue = true;
  365. m_nStrLength = 0;
  366. }
  367. void Restart (void) // 重新开始
  368. {
  369. m_szDoc = m_Str;
  370. Clear ();
  371. m_nStrLength = strlen (m_szDoc);
  372. Next ();
  373. }
  374. bool SkipPunctuation (bool bSkipPunctuation)
  375. {
  376. bool tmp = m_bSkipPunctuation;
  377. m_bSkipPunctuation =bSkipPunctuation;
  378. return tmp;
  379. }
  380. void operator ++ () // ++Token; prevfix
  381. {
  382. Next ();
  383. }
  384. void operator ++ (int) // Token++; postfix
  385. {
  386. Next ();
  387. }
  388. DString operator () (void) const
  389. {
  390. return Current ();
  391. }
  392. protected:
  393. int FindWhitespace (int nChar) const; // 从nChar开始,定位到下一个非空字符,并返回这个位置的索引,如果找不到,返回-1
  394. int FindChar (int nChar, char ch) const; // 从nChar开始,在字符串中寻找与ch相同的下一个ch,并返回这个位置的索引,如果找不到,返回-1
  395. protected:
  396. const DString & m_Str;
  397. const char * m_szDoc;
  398. int m_nL; // 当前标识符的左边界
  399. int m_nR; // 当前标识符的右边界
  400. int m_nNext; // 下一个标识符的初始位置
  401. bool m_bContinue; // 可用继续迭代吗?
  402. int m_nStrLength; // 字符串长度;
  403. bool m_bSkipPunctuation; // Next()时跳过标点符号,即Current()不会返回遇到的标点符号
  404. };
  405. //-----------------------------------------------------------------------------
  406. // DFileName类用来对Windows的文件名进行切分和组合
  407. //-----------------------------------------------------------------------------
  408. class DICOM_API DFileName
  409. {
  410. public:
  411. DFileName (const char * FileName) { Init (FileName); }
  412. public:
  413. const char * FullFileName () const // 获得全文件名
  414. {
  415. return m_szFullFileName;
  416. }
  417. const char * FileName () const // 获得文件名
  418. {
  419. return m_szFileName;
  420. }
  421. const char * FileExt () const // 获得扩展名
  422. {
  423. return m_ext;
  424. }
  425. const char * Drive () const // 获得驱动器名
  426. {
  427. return m_drive;
  428. }
  429. const char * FilePath () const; // 获得全路径名
  430. BOOL IsFile (const char * FileName) const; // 判断是否是某个文件,FileName必须是文件名,不能含有路径
  431. void SetPath (const char * Path); // 将路径设置为Path
  432. protected:
  433. void Init (const char * FileName);
  434. protected:
  435. char m_szFileName [_MAX_PATH + _MAX_PATH];
  436. char m_szFullFileName [_MAX_PATH + _MAX_PATH];
  437. mutable char m_szFilePath [_MAX_PATH + _MAX_PATH];
  438. char m_drive [_MAX_PATH];
  439. char m_path [_MAX_PATH];
  440. char m_filename [_MAX_PATH];
  441. char m_ext [_MAX_PATH];
  442. };
  443. };
  444. // Compare helpers
  445. DICOM_API inline bool __stdcall operator == (const DString& s1, const DString& s2) { return s1.Compare (s2) == 0; }
  446. DICOM_API inline bool __stdcall operator == (const DString& s1, const char * s2) { return s1.Compare (s2) == 0; }
  447. DICOM_API inline bool __stdcall operator == (const char * s1 , const DString& s2) { return s2.Compare (s1) == 0; }
  448. DICOM_API inline bool __stdcall operator != (const DString& s1, const DString& s2) { return s1.Compare (s2) != 0; }
  449. DICOM_API inline bool __stdcall operator != (const DString& s1, const char * s2) { return s1.Compare (s2) != 0; }
  450. DICOM_API inline bool __stdcall operator != (const char * s1 , const DString& s2) { return s2.Compare (s1) != 0; }
  451. DICOM_API inline bool __stdcall operator < (const DString& s1, const DString& s2) { return s1.Compare (s2) < 0; }
  452. DICOM_API inline bool __stdcall operator < (const DString& s1, const char * s2) { return s1.Compare (s2) < 0; }
  453. DICOM_API inline bool __stdcall operator < (const char * s1 , const DString& s2) { return s2.Compare (s1) > 0; }
  454. DICOM_API inline bool __stdcall operator > (const DString& s1, const DString& s2) { return s1.Compare (s2) > 0; }
  455. DICOM_API inline bool __stdcall operator > (const DString& s1, const char * s2) { return s1.Compare (s2) > 0; }
  456. DICOM_API inline bool __stdcall operator > (const char * s1 , const DString& s2) { return s2.Compare (s1) < 0; }
  457. DICOM_API inline bool __stdcall operator <= (const DString& s1, const DString& s2) { return s1.Compare (s2) <= 0; }
  458. DICOM_API inline bool __stdcall operator <= (const DString& s1, const char * s2) { return s1.Compare (s2) <= 0; }
  459. DICOM_API inline bool __stdcall operator <= (const char * s1 , const DString& s2) { return s2.Compare (s1) >= 0; }
  460. DICOM_API inline bool __stdcall operator >= (const DString& s1, const DString& s2) { return s1.Compare (s2) >= 0; }
  461. DICOM_API inline bool __stdcall operator >= (const DString& s1, const char * s2) { return s1.Compare (s2) >= 0; }
  462. DICOM_API inline bool __stdcall operator >= (const char * s1 , const DString& s2) { return s2.Compare (s1) <= 0; }
  463. #endif