Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
3.1 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: cyclestr.cpp
  3. //
  4. // Desc: Implements a circular queue that provides space to hold a string
  5. // without repeatedly allocating and deallocating memory. This is
  6. // only for short-term use such as outputting debug message to
  7. // ensure that the same buffer is not used at more than one place
  8. // simultaneously.
  9. //
  10. // Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  11. //-----------------------------------------------------------------------------
  12. #include "common.hpp"
  13. static const int g_cycles = 16;
  14. static const int g_cyclelen = 256;
  15. LPTSTR getcyclestr()
  16. {
  17. static int on = g_cycles;
  18. static TCHAR cycle[g_cycles][g_cyclelen];
  19. on++;
  20. if (on >= g_cycles)
  21. on = 0;
  22. return cycle[on];
  23. }
  24. inline static void cap(LPTSTR c)
  25. {
  26. c[g_cyclelen - 1] = 0;
  27. }
  28. #define SAFESTR_noconv \
  29. if (str) \
  30. return str; \
  31. else \
  32. return _T("NULL");
  33. #define SAFESTR_conv \
  34. LPTSTR c = getcyclestr(); \
  35. CopyStr(c, str, g_cyclelen); \
  36. cap(c); \
  37. return SAFESTR(c);
  38. LPCTSTR SAFESTR(LPCWSTR str)
  39. {
  40. #ifdef UNICODE
  41. SAFESTR_noconv
  42. #else
  43. SAFESTR_conv
  44. #endif
  45. }
  46. LPCTSTR SAFESTR(LPCSTR str)
  47. {
  48. #ifdef UNICODE
  49. SAFESTR_conv
  50. #else
  51. SAFESTR_noconv
  52. #endif
  53. }
  54. #define QSAFESTR_doit(tf) \
  55. if (!str) \
  56. return _T("NULL"); \
  57. \
  58. LPTSTR c = getcyclestr(); \
  59. _sntprintf(c, g_cyclelen, _T("\"") tf _T("\""), str); \
  60. cap(c); \
  61. return c;
  62. LPCTSTR QSAFESTR(LPCWSTR str)
  63. {
  64. QSAFESTR_doit(_tfWSTR)
  65. }
  66. LPCTSTR QSAFESTR(LPCSTR str)
  67. {
  68. QSAFESTR_doit(_tfSTR)
  69. }
  70. LPCTSTR BOOLSTR(BOOL b)
  71. {
  72. return b ? _T("TRUE"): _T("FALSE");
  73. }
  74. LPCTSTR RECTSTR(RECT &rect)
  75. {
  76. LPTSTR c = getcyclestr();
  77. _sntprintf(c, g_cyclelen, _T("{%d,%d,%d,%d}"),
  78. rect.left,
  79. rect.top,
  80. rect.right,
  81. rect.bottom);
  82. cap(c);
  83. return c;
  84. }
  85. LPCTSTR RECTDIMSTR(RECT &rect)
  86. {
  87. LPTSTR c = getcyclestr();
  88. _sntprintf(c, g_cyclelen, _T("{%dx%d}"),
  89. rect.right - rect.left,
  90. rect.bottom - rect.top);
  91. cap(c);
  92. return c;
  93. }
  94. LPCTSTR POINTSTR(POINT &point)
  95. {
  96. LPTSTR c = getcyclestr();
  97. _sntprintf(c, g_cyclelen, _T("{%d,%d}"),
  98. point.x,
  99. point.y);
  100. cap(c);
  101. return c;
  102. }
  103. LPCTSTR GUIDSTR(const GUID &guid)
  104. {
  105. LPTSTR c = getcyclestr();
  106. wsprintf(c, _T("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  107. guid.Data1, guid.Data2, guid.Data3,
  108. guid.Data4[0], guid.Data4[1],
  109. guid.Data4[2], guid.Data4[3],
  110. guid.Data4[4], guid.Data4[5],
  111. guid.Data4[6], guid.Data4[7]);
  112. cap(c);
  113. return c;
  114. }
  115. template<class T>
  116. static LPCTSTR _superstr(const T *str)
  117. {
  118. static LPCTSTR
  119. prefix = _T("(\""),
  120. midfix = _T("\",\""),
  121. suffix = _T("\")");
  122. LPTSTR c = getcyclestr(), c2 = getcyclestr();
  123. c[0] = 0;
  124. for (int i = 0, n = CountSubStrings(str); i < n; i++)
  125. {
  126. if (!i)
  127. _tcsncat(c, prefix, g_cyclelen);
  128. else
  129. _tcsncat(c, midfix, g_cyclelen);
  130. CopyStr(c2, GetSubString(str, i), g_cyclelen);
  131. cap(c2);
  132. _tcsncat(c, c2, g_cyclelen);
  133. cap(c);
  134. if (i == n - 1)
  135. _tcsncat(c, suffix, g_cyclelen);
  136. }
  137. cap(c);
  138. return c;
  139. }
  140. LPCTSTR SUPERSTR(LPCWSTR str) {return _superstr(str);}
  141. LPCTSTR SUPERSTR(LPCSTR str) {return _superstr(str);}