Leaked source code of windows server 2003
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.

296 lines
6.7 KiB

  1. /*****************************************************************/
  2. /** Microsoft Windows for Workgroups **/
  3. /** Copyright (C) Microsoft Corp., 1991-1992 **/
  4. /*****************************************************************/
  5. /*
  6. strcat.cxx
  7. NLS/DBCS-aware string class: strcat method
  8. This file contains the implementation of the strcat method
  9. for the STRING class. It is separate so that clients of STRING which
  10. do not use this operator need not link to it.
  11. FILE HISTORY:
  12. beng 01/18/91 Separated from original monolithic .cxx
  13. beng 02/07/91 Uses lmui.hxx
  14. beng 07/26/91 Replaced min with local inline
  15. */
  16. #include "npcommon.h"
  17. extern "C"
  18. {
  19. #include <netlib.h>
  20. }
  21. #if defined(DEBUG)
  22. static const CHAR szFileName[] = __FILE__;
  23. #define _FILENAME_DEFINED_ONCE szFileName
  24. #endif
  25. #include <npassert.h>
  26. #include <npstring.h>
  27. /*******************************************************************
  28. NAME: NLS_STR::strcat
  29. SYNOPSIS: Concantenate string
  30. ENTRY: nlsSuffix - appended to end of string
  31. - or -
  32. pszSuffix - appended to end of string
  33. EXIT:
  34. NOTES: String doesn't change if a memory allocation failure occurs
  35. Currently checks to see if we need to reallocate the
  36. string (but we have to traverse it to determine the
  37. actual storage required). We may want to change
  38. this.
  39. HISTORY:
  40. johnl 11/13/90 Written
  41. beng 07/22/91 Allow on erroneous strings
  42. gregj 07/05/94 Added LPCSTR overload
  43. ********************************************************************/
  44. NLS_STR & NLS_STR::strcat( const NLS_STR & nlsSuffix )
  45. {
  46. if (QueryError() || !nlsSuffix)
  47. return *this;
  48. if ( QueryAllocSize() < (strlen() + nlsSuffix.strlen() + 1) )
  49. {
  50. if (IsOwnerAlloc() || !realloc( strlen() + nlsSuffix.strlen() + 1 ))
  51. {
  52. ReportError( WN_OUT_OF_MEMORY );
  53. return *this;
  54. }
  55. }
  56. ::strcatf( _pchData, nlsSuffix.QueryPch() );
  57. _cchLen += nlsSuffix.strlen();
  58. return *this;
  59. }
  60. NLS_STR & NLS_STR::strcat( LPCSTR pszSuffix )
  61. {
  62. if (QueryError())
  63. return *this;
  64. UINT cbSuffix = ::strlenf(pszSuffix);
  65. if ( (UINT)QueryAllocSize() < (strlen() + cbSuffix + 1) )
  66. {
  67. if (IsOwnerAlloc() || !realloc( strlen() + cbSuffix + 1 ))
  68. {
  69. ReportError( WN_OUT_OF_MEMORY );
  70. return *this;
  71. }
  72. }
  73. ::strcatf( _pchData, pszSuffix );
  74. _cchLen += cbSuffix;
  75. return *this;
  76. }
  77. #ifdef EXTENDED_STRINGS
  78. /*******************************************************************
  79. NAME: NLS_STR::Append
  80. SYNOPSIS: Append a string to the end of current string
  81. ENTRY: nlsSuffix - appended to end of string
  82. EXIT:
  83. RETURNS:
  84. NOTES: Little more than a wrapper around strcat.
  85. HISTORY:
  86. beng 22-Jul-1991 Created (parallel of AppendChar)
  87. ********************************************************************/
  88. APIERR NLS_STR::Append( const NLS_STR &nlsSuffix )
  89. {
  90. strcat(nlsSuffix);
  91. return QueryError();
  92. }
  93. /*******************************************************************
  94. NAME: NLS_STR::AppendChar
  95. SYNOPSIS: Append a single character to the end of current string
  96. ENTRY: wch - appended to end of string
  97. EXIT:
  98. RETURNS: 0 if successful
  99. NOTES:
  100. CODEWORK: This member would do well to skip the "strcat" step
  101. and append directly to the subject string.
  102. HISTORY:
  103. beng 23-Jul-1991 Created
  104. ********************************************************************/
  105. APIERR NLS_STR::AppendChar( WCHAR wch )
  106. {
  107. #if defined(UNICODE)
  108. STACK_NLS_STR(nlsTemp, 1);
  109. nlsTemp._pchData[0] = (CHAR)wch;
  110. nlsTemp._pchData[1] = 0;
  111. nlsTemp._cchLen = sizeof(CHAR); // since it's really in bytes
  112. #else
  113. STACK_NLS_STR(nlsTemp, 2);
  114. if (HIBYTE(wch) == 0)
  115. {
  116. // Single-byte character
  117. nlsTemp._pchData[0] = LOBYTE(wch);
  118. nlsTemp._pchData[1] = '\0';
  119. nlsTemp._cchLen = sizeof(CHAR);
  120. }
  121. else
  122. {
  123. // Double-byte character
  124. nlsTemp._pchData[0] = HIBYTE(wch); // lead byte
  125. nlsTemp._pchData[1] = LOBYTE(wch);
  126. nlsTemp._pchData[2] = '\0';
  127. nlsTemp._cchLen = 2*sizeof(CHAR);
  128. }
  129. #endif
  130. strcat(nlsTemp);
  131. return QueryError();
  132. }
  133. #endif // EXTENDED_STRINGS
  134. /*******************************************************************
  135. NAME: NLS_STR::operator+=
  136. SYNOPSIS: Append a string to the end of current string
  137. ENTRY: wch - character to append
  138. EXIT:
  139. RETURNS:
  140. NOTES: Little more than a wrapper around strcat.
  141. HISTORY:
  142. beng 07/23/91 Header added
  143. gregj 03/25/93 Added WCHAR version to replace AppendChar
  144. gregj 07/13/94 NLS_STR version was identical to strcat, so inlined
  145. ********************************************************************/
  146. NLS_STR & NLS_STR::operator+=( WCHAR wch )
  147. {
  148. #if defined(UNICODE)
  149. STACK_NLS_STR(nlsTemp, 1);
  150. nlsTemp._pchData[0] = (CHAR)wch;
  151. nlsTemp._pchData[1] = 0;
  152. nlsTemp._cchLen = sizeof(CHAR); // since it's really in bytes
  153. #else
  154. STACK_NLS_STR(nlsTemp, 2);
  155. if (HIBYTE(wch) == 0)
  156. {
  157. // Single-byte character
  158. nlsTemp._pchData[0] = LOBYTE(wch);
  159. nlsTemp._pchData[1] = '\0';
  160. nlsTemp._cchLen = sizeof(CHAR);
  161. }
  162. else
  163. {
  164. // Double-byte character
  165. nlsTemp._pchData[0] = HIBYTE(wch); // lead byte
  166. nlsTemp._pchData[1] = LOBYTE(wch);
  167. nlsTemp._pchData[2] = '\0';
  168. nlsTemp._cchLen = 2*sizeof(CHAR);
  169. }
  170. #endif
  171. strcat(nlsTemp);
  172. return *this;
  173. }
  174. /*******************************************************************
  175. NAME: NLS_STR::realloc
  176. SYNOPSIS: Reallocate an NLS_STR to the passed count of bytes, copying
  177. the current contents to the reallocated string.
  178. ENTRY: cb - number of bytes desired in string storage
  179. EXIT:
  180. Returns TRUE if successful:
  181. _pchData points to allocated storage of "cb" bytes.
  182. _cbData set to cb.
  183. Old storage is copied
  184. Returns FALSE upon allocation failure, the string is preserved
  185. NOTES:
  186. A string will never be downsized (i.e., realloc can only be used
  187. to increase the size of a string). If a request comes in to make
  188. the string smaller, it will be ignored, and TRUE will be returned.
  189. DO NOT CALL REALLOC ON AN OWNERALLOCED STRING!! You will cause
  190. an assertion error if you do.
  191. HISTORY:
  192. johnl 11/11/90 Created
  193. beng 04/26/91 Changed USHORT parm to INT
  194. ********************************************************************/
  195. BOOL NLS_STR::realloc( INT cb )
  196. {
  197. UIASSERT( !IsOwnerAlloc() );
  198. UIASSERT( cb != 0 );
  199. if ( cb <= QueryAllocSize() )
  200. return TRUE;
  201. CHAR * pchNewMem = new CHAR[cb];
  202. if (pchNewMem == NULL)
  203. return FALSE;
  204. ::memcpyf( pchNewMem, _pchData, min( cb-1, QueryAllocSize() ) );
  205. delete _pchData;
  206. _pchData = pchNewMem;
  207. _cbData = cb;
  208. *( _pchData + cb - 1 ) = '\0';
  209. return TRUE;
  210. }