123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /* ---------------------------------------------------------------------------
- Nullsoft Database Engine
- --------------------
- codename: Near Death Experience
- --------------------------------------------------------------------------- */
- /* ---------------------------------------------------------------------------
- StringField Class
- Mac OS X (CFStringRef) implementation
- --------------------------------------------------------------------------- */
- #include "../nde.h"
- #include "StringField.h"
- //---------------------------------------------------------------------------
- StringField::StringField(CFStringRef Str)
- {
- InitField();
- Type = FIELD_STRING;
- if (Str)
- {
- SetNDEString(Str);
- }
- }
- //---------------------------------------------------------------------------
- void StringField::InitField(void)
- {
- Type = FIELD_STRING;
- String=0;
- }
- //---------------------------------------------------------------------------
- StringField::StringField()
- {
- InitField();
- }
- //---------------------------------------------------------------------------
- StringField::~StringField()
- {
- if (String)
- CFRelease(String);
- }
- //---------------------------------------------------------------------------
- void StringField::ReadTypedData(const uint8_t *data, size_t len)
- {
- unsigned short c;
- CHECK_SHORT(len);
- c = (unsigned short)(data[0]|(data[1]<<8));
- data+=2;
- if (c)
- {
- bool unicode=false;
- if (c >= 2 // enough room for BOM
- && (c % 2) == 0) // can't be unicode if it's not an even multiple of 2
- {
- wchar_t BOM=0;
- memcpy(&BOM, data, 2);
- if (BOM == 0xFEFF || BOM == 0xFFFE)
- {
- unicode=true;
- }
- }
- CHECK_BIN(len, c);
- if (unicode)
- {
- if (String)
- CFRelease(String);
- String = CFStringCreateWithBytes(kCFAllocatorDefault, data, c, kCFStringEncodingUTF16, true);
- }
- else
- {
- if (String)
- CFRelease(String);
- String = CFStringCreateWithBytes(kCFAllocatorDefault, data, c, kCFStringEncodingWindowsLatin1, false);
- }
- }
- }
- //---------------------------------------------------------------------------
- void StringField::WriteTypedData(uint8_t *data, size_t len)
- {
- int pos=0;
- CHECK_SHORT(len);
- if (String)
- {
- CFIndex lengthRequired=0;
- CFStringGetBytes(String, CFRangeMake(0, CFStringGetLength(String)), kCFStringEncodingUTF16, 0, true, NULL, 0, &lengthRequired);
- CHECK_BIN(len, lengthRequired+2);
- PUT_SHORT(lengthRequired); pos+=2;
- CFStringGetBytes(String, CFRangeMake(0, CFStringGetLength(String)), kCFStringEncodingUTF16, 0, true, data+pos, lengthRequired, 0);
- }
- else
- {
- PUT_SHORT(0);
- }
- }
- CFStringRef StringField::GetString()
- {
- return String;
- }
- void StringField::SetNDEString(CFStringRef Str)
- {
- if (!Str)
- return;
-
- CFStringRef old = String;
- String = (CFStringRef)CFRetain(Str);
- CFRelease(old);
- }
- //---------------------------------------------------------------------------
- size_t StringField::GetDataSize(void)
- {
- if (String)
- {
- CFIndex lengthRequired=0;
- CFStringGetBytes(String, CFRangeMake(0, CFStringGetLength(String)), kCFStringEncodingUTF16, 0, true, NULL, 0, &lengthRequired);
- return lengthRequired+2;
- }
- else
- return 2;
- }
- //---------------------------------------------------------------------------
- int StringField::Compare(Field *Entry)
- {
- if (!Entry) return -1;
- if (Entry->GetType() != GetType()) return 0;
- CFStringRef compareString = ((StringField*)Entry)->GetString();
- if (!String && !compareString) return 0;
- if (!String && compareString) return 1;
- if (!compareString) return -1;
- return CFStringCompare(String, compareString, kCFCompareCaseInsensitive|kCFCompareNonliteral|kCFCompareDiacriticInsensitive);
- }
- //---------------------------------------------------------------------------
- int StringField::Starts(Field *Entry)
- {
- if (!Entry) return -1;
- if (Entry->GetType() != GetType()) return 0;
- CFStringRef compareString = ((StringField*)Entry)->GetString();
- if (!String || !compareString) return 0;
- CFRange findRange = CFStringFind(String, compareString, kCFCompareCaseInsensitive|kCFCompareNonliteral|kCFCompareAnchored|kCFCompareDiacriticInsensitive);
- if (findRange.location == kCFNotFound)
- return 0;
- return findRange.location == 0;
- }
- //---------------------------------------------------------------------------
- int StringField::Contains(Field *Entry)
- {
- if (!Entry) return -1;
- if (Entry->GetType() != GetType()) return 0;
- CFStringRef compareString = ((StringField*)Entry)->GetString();
- if (!String || !compareString) return 0;
- CFRange findRange = CFStringFind(String, compareString, kCFCompareCaseInsensitive|kCFCompareNonliteral|kCFCompareDiacriticInsensitive);
- return findRange.location != kCFNotFound;
- }
- Field *StringField::Clone(Table *pTable)
- {
- StringField *clone = new StringField(String);
- clone->Pos = FIELD_CLONE;
- clone->ID = ID;
- clone->MaxSizeOnDisk = GetDataSize();
- return clone;
- }
- //---------------------------------------------------------------------------
- bool StringField::ApplyFilter(Field *Data, int op)
- {
- if (op == FILTER_ISEMPTY || op == FILTER_ISNOTEMPTY)
- {
- bool r = (op == FILTER_ISEMPTY);
- if (!String)
- return r;
- if (CFStringGetLength(String) == 0)
- return r;
- return !r;
- }
- //
- bool r;
- StringField *compField = (StringField *)Data;
- switch (op)
- {
- case FILTER_EQUALS:
- r = !Compare(Data);
- break;
- case FILTER_NOTEQUALS:
- r = !!Compare(Data);
- break;
- case FILTER_CONTAINS:
- r = !!Contains(Data);
- break;
- case FILTER_NOTCONTAINS:
- r = !Contains(Data);
- break;
- case FILTER_ABOVE:
- r = (bool)(Compare(Data) > 0);
- break;
- case FILTER_ABOVEOREQUAL:
- r = (bool)(Compare(compField) >= 0);
- break;
- case FILTER_BELOW:
- r = (bool)(Compare(compField) < 0);
- break;
- case FILTER_BELOWOREQUAL:
- r = (bool)(Compare(compField) <= 0);
- break;
- case FILTER_BEGINS:
- r = !!Starts(compField);
- break;
- case FILTER_ENDS:
- {
- CFStringRef compareString = ((StringField*)Data)->GetString();
- if (!String || !compareString) return 0;
- CFRange findRange = CFStringFind(String, compareString, kCFCompareCaseInsensitive|kCFCompareNonliteral|kCFCompareAnchored|kCFCompareBackwards);
- if (findRange.location == kCFNotFound)
- r=0;
- else
- r = findRange.location != 0;
- }
- break;
- case FILTER_LIKE:
- /* TODO
- if (compField->optimized_the)
- p = compField->optimized_the;
- else
- {
- SKIP_THE_AND_WHITESPACEW(p);
- compField->optimized_the = p;
- }
- if (optimized_the)
- d = optimized_the;
- else
- {
- SKIP_THE_AND_WHITESPACEW(d);
- optimized_the=d;
- }
- r = (bool)(nde_wcsicmp(d, p) == 0);
- */
- r = !!Compare(compField);
- break;
- case FILTER_BEGINSLIKE:
- /*
- if (compField->optimized_the)
- p = compField->optimized_the;
- else
- {
- SKIP_THE_AND_WHITESPACEW(p);
- compField->optimized_the = p;
- }
- if (optimized_the)
- d = optimized_the;
- else
- {
- SKIP_THE_AND_WHITESPACEW(d);
- optimized_the=d;
- }
- r = (bool)(nde_wcsnicmp(d, p, wcslen(p)) == 0);
- */
- r = !!Starts(compField);
- break;
- default:
- r = true;
- break;
- }
- return r;
- }
|