aspnetcore/src/AspNetCoreModuleV1/IISLib/stringa.h

516 lines
9.9 KiB
C++

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
#include "buffer.h"
#include "macros.h"
#include <strsafe.h>
class STRA
{
public:
STRA(
VOID
);
STRA(
__inout_ecount(cchInit) CHAR* pbInit,
__in DWORD cchInit
);
BOOL
IsEmpty(
VOID
) const;
BOOL
Equals(
__in PCSTR pszRhs,
__in BOOL fIgnoreCase = FALSE
) const;
BOOL
Equals(
__in const STRA * pstrRhs,
__in BOOL fIgnoreCase = FALSE
) const;
BOOL
Equals(
__in const STRA & strRhs,
__in BOOL fIgnoreCase = FALSE
) const;
static
BOOL
Equals(
__in PCSTR pszLhs,
__in PCSTR pszRhs,
__in bool fIgnoreCase = false
)
{
// Return FALSE if either or both strings are NULL.
if (!pszLhs || !pszRhs) return FALSE;
if( fIgnoreCase )
{
return ( 0 == _stricmp( pszLhs, pszRhs ) );
}
return ( 0 == strcmp( pszLhs, pszRhs ) );
}
VOID
Trim();
BOOL
StartsWith(
__in const STRA * pStraPrefix,
__in bool fIgnoreCase = FALSE
) const;
BOOL
StartsWith(
__in const STRA & straPrefix,
__in bool fIgnoreCase = FALSE
) const;
BOOL
StartsWith(
__in PCSTR pszPrefix,
__in bool fIgnoreCase = FALSE
) const;
BOOL
EndsWith(
__in const STRA * pStraSuffix,
__in bool fIgnoreCase = FALSE
) const;
BOOL
EndsWith(
__in const STRA & straSuffix,
__in bool fIgnoreCase = FALSE
) const;
BOOL
EndsWith(
__in PCSTR pszSuffix,
__in bool fIgnoreCase = FALSE
) const;
INT
IndexOf(
__in CHAR charValue,
__in DWORD dwStartIndex = 0
) const;
INT
IndexOf(
__in PCSTR pszValue,
__in DWORD dwStartIndex = 0
) const;
INT
LastIndexOf(
__in CHAR charValue,
__in DWORD dwStartIndex = 0
) const;
DWORD
QueryCB(
VOID
) const;
DWORD
QueryCCH(
VOID
) const;
DWORD
QuerySizeCCH(
VOID
) const;
DWORD
QuerySize(
VOID
) const;
__nullterminated
__bcount(this->m_cchLen)
CHAR *
QueryStr(
VOID
) const;
VOID
Reset(
VOID
);
HRESULT
Resize(
__in DWORD cchSize
);
HRESULT
SyncWithBuffer(
VOID
);
HRESULT
Copy(
__in PCSTR pszCopy
);
HRESULT
Copy(
__in_ecount(cbLen)
PCSTR pszCopy,
__in SIZE_T cbLen
);
HRESULT
Copy(
__in const STRA * pstrRhs
);
HRESULT
Copy(
__in const STRA & strRhs
);
HRESULT
CopyW(
__in PCWSTR pszCopyW
);
HRESULT
CopyW(
__in_ecount(cchLen)
PCWSTR pszCopyW,
__in SIZE_T cchLen,
__in UINT CodePage = CP_UTF8,
__in BOOL fFailIfNoTranslation = FALSE
)
{
_ASSERTE( cchLen <= MAXDWORD );
return AuxAppendW(
pszCopyW,
static_cast<DWORD>(cchLen),
0,
CodePage,
fFailIfNoTranslation
);
}
HRESULT
CopyWTruncate(
__in PCWSTR pszCopyWTruncate
);
HRESULT
CopyWTruncate(
__in_ecount(cchLen)
PCWSTR pszCopyWTruncate,
__in SIZE_T cchLen
);
HRESULT
Append(
__in PCSTR pszAppend
);
HRESULT
Append(
__in_ecount(cbLen)
PCSTR pszAppend,
__in SIZE_T cbLen
);
HRESULT
Append(
__in const STRA * pstrRhs
);
HRESULT
Append(
__in const STRA & strRhs
);
HRESULT
AppendW(
__in PCWSTR pszAppendW
)
{
HRESULT hr;
size_t cchLen;
hr = StringCchLengthW( pszAppendW,
STRSAFE_MAX_CCH,
&cchLen );
if ( FAILED( hr ) )
{
return hr;
}
return AppendW( pszAppendW, cchLen );
}
HRESULT
AppendW(
__in_ecount(cchLen)
PCWSTR pszAppendW,
__in SIZE_T cchLen,
__in UINT CodePage = CP_UTF8,
__in BOOL fFailIfNoTranslation = FALSE
)
{
_ASSERTE( cchLen <= MAXDWORD );
if ( cchLen == 0 )
{
return S_OK;
}
return AuxAppendW(
pszAppendW,
static_cast<DWORD>(cchLen),
QueryCB(),
CodePage,
fFailIfNoTranslation
);
}
HRESULT
AppendWTruncate(
__in PCWSTR pszAppendWTruncate
);
HRESULT
AppendWTruncate(
__in_ecount(cchLen)
PCWSTR pszAppendWTruncate,
__in SIZE_T cchLen
);
HRESULT
CopyToBuffer(
__out_bcount(*pcb) CHAR* pszBuffer,
__inout DWORD * pcb
) const;
HRESULT
SetLen(
__in DWORD cchLen
);
HRESULT
SafeSnprintf(
__in __format_string
PCSTR pszFormatString,
...
);
HRESULT
SafeVsnprintf(
__in __format_string
PCSTR pszFormatString,
va_list argsList
);
HRESULT
Escape(
VOID
);
HRESULT
EscapeUtf8(
VOID
);
VOID
Unescape(
VOID
);
HRESULT
CopyWToUTF8Unescaped(
__in LPCWSTR cpchStr
);
HRESULT
CopyWToUTF8Unescaped(
__in_ecount(cch)
LPCWSTR cpchStr,
__in DWORD cch
);
HRESULT
CopyWToUTF8Escaped(
__in LPCWSTR cpchStr
);
HRESULT
CopyWToUTF8Escaped(
__in_ecount(cch)
LPCWSTR cpchStr,
__in DWORD cch
);
private:
//
// Avoid C++ errors. This object should never go through a copy
// constructor, unintended cast or assignment.
//
STRA( const STRA &);
STRA & operator = (const STRA &);
HRESULT
AuxAppend(
__in_ecount(cbLen)
LPCSTR pStr,
__in DWORD cbLen,
__in DWORD cbOffset
);
HRESULT
AuxAppendW(
__in_ecount(cchAppendW)
PCWSTR pszAppendW,
__in DWORD cchAppendW,
__in DWORD cbOffset,
__in UINT CodePage,
__in BOOL fFailIfNoTranslation
)
{
DWORD dwFlags = 0;
if( CP_ACP == CodePage )
{
dwFlags = WC_NO_BEST_FIT_CHARS;
}
else if( fFailIfNoTranslation && CodePage == CP_UTF8 )
{
//
// WC_ERR_INVALID_CHARS is only supported in Longhorn or greater.
//
#if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN
dwFlags |= WC_ERR_INVALID_CHARS;
#else
UNREFERENCED_PARAMETER(fFailIfNoTranslation);
#endif
}
return AuxAppendW( pszAppendW,
cchAppendW,
cbOffset,
CodePage,
fFailIfNoTranslation,
dwFlags );
}
HRESULT
AuxAppendW(
__in_ecount(cchAppendW)
PCWSTR pszAppendW,
__in DWORD cchAppendW,
__in DWORD cbOffset,
__in UINT CodePage,
__in BOOL fFailIfNoTranslation,
__in DWORD dwFlags
);
HRESULT
AuxAppendWTruncate(
__in_ecount(cchAppendW)
__in PCWSTR pszAppendW,
__in DWORD cchAppendW,
__in DWORD cbOffset
);
static
int
ConvertUnicodeToCodePage(
__in_ecount(dwStringLen)
LPCWSTR pszSrcUnicodeString,
__inout BUFFER_T<CHAR,1> * pbufDstAnsiString,
__in DWORD dwStringLen,
__in UINT uCodePage
);
static
HRESULT
ConvertUnicodeToMultiByte(
__in_ecount(dwStringLen)
LPCWSTR pszSrcUnicodeString,
__in BUFFER_T<CHAR,1> * pbufDstAnsiString,
__in DWORD dwStringLen
);
static
HRESULT
ConvertUnicodeToUTF8(
__in_ecount(dwStringLen)
LPCWSTR pszSrcUnicodeString,
__in BUFFER_T<CHAR,1> * pbufDstAnsiString,
__in DWORD dwStringLen
);
typedef bool (* PFN_F_SHOULD_ESCAPE)(BYTE ch);
HRESULT
EscapeInternal(
PFN_F_SHOULD_ESCAPE pfnFShouldEscape
);
//
// Buffer with an inline buffer of 1,
// enough to hold null-terminating character.
//
BUFFER_T<CHAR,1> m_Buff;
DWORD m_cchLen;
};
inline
HRESULT
AppendToString(
ULONGLONG Number,
STRA & String
)
{
// prefast complains Append requires input
// to be null terminated, so zero initialize
// and pass the size of the buffer minus one
// to _ui64toa_s
CHAR chNumber[32] = {0};
if (_ui64toa_s(Number,
chNumber,
sizeof(chNumber) - sizeof(CHAR),
10) != 0)
{
return E_INVALIDARG;
}
return String.Append(chNumber);
}
template<DWORD size>
CHAR* InitHelper(__out CHAR (&psz)[size])
{
psz[0] = '\0';
return psz;
}
//
// Heap operation reduction macros
//
#define STACK_STRA(name, size) CHAR __ach##name[size];\
STRA name(InitHelper(__ach##name), sizeof(__ach##name))
#define INLINE_STRA(name, size) CHAR __ach##name[size];\
STRA name;
#define INLINE_STRA_INIT(name) name(InitHelper(__ach##name), sizeof(__ach##name))