OCILIB (C Driver for Oracle) 3.12.1
string.c
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