#ifndef BZS_DB_PROTOCOL_TDAP_FIELD_COMP_H #define BZS_DB_PROTOCOL_TDAP_FIELD_COMP_H /*================================================================= Copyright (C) 2014 BizStation Corp All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =================================================================*/ #include #include #include #include inline __int64 changeEndian2(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[1]; l[1] = r[0]; return ret; } inline __int64 changeEndian3(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[2]; l[1] = r[1]; l[2] = r[0]; return ret; } inline __int64 changeEndian4(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[3]; l[1] = r[2]; l[2] = r[1]; l[3] = r[0]; return ret; } inline __int64 changeEndian5(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[4]; l[1] = r[3]; l[2] = r[2]; l[3] = r[1]; l[4] = r[0]; return ret; } inline __int64 changeEndian6(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[5]; l[1] = r[4]; l[2] = r[3]; l[3] = r[2]; l[4] = r[1]; l[5] = r[0]; return ret; } inline __int64 changeEndian7(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[6]; l[1] = r[5]; l[2] = r[4]; l[3] = r[3]; l[4] = r[2]; l[5] = r[1]; l[6] = r[0]; return ret; } inline __int64 changeEndian8(__int64 v) { __int64 ret = 0; char* l = (char*)&ret; char* r = (char*)&v; l[0] = r[7]; l[1] = r[6]; l[2] = r[5]; l[3] = r[4]; l[4] = r[3]; l[5] = r[2]; l[6] = r[1]; l[7] = r[0]; return ret; } inline __int64 changeEndian(__int64 v, int len) { switch(len) { case 1: return v; case 2: return changeEndian2(v); case 3: return changeEndian3(v); case 4: return changeEndian4(v); case 5: return changeEndian5(v); case 6: return changeEndian6(v); case 7: return changeEndian7(v); case 8: return changeEndian8(v); } return v; } inline int int24toInt(const char* p) { return ((*((int*)p) & 0xFFFFFF) << 8) / 0x100; } inline unsigned int int24toUint(const char* p) { return *((unsigned int*)p) & 0xFFFFFF; } inline __int64 myBittoInt64(const char* p, int len) { __int64 v = 0; memcpy(&v, p, len); return changeEndian8(v); } inline void storeInt24(int v, char* p) { memcpy(p, &v, 3); } inline void storeUint24(unsigned int v, char* p) { memcpy(p, &v, 3); } inline int compareUint24(const char* l, const char* r) { unsigned int lv = int24toUint(l); unsigned int rv = int24toUint(r);; if (lv < rv) return -1; if (lv > rv) return 1; return 0; } inline int compareInt24(const char* l, const char* r) { int lv = int24toInt(l); int rv = int24toInt(r); if (lv < rv) return -1; else if (lv > rv) return 1; return 0; } template inline int compare(const char* l, const char* r) { if (*((T*)l) < *((T*)r)) return -1; else if (*((T*)l) > *((T*)r)) return 1; return 0; } template inline int bitMask(const char* l, const char* r) { T v = *((T*)l) & *((T*)r); v = (*((T*)r) - v); /* When T is __int64 then v is incoreect value. Because return size is int. */ return (v > 0) ? 1 : ((v < 0) ? -1 : 0); } template inline int compare(T l, T r) { if (l < r) return -1; else if (l > r) return 1; return 0; } template inline int compareVartype(const char* l, const char* r, bool bin, bool all, bool incase) { int llen = (*(T*)l); int rlen = (*(T*)r); int tmp = std::min(llen, rlen); if (incase) tmp = _strnicmp(l + sizeof(T), r + sizeof(T), tmp); else if (bin) tmp = memcmp(l + sizeof(T), r + sizeof(T), tmp); else tmp = strncmp(l + sizeof(T), r + sizeof(T), tmp); if (all) return (tmp == 0) ? compare(llen, rlen) : tmp; // match complete return (tmp == 0 && (llen < rlen)) ? -1 : tmp; // match a part } template inline int compareWvartype(const char* l, const char* r, bool bin, bool all, bool incase) { int llen = (*(T*)l) / sizeof(char16_t); int rlen = (*(T*)r) / sizeof(char16_t); int tmp = std::min(llen, rlen); if (incase) tmp = wcsnicmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)), tmp); else if (bin) tmp = wmemcmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)), tmp); else tmp = wcsncmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)), tmp); if (all) return (tmp == 0) ? compare(llen, rlen) : tmp; // match complete return (tmp == 0 && (llen < rlen)) ? -1 : tmp; // match a part } inline int compareBlobType(const char* l, const char* r, bool bin, bool all, bool incase, int sizeByte) { int llen = 0; int rlen = 0; memcpy(&llen, l, sizeByte); memcpy(&rlen, r, sizeByte); int tmp = std::min(llen, rlen); const char* lptr = *((const char**)(l + sizeByte)); const char* rptr = r + sizeByte; if (incase) tmp = _strnicmp(lptr, rptr, tmp); else if (bin) tmp = memcmp(lptr, rptr, tmp); else tmp = strncmp(lptr, rptr, tmp); if (all) return (tmp == 0) ? compare(llen, rlen) : tmp; return (tmp == 0 && (llen < rlen)) ? -1 : tmp; } /* int nullComp(bool lnull, bool rnull, char log) lnull rnull log ret ----------------------------------------------- true true isNull 0 true true isNotNull -1 true false 0 -1 false true isNull 1 false true isNotNull 0 false false 0 2 ----------------------------------------------- real value example lval rval ret ----------------------------------------------- NULL isNull 0 NULL isNotNull -1 NULL 2 -1 1 isNull 1 1 isNotNull 0 1 2 2 ----------------------------------------------- */ inline int nullComp(bool lnull, bool rnull, char log) { if (lnull) return (log == eIsNull) ? 0 : -1; else if (rnull) return (log == eIsNull) ? 1 : 0; return 2; } template inline int compBitAnd(const char* l, const char* r, int len) { return bitMask(l, r); } inline int compBitAnd24(const char* l, const char* r, int len) { int lv = int24toInt(l); int rv = int24toInt(r); return bitMask((const char*)&lv, (const char*)&rv); } inline int compBitAnd64(const char* l, const char* r, int len) { __int64 lv = 0; __int64 rv = 0; memcpy(&lv, l, len); memcpy(&rv, r, len); return bitMask<__int64>((const char*)&lv, (const char*)&rv); } template inline int compNumber(const char* l, const char* r, int len) { return compare(l, r); } inline int compNumber24(const char* l, const char* r, int len) { return compareInt24(l, r); } inline int compNumberU24(const char* l, const char* r, int len) { return compareUint24(l, r); } inline int compMem(const char* l, const char* r, int len) { return memcmp(l, r, len); } inline int compString(const char* l, const char* r, int len) { return strncmp(l, r, len); } inline int compiString(const char* l, const char* r, int len) { return _strnicmp(l, r, len); } inline int compWString(const char* l, const char* r, int len) { return wcsncmp16((char16_t*)l, (char16_t*)r, len/2); } inline int compiWString(const char* l, const char* r, int len) { return wcsnicmp16((char16_t*)l, (char16_t*)r, len/2); } #define T_BIN true #define T_STR false #define T_INCASE true #define T_CASE false #define T_CMP_ALL true #define T_CMP_PART false template inline int compVarString(const char* l, const char* r, int len) { return compareVartype(l, r, T_STR, all, T_CASE); } template inline int compVarString_bin(const char* l, const char* r, int len) { return compareVartype(l, r, T_BIN, all, T_CASE); } template inline int compVarString_i(const char* l, const char* r, int len) { return compareVartype(l, r, T_STR, all, T_INCASE); } template inline int compVarString_bin_i(const char* l, const char* r, int len) { return compareVartype(l, r, T_BIN, all, T_INCASE); } template inline int compWVarString(const char* l, const char* r, int len) { return compareWvartype(l, r, T_STR, all, T_CASE); } template inline int compWVarString_bin(const char* l, const char* r, int len) { return compareWvartype(l, r, T_BIN, all, T_CASE); } template inline int compWVarString_i(const char* l, const char* r, int len) { return compareWvartype(l, r, T_STR, all, T_INCASE); } template inline int compWVarString_bin_i(const char* l, const char* r, int len) { return compareWvartype(l, r, T_BIN, all, T_INCASE); } template inline int compBlob(const char* l, const char* r, int len) { return compareBlobType(l, r, T_STR, all, T_CASE, sizeByte); } template inline int compBlob_bin(const char* l, const char* r, int len) { return compareBlobType(l, r, T_BIN, all, T_CASE, sizeByte); } template inline int compBlob_i(const char* l, const char* r, int len) { return compareBlobType(l, r, T_STR, all, T_INCASE, sizeByte); } template inline int compBlob_bin_i(const char* l, const char* r, int len) { return compareBlobType(l, r, T_BIN, all, T_INCASE, sizeByte); } typedef int (*comp1Func)(const char* l, const char* r,int len); typedef bool (*judgeFunc)(int); inline comp1Func getCompFunc(uchar_td type, ushort_td len, char logType, int sizeByte) { bool compAll = (logType & CMPLOGICAL_VAR_COMP_ALL) != 0; bool incase = (logType & CMPLOGICAL_CASEINSENSITIVE) != 0; switch (type) { case ft_integer: case ft_autoinc: case ft_currency: { if (logType & (char)eBitAnd) { switch (len) { case 1: return &compBitAnd; case 2: return &compBitAnd; case 3: return &compBitAnd24; case 4: return &compBitAnd; case 8: return &compBitAnd<__int64>; } }else { switch (len) { case 1: return &compNumber; case 2: return &compNumber; case 3: return &compNumber24; case 4: return &compNumber; case 8: return &compNumber<__int64>; } } } case ft_mychar: case ft_string: if (incase) return &compiString; return &compMem; case ft_zstring: case ft_note: if (incase) return &compiString; return &compString; case ft_logical: case ft_uinteger: case ft_autoIncUnsigned: case ft_date: case ft_time: case ft_timestamp: case ft_myyear: case ft_mydate: case ft_mytime_num_cmp: case ft_mydatetime_num_cmp: case ft_mytimestamp_num_cmp: case ft_set: case ft_enum: { if (logType & (char)eBitAnd) { switch (len) { case 1: return &compBitAnd; case 2: return &compBitAnd; case 3: return &compBitAnd24; case 4: return &compBitAnd; case 8: return &compBitAnd<__int64>; } }else { switch (len) { case 1: return &compNumber; case 2: return &compNumber; case 3: return &compNumberU24; case 4: return &compNumber; case 8: return &compNumber; } } } case ft_bit: if (logType & (char)eBitAnd) return &compBitAnd64; return &compMem; case ft_mytime: case ft_mydatetime: case ft_mytimestamp: case ft_mydecimal: return &compMem; case ft_float: switch (len) { case 4: return &compNumber; case 8: return &compNumber; } case ft_mywchar: case ft_wstring: case ft_wzstring: if (incase) return &compiWString; if ((type == ft_wstring) || (type == ft_mywchar)) return &compMem; return &compWString; case ft_lstring: case ft_myvarchar: if (sizeByte == 1) { if (incase) { if (compAll) return &compVarString_i; return &compVarString_i; }else { if (compAll) return &compVarString; return &compVarString; } } if (incase) { if (compAll) return &compVarString_i; return &compVarString_i; } if (compAll) return &compVarString; return &compVarString; case ft_myvarbinary: if (sizeByte == 1) { if (incase) { if (compAll) return &compVarString_bin_i; return &compVarString_bin_i; } if (compAll) return &compVarString_bin; return &compVarString_bin; } if (incase) { if (compAll) return &compVarString_bin_i; return &compVarString_bin_i; } if (compAll) return &compVarString_bin; return &compVarString_bin; case ft_mywvarchar: if (sizeByte == 1) { if (incase) { if (compAll) return &compWVarString_i; return &compWVarString_i; } if (compAll) return &compWVarString; return &compWVarString; } if (incase) { if (compAll) return &compWVarString_i; return &compWVarString_i; } if (compAll) return &compWVarString; return &compWVarString; case ft_mywvarbinary: if (sizeByte == 1) { if (incase) { if (compAll) return &compWVarString_bin_i; return &compWVarString_bin_i; } if (compAll) return &compWVarString_bin; return &compWVarString_bin; } if (incase) { if (compAll) return &compWVarString_bin_i; return &compWVarString_bin_i; } if (compAll) return &compWVarString_bin; return &compWVarString_bin; case ft_mytext: { if (compAll) { if (incase) { switch(sizeByte) { case 1:return &compBlob_i<1, T_CMP_ALL>; case 2:return &compBlob_i<2, T_CMP_ALL>; case 3:return &compBlob_i<3, T_CMP_ALL>; case 4:return &compBlob_i<4, T_CMP_ALL>; } } switch(sizeByte) { case 1:return &compBlob<1, T_CMP_ALL>; case 2:return &compBlob<2, T_CMP_ALL>; case 3:return &compBlob<3, T_CMP_ALL>; case 4:return &compBlob<4, T_CMP_ALL>; } } if (incase) { switch(sizeByte) { case 1:return &compBlob_i<1, T_CMP_PART>; case 2:return &compBlob_i<2, T_CMP_PART>; case 3:return &compBlob_i<3, T_CMP_PART>; case 4:return &compBlob_i<4, T_CMP_PART>; } } switch(sizeByte) { case 1:return &compBlob<1, T_CMP_PART>; case 2:return &compBlob<2, T_CMP_PART>; case 3:return &compBlob<3, T_CMP_PART>; case 4:return &compBlob<4, T_CMP_PART>; } } case ft_myblob: case ft_myjson: //TODO Json binary comp case ft_mygeometry: //TODO geometory binary comp { if (compAll) { if (incase) { switch(sizeByte) { case 1:return &compBlob_bin_i<1, T_CMP_ALL>; case 2:return &compBlob_bin_i<2, T_CMP_ALL>; case 3:return &compBlob_bin_i<3, T_CMP_ALL>; case 4:return &compBlob_bin_i<4, T_CMP_ALL>; } } switch(sizeByte) { case 1:return &compBlob_bin<1, T_CMP_ALL>; case 2:return &compBlob_bin<2, T_CMP_ALL>; case 3:return &compBlob_bin<3, T_CMP_ALL>; case 4:return &compBlob_bin<4, T_CMP_ALL>; } } if (incase) { switch(sizeByte) { case 1:return &compBlob_bin_i<1, T_CMP_PART>; case 2:return &compBlob_bin_i<2, T_CMP_PART>; case 3:return &compBlob_bin_i<3, T_CMP_PART>; case 4:return &compBlob_bin_i<4, T_CMP_PART>; } } switch(sizeByte) { case 1:return &compBlob_bin<1, T_CMP_PART>; case 2:return &compBlob_bin<2, T_CMP_PART>; case 3:return &compBlob_bin<3, T_CMP_PART>; case 4:return &compBlob_bin<4, T_CMP_PART>; } assert(0); } } return NULL; } inline bool isMatch1(int v) // eEqual eBitAnd { return (v == 0); } inline bool isMatch2(int v) // eGreater { return (v > 0); } inline bool isMatch3(int v) // eLess { return (v < 0); } inline bool isMatch4(int v) // eNotEq eNotBitAnd { return (v != 0); } inline bool isMatch5(int v) // eGreaterEq { return (v >= 0); } inline bool isMatch6(int v) // eLessEq { return (v <= 0); } inline judgeFunc getJudgeFunc(eCompType log) { switch (log & 0xF) { case eEqual: case eBitAnd: return isMatch1; case eGreater: return isMatch2; case eLess: return isMatch3; case eNotEq: return isMatch4; case eNotBitAnd: case eGreaterEq: return isMatch5; case eLessEq: return isMatch6; case eIsNull: case eIsNotNull: return NULL; } assert(0); return NULL; } inline bool isEndComp(uchar_td opr, bool ret) { return (opr == eCend) || (!ret && (opr == eCand)) || (ret && (opr == eCor)); } #endif