internal unsafe bool Validate()
{
if (memoryMapFile == null) // we only validate custom cultures.
return true;
long fileSize = memoryMapFile.FileSize;
if (sizeof(EndianessHeader) + sizeof(CultureTableHeader) + sizeof(CultureTableData) + 2 * sizeof(int) > fileSize)
return false;
// EndianessHeader
EndianessHeader* pEndianHeader = (EndianessHeader*) m_pDataFileStart;
#if BIGENDIAN
if (pEndianHeader->beOffset > fileSize)
return false;
#else
if (pEndianHeader->leOffset > fileSize)
return false;
#endif // BIGENDIAN
// CultureTableHeader
if (m_pCultureHeader->offsetToCultureItemData + m_pCultureHeader->sizeCultureItem > fileSize) { return false; }
if (m_pCultureHeader->cultureIDTableOffset > fileSize) { return false; }
if (m_pCultureHeader->cultureNameTableOffset + sizeofNameOffsetItem > fileSize) { return false; }
if (m_pCultureHeader->regionNameTableOffset > fileSize) { return false; }
if (m_pCultureHeader->offsetToCalendarItemData + m_pCultureHeader->sizeCalendarItem > fileSize){ return false; }
if (m_pCultureHeader->ietfNameTableOffset > fileSize) { return false; }
if (m_pCultureHeader->offsetToDataPool > fileSize) { return false; }
ushort *pDataPool = (ushort*)(m_pDataFileStart + m_pCultureHeader->offsetToDataPool);
int poolSizeInChar = (int) (fileSize - ((long)pDataPool - (long)m_pDataFileStart)) / 2; // number of characters in the pool
if (poolSizeInChar <= 0)
return false;
// SNAME
uint sNameOffset = (uint)((char *)(m_pDataFileStart + m_pCultureHeader->cultureNameTableOffset))[0];
// CultureTableData
CultureTableData *cultureData = (CultureTableData*) (m_pDataFileStart + m_pCultureHeader->offsetToCultureItemData);
if (cultureData->iLanguage == 0x7F || !IsValidLcid(cultureData->iLanguage, true))
return false;
string cultureName = CheckAndGetTheString(pDataPool, cultureData->sName, poolSizeInChar);
if (String.IsNullOrEmpty(cultureName))
return false;
if (sNameOffset != cultureData->sName)
{
if (!cultureName.Equals(CheckAndGetTheString(pDataPool, sNameOffset, poolSizeInChar)))
return false;
}
string parentName = CheckAndGetTheString(pDataPool, cultureData->sParent, poolSizeInChar);
if (parentName == null || parentName.Equals(cultureName, StringComparison.OrdinalIgnoreCase))
return false;
if (!IsValidLcid((int) cultureData->iTextInfo, false) || !IsValidLcid((int) cultureData->iCompareInfo, false))
return false;
// We could use the reflection instead of checking each field manually but this was hurting
// the performance (almost 35% from the creation time)
if (!ValidateString(pDataPool, cultureData->waGrouping, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->waMonetaryGrouping, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sListSeparator, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sDecimalSeparator, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sThousandSeparator, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sCurrency, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sMonetaryDecimal, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sMonetaryThousand, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sPositiveSign, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNegativeSign, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sAM1159, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sPM2359, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saNativeDigits, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saTimeFormat, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saShortDate, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saLongDate, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saYearMonth, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saDuration, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->waCalendars, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sAbbrevLang, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sISO639Language, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sEnglishLanguage, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNativeLanguage, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sEnglishCountry, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNativeCountry, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sAbbrevCountry, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sISO3166CountryName, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sIntlMonetarySymbol, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sEnglishCurrency, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNativeCurrency, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->waFontSignature, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sISO639Language2, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sISO3166CountryName2, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saDayNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saAbbrevDayNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saMonthNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saAbbrevMonthNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saMonthGenitiveNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saAbbrevMonthGenitiveNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saNativeCalendarNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saAltSortID, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sEnglishDisplayName, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNativeDisplayName, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sPercent, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNaN, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sPositiveInfinity, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sNegativeInfinity, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sMonthDay, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sAdEra, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sAbbrevAdEra, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sRegionName, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sConsoleFallbackName, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saShortTime, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saSuperShortDayNames, poolSizeInChar)) { return false; }
if (!ValidateStringArray(pDataPool, cultureData->saDateWords, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sSpecificCulture, poolSizeInChar)) { return false; }
if (!ValidateString(pDataPool, cultureData->sIetfLanguage, poolSizeInChar)) { return false; }
/*
Object cultureTableData = (object) *cultureData;
Type type = cultureTableData.GetType();
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int i=0; i<fields.Length; i++)
{
BCLDebug.Assert(
fields[i].Name[0] == 'i' ||
fields[i].Name[0] == 's' ||
fields[i].Name[0] == 'w' , "Invalid structure field name.");
if (fields[i].Name.Length<2 || (fields[i].Name[0] != 's' && fields[i].Name[0] != 'w'))
continue;
Object objectValue = type.InvokeMember(
fields[i].Name,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField,
null,
cultureTableData,
null,
CultureInfo.InvariantCulture);
int value;
if (fields[i].FieldType == typeof(System.UInt16))
value = (int) (ushort) objectValue;
else if (fields[i].FieldType == typeof(System.UInt32))
value = (int) (uint) objectValue;
else
return false;
bool result = false;
if (fields[i].Name[0] == 's')
{
if (fields[i].Name[1] == 'a')
result = ValidateStringArray(value, poolSizeInChar);
else
result = ValidateString(value, poolSizeInChar);
}
else
{
BCLDebug.Assert(fields[i].Name[1] == 'a', "Expected field starts with wa.");
result = ValidateString(value, poolSizeInChar);
}
if (!result)
return false;
}
*/
return true;
}
#endregion CustomCultureValidation