OCILIB (C Driver for Oracle) 3.12.1
|
00001 /* 00002 +-----------------------------------------------------------------------------------------+ 00003 | | 00004 | OCILIB - C Driver for Oracle | 00005 | | 00006 | (C Wrapper for Oracle OCI) | 00007 | | 00008 | Website : http://www.ocilib.net | 00009 | | 00010 | Copyright (c) 2007-2013 Vincent ROGIER <vince.rogier@ocilib.net> | 00011 | | 00012 +-----------------------------------------------------------------------------------------+ 00013 | | 00014 | This library is free software; you can redistribute it and/or | 00015 | modify it under the terms of the GNU Lesser General Public | 00016 | License as published by the Free Software Foundation; either | 00017 | version 2 of the License, or (at your option) any later version. | 00018 | | 00019 | This library is distributed in the hope that it will be useful, | 00020 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00021 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 00022 | Lesser General Public License for more details. | 00023 | | 00024 | You should have received a copy of the GNU Lesser General Public | 00025 | License along with this library; if not, write to the Free | 00026 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 00027 | | 00028 +-----------------------------------------------------------------------------------------+ 00029 */ 00030 00031 /* --------------------------------------------------------------------------------------------- * 00032 * $Id: string.c, Vincent Rogier $ 00033 * --------------------------------------------------------------------------------------------- */ 00034 00035 #include "ocilib_internal.h" 00036 00037 /* ********************************************************************************************* * 00038 * PRIVATE FUNCTIONS 00039 * ********************************************************************************************* */ 00040 00041 /* --------------------------------------------------------------------------------------------- * 00042 * Widechar/Multibytes String functions 00043 * 00044 * StringCopy4to2bytes() and StringCopy2to4bytes() are based on the 00045 * ConvertUTF source file by Mark E. Davis - Copyright 2001 Unicode, Inc. 00046 * 00047 * --------------------------------------------------------------------------------------------- */ 00048 00049 /* --------------------------------------------------------------------------------------------- * 00050 * OCI_StringCopy4to2bytes 00051 * --------------------------------------------------------------------------------------------- */ 00052 00053 int OCI_StringCopy4to2bytes 00054 ( 00055 const unsigned int* src, 00056 size_t src_size, 00057 unsigned short * dst, 00058 size_t dst_size 00059 ) 00060 { 00061 int cp_size = 0; 00062 00063 const unsigned int *src_end = NULL; 00064 const unsigned short *dst_end = NULL; 00065 00066 OCI_CHECK(src == NULL, 0); 00067 OCI_CHECK(dst == NULL, 0); 00068 00069 src_end = src + src_size; 00070 dst_end = dst + dst_size; 00071 00072 while (src < src_end) 00073 { 00074 unsigned int c; 00075 00076 if (dst >= dst_end) return -1; 00077 00078 c = *src++; 00079 00080 if (c <= UNI_MAX_BMP) 00081 { 00082 if ((c >= UNI_SUR_HIGH_START) && (c < UNI_SUR_LOW_END)) 00083 { 00084 *dst++ = UNI_REPLACEMENT_CHAR; 00085 } 00086 else 00087 { 00088 *dst++ = (unsigned short) c; 00089 } 00090 00091 cp_size++; 00092 } 00093 else if (c > UNI_MAX_LEGAL_UTF32) 00094 { 00095 *dst++ = UNI_REPLACEMENT_CHAR; 00096 00097 cp_size++; 00098 } 00099 else 00100 { 00101 if ((dst + (size_t) 1) >= dst_end) 00102 { 00103 return -2; 00104 } 00105 00106 c -= UNI_BASE; 00107 00108 if (dst) 00109 { 00110 *dst++ = (unsigned short)((c >> UNI_SHIFT) + UNI_SUR_HIGH_START); 00111 *dst++ = (unsigned short)((c & UNI_MASK ) + UNI_SUR_LOW_START ); 00112 } 00113 00114 cp_size++; 00115 cp_size++; 00116 } 00117 } 00118 00119 return cp_size; 00120 } 00121 00122 /* --------------------------------------------------------------------------------------------- * 00123 * OCI_StringCopy2to4bytes 00124 * --------------------------------------------------------------------------------------------- */ 00125 00126 int OCI_StringCopy2to4bytes 00127 ( 00128 const unsigned short* src, 00129 size_t src_size, 00130 unsigned int * dst, 00131 size_t dst_size 00132 ) 00133 { 00134 int cp_size = 0; 00135 00136 const unsigned short *src_end = NULL; 00137 const unsigned int *dst_end = NULL; 00138 00139 unsigned int c1, c2; 00140 00141 OCI_CHECK(src == NULL, 0); 00142 OCI_CHECK(dst == NULL, 0); 00143 00144 src_end = src + src_size; 00145 dst_end = dst + dst_size; 00146 00147 while (src < src_end) 00148 { 00149 c1 = *src++; 00150 00151 if ((c1 >= UNI_SUR_HIGH_START) && (c1 <= UNI_SUR_HIGH_END)) 00152 { 00153 if (src < src_end) 00154 { 00155 c2 = *src; 00156 00157 if ((c2 >= UNI_SUR_LOW_START) && (c2 <= UNI_SUR_LOW_END)) 00158 { 00159 c1 = ((c1 - UNI_SUR_HIGH_START) << UNI_SHIFT) + 00160 (c2 - UNI_SUR_LOW_START ) + UNI_BASE; 00161 00162 ++src; 00163 } 00164 } 00165 else 00166 { 00167 return -1; 00168 } 00169 } 00170 00171 if (dst >= dst_end) 00172 { 00173 return -2; 00174 } 00175 00176 *dst++ = c1; 00177 00178 cp_size++; 00179 } 00180 00181 return cp_size; 00182 } 00183 00184 /* --------------------------------------------------------------------------------------------- * 00185 * OCI_StringLength 00186 * --------------------------------------------------------------------------------------------- */ 00187 00188 size_t OCI_StringLength 00189 ( 00190 void *ptr, 00191 size_t size_elem 00192 ) 00193 { 00194 int size = 0; 00195 00196 OCI_CHECK(ptr == NULL, 0); 00197 00198 if (size_elem == sizeof(char)) 00199 { 00200 const char *s = (const char *) ptr; 00201 const char *e = (const char *) ptr; 00202 00203 while (*e++) ; 00204 00205 size = (int) (e - s - (size_t) 1); 00206 } 00207 else if (size_elem == sizeof(short)) 00208 { 00209 const short *s = (const short *) ptr; 00210 const short *e = (const short *) ptr; 00211 00212 while (*e++) ; 00213 00214 size = (int) (e - s - (size_t) 1); 00215 } 00216 else if (size_elem == sizeof(int)) 00217 { 00218 const int *s = (const int *) ptr; 00219 const int *e = (const int *) ptr; 00220 00221 while (*e++) ; 00222 00223 size = (int) (e - s - (size_t) 1); 00224 } 00225 00226 return size; 00227 } 00228 00229 /* --------------------------------------------------------------------------------------------- * 00230 * OCI_StringUTF8Length 00231 * --------------------------------------------------------------------------------------------- */ 00232 00233 int OCI_StringUTF8Length 00234 ( 00235 const char *str 00236 ) 00237 { 00238 int size = 0; 00239 00240 while (*str) 00241 { 00242 if ((*str & 0xc0) != 0x80) 00243 { 00244 size++; 00245 } 00246 00247 str++; 00248 } 00249 00250 return size; 00251 } 00252 00253 /* --------------------------------------------------------------------------------------------- * 00254 * OCI_GetInputString 00255 * --------------------------------------------------------------------------------------------- */ 00256 00257 void * OCI_GetInputString 00258 ( 00259 void *src, 00260 int *size, 00261 size_t size_char_in, 00262 size_t size_char_out 00263 ) 00264 { 00265 OCI_CHECK(src == NULL, NULL); 00266 OCI_CHECK(size == NULL, NULL); 00267 00268 if (size_char_in == size_char_out) 00269 { 00270 /* in/out type sizes are equal, so no conversion ! */ 00271 00272 if (*size == -1) 00273 { 00274 *size = (int) (OCI_StringLength(src, size_char_in) * size_char_in); 00275 } 00276 00277 return src; 00278 } 00279 else 00280 { 00281 /* in/out type size are not equal, so conversion needed ! */ 00282 00283 int char_count = 0; 00284 void *dest = NULL; 00285 00286 if (*size == -1) 00287 { 00288 char_count = (int) OCI_StringLength(src, size_char_in); 00289 } 00290 else 00291 { 00292 char_count = *size / (int) size_char_in; 00293 } 00294 00295 *size = 0; 00296 00297 dest = OCI_MemAlloc(OCI_IPC_STRING, size_char_out, char_count + 1, 0); 00298 00299 if (dest != NULL) 00300 { 00301 unsigned int null_char = 0; 00302 00303 if (memcmp(src, &null_char, (size_t) size_char_in) != 0) 00304 { 00305 if (size_char_in > size_char_out) 00306 { 00307 if ((size_char_in == sizeof(int)) && (size_char_out == sizeof(short))) 00308 { 00309 /* UTF32 to UTF16 */ 00310 00311 char_count = OCI_StringCopy4to2bytes 00312 ( 00313 (unsigned int *) src, char_count, 00314 (unsigned short *) dest, char_count 00315 ); 00316 } 00317 else 00318 { 00319 /* widechar to multibytes */ 00320 00321 char_count = (int) wcstombs(dest, src, (size_t) (char_count+1)); 00322 } 00323 } 00324 else 00325 { 00326 if ((size_char_in == sizeof(short)) && (size_char_out == sizeof(int))) 00327 { 00328 /* UTF16 to UTF32 */ 00329 00330 char_count = OCI_StringCopy2to4bytes 00331 ( 00332 (unsigned short *) src, char_count, 00333 (unsigned int *) dest, char_count 00334 ); 00335 } 00336 else 00337 { 00338 /* multibytes to widechar */ 00339 00340 char_count = (int) mbstowcs(dest, src, (size_t) (char_count+1)); 00341 } 00342 } 00343 } 00344 00345 *size = char_count * (int) size_char_out; 00346 00347 memset( (void*) (((char*) dest) + (size_t) (*size)), 0, size_char_out); 00348 } 00349 00350 return dest; 00351 } 00352 } 00353 00354 /* --------------------------------------------------------------------------------------------- * 00355 * OCI_GetOutputString 00356 * --------------------------------------------------------------------------------------------- */ 00357 00358 void OCI_GetOutputString 00359 ( 00360 void *src, 00361 void *dest, 00362 int *size, 00363 size_t size_char_in, 00364 size_t size_char_out 00365 ) 00366 { 00367 if ((src == NULL) || (dest == NULL) || (size == NULL)) 00368 return; 00369 00370 /* do something only if in/out type sizes are not equal ! */ 00371 00372 if (size_char_in != size_char_out) 00373 { 00374 int char_count = 0; 00375 00376 if (*size == -1) 00377 { 00378 char_count = (int) OCI_StringLength(src, size_char_in); 00379 } 00380 else 00381 { 00382 char_count = *size / (int) size_char_in; 00383 } 00384 00385 if (size_char_in > size_char_out) 00386 { 00387 if ((size_char_in == sizeof(int)) && (size_char_out == sizeof(short))) 00388 { 00389 /* UTF32 to UTF16 */ 00390 00391 char_count = OCI_StringCopy4to2bytes 00392 ( 00393 (unsigned int *) src, char_count, 00394 (unsigned short *) dest, char_count 00395 ); 00396 } 00397 else 00398 { 00399 /* widechar to multibytes */ 00400 00401 char_count = (int) wcstombs(dest, src, (size_t) (char_count+1)); 00402 } 00403 } 00404 else 00405 { 00406 if ((size_char_in == sizeof(short)) && (size_char_out == sizeof(int))) 00407 { 00408 /* UTF16 to UTF32 */ 00409 00410 char_count = OCI_StringCopy2to4bytes 00411 ( 00412 (unsigned short *) src, char_count, 00413 (unsigned int *) dest, char_count 00414 ); 00415 } 00416 else 00417 { 00418 /* multibytes to widechar */ 00419 00420 char_count = (int) mbstowcs(dest, src, (size_t) (char_count+1)); 00421 } 00422 } 00423 00424 *size = char_count * (int) size_char_out; 00425 } 00426 } 00427 00428 /* --------------------------------------------------------------------------------------------- * 00429 * OCI_MoveString 00430 * --------------------------------------------------------------------------------------------- */ 00431 00432 void OCI_MoveString 00433 ( 00434 void *src, 00435 void *dst, 00436 int char_count, 00437 size_t size_char_in, 00438 size_t size_char_out 00439 ) 00440 { 00441 if ((src == NULL) || (dst == NULL)) 00442 { 00443 return; 00444 } 00445 00446 /* raw string packing/expansion without charset conversion */ 00447 00448 if (size_char_out > size_char_in) 00449 { 00450 /* expand string */ 00451 00452 if ((size_char_in == sizeof(short)) && (size_char_out == sizeof(int))) 00453 { 00454 /* 2 => 4 bytes */ 00455 00456 unsigned short *str1 = (unsigned short *) src; 00457 unsigned int *str2 = (unsigned int *) dst; 00458 00459 if (*str1 == 0) 00460 { 00461 return; 00462 } 00463 00464 while (char_count--) 00465 { 00466 str2[char_count] = (unsigned int) str1[char_count]; 00467 } 00468 } 00469 00470 else if ((size_char_in == sizeof(char)) && (size_char_out == sizeof(short))) 00471 { 00472 /* 1 => 2 bytes */ 00473 00474 unsigned char *str1 = (unsigned char *) src; 00475 unsigned short *str2 = (unsigned short *) dst; 00476 00477 if (*str1 == 0) 00478 { 00479 return; 00480 } 00481 00482 while (char_count--) 00483 { 00484 str2[char_count] = (unsigned short) str1[char_count]; 00485 } 00486 } 00487 else if ((size_char_in == sizeof(char)) && (size_char_out == sizeof(int))) 00488 { 00489 /* 1 => 4 bytes */ 00490 00491 unsigned char *str1 = (unsigned char *) src; 00492 unsigned int *str2 = (unsigned int *) dst; 00493 00494 if (*str1 == 0) 00495 { 00496 return; 00497 } 00498 00499 while (char_count--) 00500 { 00501 str2[char_count] = (unsigned int) str1[char_count]; 00502 } 00503 } 00504 } 00505 else if (size_char_out < size_char_in) 00506 { 00507 /* pack string */ 00508 00509 if ((size_char_in == sizeof(int)) && (size_char_out == sizeof(short))) 00510 { 00511 /* 4 => 2 bytes */ 00512 00513 unsigned int *str1 = (unsigned int *) src; 00514 unsigned short *str2 = (unsigned short *) dst; 00515 int i = 0; 00516 00517 if (*str1 == 0) 00518 { 00519 return; 00520 } 00521 00522 while (++i < char_count) 00523 { 00524 str2[i] = (unsigned short) str1[i]; 00525 } 00526 } 00527 else if ((size_char_in == sizeof(short)) && (size_char_out == sizeof(char))) 00528 { 00529 /* 2 => 1 bytes */ 00530 00531 unsigned short *str1 = (unsigned short *) src; 00532 unsigned char *str2 = (unsigned char *) dst; 00533 int i = 0; 00534 00535 if (*str1 == 0) 00536 { 00537 return; 00538 } 00539 00540 while (++i < char_count) 00541 { 00542 str2[i] = (unsigned char) str1[i]; 00543 } 00544 } 00545 else if ((size_char_in == sizeof(int)) && (size_char_out == sizeof(char))) 00546 { 00547 /* 4 => 1 bytes */ 00548 00549 unsigned int *str1 = (unsigned int *) src; 00550 unsigned char *str2 = (unsigned char *) dst; 00551 int i = 0; 00552 00553 if (*str1 == 0) 00554 { 00555 return; 00556 } 00557 00558 while (++i < char_count) 00559 { 00560 str2[i] = (unsigned char) str1[i]; 00561 } 00562 } 00563 } 00564 } 00565 00566 /* --------------------------------------------------------------------------------------------- * 00567 * OCI_ConvertString 00568 * --------------------------------------------------------------------------------------------- */ 00569 00570 void OCI_ConvertString 00571 ( 00572 void *str, 00573 int char_count, 00574 size_t size_char_in, 00575 size_t size_char_out 00576 ) 00577 { 00578 /* inplace string packing / expansion */ 00579 00580 OCI_MoveString(str, str, char_count, size_char_in, size_char_out); 00581 } 00582 00583 /* --------------------------------------------------------------------------------------------- * 00584 * 00585 * --------------------------------------------------------------------------------------------- */ 00586 00587 void OCI_CopyString 00588 ( 00589 void *src, 00590 void *dest, 00591 int *size, 00592 size_t size_char_in, 00593 size_t size_char_out 00594 ) 00595 { 00596 if ((src == NULL) || (dest == NULL) || (size == NULL)) 00597 { 00598 return; 00599 } 00600 00601 if (size_char_out == size_char_in) 00602 { 00603 memcpy(dest, src, (size_t) *size); 00604 memset((void*) (((char*) dest) + (size_t) (*size)), 0, (size_t) size_char_out); 00605 } 00606 else 00607 { 00608 OCI_GetOutputString(src, dest, size, size_char_in, size_char_out); 00609 } 00610 } 00611 00612 /* --------------------------------------------------------------------------------------------- * 00613 * OCI_ReleaseMetaString 00614 * --------------------------------------------------------------------------------------------- */ 00615 00616 void OCI_ReleaseMetaString 00617 ( 00618 void *str 00619 ) 00620 { 00621 #ifdef OCI_CHECK_METASTRINGS 00622 00623 if (str != NULL) 00624 { 00625 OCI_MemFree(str); 00626 } 00627 00628 #else 00629 00630 OCI_NOT_USED(str) 00631 00632 #endif 00633 } 00634 00635 /* --------------------------------------------------------------------------------------------- * 00636 * OCI_ReleaseDataString 00637 * --------------------------------------------------------------------------------------------- */ 00638 00639 void OCI_ReleaseDataString 00640 ( 00641 void *str 00642 ) 00643 { 00644 #ifdef OCI_CHECK_DATASTRINGS 00645 00646 if (str != NULL) 00647 { 00648 OCI_MemFree(str); 00649 } 00650 00651 #else 00652 00653 OCI_NOT_USED(str) 00654 00655 #endif 00656 } 00657 00658 /* --------------------------------------------------------------------------------------------- * 00659 * OCI_StringFromStringPtr 00660 * --------------------------------------------------------------------------------------------- */ 00661 00662 void * OCI_StringFromStringPtr 00663 ( 00664 OCIEnv *env, 00665 OCIString *str, 00666 void **buf, 00667 int *buflen 00668 ) 00669 { 00670 void *tmp = NULL; 00671 void *ret = NULL; 00672 00673 int olen = 0; 00674 int osize = 0; 00675 int esize = 0; 00676 int msize = 0; 00677 00678 OCI_CHECK(buf == NULL, NULL); 00679 OCI_CHECK(buflen == NULL, NULL); 00680 00681 tmp = OCIStringPtr(env, str); 00682 00683 if (tmp != NULL) 00684 { 00685 00686 #if defined(OCI_CHARSET_MIXED) 00687 00688 /* tmp is ANSI and must be converted to UTF16 */ 00689 00690 esize = 1; 00691 msize = (int) sizeof(dtext); 00692 olen = (int) strlen((char* ) tmp); 00693 osize = olen * esize; 00694 00695 #elif defined(OCI_CHECK_DATASTRINGS) 00696 00697 /* tmp is UTF16 and might be converted to UTF32 on unixes */ 00698 00699 esize = (int) sizeof(odtext); 00700 msize = (int) sizeof(dtext); 00701 olen = (int) OCI_StringLength(tmp, sizeof(odtext)); 00702 osize = olen * esize; 00703 00704 #else 00705 00706 OCI_NOT_USED(esize); 00707 00708 #endif 00709 00710 /* do we need to use a buffer */ 00711 00712 if (olen > 0) 00713 { 00714 /* do we need to allocate/reallocate the buffer */ 00715 00716 if ((*buf) == NULL) 00717 { 00718 *buflen = (olen+1) * msize; 00719 *buf = OCI_MemAlloc(OCI_IPC_STRING, (size_t) msize, (size_t) (olen+1), FALSE); 00720 } 00721 else if ((*buflen) < ((olen+1) * msize)) 00722 { 00723 *buflen = (olen+1) * msize; 00724 *buf = OCI_MemRealloc(*buf, OCI_IPC_STRING, (size_t) msize, (size_t) (olen+1)); 00725 } 00726 } 00727 00728 #if defined(OCI_CHARSET_MIXED) 00729 00730 mbstowcs(*buf, tmp, olen + OCI_CVT_CHAR); 00731 00732 memset( (void*) (((char*) *buf) + (olen*msize)), 0, msize); 00733 00734 ret = *buf; 00735 00736 #elif defined(OCI_CHECK_DATASTRINGS) 00737 00738 OCI_GetOutputDataString(tmp, *buf, &osize); 00739 00740 memset( (void*) (((char*) *buf) + (osize)), 0, msize); 00741 00742 ret = *buf; 00743 00744 #else 00745 00746 osize = 0; 00747 ret = tmp; 00748 00749 #endif 00750 00751 } 00752 else 00753 { 00754 ret = tmp; 00755 } 00756 00757 return ret; 00758 } 00759 00760 /* --------------------------------------------------------------------------------------------- * 00761 * OCI_StringFromStringPtr 00762 * --------------------------------------------------------------------------------------------- */ 00763 00764 boolean OCI_StringToStringPtr 00765 ( 00766 OCIEnv *env, 00767 OCIString **str, 00768 OCIError *err, 00769 void *value, 00770 void **buf, 00771 int *buflen 00772 ) 00773 { 00774 boolean res = TRUE; 00775 void *ostr = NULL; 00776 int osize = 0; 00777 00778 #ifdef OCI_CHARSET_MIXED 00779 00780 int olen = 0; 00781 int esize = 0; 00782 00783 #endif 00784 00785 OCI_CHECK(str == NULL, FALSE); 00786 OCI_CHECK(buf == NULL, FALSE); 00787 OCI_CHECK(buflen == NULL, FALSE); 00788 00789 #ifdef OCI_CHARSET_MIXED 00790 00791 /* value is wchar_t and must be converted to ANSI */ 00792 00793 esize = (int) 1; 00794 olen = (int) dtslen((dtext*) value); 00795 osize = olen; 00796 00797 /* do we need to use a buffer */ 00798 00799 if (olen > 0) 00800 { 00801 /* do we need to allocate/reallocate the buffer */ 00802 00803 if ((*buf) == NULL) 00804 { 00805 *buflen = (olen+1) * esize; 00806 *buf = OCI_MemAlloc(OCI_IPC_STRING, esize, olen+1, FALSE); 00807 } 00808 else if ((*buflen) < ((olen+1) * esize)) 00809 { 00810 *buflen = (olen+1) * esize; 00811 *buf = OCI_MemRealloc(*buf, OCI_IPC_STRING, esize, olen+1); 00812 } 00813 00814 } 00815 00816 wcstombs((char *) *buf, (dtext *) value, olen + OCI_CVT_CHAR); 00817 00818 ostr = *buf; 00819 00820 #else 00821 00822 osize = -1; 00823 ostr = OCI_GetInputDataString(value, &osize); 00824 00825 #endif 00826 00827 OCI_CALL3 00828 ( 00829 res, err, 00830 00831 OCIStringAssignText(env, err, (oratext *) ostr, (ub4) osize, str) 00832 ) 00833 00834 #ifndef OCI_CHARSET_MIXED 00835 00836 OCI_ReleaseDataString(ostr); 00837 00838 #endif 00839 00840 return res; 00841 } 00842 00843 /* --------------------------------------------------------------------------------------------- * 00844 * OCI_StringGetFromAttrHandle 00845 * --------------------------------------------------------------------------------------------- */ 00846 00847 boolean OCI_StringGetFromAttrHandle 00848 ( 00849 OCI_Connection *con, 00850 void *handle, 00851 unsigned int type, 00852 unsigned int attr, 00853 mtext **str 00854 ) 00855 { 00856 boolean res = TRUE; 00857 void *ostr = NULL; 00858 int osize = -1; 00859 int size_char_in = (int) sizeof(mtext); 00860 00861 OCI_CHECK(str == NULL, FALSE); 00862 00863 OCI_CALL2 00864 ( 00865 res, con, 00866 00867 OCIAttrGet((dvoid *) handle, 00868 (ub4 ) type, 00869 (dvoid *) &ostr, 00870 (ub4 *) &osize, 00871 (ub4 ) attr, 00872 con->err) 00873 ) 00874 00875 if ((res == TRUE) && (ostr != NULL)) 00876 { 00877 /* Oracle BUG using OCI in Unicode mode (once again...) 00878 Some connection server handle attributes are returned 00879 as ANSI buffer even when OCI is initialized in UTF16 mode 00880 Some we check if the first character slot has any zero bytes set 00881 to detect this defect ! */ 00882 00883 #ifdef OCI_METADATA_WIDE 00884 00885 int i; 00886 00887 for (i = 0; i < sizeof(omtext); i ++) 00888 { 00889 if (((char*) ostr)[i] == 0) 00890 { 00891 break; 00892 } 00893 } 00894 00895 if (i >= sizeof(omtext)) 00896 { 00897 /* ansi buffer returned instead of an UTF15 one ! */ 00898 00899 size_char_in = 1; 00900 } 00901 00902 00903 #endif 00904 00905 *str = (void *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), 00906 (size_t) ((osize / size_char_in) + 1), TRUE); 00907 00908 if (*str != NULL) 00909 { 00910 OCI_CopyString(ostr, *str, &osize, size_char_in, sizeof(mtext)); 00911 } 00912 else 00913 { 00914 res = FALSE; 00915 } 00916 } 00917 00918 return res; 00919 } 00920 00921 /* --------------------------------------------------------------------------------------------- * 00922 * OCI_StringSetToAttrHandle 00923 * --------------------------------------------------------------------------------------------- */ 00924 00925 boolean OCI_StringSetToAttrHandle 00926 ( 00927 OCI_Connection *con, 00928 void *handle, 00929 unsigned int type, 00930 unsigned int attr, 00931 mtext **str, 00932 const mtext *value 00933 ) 00934 { 00935 boolean res = TRUE; 00936 void *ostr = NULL; 00937 int osize = -1; 00938 00939 ostr = OCI_GetInputMetaString(value, &osize); 00940 00941 if (osize == -1) 00942 { 00943 osize = 0; 00944 } 00945 00946 OCI_CALL2 00947 ( 00948 res, con, 00949 00950 OCIAttrSet((dvoid *) handle, 00951 (ub4 ) type, 00952 (dvoid *) ostr, 00953 (ub4 ) osize, 00954 (ub4 ) attr, 00955 con->err) 00956 ) 00957 00958 OCI_ReleaseMetaString(ostr); 00959 00960 if ((res == TRUE) && (str != NULL)) 00961 { 00962 OCI_FREE(*str); 00963 00964 if (value != NULL) 00965 { 00966 *str = mtsdup(value); 00967 } 00968 } 00969 00970 return res; 00971 } 00972 00973 /* ********************************************************************************************* * 00974 * PUBLIC FUNCTIONS 00975 * ********************************************************************************************* */ 00976 00977 /* --------------------------------------------------------------------------------------------- * 00978 * ocistrdup 00979 * --------------------------------------------------------------------------------------------- */ 00980 00981 char * ocistrdup 00982 ( 00983 const char * src 00984 ) 00985 { 00986 char *dst; 00987 00988 OCI_CHECK(src == NULL, NULL) 00989 00990 dst = (char *) OCI_MemAlloc(OCI_IPC_STRING, 1, strlen(src) + 1, 0); 00991 00992 if (dst != NULL) 00993 { 00994 strcpy(dst, src); 00995 } 00996 00997 return dst; 00998 } 00999 01000 /* --------------------------------------------------------------------------------------------- * 01001 * ocistrcasecmp 01002 * --------------------------------------------------------------------------------------------- */ 01003 01004 int ocistrcasecmp 01005 ( 01006 const char *str1, 01007 const char *str2 01008 ) 01009 { 01010 if (str1 == NULL && str2 == NULL) 01011 { 01012 return 0; 01013 } 01014 01015 if (str1 == NULL) 01016 { 01017 return 1; 01018 } 01019 01020 if (str2 == NULL) 01021 { 01022 return -1; 01023 } 01024 01025 while (((*str1) != 0) && 01026 ((*str2) != 0) && 01027 (tolower((int)(*str1)) == tolower((int)(*str2)))) 01028 { 01029 str1++; 01030 str2++; 01031 } 01032 01033 return (tolower((int) (*str1)) - tolower((int) (*str2))); 01034 } 01035 01036 /* --------------------------------------------------------------------------------------------- * 01037 * ocisprintf 01038 * --------------------------------------------------------------------------------------------- */ 01039 01040 int ocisprintf 01041 ( 01042 char *str, 01043 int size, 01044 const char *format, 01045 ... 01046 ) 01047 { 01048 va_list args; 01049 int n; 01050 01051 va_start(args, format); 01052 01053 n = (int) vsnprintf(str, (size_t) size, format, args); 01054 01055 va_end(args); 01056 01057 return n; 01058 } 01059 01060 #ifdef OCI_INCLUDE_WCHAR 01061 01062 /* --------------------------------------------------------------------------------------------- * 01063 * ociwcsdup 01064 * --------------------------------------------------------------------------------------------- */ 01065 01066 wchar_t * ociwcsdup 01067 ( 01068 const wchar_t * src 01069 ) 01070 { 01071 wchar_t *dst; 01072 01073 OCI_CHECK(src == NULL, NULL) 01074 01075 dst = (wchar_t *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(wchar_t), wcslen(src) + 1, 0); 01076 01077 if (dst != NULL) 01078 { 01079 wcscpy(dst, src); 01080 } 01081 01082 return dst; 01083 } 01084 01085 /* --------------------------------------------------------------------------------------------- * 01086 * ociwcscasecmp 01087 * --------------------------------------------------------------------------------------------- */ 01088 01089 int ociwcscasecmp 01090 ( 01091 const wchar_t *str1, 01092 const wchar_t *str2 01093 ) 01094 { 01095 if (str1 == NULL && str2 == NULL) 01096 { 01097 return 0; 01098 } 01099 01100 if (str1 == NULL) 01101 { 01102 return 1; 01103 } 01104 01105 if (str2 == NULL) 01106 { 01107 return -1; 01108 } 01109 01110 while (((*str1) != 0) && 01111 ((*str2) != 0) && 01112 (towlower((wint_t)*str1) == towlower((wint_t)*str2))) 01113 { 01114 str1++; 01115 str2++; 01116 } 01117 01118 return (towlower((wint_t) *str1) - towlower((wint_t) *str2)); 01119 } 01120 01121 #endif