aboutsummaryrefslogtreecommitdiff
path: root/Src/nde/osx/StringField.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/nde/osx/StringField.cpp')
-rw-r--r--Src/nde/osx/StringField.cpp297
1 files changed, 297 insertions, 0 deletions
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;
+}
+