//************************************************************************************** // Filename: CEncodingArray.cp // Copyright © 2000 Tomasz Kukielka. All rights reserved. // // Description: An array of encoding values with their names // sorted by name, accessors mostly by encoding value // //************************************************************************************** // Revision History: // Tuesday, May 16, 2000 - Original //************************************************************************************** #include "CEncodingArray.h" #include "CConverter.h" CEncodingArray::CEncodingArray() : LVariableArray(new CEncNameComparator(), true) { } CEncodingArray::~CEncodingArray() { } ArrayIndexT CEncodingArray::AddEncoding(TextEncoding inEncoding) { EncAndNameRec element; element.encoding = inEncoding; CConverter::GetEncodingName( element.encoding, kTextEncodingBaseName, element.name ); return AddItem( &element, sizeof(TextEncoding) + element.name[0] + 1 ); } Boolean CEncodingArray::FetchEncValueAt( ArrayIndexT inAtIndex, TextEncoding* outEnc) const { UInt32 theSize = sizeof(TextEncoding); return FetchItemAt(inAtIndex, (void *)outEnc, theSize);//only first long, which is encoding value } Boolean CEncodingArray::FetchEncNameAt( ArrayIndexT inAtIndex, Str255 outName) const { Boolean itemExists = ValidIndex(inAtIndex); if (itemExists) { EncAndNameRec *theEnc = (EncAndNameRec *)GetItemPtr(inAtIndex); UInt32 dataSize = GrabItemSize(inAtIndex); dataSize -= sizeof(TextEncoding); //text size only Assert_( (theEnc->name[0] + 1) == dataSize );//plus one for string len byte ::BlockMoveData(theEnc->name, outName, (SInt32) dataSize); } return itemExists; } ArrayIndexT CEncodingArray::FetchIndexByEncoding( TextEncoding inEncoding ) { LComparator *prevComparator = mComparator;//don't delete it, just change mComparator = CEncValueComparator::GetComparator(); bool prevSorted = mIsSorted; mIsSorted = false;//use linear search because our array is sorted by name ArrayIndexT outIndx = FetchIndexOf( &inEncoding ); //return to original state mIsSorted = prevSorted; mComparator = prevComparator; return outIndx; } ArrayIndexT CEncodingArray::FetchIndexByEncodingBase( TextEncoding inEncoding ) { TextEncodingBase theBase = ::GetTextEncodingBase(inEncoding); Boolean isFound = false; ArrayIndexT i; for( i = 1; i <= mItemCount; i++) { UInt32 theSize = sizeof(TextEncoding); TextEncoding currEnc; FetchItemAt(i, (void *)&currEnc, theSize); if( ::GetTextEncodingBase( currEnc ) == theBase ) { isFound = true; break; } } if(isFound) return i; return index_Bad; } #pragma mark - // =========================================================================== // ¥ CEncNameComparator // =========================================================================== // Compares encoding names CEncNameComparator* CEncNameComparator::sEncNameComparator = nil; CEncNameComparator::CEncNameComparator() { } CEncNameComparator::~CEncNameComparator() { if(sEncNameComparator == this) sEncNameComparator = nil; } SInt32 CEncNameComparator::Compare( const void* inItemOne, const void* inItemTwo, UInt32 inSizeOne, UInt32 inSizeTwo) const { #ifndef Debug_Signal #pragma unused (inSizeOne, inSizeTwo) #endif EncAndNameRec *enc1 = (EncAndNameRec *)inItemOne; EncAndNameRec *enc2 = (EncAndNameRec *)inItemTwo; Assert_(inSizeOne == (enc1->name[0] + 1 + sizeof(TextEncoding)) ); Assert_(inSizeTwo == (enc2->name[0] + 1 + sizeof(TextEncoding)) ); return ::RelString( enc1->name, enc2->name, true, true ); } /* use inherited: return (Compare(inItemOne, inItemTwo, inSizeOne, inSizeTwo) == 0); Boolean CEncNameComparator::IsEqualTo( const void* inItemOne, const void* inItemTwo, UInt32 inSizeOne, UInt32 inSizeTwo) const { //when encoding value is equal, it is enough return ( ((EncAndNameRec*)inItemOne)->encoding == ((EncAndNameRec*)inItemTwo)->encoding ); } */ CEncNameComparator* CEncNameComparator::GetComparator() { if (sEncNameComparator == nil) { sEncNameComparator = new CEncNameComparator; } return sEncNameComparator; } CEncNameComparator* CEncNameComparator::Clone() { return new CEncNameComparator; } #pragma mark - // =========================================================================== // ¥ CEncValueComparator // =========================================================================== // Compares items as text encoding values CEncValueComparator* CEncValueComparator::sEncValueComparator = nil; CEncValueComparator::CEncValueComparator() { } CEncValueComparator::~CEncValueComparator() { if(sEncValueComparator == this) sEncValueComparator = nil; } SInt32 CEncValueComparator::Compare( const void* inItemOne, const void* inItemTwo, UInt32 /* inSizeOne */, UInt32 /* inSizeTwo */) const { SInt32 result = ::GetTextEncodingBase( (*(TextEncoding*) inItemOne) ) - ::GetTextEncodingBase( (*(TextEncoding*) inItemTwo) ); if(result == 0)//only when base encodings are the same - we perform extended comparizon of variants/forms result = ( (*(TextEncoding*) inItemOne) - (*(TextEncoding*) inItemTwo) ); return result; } Boolean CEncValueComparator::IsEqualTo( const void* inItemOne, const void* inItemTwo, UInt32 /* inSizeOne */, UInt32 /* inSizeTwo */) const { return ( (*(TextEncoding*) inItemOne) == (*(TextEncoding*) inItemTwo) ); } CEncValueComparator* CEncValueComparator::GetComparator() { if (sEncValueComparator == nil) { sEncValueComparator = new CEncValueComparator; } return sEncValueComparator; } CEncValueComparator* CEncValueComparator::Clone() { return new CEncValueComparator; }