Skip to content

Fix the remaining culture-sensitive lookups (Esent type names, unit symbols, property sets) - #673

Open
oguzozshn wants to merge 3 commits into
xBimTeam:developfrom
oguzozshn:fix/remaining-culture-sensitivity
Open

Fix the remaining culture-sensitive lookups (Esent type names, unit symbols, property sets)#673
oguzozshn wants to merge 3 commits into
xBimTeam:developfrom
oguzozshn:fix/remaining-culture-sensitivity

Conversation

@oguzozshn

Copy link
Copy Markdown

Follow-up to #672, taking you up on the offer to look at the remaining culture-sensitive code.
Three separate defects, one commit each, each with a test that fails without its fix.

1. Express type name lookup in the Esent store

EntityCollection.OfType(string) already upper-cases with the invariant culture before hitting the
metadata dictionary, which is keyed on invariant upper case. PersistedEntityInstanceCache.OfType
used ToUpper(), so the same public API returned results or nothing depending on which store backed
the model. Under tr-TR, "IfcBuilding" upper-cases to "IFCBUİLDİNG" and never matches.

The test deliberately queries IfcBuilding rather than IfcWall — a type name only trips the
Turkish casing rules if it contains a lower case i, and IfcWall does not.

2. Imperial unit symbols

IfcConversionBasedUnit.Symbol matched the unit name against "FEET", "FOOT" and "INCH" after
upper-casing it. Under tr-TR, "inch" becomes "İNCH", which does not contain "INCH", so the
symbol fell through to the raw name instead of "in". Replaced with an ordinal case-insensitive
IndexOf, which also drops the intermediate allocation. All three schemas.

3. Property set lookups

GetPropertySet and GetElementQuantity implemented their caseSensitive: false option with
culture-sensitive comparisons — string.Compare(a, b, ignoreCase), one explicit
CurrentCultureIgnoreCase, and a pair of ToLower() calls. Property set names are IFC identifiers
rather than prose, so these now use OrdinalIgnoreCase, and the case-sensitive path Ordinal.
Ifc4x3 has no equivalent helpers.

Deliberately left alone

I went through every remaining ToUpper() / ToLower() in the tree and did not touch:

  • ~2650 occurrences in the generated schema projects — all of the form
    GetType().Name.ToUpper() inside XbimParserException messages. They only affect the text of an
    error, and they come from the code generator rather than these files.
  • XbimXmlReader3's switch (pt.ToString().ToLower()) — its only labels are "string" and
    "boolean"; neither contains a lower case i, so the casing cannot change the outcome.
  • The Esent enum write in IPersistEntityExtensions — I had changed this, then reverted it after
    confirming every IFC enum member is already upper case ASCII, which makes ToUpper() a no-op
    there. It seemed better to leave the diff honest than to pad it.

Happy to fold any of these in if you would rather have the codebase uniform.

Verification

On a tr-TR machine: Xbim.Essentials.Tests 500/500 on both net10.0 and net48,
Xbim.Essentials.NetCore.Tests 94/94. Each fix was also checked by stashing it and confirming its
test fails.

Refs #670.

EntityCollection.OfType(string) already upper-cases with the invariant culture
before hitting the metadata dictionary, which is keyed on invariant upper case.
The Esent implementation used the culture-sensitive ToUpper(), so the same
public API returned results or nothing depending on which store backed the
model: under tr-TR "IfcBuilding" upper-cases to "IFCBUİLDİNG" and never matches.

The added test uses IfcBuilding rather than IfcWall on purpose - a type name
only trips the Turkish casing rules if it contains a lower case 'i'.

Refs xBimTeam#670
IfcConversionBasedUnit.Symbol matched the unit name against "FEET", "FOOT" and
"INCH" by upper-casing it first. ToUpper() is culture sensitive, so under the
Turkish rules "inch" becomes "İNCH", which does not contain "INCH", and the
symbol fell through to the raw name instead of "in".

Replaced with an ordinal case-insensitive IndexOf, which also drops the
intermediate allocation. Applied to all three schemas.

Refs xBimTeam#670
GetPropertySet and GetElementQuantity implemented their caseSensitive: false
option with culture-sensitive comparisons - string.Compare(a, b, ignoreCase),
CurrentCultureIgnoreCase, and a pair of ToLower() calls. Turkish treats 'i' and
'I' as different letters, so under tr-TR looking up "Pset_WindowCommon" as
"PSET_WINDOWCOMMON" found nothing.

Property set names are IFC identifiers rather than prose, so the case-insensitive
path now uses OrdinalIgnoreCase, and the case-sensitive path Ordinal. Ifc4x3 has
no equivalent helpers.

Refs xBimTeam#670
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant