Go to the source code of this file.
Functions | |
FENNEL_BEGIN_NAMESPACE int | SqlStrCat_Ascii (char *dest, int destStorageBytes, int destLenBytes, char const *const str, int strLenBytes) |
Strcat. | |
int | SqlStrCat_Ascii (char *dest, int destStorageBytes, char const *const str1, int str1LenBytes, char const *const str2, int str2LenBytes) |
StrCat. | |
int | SqlStrCmp_Ascii_Fix (char const *const str1, int str1LenBytes, char const *const str2, int str2LenBytes, char trimchar) |
StrCmp. | |
int | SqlStrCmp_Ascii_Var (char const *const str1, int str1LenBytes, char const *const str2, int str2LenBytes) |
StrCmp. | |
int | SqlStrLenBit_Ascii (char const *const str, int strLenBytes) |
StrLen in bits. | |
int | SqlStrLenChar_Ascii (char const *const str, int strLenBytes) |
StrLen in characters. | |
int | SqlStrLenOct_Ascii (char const *const str, int strLenBytes) |
StrLen in octets. | |
int | SqlStrOverlay_Ascii (char *dest, int destStorageBytes, char const *const str, int strLenBytes, char const *const over, int overLenBytes, int startChar, int lengthChar, int lenSpecified) |
Overlay. | |
int | SqlStrPos_Ascii (char const *const str, int strLenBytes, char const *const find, int findLenBytes) |
Position. | |
int | SqlStrSubStr_Ascii (char const **dest, int destStorageBytes, char const *const str, int strLenBytes, int subStartChar, int subLengthChar, int subLenSpecified) |
Substring by reference. | |
int | SqlStrToLower_Ascii (char *dest, int destStorageBytes, char const *src, int srcLenBytes) |
toLower. Ascii. CHAR/VARCHAR. Returns length. | |
int | SqlStrToUpper_Ascii (char *dest, int destStorageBytes, char const *src, int srcLenBytes) |
toUpper. Ascii. CHAR/VARCHAR. Returns length. | |
int | SqlStrTrim_Ascii (char *dest, int destStorageBytes, char const *const str, int strLenBytes, int trimLeft, int trimRight, char trimchar) |
Trim padding. | |
int | SqlStrTrim_Ascii (char const **result, char const *const str, int strLenBytes, int trimLeft, int trimRight, char trimchar) |
Trim padding by reference. |
int SqlStrCat_Ascii | ( | char * | dest, | |
int | destStorageBytes, | |||
char const *const | str1, | |||
int | str1LenBytes, | |||
char const *const | str2, | |||
int | str2LenBytes | |||
) |
StrCat.
Ascii. SQL VARCHAR & CHAR. dest = str1 || str2. dest = str1 || str2
Returns new length in bytes.
This is an optimization for creating a concatenated string from two other strings, eliminating a separate string copy. The assumption is that this is the common case with concatenation. Subsequent concatenations may occur with other form.
If either string is variable width, the result is variable width: per SQL99 Part 2 Section 6.27 Syntax Rule 3.a.i. If both strings are fixed width, the result is fixed width, item ii.
Note: CHAR('1 ') || CHAR('2 ') is CHAR('1 2 ') and is not CHAR('12 ').
When used with CHARs, ignore the return value, and set destLenBytes = destStorageBytes
Definition at line 51 of file SqlStringAscii.cpp.
00058 { 00059 if (str1LenBytes + str2LenBytes > destStorageBytes) { 00060 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00061 throw "22001"; 00062 } 00063 00064 memcpy(dest, str1, str1LenBytes); 00065 memcpy(dest + str1LenBytes, str2, str2LenBytes); 00066 return str1LenBytes + str2LenBytes; 00067 }
FENNEL_BEGIN_NAMESPACE int SqlStrCat_Ascii | ( | char * | dest, | |
int | destStorageBytes, | |||
int | destLenBytes, | |||
char const *const | str, | |||
int | strLenBytes | |||
) |
Strcat.
Ascii. SQL VARCHAR & CHAR. dest = dest || str. Returns new length in bytes.
If either string is variable width, the result is variable width: per SQL99 Part 2 Section 6.27 Syntax Rule 3.a.i. If both strings are fixed width, the result is fixed width, per item ii.
Note that CHAR('1 ') || CHAR('2 ') = CHAR('1 2 ') and not CHAR('12 ').
When called repeatedly to cat multiple strings together (e.g. A || B || C), the final destLength must be exactly equal to the defined resulting width. (e.g. width of A+B+C) for both VARCHAR & CHAR. Take care that these length semantics are adhered to in the final result, even though intermediate results (say A || B) may not have the correct length.
When used with CHARs, set strLenBytes to strStorageBytes. On intermediate results set destLenBytes = return value of previous call. Final result should/must have return value == destStorage.
Definition at line 33 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringCat_Ascii_Fix(), SqlStringAsciiTest::testSqlStringCat_Ascii_Var(), and SqlStringAsciiTest::testSqlStringCat_Ascii_Var2().
00039 { 00040 if (destLenBytes + strLenBytes > destStorageBytes) { 00041 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00042 throw "22001"; 00043 } 00044 00045 memcpy(dest + destLenBytes, str, strLenBytes); 00046 return destLenBytes + strLenBytes; 00047 }
int SqlStrCmp_Ascii_Fix | ( | char const *const | str1, | |
int | str1LenBytes, | |||
char const *const | str2, | |||
int | str2LenBytes, | |||
char | trimchar = ' ' | |||
) |
StrCmp.
Ascii. Fixed Width / SQL CHAR.
Returns -1, 0, 1.
Definition at line 70 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringCmp_Ascii_Fix_Helper().
00076 { 00077 char const * start = str1; 00078 char const * end = str1 + str1LenBytes; 00079 00080 if (end != start) { 00081 end--; 00082 while (end != start && *end == trimchar) { 00083 end--; 00084 } 00085 if (end != start || *end != trimchar) { 00086 end++; 00087 } 00088 } 00089 int str1TrimLenBytes = end - start; 00090 00091 start = str2; 00092 end = str2 + str2LenBytes; 00093 00094 if (end != start) { 00095 end--; 00096 while (end != start && *end == trimchar) { 00097 end--; 00098 } 00099 if (end != start || *end != trimchar) { 00100 end++; 00101 } 00102 } 00103 int str2TrimLenBytes = end - start; 00104 00105 if (str1TrimLenBytes > str2TrimLenBytes) { 00106 return 1; 00107 } else if (str1TrimLenBytes < str2TrimLenBytes) { 00108 return -1; 00109 } 00110 00111 assert(str1TrimLenBytes == str2TrimLenBytes); 00112 00113 // comparison must be unsigned to work for > 128 00114 unsigned char const *s1 = reinterpret_cast<unsigned char const *>(str1); 00115 unsigned char const *s2 = reinterpret_cast<unsigned char const *>(str2); 00116 int len = str1TrimLenBytes; 00117 00118 while (len-- > 0) { 00119 if (*s1 != *s2) { 00120 return (*s1 > *s2) ? 1 : -1; 00121 } 00122 s1++; 00123 s2++; 00124 } 00125 return 0; 00126 }
int SqlStrCmp_Ascii_Var | ( | char const *const | str1, | |
int | str1LenBytes, | |||
char const *const | str2, | |||
int | str2LenBytes | |||
) |
StrCmp.
Ascii. Variable Width / VARCHAR.
Returns -1, 0, 1
Definition at line 129 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringCmp_Ascii_Var_Helper().
00134 { 00135 // consider strcoll for I18N 00136 if (str1LenBytes > str2LenBytes) { 00137 return 1; 00138 } else if (str1LenBytes < str2LenBytes) { 00139 return -1; 00140 } 00141 00142 assert(str1LenBytes == str2LenBytes); 00143 00144 // comparison must be unsigned to work for > 128 00145 unsigned char const *s1 = reinterpret_cast<unsigned char const *>(str1); 00146 unsigned char const *s2 = reinterpret_cast<unsigned char const *>(str2); 00147 int len = str1LenBytes; 00148 00149 while (len-- > 0) { 00150 if (*s1 != *s2) { 00151 return (*s1 > *s2) ? 1 : -1; 00152 } 00153 s1++; 00154 s2++; 00155 } 00156 return 0; 00157 }
int SqlStrLenBit_Ascii | ( | char const *const | str, | |
int | strLenBytes | |||
) |
StrLen in bits.
Ascii. CHAR/VARCHAR.
Parameter str is ignored for ascii strings.
Definition at line 161 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringLenBit_Ascii().
int SqlStrLenChar_Ascii | ( | char const *const | str, | |
int | strLenBytes | |||
) |
StrLen in characters.
Ascii. CHAR/VARCHAR.
Parameter str is ignored for ascii strings.
Definition at line 169 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringLenChar_Ascii().
int SqlStrLenOct_Ascii | ( | char const *const | str, | |
int | strLenBytes | |||
) |
StrLen in octets.
Ascii. CHAR/VARCHAR.
Parameter str is ignored for ascii strings.
Definition at line 177 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringLenOct_Ascii().
int SqlStrOverlay_Ascii | ( | char * | dest, | |
int | destStorageBytes, | |||
char const *const | str, | |||
int | strLenBytes, | |||
char const *const | over, | |||
int | overLenBytes, | |||
int | startChar, | |||
int | lengthChar, | |||
int | lenSpecified | |||
) |
Overlay.
Ascii. CHAR/VARCHAR. Returns new length in bytes
See SQL99 Part 2 Section 6.18 Syntax Rule 10. Overlay is defined in terms of Substring an concatenation. If start is < 1 or length < 0, a substring error may be thrown. Result is VARCHAR, as the result of substring is always VARCHAR, and concatenation results in VARCHAR if any of its operands are VARCHAR. startChar is 1-indexed, as per SQL standard.
Definition at line 186 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringOverlay_Ascii().
00196 { 00197 if (!lenSpecified) { 00198 lengthChar = overLenBytes; 00199 } 00200 if (lengthChar < 0 || startChar < 1) { 00201 // Overlay is defined in terms of substring. These conditions 00202 // would, I believe, generate a substring error. Also 00203 // another "reference" sql database gets angry under these 00204 // conditions. Therefore, per: 00205 // SQL99 Part 2 Section 6.18 General Rule 3.d generate a 00206 // SQL99 Part 2 Section 22.1 22-011 "data exception substring error". 00207 throw "22011"; 00208 } 00209 00210 int leftLenBytes = startChar - 1; // 1-index to 0-index 00211 if (leftLenBytes > strLenBytes) { 00212 leftLenBytes = strLenBytes; 00213 } 00214 char const *rightP = str + leftLenBytes + lengthChar; 00215 int rightLenBytes = strLenBytes - (leftLenBytes + lengthChar); 00216 if (rightLenBytes < 0) { 00217 rightLenBytes = 0; 00218 } 00219 assert(leftLenBytes >= 0); 00220 assert(rightLenBytes >= 0); 00221 assert(rightP >= str); 00222 00223 if (leftLenBytes + rightLenBytes + overLenBytes > destStorageBytes) { 00224 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00225 throw "22001"; 00226 } 00227 00228 char *dp = dest; 00229 00230 memcpy(dp, str, leftLenBytes); 00231 dp += leftLenBytes; 00232 memcpy(dp, over, overLenBytes); 00233 dp += overLenBytes; 00234 memcpy(dp, rightP, rightLenBytes); 00235 dp += rightLenBytes; 00236 00237 return dp - dest; 00238 }
int SqlStrPos_Ascii | ( | char const *const | str, | |
int | strLenBytes, | |||
char const *const | find, | |||
int | findLenBytes | |||
) |
Position.
Ascii. CHAR/VARHCAR. Returns 1-index string position.
Returns 0 if not found. Returns 1 if find is zero length. See SQL99 Part 2 Section 6.17 General Rule 2.
Definition at line 241 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringPos_Ascii().
00246 { 00247 // SQL99 Part 2 Section 6.17 General Rule 2.a. 00248 if (!findLenBytes) { 00249 return 1; 00250 } 00251 // SQL99 Part 2 Section 6.17 General Rule 2.c. 00252 if (findLenBytes > strLenBytes) { 00253 return 0; 00254 } 00255 assert(findLenBytes > 0); 00256 assert(strLenBytes > 0); 00257 assert(strLenBytes - findLenBytes >= 0); 00258 00259 register char const * s = str; 00260 char const * end = 1 + s + (strLenBytes - findLenBytes); 00261 00262 while (s < end) { 00263 // search for first char of find 00264 s = reinterpret_cast<char const *>(memchr(s, *find, end - s)); 00265 if (!s) { 00266 return 0; // Case C. 00267 } 00268 if (!memcmp(s, find, findLenBytes)) { 00269 // add 1 to make result 1-indexed. 00270 return (s - str) + 1; // Case B. 00271 } else { 00272 s++; 00273 } 00274 } 00275 return 0; // Case C. 00276 }
int SqlStrSubStr_Ascii | ( | char const ** | dest, | |
int | destStorageBytes, | |||
char const *const | str, | |||
int | strLenBytes, | |||
int | subStartChar, | |||
int | subLenChar, | |||
int | subLenBytesSpecified | |||
) |
Substring by reference.
Ascii. Returns VARCHAR. Accepts CHAR/VARCHAR. Sets dest to start of of substring. Returns length of substring.
Note that subStart is 1-indexed, as per SQL99 spec. All substring parameters are handled as signed, as spec implies that they could be negative. Some combinations of subStart and subLenBytes may throw an exception. Results in a VARCHAR. See SQL99 Part 2 Section 6.18 General Rule 3. subStartChar is 1-indexed.
Definition at line 280 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringSubStr_Ascii().
00288 { 00289 int e; 00290 if (subLenSpecified) { 00291 e = subStartChar + subLengthChar; 00292 } else { 00293 e = strLenBytes + 1; 00294 if (subStartChar > e) { 00295 e = subStartChar; 00296 } 00297 } 00298 00299 if (e < subStartChar) { 00300 // Per SQL99 Part 2 Section 6.18 General Rule 3.d, generate a 00301 // "data exception substring error". SQL99 Part 2 Section 22.1 22-011 00302 throw "22011"; 00303 } 00304 00305 if (subStartChar > strLenBytes || e < 1) { 00306 return 0; 00307 } 00308 00309 int s1 = 1; 00310 if (subStartChar > s1) { 00311 s1 = subStartChar; 00312 } 00313 00314 int e1 = strLenBytes + 1; 00315 if (e < e1) { 00316 e1 = e; 00317 } 00318 int l1 = e1 - s1; 00319 00320 00321 if (l1 > destStorageBytes) { 00322 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00323 throw "22001"; 00324 } 00325 if (l1 < 0) { 00326 // Expected behavior not clear. 00327 // SQL99 Part 2 Section 22.1 22-011 "data exception substring error". 00328 throw "22011"; 00329 } 00330 00331 // - 1 converts from 1-indexed to 0-indexed 00332 *dest = str + s1 - 1; 00333 return l1; 00334 }
int SqlStrToLower_Ascii | ( | char * | dest, | |
int | destStorageBytes, | |||
char const * | src, | |||
int | srcLenBytes | |||
) |
toLower. Ascii. CHAR/VARCHAR. Returns length.
Definition at line 337 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringToLower_Ascii().
00342 { 00343 register char const * s = src; 00344 register char* d = dest; 00345 char* e = dest + srcLenBytes; 00346 00347 if (srcLenBytes > destStorageBytes) { 00348 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00349 throw "22001"; 00350 } 00351 00352 while (d < e) { 00353 *(d++) = tolower(*(s++)); 00354 } 00355 return srcLenBytes; 00356 }
int SqlStrToUpper_Ascii | ( | char * | dest, | |
int | destStorageBytes, | |||
char const * | src, | |||
int | srcLenBytes | |||
) |
toUpper. Ascii. CHAR/VARCHAR. Returns length.
Definition at line 359 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringToUpper_Ascii().
00364 { 00365 register char const * s = src; 00366 register char* d = dest; 00367 char* e = dest + srcLenBytes; 00368 00369 if (srcLenBytes > destStorageBytes) { 00370 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00371 throw "22001"; 00372 } 00373 00374 while (d < e) { 00375 *(d++) = toupper(*(s++)); 00376 } 00377 return srcLenBytes; 00378 }
int SqlStrTrim_Ascii | ( | char const ** | result, | |
char const *const | str, | |||
int | strLenBytes, | |||
int | trimLeft, | |||
int | trimRight, | |||
char | trimchar = ' ' | |||
) |
Trim padding by reference.
Ascii. CHAR/VARCHAR. Returns new length.
See SQL99 Part 2 Section 6.18 General Rule 8. Results in a VARCHAR. Note: Does not check that result has enough capacity to contain substring as this is irrelevant. If a program depends on the size of result not changing, and this instruction enforcing that invariant -- probably a bad practice anyway -- trouble could result.
Definition at line 420 of file SqlStringAscii.cpp.
00427 { 00428 char const * start = str; 00429 char const * end = str + strLenBytes; 00430 00431 // If many pad characters are expected, consider using memrchr() 00432 if (trimLeft) { 00433 while (start != end && *start == trimchar) { 00434 start++; 00435 } 00436 } 00437 if (trimRight && end != start) { 00438 end--; 00439 while (end != start && *end == trimchar) { 00440 end--; 00441 } 00442 if (end != start || *end != trimchar) { 00443 end++; 00444 } 00445 } 00446 00447 *result = start; 00448 return end - start; 00449 }
int SqlStrTrim_Ascii | ( | char * | dest, | |
int | destStorageBytes, | |||
char const *const | str, | |||
int | strLenBytes, | |||
int | trimLeft, | |||
int | trimRight, | |||
char | trimchar = ' ' | |||
) |
Trim padding.
Ascii. CHAR/VARCHAR. Returns new length.
See SQL99 Part 2 Section 6.18 General Rule 8. Results in a VARCHAR.
Definition at line 381 of file SqlStringAscii.cpp.
Referenced by SqlStringAsciiTest::testSqlStringTrim_Ascii().
00389 { 00390 char const * start = str; 00391 char const * end = str + strLenBytes; 00392 int newLenBytes; 00393 00394 // If many pad characters are expected, consider using memrchr() 00395 if (trimLeft) { 00396 while (start != end && *start == trimchar) { 00397 start++; 00398 } 00399 } 00400 if (trimRight && end != start) { 00401 end--; 00402 while (end != start && *end == trimchar) { 00403 end--; 00404 } 00405 if (end != start || *end != trimchar) { 00406 end++; 00407 } 00408 } 00409 newLenBytes = end - start; 00410 00411 if (newLenBytes > destStorageBytes) { 00412 // SQL99 Part 2 Section 22.1 22-001 "String Data Right truncation" 00413 throw "22001"; 00414 } 00415 memcpy(dest, start, newLenBytes); 00416 return newLenBytes; 00417 }