StrAlign.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:12k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*++
  2. Copyright (c) 2000  Microsoft Corporation
  3. Module Name:
  4.     stralign.h
  5. Abstract:
  6.     This module contains macros and prototypes to expose the unaligned wide
  7.     character interfaces.
  8.     Public interfaces created or declared here include:
  9.     ua_CharUpper()
  10.     ua_CharUpperW()
  11.     ua_lstrcmp()
  12.     ua_lstrcmpW()
  13.     ua_lstrcmpi()
  14.     ua_lstrcmpiW()
  15.     ua_lstrlen()
  16.     ua_lstrlenW()
  17.     ua_tcscpy()
  18.     ua_wcschr()
  19.     ua_wcscpy()
  20.     ua_wcslen()
  21.     ua_wcsrchr()
  22.     STRUC_ALIGNED_STACK_COPY()
  23.     TSTR_ALIGNED()
  24.     TSTR_ALIGNED_STACK_COPY()
  25.     WSTR_ALIGNED()
  26.     WSTR_ALIGNED_STACK_COPY()
  27. Author:
  28. Revision History:
  29. --*/
  30. #if !defined(__STRALIGN_H_) && !defined(MIDL_PASS)
  31. #define __STRALIGN_H_
  32. #ifdef __cplusplus
  33. extern "C" {
  34. #endif
  35. #if defined(_X86_)
  36. //
  37. // Alignment of unicode strings is not necessary on X86.
  38. //
  39. #define WSTR_ALIGNED(s) TRUE
  40. #define ua_CharUpperW CharUpperW
  41. #define ua_lstrcmpiW  lstrcmpiW
  42. #define ua_lstrcmpW   lstrcmpW
  43. #define ua_lstrlenW   lstrlenW
  44. #define ua_wcschr     wcschr
  45. #define ua_wcscpy     wcscpy
  46. #define ua_wcslen     wcslen
  47. #define ua_wcsrchr    wcsrchr
  48. #else
  49. //
  50. // The C runtime libraries expect aligned string pointers.  Following are the
  51. // prototypes for our own, slower worker functions that accept unaligned
  52. // UNICODE strings.
  53. //
  54. //
  55. // Macro to determine whether a pointer to a unicode character is naturally
  56. // aligned.
  57. //
  58. #define WSTR_ALIGNED(s) (((DWORD_PTR)(s) & (sizeof(WCHAR)-1)) == 0)
  59. //
  60. // Platform-specific prototypes for worker functions exported from kernel32.
  61. // Do not call these directly, they do not exist on all platforms.  Instead
  62. // use the equivalent ua_xxx() routines.
  63. //
  64. LPUWSTR
  65. WINAPI
  66. uaw_CharUpperW(
  67.     IN OUT LPUWSTR String
  68.     );
  69. int
  70. APIENTRY
  71. uaw_lstrcmpW(
  72.     IN PCUWSTR String1,
  73.     IN PCUWSTR String2
  74.     );
  75. int
  76. APIENTRY
  77. uaw_lstrcmpiW(
  78.     IN PCUWSTR String1,
  79.     IN PCUWSTR String2
  80.     );
  81. int
  82. WINAPI
  83. uaw_lstrlenW(
  84.     IN LPCUWSTR String
  85.     );
  86. PUWSTR
  87. __cdecl
  88. uaw_wcschr(
  89.     IN PCUWSTR String,
  90.     IN WCHAR   Character
  91.     );
  92. PUWSTR
  93. _cdecl
  94. uaw_wcscpy(
  95.     IN PUWSTR Destination,
  96.     IN PCUWSTR Source
  97.     );
  98. size_t
  99. __cdecl
  100. uaw_wcslen(
  101.     IN PCUWSTR String
  102.     );
  103. PUWSTR
  104. __cdecl
  105. uaw_wcsrchr(
  106.     IN PCUWSTR String,
  107.     IN WCHAR   Character
  108.     );
  109. //
  110. // Following are the inline wrappers that determine the optimal worker function
  111. // to call based on the alignment of the UNICODE string arguments.  Their
  112. // behavior is otherwise identical to the corresponding standard run-time
  113. // routiunes.
  114. //
  115. #if defined(CharUpper)
  116. __inline
  117. LPUWSTR
  118. static
  119. ua_CharUpperW(
  120.     LPUWSTR String
  121.     )
  122. {
  123.     if (WSTR_ALIGNED(String)) {
  124.         return CharUpperW( (PWSTR)String );
  125.     } else {
  126.         return uaw_CharUpperW( String );
  127.     }
  128. }
  129. #endif
  130. #if defined(lstrcmp)
  131. __inline
  132. int
  133. static
  134. ua_lstrcmpW(
  135.     IN LPCUWSTR String1,
  136.     IN LPCUWSTR String2
  137.     )
  138. {
  139.     if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
  140.         return lstrcmpW( (LPCWSTR)String1, (LPCWSTR)String2);
  141.     } else {
  142.         return uaw_lstrcmpW( String1, String2 );
  143.     }
  144. }
  145. #endif
  146. #if defined(lstrcmpi)
  147. __inline
  148. int
  149. static
  150. ua_lstrcmpiW(
  151.     IN LPCUWSTR String1,
  152.     IN LPCUWSTR String2
  153.     )
  154. {
  155.     if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
  156.         return lstrcmpiW( (LPCWSTR)String1, (LPCWSTR)String2 );
  157.     } else {
  158.         return uaw_lstrcmpiW( String1, String2 );
  159.     }
  160. }
  161. #endif
  162. #if defined(lstrlen)
  163. __inline
  164. int
  165. static
  166. ua_lstrlenW(
  167.     IN LPCUWSTR String
  168.     )
  169. {
  170.     if (WSTR_ALIGNED(String)) {
  171.         return lstrlenW( (PCWSTR)String );
  172.     } else {
  173.         return uaw_lstrlenW( String );
  174.     }
  175. }
  176. #endif
  177. #if defined(_WSTRING_DEFINED)
  178. //
  179. // Certain run-time string functions are overloaded in C++, to avoid
  180. // inadvertent stripping of the const attribute.
  181. //
  182. // The functions of interest here include: wcschr and wcsrchr.
  183. //
  184. // There are three flavors of these functions:
  185. //
  186. // Flavor  Returns    Parameter
  187. //
  188. // 1       PWSTR      PCWSTR
  189. // 2       PCWSTR     PCWSTR
  190. // 3       PWSTR      PWSTR
  191. //
  192. // string.h declares flavor 1 whether for C or C++.  This is the non-ANSI,
  193. // backward compatible mode.
  194. //
  195. // wchar.h declares flavor 1 if C, or flavors 2 and 3 if C++.  This is the
  196. // ANSI method.
  197. //
  198. // Our corresponding functions need to match what was declared.  The way
  199. // we can tell is by looking at _WConst_return... if it is defined then
  200. // we want to match the prototypes in wchar.h, otherwise we'll match
  201. // the prototypes in string.h.
  202. //
  203. #if defined(_WConst_return) 
  204. typedef _WConst_return WCHAR UNALIGNED *PUWSTR_C;
  205. #else
  206. typedef WCHAR UNALIGNED *PUWSTR_C;
  207. #endif
  208. //
  209. // Here is flavor 1 or 2
  210. //
  211. __inline
  212. PUWSTR_C
  213. static
  214. ua_wcschr(
  215.     IN PCUWSTR String,
  216.     IN WCHAR   Character
  217.     )
  218. {
  219.     if (WSTR_ALIGNED(String)) {
  220.         return wcschr((PCWSTR)String, Character);
  221.     } else {
  222.         return (PUWSTR_C)uaw_wcschr(String, Character);
  223.     }
  224. }
  225. __inline
  226. PUWSTR_C
  227. static
  228. ua_wcsrchr(
  229.     IN PCUWSTR String,
  230.     IN WCHAR   Character
  231.     )
  232. {
  233.     if (WSTR_ALIGNED(String)) {
  234.         return wcsrchr((PCWSTR)String, Character);
  235.     } else {
  236.         return (PUWSTR_C)uaw_wcsrchr(String, Character);
  237.     }
  238. }
  239. #if defined(__cplusplus) && defined(_WConst_Return)
  240. //
  241. // Here is flavor 3
  242. //
  243. __inline
  244. PUWSTR
  245. static
  246. ua_wcschr(
  247.     IN PUWSTR String,
  248.     IN WCHAR  Character
  249.     )
  250. {
  251.     if (WSTR_ALIGNED(String)) {
  252.         return wcschr(String, Character);
  253.     } else {
  254.         return uaw_wcschr((PCUWSTR)String, Character);
  255.     }
  256. }
  257. __inline
  258. PUWSTR
  259. static
  260. ua_wcsrchr(
  261.     IN PUWSTR String,
  262.     IN WCHAR  Character
  263.     )
  264. {
  265.     if (WSTR_ALIGNED(String)) {
  266.         return wcsrchr(String, Character);
  267.     } else {
  268.         return uaw_wcsrchr((PCUWSTR)String, Character);
  269.     }
  270. }
  271. #endif  // __cplusplus && _WConst_Return
  272. __inline
  273. PUWSTR
  274. static
  275. ua_wcscpy(
  276.     IN PUWSTR  Destination,
  277.     IN PCUWSTR Source
  278.     )
  279. {
  280.     if (WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) {
  281.         return wcscpy( (PWSTR)Destination, (PCWSTR)Source );
  282.     } else {
  283.         return uaw_wcscpy( Destination, Source );
  284.     }
  285. }
  286. __inline
  287. size_t
  288. static
  289. ua_wcslen(
  290.     IN PCUWSTR String
  291.     )
  292. {
  293.     if (WSTR_ALIGNED(String)) {
  294.         return wcslen( (PCWSTR)String );
  295.     } else {
  296.         return uaw_wcslen( String );
  297.     }
  298. }
  299. #endif  // _WSTRING_DEFINED
  300. #endif  // _X86_
  301. //++
  302. //
  303. // VOID
  304. // WSTR_ALIGNED_STACK_COPY (
  305. //    OUT PCWSTR *TargetString,
  306. //    IN  PCUWSTR SourceString OPTIONAL
  307. //    )
  308. //
  309. // VOID
  310. // TSTR_ALIGNED_STACK_COPY (
  311. //    OUT PCTSTR *TargetString,
  312. //    IN  PCUTSTR SourceString OPTIONAL
  313. //    )
  314. //
  315. // Routine Description:
  316. //
  317. //    These macros set TargetString to an aligned pointer to the string
  318. //    represented by SourceString.  If necessary, an aligned copy of
  319. //    SourceString is copied onto the stack.
  320. //
  321. // Arguments:
  322. //
  323. //    TargetString - Supplies a pointer to a pointer to the resultant
  324. //                   string.  This may be the same as SourceString if
  325. //                   that argument is aligned.
  326. //
  327. //    SourceString - Supplies a pointer to the possibly unaligned UNICODE
  328. //                   string.
  329. //
  330. // Return Value:
  331. //
  332. //    None.
  333. //
  334. // Note:
  335. //
  336. //    These macros may allocate memory on the stack via the CRT function
  337. //    _alloca().  This memory is "freed" when the calling function exits.
  338. //    As a result, do not use these macros inside of a loop that may execute
  339. //    a large number of times - instead, use a wrapper function, or use
  340. //    an explicit buffer like this:
  341. //
  342. //    TCHAR AlignedStringBuffer[ MAX_FOOSTR_CHARS ];
  343. //    PTSTR AlignedString;
  344. //
  345. //    while (a < b) {
  346. //        ...
  347. //        if (TSTR_ALIGNED(s) {
  348. //            AlignedString = s;
  349. //        } else {
  350. //            AlignedString = (PTSTR)ua_tcscpy(AlignedStringBuffer,s);
  351. //        }
  352. //        SomeSystemFunction(AlignedString);
  353. //        ...
  354. //    }
  355. //        
  356. //        
  357. //--
  358. //
  359. // __UA_WSTRSIZE returns the number of bytes required to store the
  360. // supplied null-terminated UNICODE string.
  361. //        
  362. // __UA_LOCALCOPY accepts a pointer to unaligned data and a size.  It
  363. // allocates an aligned buffer on the stack and copies the data into
  364. // it, returning a pointer to the buffer.
  365. //
  366. #if !defined(__UA_WCSLEN)
  367. #define __UA_WCSLEN ua_wcslen
  368. #endif
  369. #define __UA_WSTRSIZE(s)    ((__UA_WCSLEN(s)+1)*sizeof(WCHAR))
  370. #define __UA_STACKCOPY(p,s) memcpy(_alloca(s),p,s)
  371. //
  372. // Note that NULL is aligned.
  373. //
  374. #if defined(_X86_)
  375. #define WSTR_ALIGNED_STACK_COPY(d,s) (*(d) = (PCWSTR)(s))
  376. #else
  377. //
  378. // Use of an inline function here is not possible, as the results of
  379. // the _alloca() will not be preserved upon return from the function.
  380. //
  381. #define WSTR_ALIGNED_STACK_COPY(d,s)                                
  382.     {                                                               
  383.         PCUWSTR __ua_src;                                           
  384.         ULONG   __ua_size;                                          
  385.         PWSTR  __ua_dst;                                            
  386.                                                                     
  387.         __ua_src = (s);                                             
  388.         if (WSTR_ALIGNED(__ua_src)) {                               
  389.             __ua_dst = (PWSTR)__ua_src;                             
  390.         } else {                                                    
  391.             __ua_size = __UA_WSTRSIZE(__ua_src);                    
  392.             __ua_dst = (PWSTR)_alloca(__ua_size);                   
  393.             memcpy(__ua_dst,__ua_src,__ua_size);                    
  394.         }                                                           
  395.         *(d) = (PCWSTR)__ua_dst;                                    
  396.     }
  397. #endif
  398. #define ASTR_ALIGNED_STACK_COPY(d,s) (*(d) = (PCSTR)(s))
  399. //++
  400. //
  401. // <type> CONST *
  402. // STRUC_ALIGNED_STACK_COPY (
  403. //     IN <type name>,
  404. //     IN PVOID Struc OPTIONAL
  405. //     )
  406. // 
  407. // Routine Description:
  408. //
  409. //    This macro returns an aligned pointer to Struc, creating a local
  410. //    copy on the stack if necessary.
  411. //
  412. //    This should be used only for relatively small structures, and efforts
  413. //    should be made to align the structure properly in the first place.  Use
  414. //    this macro only as a last resort.
  415. //
  416. // Arguments:
  417. //
  418. //    <type> - The type specifier of Struc
  419. //
  420. //    Struc - Supplies a pointer to the structure in question.
  421. //
  422. // Return Value:
  423. //
  424. //    Returns a const pointer to Struc if it is properly aligned, or a pointer 
  425. //    to a stack-allocated copy of Struc if it is not.
  426. //
  427. //--
  428. #if !defined(_X86_)
  429. #define __UA_STRUC_ALIGNED(t,s) 
  430.     (((DWORD_PTR)(s) & (TYPE_ALIGNMENT(t)-1)) == 0)
  431. #define STRUC_ALIGNED_STACK_COPY(t,s) 
  432.     __UA_STRUC_ALIGNED(t,s) ?   
  433.         ((t const *)(s)) :      
  434.         ((t const *)__UA_STACKCOPY((s),sizeof(t)))
  435. #else
  436. #define STRUC_ALIGNED_STACK_COPY(t,s) ((CONST t *)(s))
  437. #endif
  438. #if defined(UNICODE)
  439. #define TSTR_ALIGNED_STACK_COPY(d,s)    WSTR_ALIGNED_STACK_COPY(d,s)
  440. #define TSTR_ALIGNED(x)                 WSTR_ALIGNED(x)
  441. #define ua_CharUpper                    ua_CharUpperW
  442. #define ua_lstrcmp                      ua_lstrcmpW
  443. #define ua_lstrcmpi                     ua_lstrcmpiW
  444. #define ua_lstrlen                      ua_lstrlenW
  445. #define ua_tcscpy                       ua_wcscpy
  446. #else
  447. #define TSTR_ALIGNED_STACK_COPY(d,s)    ASTR_ALIGNED_STACK_COPY(d,s)
  448. #define TSTR_ALIGNED(x)                 TRUE
  449. #define ua_CharUpper                    CharUpperA
  450. #define ua_lstrcmp                      lstrcmpA
  451. #define ua_lstrcmpi                     lstrcmpiA
  452. #define ua_lstrlen                      lstrlenA
  453. #define ua_tcscpy                       strcpy
  454. #endif  // UNICODE
  455. #ifdef __cplusplus
  456. }
  457. #endif
  458. #endif  // __STRALIGN_H_
  459.     
  460.                                          
  461.