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.

265 lines
5.8 KiB

  1. /*****************************************************************/
  2. /** Microsoft Windows for Workgroups **/
  3. /** Copyright (C) Microsoft Corp., 1991-1992 **/
  4. /*****************************************************************/
  5. /*
  6. strassgn.cxx
  7. NLS/DBCS-aware string class: assignment operator
  8. This file contains the implementation of the assignment operator
  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. gregj 04/02/93 Do buffer overflow checks for OWNERALLOC strings
  16. instead of asserting
  17. */
  18. #include "npcommon.h"
  19. extern "C"
  20. {
  21. #include <netlib.h>
  22. }
  23. #if defined(DEBUG)
  24. static const CHAR szFileName[] = __FILE__;
  25. #define _FILENAME_DEFINED_ONCE szFileName
  26. #endif
  27. #include <npassert.h>
  28. #include <npstring.h>
  29. /*******************************************************************
  30. NAME: NLS_STR::operator=
  31. SYNOPSIS: Assignment operator
  32. ENTRY: Either NLS_STR or CHAR*.
  33. EXIT: If successful, contents of string overwritten.
  34. If failed, the original contents of the string remain.
  35. RETURNS: Reference to self.
  36. HISTORY:
  37. beng 10/23/90 Created
  38. johnl 11/13/90 Added UIASSERTion checks for using bad
  39. strings
  40. beng 02/05/91 Uses CHAR * instead of PCH
  41. Johnl 03/06/91 Removed assertion check for *this
  42. being valid
  43. johnl 04/12/91 Resets error variable on PCH assignment
  44. if successful.
  45. beng 07/22/91 Allow assignment of an erroneous string;
  46. reset error on nls assignment as well
  47. gregj 04/02/93 Do buffer overflow checks for OWNERALLOC strings
  48. instead of asserting
  49. ********************************************************************/
  50. NLS_STR& NLS_STR::operator=( const NLS_STR& nlsSource )
  51. {
  52. if ( this == &nlsSource )
  53. return *this;
  54. if (!nlsSource)
  55. {
  56. // Assignment of an erroneous string
  57. //
  58. ReportError((unsigned short)nlsSource.QueryError());
  59. return *this;
  60. }
  61. INT cbToCopy = nlsSource.strlen();
  62. if ( !IsOwnerAlloc() )
  63. {
  64. if ( QueryAllocSize() < nlsSource.strlen()+1 )
  65. {
  66. /* Don't use Realloc because we want to retain the contents
  67. * of the string if we fail to get the memory.
  68. */
  69. CHAR * pchNew = new CHAR[nlsSource.strlen()+1];
  70. if ( pchNew == NULL )
  71. {
  72. ReportError( WN_OUT_OF_MEMORY );
  73. return *this;
  74. }
  75. delete _pchData;
  76. _pchData = pchNew;
  77. _cbData = nlsSource.strlen()+1;
  78. }
  79. }
  80. else
  81. {
  82. if (::fDBCSEnabled) {
  83. if (QueryAllocSize() <= cbToCopy) {
  84. cbToCopy = QueryAllocSize() - 1; /* leave room for the null */
  85. const CHAR *p = nlsSource.QueryPch();
  86. while (p < nlsSource.QueryPch() + cbToCopy)
  87. p += nlsSource.IsDBCSLeadByte(*p) ? 2 : 1;
  88. if (p - nlsSource.QueryPch() != cbToCopy) /* last char was DB */
  89. cbToCopy--; /* don't copy lead byte either */
  90. }
  91. }
  92. else {
  93. if (QueryAllocSize() <= cbToCopy)
  94. cbToCopy = QueryAllocSize() - 1;
  95. }
  96. }
  97. if (nlsSource.IsOEM())
  98. SetOEM();
  99. else
  100. SetAnsi();
  101. ::memcpyf( _pchData, nlsSource.QueryPch(), cbToCopy ); /* copy string data */
  102. _pchData[cbToCopy] = '\0'; /* terminate the string */
  103. _cchLen = cbToCopy;
  104. IncVers();
  105. /* Reset the error state, since the string is now valid.
  106. */
  107. ReportError( WN_SUCCESS );
  108. return *this;
  109. }
  110. NLS_STR& NLS_STR::operator=( const CHAR *pchSource )
  111. {
  112. if ( pchSource == NULL )
  113. {
  114. if ( !IsOwnerAlloc() && !QueryAllocSize() )
  115. {
  116. if ( !Alloc(1) )
  117. ReportError( WN_OUT_OF_MEMORY );
  118. return *this;
  119. }
  120. UIASSERT( QueryAllocSize() > 0 );
  121. *_pchData = '\0';
  122. _cchLen = 0;
  123. }
  124. else
  125. {
  126. INT iSourceLen = ::strlenf( pchSource );
  127. INT cbToCopy;
  128. if ( !IsOwnerAlloc() )
  129. {
  130. if ( QueryAllocSize() < iSourceLen + 1 )
  131. {
  132. CHAR * pchNew = new CHAR[iSourceLen + 1];
  133. if ( pchNew == NULL )
  134. {
  135. ReportError( WN_OUT_OF_MEMORY );
  136. return *this;
  137. }
  138. delete _pchData;
  139. _pchData = pchNew;
  140. _cbData = iSourceLen + 1;
  141. }
  142. cbToCopy = iSourceLen;
  143. }
  144. else
  145. {
  146. if (QueryAllocSize() <= iSourceLen) {
  147. if (::fDBCSEnabled) {
  148. cbToCopy = QueryAllocSize() - 1; /* leave room for the null */
  149. const CHAR *p = pchSource;
  150. while (p < pchSource + cbToCopy)
  151. p += IsDBCSLeadByte(*p) ? 2 : 1;
  152. if (p - pchSource != cbToCopy) /* last char was DB */
  153. cbToCopy--; /* don't copy lead byte either */
  154. }
  155. else
  156. cbToCopy = QueryAllocSize() - 1;
  157. }
  158. else
  159. cbToCopy = iSourceLen;
  160. }
  161. ::memcpyf( _pchData, pchSource, cbToCopy );
  162. _pchData[cbToCopy] = '\0'; /* terminate the string */
  163. _cchLen = cbToCopy;
  164. }
  165. IncVers();
  166. /* Reset the error state, since the string is now valid.
  167. */
  168. ReportError( WN_SUCCESS );
  169. return *this;
  170. }
  171. #ifdef EXTENDED_STRINGS
  172. /*******************************************************************
  173. NAME: NLS_STR::CopyFrom()
  174. SYNOPSIS: Assignment method which returns an error code
  175. ENTRY:
  176. nlsSource - source argument, either a nlsstr or char vector.
  177. achSource
  178. EXIT:
  179. Copied argument into this. Error code of string set.
  180. RETURNS:
  181. Error code of string - WN_SUCCESS if successful.
  182. NOTES:
  183. If the CopyFrom fails, the current string will retain its
  184. original contents and error state.
  185. HISTORY:
  186. beng 09/18/91 Created
  187. beng 09/19/91 Added content-preserving behavior
  188. ********************************************************************/
  189. APIERR NLS_STR::CopyFrom( const NLS_STR & nlsSource )
  190. {
  191. if (!nlsSource)
  192. return nlsSource.QueryError();
  193. *this = nlsSource;
  194. APIERR err = QueryError();
  195. if (err)
  196. Reset();
  197. else {
  198. if (nlsSource.IsOEM())
  199. SetOEM();
  200. else
  201. SetAnsi();
  202. }
  203. return err;
  204. }
  205. APIERR NLS_STR::CopyFrom( const CHAR * achSource )
  206. {
  207. *this = achSource;
  208. APIERR err = QueryError();
  209. if (err)
  210. Reset();
  211. return err;
  212. }
  213. #endif // EXTENDED_STRINGS