StrAlign.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:12k
- /*++
- Copyright (c) 2000 Microsoft Corporation
- Module Name:
- stralign.h
- Abstract:
- This module contains macros and prototypes to expose the unaligned wide
- character interfaces.
- Public interfaces created or declared here include:
- ua_CharUpper()
- ua_CharUpperW()
- ua_lstrcmp()
- ua_lstrcmpW()
- ua_lstrcmpi()
- ua_lstrcmpiW()
- ua_lstrlen()
- ua_lstrlenW()
- ua_tcscpy()
- ua_wcschr()
- ua_wcscpy()
- ua_wcslen()
- ua_wcsrchr()
- STRUC_ALIGNED_STACK_COPY()
- TSTR_ALIGNED()
- TSTR_ALIGNED_STACK_COPY()
- WSTR_ALIGNED()
- WSTR_ALIGNED_STACK_COPY()
- Author:
- Revision History:
- --*/
- #if !defined(__STRALIGN_H_) && !defined(MIDL_PASS)
- #define __STRALIGN_H_
- #ifdef __cplusplus
- extern "C" {
- #endif
- #if defined(_X86_)
- //
- // Alignment of unicode strings is not necessary on X86.
- //
- #define WSTR_ALIGNED(s) TRUE
- #define ua_CharUpperW CharUpperW
- #define ua_lstrcmpiW lstrcmpiW
- #define ua_lstrcmpW lstrcmpW
- #define ua_lstrlenW lstrlenW
- #define ua_wcschr wcschr
- #define ua_wcscpy wcscpy
- #define ua_wcslen wcslen
- #define ua_wcsrchr wcsrchr
- #else
- //
- // The C runtime libraries expect aligned string pointers. Following are the
- // prototypes for our own, slower worker functions that accept unaligned
- // UNICODE strings.
- //
- //
- // Macro to determine whether a pointer to a unicode character is naturally
- // aligned.
- //
- #define WSTR_ALIGNED(s) (((DWORD_PTR)(s) & (sizeof(WCHAR)-1)) == 0)
- //
- // Platform-specific prototypes for worker functions exported from kernel32.
- // Do not call these directly, they do not exist on all platforms. Instead
- // use the equivalent ua_xxx() routines.
- //
- LPUWSTR
- WINAPI
- uaw_CharUpperW(
- IN OUT LPUWSTR String
- );
- int
- APIENTRY
- uaw_lstrcmpW(
- IN PCUWSTR String1,
- IN PCUWSTR String2
- );
- int
- APIENTRY
- uaw_lstrcmpiW(
- IN PCUWSTR String1,
- IN PCUWSTR String2
- );
- int
- WINAPI
- uaw_lstrlenW(
- IN LPCUWSTR String
- );
- PUWSTR
- __cdecl
- uaw_wcschr(
- IN PCUWSTR String,
- IN WCHAR Character
- );
- PUWSTR
- _cdecl
- uaw_wcscpy(
- IN PUWSTR Destination,
- IN PCUWSTR Source
- );
- size_t
- __cdecl
- uaw_wcslen(
- IN PCUWSTR String
- );
- PUWSTR
- __cdecl
- uaw_wcsrchr(
- IN PCUWSTR String,
- IN WCHAR Character
- );
- //
- // Following are the inline wrappers that determine the optimal worker function
- // to call based on the alignment of the UNICODE string arguments. Their
- // behavior is otherwise identical to the corresponding standard run-time
- // routiunes.
- //
- #if defined(CharUpper)
- __inline
- LPUWSTR
- static
- ua_CharUpperW(
- LPUWSTR String
- )
- {
- if (WSTR_ALIGNED(String)) {
- return CharUpperW( (PWSTR)String );
- } else {
- return uaw_CharUpperW( String );
- }
- }
- #endif
- #if defined(lstrcmp)
- __inline
- int
- static
- ua_lstrcmpW(
- IN LPCUWSTR String1,
- IN LPCUWSTR String2
- )
- {
- if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
- return lstrcmpW( (LPCWSTR)String1, (LPCWSTR)String2);
- } else {
- return uaw_lstrcmpW( String1, String2 );
- }
- }
- #endif
- #if defined(lstrcmpi)
- __inline
- int
- static
- ua_lstrcmpiW(
- IN LPCUWSTR String1,
- IN LPCUWSTR String2
- )
- {
- if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
- return lstrcmpiW( (LPCWSTR)String1, (LPCWSTR)String2 );
- } else {
- return uaw_lstrcmpiW( String1, String2 );
- }
- }
- #endif
- #if defined(lstrlen)
- __inline
- int
- static
- ua_lstrlenW(
- IN LPCUWSTR String
- )
- {
- if (WSTR_ALIGNED(String)) {
- return lstrlenW( (PCWSTR)String );
- } else {
- return uaw_lstrlenW( String );
- }
- }
- #endif
- #if defined(_WSTRING_DEFINED)
- //
- // Certain run-time string functions are overloaded in C++, to avoid
- // inadvertent stripping of the const attribute.
- //
- // The functions of interest here include: wcschr and wcsrchr.
- //
- // There are three flavors of these functions:
- //
- // Flavor Returns Parameter
- //
- // 1 PWSTR PCWSTR
- // 2 PCWSTR PCWSTR
- // 3 PWSTR PWSTR
- //
- // string.h declares flavor 1 whether for C or C++. This is the non-ANSI,
- // backward compatible mode.
- //
- // wchar.h declares flavor 1 if C, or flavors 2 and 3 if C++. This is the
- // ANSI method.
- //
- // Our corresponding functions need to match what was declared. The way
- // we can tell is by looking at _WConst_return... if it is defined then
- // we want to match the prototypes in wchar.h, otherwise we'll match
- // the prototypes in string.h.
- //
- #if defined(_WConst_return)
- typedef _WConst_return WCHAR UNALIGNED *PUWSTR_C;
- #else
- typedef WCHAR UNALIGNED *PUWSTR_C;
- #endif
- //
- // Here is flavor 1 or 2
- //
- __inline
- PUWSTR_C
- static
- ua_wcschr(
- IN PCUWSTR String,
- IN WCHAR Character
- )
- {
- if (WSTR_ALIGNED(String)) {
- return wcschr((PCWSTR)String, Character);
- } else {
- return (PUWSTR_C)uaw_wcschr(String, Character);
- }
- }
- __inline
- PUWSTR_C
- static
- ua_wcsrchr(
- IN PCUWSTR String,
- IN WCHAR Character
- )
- {
- if (WSTR_ALIGNED(String)) {
- return wcsrchr((PCWSTR)String, Character);
- } else {
- return (PUWSTR_C)uaw_wcsrchr(String, Character);
- }
- }
- #if defined(__cplusplus) && defined(_WConst_Return)
- //
- // Here is flavor 3
- //
- __inline
- PUWSTR
- static
- ua_wcschr(
- IN PUWSTR String,
- IN WCHAR Character
- )
- {
- if (WSTR_ALIGNED(String)) {
- return wcschr(String, Character);
- } else {
- return uaw_wcschr((PCUWSTR)String, Character);
- }
- }
- __inline
- PUWSTR
- static
- ua_wcsrchr(
- IN PUWSTR String,
- IN WCHAR Character
- )
- {
- if (WSTR_ALIGNED(String)) {
- return wcsrchr(String, Character);
- } else {
- return uaw_wcsrchr((PCUWSTR)String, Character);
- }
- }
- #endif // __cplusplus && _WConst_Return
- __inline
- PUWSTR
- static
- ua_wcscpy(
- IN PUWSTR Destination,
- IN PCUWSTR Source
- )
- {
- if (WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) {
- return wcscpy( (PWSTR)Destination, (PCWSTR)Source );
- } else {
- return uaw_wcscpy( Destination, Source );
- }
- }
- __inline
- size_t
- static
- ua_wcslen(
- IN PCUWSTR String
- )
- {
- if (WSTR_ALIGNED(String)) {
- return wcslen( (PCWSTR)String );
- } else {
- return uaw_wcslen( String );
- }
- }
- #endif // _WSTRING_DEFINED
- #endif // _X86_
- //++
- //
- // VOID
- // WSTR_ALIGNED_STACK_COPY (
- // OUT PCWSTR *TargetString,
- // IN PCUWSTR SourceString OPTIONAL
- // )
- //
- // VOID
- // TSTR_ALIGNED_STACK_COPY (
- // OUT PCTSTR *TargetString,
- // IN PCUTSTR SourceString OPTIONAL
- // )
- //
- // Routine Description:
- //
- // These macros set TargetString to an aligned pointer to the string
- // represented by SourceString. If necessary, an aligned copy of
- // SourceString is copied onto the stack.
- //
- // Arguments:
- //
- // TargetString - Supplies a pointer to a pointer to the resultant
- // string. This may be the same as SourceString if
- // that argument is aligned.
- //
- // SourceString - Supplies a pointer to the possibly unaligned UNICODE
- // string.
- //
- // Return Value:
- //
- // None.
- //
- // Note:
- //
- // These macros may allocate memory on the stack via the CRT function
- // _alloca(). This memory is "freed" when the calling function exits.
- // As a result, do not use these macros inside of a loop that may execute
- // a large number of times - instead, use a wrapper function, or use
- // an explicit buffer like this:
- //
- // TCHAR AlignedStringBuffer[ MAX_FOOSTR_CHARS ];
- // PTSTR AlignedString;
- //
- // while (a < b) {
- // ...
- // if (TSTR_ALIGNED(s) {
- // AlignedString = s;
- // } else {
- // AlignedString = (PTSTR)ua_tcscpy(AlignedStringBuffer,s);
- // }
- // SomeSystemFunction(AlignedString);
- // ...
- // }
- //
- //
- //--
- //
- // __UA_WSTRSIZE returns the number of bytes required to store the
- // supplied null-terminated UNICODE string.
- //
- // __UA_LOCALCOPY accepts a pointer to unaligned data and a size. It
- // allocates an aligned buffer on the stack and copies the data into
- // it, returning a pointer to the buffer.
- //
- #if !defined(__UA_WCSLEN)
- #define __UA_WCSLEN ua_wcslen
- #endif
- #define __UA_WSTRSIZE(s) ((__UA_WCSLEN(s)+1)*sizeof(WCHAR))
- #define __UA_STACKCOPY(p,s) memcpy(_alloca(s),p,s)
- //
- // Note that NULL is aligned.
- //
- #if defined(_X86_)
- #define WSTR_ALIGNED_STACK_COPY(d,s) (*(d) = (PCWSTR)(s))
- #else
- //
- // Use of an inline function here is not possible, as the results of
- // the _alloca() will not be preserved upon return from the function.
- //
- #define WSTR_ALIGNED_STACK_COPY(d,s)
- {
- PCUWSTR __ua_src;
- ULONG __ua_size;
- PWSTR __ua_dst;
-
- __ua_src = (s);
- if (WSTR_ALIGNED(__ua_src)) {
- __ua_dst = (PWSTR)__ua_src;
- } else {
- __ua_size = __UA_WSTRSIZE(__ua_src);
- __ua_dst = (PWSTR)_alloca(__ua_size);
- memcpy(__ua_dst,__ua_src,__ua_size);
- }
- *(d) = (PCWSTR)__ua_dst;
- }
- #endif
- #define ASTR_ALIGNED_STACK_COPY(d,s) (*(d) = (PCSTR)(s))
- //++
- //
- // <type> CONST *
- // STRUC_ALIGNED_STACK_COPY (
- // IN <type name>,
- // IN PVOID Struc OPTIONAL
- // )
- //
- // Routine Description:
- //
- // This macro returns an aligned pointer to Struc, creating a local
- // copy on the stack if necessary.
- //
- // This should be used only for relatively small structures, and efforts
- // should be made to align the structure properly in the first place. Use
- // this macro only as a last resort.
- //
- // Arguments:
- //
- // <type> - The type specifier of Struc
- //
- // Struc - Supplies a pointer to the structure in question.
- //
- // Return Value:
- //
- // Returns a const pointer to Struc if it is properly aligned, or a pointer
- // to a stack-allocated copy of Struc if it is not.
- //
- //--
- #if !defined(_X86_)
- #define __UA_STRUC_ALIGNED(t,s)
- (((DWORD_PTR)(s) & (TYPE_ALIGNMENT(t)-1)) == 0)
- #define STRUC_ALIGNED_STACK_COPY(t,s)
- __UA_STRUC_ALIGNED(t,s) ?
- ((t const *)(s)) :
- ((t const *)__UA_STACKCOPY((s),sizeof(t)))
- #else
- #define STRUC_ALIGNED_STACK_COPY(t,s) ((CONST t *)(s))
- #endif
- #if defined(UNICODE)
- #define TSTR_ALIGNED_STACK_COPY(d,s) WSTR_ALIGNED_STACK_COPY(d,s)
- #define TSTR_ALIGNED(x) WSTR_ALIGNED(x)
- #define ua_CharUpper ua_CharUpperW
- #define ua_lstrcmp ua_lstrcmpW
- #define ua_lstrcmpi ua_lstrcmpiW
- #define ua_lstrlen ua_lstrlenW
- #define ua_tcscpy ua_wcscpy
- #else
- #define TSTR_ALIGNED_STACK_COPY(d,s) ASTR_ALIGNED_STACK_COPY(d,s)
- #define TSTR_ALIGNED(x) TRUE
- #define ua_CharUpper CharUpperA
- #define ua_lstrcmp lstrcmpA
- #define ua_lstrcmpi lstrcmpiA
- #define ua_lstrlen lstrlenA
- #define ua_tcscpy strcpy
- #endif // UNICODE
- #ifdef __cplusplus
- }
- #endif
- #endif // __STRALIGN_H_
-
-
-