}
CONTRACT_END;
- CQuickBytes qbLC;
+ SString moduleName(SString::Utf8, pszModuleName);
+ moduleName.LowerCase();
- // Need to perform case insensitive hashing.
- UTF8_TO_LOWER_CASE(pszModuleName, qbLC);
- pszModuleName = (LPUTF8) qbLC.Ptr();
+ StackScratchBuffer buffer;
+ pszModuleName = moduleName.GetUTF8(buffer);
mdFile kFile = GetManifestFileToken(pszModuleName);
if (kFile == mdTokenNil)
#include "cordbpriv.h"
#include "assemblyspec.hpp"
-// A helper macro for the assembly's module hash (m_pAllowedFiles).
-#define UTF8_TO_LOWER_CASE(str, qb) \
-{ \
- WRAPPER_NO_CONTRACT; \
- INT32 allocBytes = InternalCasingHelper::InvariantToLower(NULL, 0, str); \
- qb.AllocThrows(allocBytes); \
- InternalCasingHelper::InvariantToLower((LPUTF8) qb.Ptr(), allocBytes, str); \
-}
-
-
class BaseDomain;
class AppDomain;
class DomainAssembly;
return ((dwData >> 1) & 0x00ffffff) | mdtTypeDef;
}
+static void ConstructKeyFromDataCaseInsensitive(EEClassHashTable::ConstructKeyCallback* pCallback, LPSTR pszNameSpace, LPSTR pszName)
+{
+ CONTRACTL
+ {
+ THROWS;
+ MODE_ANY;
+ }
+ CONTRACTL_END
+
+ LPUTF8 Key[2];
+
+ StackSString nameSpace(SString::Utf8, pszNameSpace);
+ nameSpace.LowerCase();
+
+ StackScratchBuffer nameSpaceBuffer;
+ Key[0] = (LPUTF8)nameSpace.GetUTF8(nameSpaceBuffer);
+
+ StackSString name(SString::Utf8, pszName);
+ name.LowerCase();
+
+ StackScratchBuffer nameBuffer;
+ Key[1] = (LPUTF8)name.GetUTF8(nameBuffer);
+
+ pCallback->UseKeys(Key);
+}
+
VOID EEClassHashTable::ConstructKeyFromData(PTR_EEClassHashEntry pEntry, // IN : Entry to compare
ConstructKeyCallback *pCallback) // This class will process the output
{
}
CONTRACTL_END;
- LPUTF8 Key[2];
- Key[0] = Key[1] = NULL;
-
{
#ifdef _DEBUG_IMPL
_ASSERTE(!(m_bCaseInsensitive && FORBIDGC_LOADER_USE_ENABLED()));
IfFailThrow(pInternalImport->GetNameOfTypeDef(UncompressedCl, (LPCSTR *)&pszName, (LPCSTR *)&pszNameSpace));
}
}
-
+
if (!m_bCaseInsensitive)
{
+ LPUTF8 Key[2];
+
Key[0] = pszNameSpace;
Key[1] = pszName;
+
+ pCallback->UseKeys(Key);
}
else
{
- CONTRACT_VIOLATION(ThrowsViolation|FaultViolation);
-
#ifndef DACCESS_COMPILE
- // We can call the nothrow version here because we fulfilled the requirement of calling
- // InitTables() in the "new" method.
- INT32 iNSLength = InternalCasingHelper::InvariantToLowerNoThrow(NULL, 0, pszNameSpace);
- if (!iNSLength)
- {
- COMPlusThrowOM();
- }
-
- INT32 iNameLength = InternalCasingHelper::InvariantToLowerNoThrow(NULL, 0, pszName);
- if (!iNameLength)
- {
- COMPlusThrowOM();
- }
-
- // Prefast overflow sanity check before alloc.
- INT32 iAllocSize;
- if (!ClrSafeInt<INT32>::addition(iNSLength, iNameLength, iAllocSize))
- COMPlusThrowOM();
- LPUTF8 pszOutNameSpace = (LPUTF8) _alloca(iAllocSize);
- if (iNSLength == 1)
- {
- *pszOutNameSpace = '\0';
- }
- else
- {
- if (!InternalCasingHelper::InvariantToLowerNoThrow(pszOutNameSpace, iNSLength, pszNameSpace))
- {
- COMPlusThrowOM();
- }
- }
- LPUTF8 pszOutName = (LPUTF8) pszOutNameSpace + iNSLength;
-
- if (!InternalCasingHelper::InvariantToLowerNoThrow(pszOutName, iNameLength, pszName))
- {
- COMPlusThrowOM();
- }
- Key[0] = pszOutNameSpace;
- Key[1] = pszOutName;
+ CONTRACT_VIOLATION(ThrowsViolation | FaultViolation);
+ ConstructKeyFromDataCaseInsensitive(pCallback, pszNameSpace, pszName);
#else
DacNotImpl();
#endif // #ifndef DACCESS_COMPILE
}
}
- pCallback->UseKeys(Key);
}
#ifndef DACCESS_COMPILE
return NULL;
}
-EEClassHashEntry_t *EEClassHashTable::FindNextNestedClass(NameHandle* pName, PTR_VOID *pData, LookupContext *pContext)
+EEClassHashEntry_t *EEClassHashTable::FindNextNestedClass(const NameHandle* pName, PTR_VOID *pData, LookupContext *pContext)
{
CONTRACTL
{
}
-EEClassHashEntry_t * EEClassHashTable::GetValue(NameHandle* pName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext)
+EEClassHashEntry_t * EEClassHashTable::GetValue(const NameHandle* pName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext)
{
CONTRACTL
{
EEClassHashEntry_t *InsertValueUsingPreallocatedEntry(EEClassHashEntry_t *pStorageForNewEntry, LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID Data, EEClassHashEntry_t *pEncloser);
EEClassHashEntry_t *GetValue(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
EEClassHashEntry_t *GetValue(LPCUTF8 pszFullyQualifiedName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
- EEClassHashEntry_t *GetValue(NameHandle* pName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
+ EEClassHashEntry_t *GetValue(const NameHandle* pName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
EEClassHashEntry_t *AllocNewEntry(AllocMemTracker *pamTracker);
EEClassHashTable *MakeCaseInsensitiveTable(Module *pModule, AllocMemTracker *pamTracker);
EEClassHashEntry_t *FindItem(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, BOOL IsNested, LookupContext *pContext);
- EEClassHashEntry_t *FindNextNestedClass(NameHandle* pName, PTR_VOID *pData, LookupContext *pContext);
+ EEClassHashEntry_t *FindNextNestedClass(const NameHandle* pName, PTR_VOID *pData, LookupContext *pContext);
EEClassHashEntry_t *FindNextNestedClass(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID *pData, LookupContext *pContext);
EEClassHashEntry_t *FindNextNestedClass(LPCUTF8 pszFullyQualifiedName, PTR_VOID *pData, LookupContext *pContext);
}
}
-BOOL ClassLoader::IsNested(NameHandle* pName, mdToken *mdEncloser)
+BOOL ClassLoader::IsNested(const NameHandle* pName, mdToken *mdEncloser)
{
CONTRACTL
{
}
void ClassLoader::GetClassValue(NameHandleTable nhTable,
- NameHandle *pName,
+ const NameHandle *pName,
HashDatum *pData,
EEClassHashTable **ppTable,
Module* pLookInThisModuleOnly,
//
//
BOOL ClassLoader::FindClassModuleThrowing(
- const NameHandle * pOriginalName,
+ const NameHandle * pName,
TypeHandle * pType,
mdToken * pmdClassToken,
Module ** ppModule,
if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS;
if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS;
if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); }
- PRECONDITION(CheckPointer(pOriginalName));
+ PRECONDITION(CheckPointer(pName));
PRECONDITION(CheckPointer(ppModule));
MODE_ANY;
SUPPORTS_DAC;
}
CONTRACTL_END
- NameHandleTable nhTable = nhCaseSensitive; // just to initialize this ...
-
- // Make a copy of the original name which we can modify (to lowercase)
- NameHandle localName = *pOriginalName;
- NameHandle * pName = &localName;
-
- switch (pName->GetTable())
- {
- case nhCaseInsensitive:
- {
-#ifndef DACCESS_COMPILE
- // GC-type users should only be loading types through tokens.
-#ifdef _DEBUG_IMPL
- _ASSERTE(!FORBIDGC_LOADER_USE_ENABLED());
-#endif
-
- // Use the case insensitive table
- nhTable = nhCaseInsensitive;
-
- // Create a low case version of the namespace and name
- LPUTF8 pszLowerNameSpace = NULL;
- LPUTF8 pszLowerClassName = NULL;
- int allocLen;
-
- if (pName->GetNameSpace())
- {
- allocLen = InternalCasingHelper::InvariantToLower(
- NULL,
- 0,
- pName->GetNameSpace());
- if (allocLen == 0)
- {
- return FALSE;
- }
-
- pszLowerNameSpace = (LPUTF8)_alloca(allocLen);
- if (allocLen == 1)
- {
- *pszLowerNameSpace = '\0';
- }
- else if (!InternalCasingHelper::InvariantToLower(
- pszLowerNameSpace,
- allocLen,
- pName->GetNameSpace()))
- {
- return FALSE;
- }
- }
+ // Note that the type name is expected to be lower-cased by the caller for case-insensitive lookups
- _ASSERTE(pName->GetName() != NULL);
- allocLen = InternalCasingHelper::InvariantToLower(NULL, 0, pName->GetName());
- if (allocLen == 0)
- {
- return FALSE;
- }
-
- pszLowerClassName = (LPUTF8)_alloca(allocLen);
- if (!InternalCasingHelper::InvariantToLower(
- pszLowerClassName,
- allocLen,
- pName->GetName()))
- {
- return FALSE;
- }
-
- // Substitute the lower case version of the name.
- // The field are will be released when we leave this scope
- pName->SetName(pszLowerNameSpace, pszLowerClassName);
- break;
-#else
- DacNotImpl();
- break;
-#endif // #ifndef DACCESS_COMPILE
- }
- case nhCaseSensitive:
- nhTable = nhCaseSensitive;
- break;
- }
+ NameHandleTable nhTable = pName->GetTable();
// Remember if there are any unhashed modules. We must do this before
// the actual look to avoid a race condition with other threads doing lookups.
//
TypeHandle
ClassLoader::LoadTypeHandleThrowing(
- NameHandle * pName,
+ NameHandle * pName,
ClassLoadLevel level,
Module * pLookInThisModuleOnly /*=NULL*/)
{
else
{ //#LoadTypeHandle_TypeForwarded
// pName is a host instance so it's okay to set fields in it in a DAC build
- HashedTypeEntry& bucket = pName->GetBucket();
+ const HashedTypeEntry& bucket = pName->GetBucket();
// Reset pName's bucket entry
if (bucket.GetEntryType() == HashedTypeEntry::IsHashedClassEntry && bucket.GetClassHashBasedEntryValue()->GetEncloser())
}
CONTRACTL_END
- // We can use the NoThrow versions here because we only call this routine if we're maintaining
- // a case-insensitive hash table, and the creation of that table initialized the
- // CasingHelper system.
- INT32 iNSLength = InternalCasingHelper::InvariantToLowerNoThrow(NULL, 0, pszNameSpace);
- if (!iNSLength)
- {
- COMPlusThrowOM();
- }
+ StackSString nameSpace(SString::Utf8, pszNameSpace);
+ nameSpace.LowerCase();
- INT32 iNameLength = InternalCasingHelper::InvariantToLowerNoThrow(NULL, 0, pszName);
- if (!iNameLength)
- {
- COMPlusThrowOM();
- }
+ StackScratchBuffer nameSpaceBuffer;
+ pszNameSpace = nameSpace.GetUTF8(nameSpaceBuffer);
- {
- //Calc & allocate path length
- //Includes terminating null
- S_SIZE_T allocSize = S_SIZE_T(iNSLength) + S_SIZE_T(iNameLength);
- if (allocSize.IsOverflow())
- {
- ThrowHR(COR_E_OVERFLOW);
- }
- AllocMemHolder<char> pszOutNameSpace (GetAssembly()->GetHighFrequencyHeap()->AllocMem(allocSize));
- *ppszOutNameSpace = pszOutNameSpace;
-
- if (iNSLength == 1)
- {
- **ppszOutNameSpace = '\0';
- }
- else
- {
- if (!InternalCasingHelper::InvariantToLowerNoThrow(*ppszOutNameSpace, iNSLength, pszNameSpace))
- {
- COMPlusThrowOM();
- }
- }
+ StackSString name(SString::Utf8, pszName);
+ name.LowerCase();
- *ppszOutName = *ppszOutNameSpace + iNSLength;
-
- if (!InternalCasingHelper::InvariantToLowerNoThrow(*ppszOutName, iNameLength, pszName))
- {
- COMPlusThrowOM();
- }
+ StackScratchBuffer nameBuffer;
+ pszName = name.GetUTF8(nameBuffer);
- pszOutNameSpace.SuppressRelease();
- }
+
+ size_t iNSLength = strlen(pszNameSpace);
+ size_t iNameLength = strlen(pszName);
+
+ //Calc & allocate path length
+ //Includes terminating null
+ S_SIZE_T allocSize = S_SIZE_T(iNSLength) + S_SIZE_T(iNameLength) + S_SIZE_T(2);
+ AllocMemHolder<char> alloc(GetAssembly()->GetHighFrequencyHeap()->AllocMem(allocSize));
+
+ memcpy(*ppszOutNameSpace = (char*)alloc, pszNameSpace, iNSLength + 1);
+ memcpy(*ppszOutName = (char*)alloc + iNSLength + 1, pszName, iNameLength + 1);
+
+ alloc.SuppressRelease();
}
#endif // #ifndef DACCESS_COMPILE
BOOL
ClassLoader::ResolveNameToTypeDefThrowing(
Module * pModule,
- NameHandle * pName,
+ const NameHandle * pName,
Module ** ppTypeDefModule,
mdTypeDef * pTypeDefToken,
Loader::LoadFlag loadFlag,
m_pClassHashEntry = PTR_NULL;
}
- EntryType GetEntryType() { return m_EntryType; }
- bool IsNull() { return m_EntryType == EntryType::IsNullEntry; }
+ EntryType GetEntryType() const { return m_EntryType; }
+ bool IsNull() const { return m_EntryType == EntryType::IsNullEntry; }
const HashedTypeEntry& SetClassHashBasedEntryValue(EEClassHashEntry_t * pClassHashEntry)
{
m_pClassHashEntry = dac_cast<PTR_EEClassHashEntry>(pClassHashEntry);
return *this;
}
- EEClassHashEntry_t * GetClassHashBasedEntryValue()
+ EEClassHashEntry_t * GetClassHashBasedEntryValue() const
{
LIMITED_METHOD_CONTRACT;
m_TokenAndModulePair.m_pModule = pModule;
return *this;
}
- const TokenTypeEntry& GetTokenBasedEntryValue()
+ const TokenTypeEntry& GetTokenBasedEntryValue() const
{
LIMITED_METHOD_CONTRACT;
}
- HashedTypeEntry& GetBucket()
+ const HashedTypeEntry& GetBucket() const
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
return (token == 0 || token != tokenNotToLoad) && tokenNotToLoad != tdAllTypes;
}
- BOOL OKToLoad()
+ BOOL OKToLoad() const
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
// Lookup the hash table entry from the hash table
void GetClassValue(NameHandleTable nhTable,
- NameHandle *pName,
+ const NameHandle *pName,
HashDatum *pData,
EEClassHashTable **ppTable,
Module* pLookInThisModuleOnly,
// Return FALSE if operation failed (e.g. type does not exist)
// *pfUsesTypeForwarder is set to TRUE if a type forwarder is found. It is never set to FALSE.
static BOOL ResolveNameToTypeDefThrowing(Module * pTypeRefModule,
- NameHandle * pName,
+ const NameHandle * pName,
Module ** ppTypeDefModule,
mdTypeDef * pTypeDefToken,
Loader::LoadFlag loadFlag = Loader::Load,
static void DECLSPEC_NORETURN ThrowTypeLoadException(TypeKey *pKey, UINT resIDWhy);
- BOOL IsNested(NameHandle* pName, mdToken *mdEncloser);
+ BOOL IsNested(const NameHandle* pName, mdToken *mdEncloser);
static BOOL IsNested(Module *pModude, mdToken typeDefOrRef, mdToken *mdEncloser);
public:
if (SUCCEEDED(spec.Init(szComma)))
{
// Need to perform case insensitive hashing.
- CQuickBytes qbLC;
- {
- UTF8_TO_LOWER_CASE(szLibName, qbLC);
- szLibName = (LPUTF8) qbLC.Ptr();
- }
+ SString moduleName(SString::Utf8, szLibName);
+ moduleName.LowerCase();
+
+ StackScratchBuffer buffer;
+ szLibName = (LPSTR)moduleName.GetUTF8(buffer);
Assembly *pAssembly = spec.LoadAssembly(FILE_LOADED);
Module *pModule = pAssembly->FindModuleByName(szLibName);
return !m_availableTypesHashtable.IsNull();
}
-BOOL ReadyToRunInfo::TryLookupTypeTokenFromName(NameHandle *pName, mdToken * pFoundTypeToken)
+BOOL ReadyToRunInfo::TryLookupTypeTokenFromName(const NameHandle *pName, mdToken * pFoundTypeToken)
{
CONTRACTL
{
MethodDesc * GetMethodDescForEntryPoint(PCODE entryPoint);
BOOL HasHashtableOfTypes();
- BOOL TryLookupTypeTokenFromName(NameHandle *pName, mdToken * pFoundTypeToken);
+ BOOL TryLookupTypeTokenFromName(const NameHandle *pName, mdToken * pFoundTypeToken);
BOOL SkipTypeValidation()
{
for (COUNT_T i = 0; i < names.GetCount(); i ++)
{
// each extra name represents one more level of nesting
- LPCWSTR wname = names[i]->GetUnicode();
+ StackSString name(*(names[i]));
- MAKE_UTF8PTR_FROMWIDE(name, wname);
- typeName.SetName(name);
+ // The type name is expected to be lower-cased by the caller for case-insensitive lookups
+ if (bIgnoreCase)
+ name.LowerCase();
+
+ StackScratchBuffer buffer;
+ typeName.SetName(name.GetUTF8(buffer));
// typeName.m_pBucket gets set here if the type is found
// it will be used in the next iteration to look up the nested type
#ifndef DACCESS_COMPILE
//
-// Casing Table Helpers for use in the EE.
-//
-
-// // Convert szIn to lower case in the Invariant locale.
-INT32 InternalCasingHelper::InvariantToLower(__out_bcount_opt(cMaxBytes) LPUTF8 szOut, int cMaxBytes, __in_z LPCUTF8 szIn)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- } CONTRACTL_END
-
- return InvariantToLowerHelper(szOut, cMaxBytes, szIn, TRUE /*fAllowThrow*/);
-}
-
-// Convert szIn to lower case in the Invariant locale.
-INT32 InternalCasingHelper::InvariantToLowerNoThrow(__out_bcount_opt(cMaxBytes) LPUTF8 szOut, int cMaxBytes, __in_z LPCUTF8 szIn)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return 0;);
- } CONTRACTL_END
-
-
- return InvariantToLowerHelper(szOut, cMaxBytes, szIn, FALSE /*fAllowThrow*/);
-}
-
-// Convert szIn to lower case in the Invariant locale.
-INT32 InternalCasingHelper::InvariantToLowerHelper(__out_bcount_opt(cMaxBytes) LPUTF8 szOut, int cMaxBytes, __in_z LPCUTF8 szIn, BOOL fAllowThrow)
-{
-
- CONTRACTL {
- // This fcn can trigger a lazy load of the TextInfo class.
- if (fAllowThrow) THROWS; else NOTHROW;
- if (fAllowThrow) GC_TRIGGERS; else GC_NOTRIGGER;
- if (fAllowThrow) {INJECT_FAULT(COMPlusThrowOM());} else {INJECT_FAULT(return 0);}
- MODE_ANY;
-
- PRECONDITION((cMaxBytes == 0) || CheckPointer(szOut));
- PRECONDITION(CheckPointer(szIn));
- } CONTRACTL_END
-
- int inLength = (int)(strlen(szIn)+1);
- INT32 result = 0;
-
- LPCUTF8 szInSave = szIn;
- LPUTF8 szOutSave = szOut;
- BOOL bFoundHighChars=FALSE;
- //Compute our end point.
- LPCUTF8 szEnd;
- INT32 wideCopyLen;
-
- CQuickBytes qbOut;
- LPWSTR szWideOut;
-
- if (cMaxBytes != 0 && szOut == NULL) {
- if (fAllowThrow) {
- COMPlusThrowHR(ERROR_INVALID_PARAMETER);
- }
- SetLastError(ERROR_INVALID_PARAMETER);
- result = 0;
- goto Exit;
- }
-
- if (cMaxBytes) {
- szEnd = szOut + min(inLength, cMaxBytes);
- //Walk the string copying the characters. Change the case on
- //any character between A-Z.
- for (; szOut<szEnd; szOut++, szIn++) {
- if (*szIn>='A' && *szIn<='Z') {
- *szOut = *szIn | 0x20;
- }
- else {
- if (((UINT32)(*szIn))>((UINT32)0x80)) {
- bFoundHighChars = TRUE;
- break;
- }
- *szOut = *szIn;
- }
- }
-
- if (!bFoundHighChars) {
- //If we copied everything, tell them how many bytes we copied,
- //and arrange it so that the original position of the string + the returned
- //length gives us the position of the null (useful if we're appending).
- if (--inLength > cMaxBytes) {
- if (fAllowThrow) {
- COMPlusThrowHR(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
- }
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- result = 0;
- goto Exit;
- }
-
- result = inLength;
- goto Exit;
- }
- }
- else {
- szEnd = szIn + inLength;
- for (; szIn<szEnd; szIn++) {
- if (((UINT32)(*szIn))>((UINT32)0x80)) {
- bFoundHighChars = TRUE;
- break;
- }
- }
-
- if (!bFoundHighChars) {
- result = inLength;
- goto Exit;
- }
- }
-
- szOut = szOutSave;
-
-#ifndef FEATURE_PAL
-
- //convert the UTF8 to Unicode
- //MAKE_WIDEPTR_FROMUTF8(szInWide, szInSave);
-
- int __lszInWide;
- LPWSTR szInWide;
- __lszInWide = WszMultiByteToWideChar(CP_UTF8, 0, szInSave, -1, 0, 0);
- if (__lszInWide > MAKE_MAX_LENGTH)
- RaiseException(EXCEPTION_INT_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, 0);
- szInWide = (LPWSTR) alloca(__lszInWide*sizeof(WCHAR));
- if (szInWide == NULL) {
- if (fAllowThrow) {
- COMPlusThrowOM();
- } else {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- result = 0;
- goto Exit;
- }
- }
- if (0==WszMultiByteToWideChar(CP_UTF8, 0, szInSave, -1, szInWide, __lszInWide)) {
- RaiseException(ERROR_NO_UNICODE_TRANSLATION, EXCEPTION_NONCONTINUABLE, 0, 0);
- }
-
-
- wideCopyLen = (INT32)wcslen(szInWide)+1;
- if (fAllowThrow) {
- szWideOut = (LPWSTR)qbOut.AllocThrows(wideCopyLen * sizeof(WCHAR));
- }
- else {
- szWideOut = (LPWSTR)qbOut.AllocNoThrow(wideCopyLen * sizeof(WCHAR));
- if (!szWideOut) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- result = 0;
- goto Exit;
- }
- }
-
- //Do the casing operation
- ::LCMapStringEx(W(""), LCMAP_LOWERCASE, szInWide, wideCopyLen, szWideOut, wideCopyLen, NULL, NULL, 0);
-
- //Convert the Unicode back to UTF8
- result = WszWideCharToMultiByte(CP_UTF8, 0, szWideOut, wideCopyLen, szOut, cMaxBytes, NULL, NULL);
-
- if ((result == 0) && fAllowThrow) {
- COMPlusThrowWin32();
- }
-
-#endif // !FEATURE_PAL
-
-Exit:
- return result;
-}
-
-//
//
// COMCharacter and Helper functions
//
int GetRandomInt(int maxVal);
-class InternalCasingHelper {
-
- private:
- // Convert szIn to lower case in the Invariant locale.
- // TODO: NLS Arrowhead -Called by the two ToLowers)
- static INT32 InvariantToLowerHelper(__out_bcount_opt(cMaxBytes) LPUTF8 szOut, int cMaxBytes, __in_z LPCUTF8 szIn, BOOL fAllowThrow);
-
- public:
- //
- // Native helper functions to do correct casing operations in
- // runtime native code.
- //
-
- // Convert szIn to lower case in the Invariant locale. (WARNING: May throw.)
- static INT32 InvariantToLower(__out_bcount_opt(cMaxBytes) LPUTF8 szOut, int cMaxBytes, __in_z LPCUTF8 szIn);
-
- // Convert szIn to lower case in the Invariant locale. (WARNING: This version
- // won't throw but it will use stack space as an intermediary (so don't
- // use for ridiculously long strings.)
- static INT32 InvariantToLowerNoThrow(__out_bcount_opt(cMaxBytes) LPUTF8 szOut, int cMaxBytes, __in_z LPCUTF8 szIn);
-};
-
//
//
// COMCHARACTER