From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/nde/osx/StringField.cpp | 297 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 Src/nde/osx/StringField.cpp (limited to 'Src/nde/osx/StringField.cpp') diff --git a/Src/nde/osx/StringField.cpp b/Src/nde/osx/StringField.cpp new file mode 100644 index 00000000..91c1c4c4 --- /dev/null +++ b/Src/nde/osx/StringField.cpp @@ -0,0 +1,297 @@ +/* --------------------------------------------------------------------------- +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; +} + -- cgit