C:/Users/vincent/Data/Perso/dev/ocilib/ocilib/src/string.c

00001 /*
00002    +----------------------------------------------------------------------+   
00003    |                                                                      |
00004    |                     OCILIB - C Driver for Oracle                     |
00005    |                                                                      |
00006    |                      (C Wrapper for Oracle OCI)                      |
00007    |                                                                      |
00008    +----------------------------------------------------------------------+
00009    |                      Website : http://www.ocilib.net                 |
00010    +----------------------------------------------------------------------+
00011    |               Copyright (c) 2007-2009 Vincent ROGIER                 |
00012    +----------------------------------------------------------------------+
00013    | This library is free software; you can redistribute it and/or        |
00014    | modify it under the terms of the GNU Lesser General Public           |
00015    | License as published by the Free Software Foundation; either         |
00016    | version 2 of the License, or (at your option) any later version.     |
00017    |                                                                      |
00018    | This library is distributed in the hope that it will be useful,      |
00019    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
00020    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
00021    | Lesser General Public License for more details.                      |
00022    |                                                                      |
00023    | You should have received a copy of the GNU Lesser General Public     |
00024    | License along with this library; if not, write to the Free           |
00025    | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   |
00026    +----------------------------------------------------------------------+
00027    |          Author: Vincent ROGIER <vince.rogier@gmail.com>             |
00028    +----------------------------------------------------------------------+ 
00029 */
00030 
00031 /* ------------------------------------------------------------------------ *
00032  * $Id: string.c, v 3.4.0 2009-07-30 17:40 Vince $
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(const unsigned int* src, int src_size, 
00054                             unsigned short* dst, int dst_size)
00055 {
00056     int cp_size = 0;
00057 
00058     const unsigned int   *src_end = NULL;
00059     const unsigned short *dst_end = NULL;
00060     
00061     OCI_CHECK(src == NULL, 0);
00062     OCI_CHECK(dst == NULL, 0);
00063 
00064     src_end = src + src_size;
00065     dst_end = dst + dst_size;
00066 
00067     while (src < src_end)
00068     {
00069         unsigned int c;
00070     
00071         if (dst >= dst_end) return -1; 
00072     
00073         c = *src++;
00074         
00075         if (c <= UNI_MAX_BMP) 
00076         { 
00077             if ((c >= UNI_SUR_HIGH_START) && (c < UNI_SUR_LOW_END))
00078                 *dst++ = UNI_REPLACEMENT_CHAR;
00079             else 
00080                 *dst++ = (unsigned short) c;
00081 
00082             cp_size++;
00083         }
00084         else if (c > UNI_MAX_LEGAL_UTF32)
00085         {
00086             *dst++ = UNI_REPLACEMENT_CHAR;
00087             
00088             cp_size++;
00089         } 
00090         else
00091         {
00092             if ((dst + 1) >= dst_end) return -2; 
00093 
00094             c -= UNI_BASE;
00095             
00096             if (dst)
00097             {
00098                 *dst++ = (unsigned short)((c >> UNI_SHIFT) + UNI_SUR_HIGH_START);
00099                 *dst++ = (unsigned short)((c &  UNI_MASK ) + UNI_SUR_LOW_START );
00100             }
00101 
00102             cp_size++;
00103             cp_size++;
00104         }
00105     }
00106 
00107     return cp_size;
00108 }
00109 
00110 /* ------------------------------------------------------------------------ *
00111  * OCI_StringCopy2to4bytes
00112  * ------------------------------------------------------------------------ */
00113 
00114 int OCI_StringCopy2to4bytes(const unsigned short* src, int src_size, 
00115                             unsigned int* dst, int dst_size)
00116 {
00117     int cp_size = 0;
00118 
00119     const unsigned short *src_end = NULL;
00120     const unsigned int   *dst_end = NULL;
00121 
00122     unsigned int c1, c2;
00123 
00124     OCI_CHECK(src == NULL, 0);
00125     OCI_CHECK(dst == NULL, 0);
00126 
00127     src_end = src + src_size;
00128     dst_end = dst + dst_size;
00129 
00130     while (src < src_end)
00131     {
00132         
00133         c1 = *src++;
00134 
00135         if ((c1 >= UNI_SUR_HIGH_START) && (c1 <= UNI_SUR_HIGH_END))
00136         {
00137             if (src < src_end)
00138             {
00139                 c2 = *src;
00140 
00141                 if ((c2 >= UNI_SUR_LOW_START) && (c2 <= UNI_SUR_LOW_END))
00142                 {
00143                     c1 = ((c1 - UNI_SUR_HIGH_START) << UNI_SHIFT) + 
00144                           (c2 - UNI_SUR_LOW_START )  + UNI_BASE;
00145                     
00146                     ++src;
00147                 }
00148             } 
00149             else 
00150                 return -1;
00151         } 
00152 
00153         if (dst >= dst_end) return -2;
00154 
00155         *dst++ = c1;
00156 
00157         cp_size++;
00158     }
00159 
00160     return cp_size;
00161 }
00162 
00163 /* ------------------------------------------------------------------------ *
00164  * OCI_StringLength
00165  * ------------------------------------------------------------------------ */
00166 
00167 int OCI_StringLength(void *ptr, int size_elem)
00168 {
00169     int size = 0;
00170 
00171     OCI_CHECK(ptr == NULL, 0);
00172     
00173     if (size_elem == sizeof(char))
00174     {
00175         const char *s = (const char *) ptr;
00176         const char *e = (const char *) ptr;
00177 
00178         while (*e++) ;
00179 
00180         size = (int) (e - s - 1);
00181     }
00182     else if (size_elem == sizeof(short))
00183     {
00184         const short *s = (const short *) ptr;
00185         const short *e = (const short *) ptr;
00186 
00187         while (*e++) ;
00188 
00189         size = (int) (e - s - 1);
00190     }
00191     else if (size_elem == sizeof(int))
00192     {
00193         const int *s = (const int *) ptr;
00194         const int *e = (const int *) ptr;
00195 
00196         while (*e++) ;
00197 
00198         size = (int) (e - s - 1);
00199     }
00200 
00201     return size;
00202 }
00203 
00204 /* ------------------------------------------------------------------------ *
00205  * OCI_GetInputString
00206  * ------------------------------------------------------------------------ */
00207 
00208 void * OCI_GetInputString(void *src, int *size, int size_char_in,
00209                           int size_char_out)
00210 {
00211     OCI_CHECK(src  == NULL, NULL);
00212     OCI_CHECK(size == NULL, NULL);
00213 
00214     if (size_char_in == size_char_out) 
00215     {
00216         /* in/out type sizes are equal, so no conversion ! */
00217        
00218         if (*size == -1)
00219             *size = OCI_StringLength(src, size_char_in) * size_char_in;
00220 
00221         return src;
00222     }
00223     else
00224     {
00225         /* in/out type size are not equal, so conversion needed ! */
00226      
00227         int char_count = 0;
00228         void *dest     = NULL;
00229 
00230         if (*size == -1)
00231             char_count = OCI_StringLength(src, size_char_in);
00232         else
00233             char_count = *size / size_char_in;
00234 
00235         *size = 0;
00236 
00237         dest = malloc((size_t) ((char_count+1)*sizeof(size_char_out)));
00238 
00239         if (dest != NULL)
00240         {
00241             if ((*(char*) src) != 0)
00242             {
00243                 if (size_char_in > size_char_out)
00244                 {
00245                     if ((size_char_in  == sizeof(int  )) &&
00246                         (size_char_out == sizeof(short)))
00247                     {
00248                         /* UTF32 to UTF16 */
00249 
00250                         char_count = OCI_StringCopy4to2bytes
00251                                      (
00252                                         (unsigned int   *)  src, char_count,
00253                                         (unsigned short *) dest, char_count
00254                                      );
00255                     }
00256                     else
00257                     {
00258                         /* widechar to multibytes */
00259 
00260                         char_count = (int) wcstombs(dest, src, char_count+1);
00261                     }
00262                 }
00263                 else
00264                 {                
00265                     if ((size_char_in  == sizeof(short)) &&
00266                         (size_char_out == sizeof(int  )))
00267                     {
00268                         /* UTF16 to UTF32 */
00269                   
00270                         char_count = OCI_StringCopy2to4bytes
00271                                      (
00272                                         (unsigned short *) src,  char_count, 
00273                                         (unsigned int   *) dest, char_count
00274                                      );
00275                     }
00276                     else
00277                     {
00278                         /* multibytes to widechar */
00279 
00280                         char_count = (int) mbstowcs(dest, src, char_count+1);
00281                     }
00282                 }
00283            }
00284                 
00285             *size = char_count * size_char_out;
00286 
00287             memset( (void*) (((char*) dest) + *size), 0, sizeof(size_char_out));
00288         }
00289 
00290         return dest;
00291     }
00292 }
00293 
00294 /* ------------------------------------------------------------------------ *
00295  * OCI_GetOutputString
00296  * ------------------------------------------------------------------------ */
00297 
00298 void OCI_GetOutputString(void *src, void *dest, int *size, int size_char_in,
00299                          int size_char_out)
00300 {
00301     if ((src == NULL) || (dest == NULL) || (size == NULL))
00302         return;
00303 
00304     /* do something only if in/out type sizes are not equal ! */
00305 
00306     if (size_char_in != size_char_out) 
00307     {        
00308         int char_count = 0;
00309      
00310         if (*size == -1)
00311             char_count = OCI_StringLength(src, size_char_in);
00312         else
00313             char_count = *size / size_char_in;
00314            
00315         if (size_char_in > size_char_out)
00316         {
00317             if ((size_char_in  == sizeof(int  )) &&
00318                 (size_char_out == sizeof(short)))
00319             {
00320                 /* UTF32 to UTF16 */
00321 
00322                 char_count = OCI_StringCopy4to2bytes
00323                              (
00324                                 (unsigned int   *)  src, char_count,
00325                                 (unsigned short *) dest, char_count
00326                              );
00327             }
00328             else
00329             {
00330                 /* widechar to multibytes */
00331 
00332                 char_count = (int) wcstombs(dest, src, char_count+1);
00333             }
00334         }
00335         else
00336         {
00337            if ((size_char_in  == sizeof(short)) &&
00338                (size_char_out == sizeof(int  )))
00339             {
00340                 /* UTF16 to UTF32 */
00341           
00342                 char_count = OCI_StringCopy2to4bytes
00343                              (
00344                                 (unsigned short *) src,  char_count, 
00345                                 (unsigned int   *) dest, char_count
00346                              );
00347             }
00348             else
00349             {
00350                 /* multibytes to widechar */
00351 
00352                 char_count = (int) mbstowcs(dest, src, char_count+1);
00353             }
00354         }
00355 
00356         *size = char_count * size_char_out;
00357     }
00358 }
00359 
00360 /* ------------------------------------------------------------------------ *
00361  * OCI_MoveString
00362  * ------------------------------------------------------------------------ */
00363 
00364 void OCI_MoveString(void *src, void *dst, int char_count,
00365                     int size_char_in, int size_char_out)
00366 {
00367     if ((src == NULL) || (dst == NULL))
00368         return;
00369  
00370     /* raw string packing/expansion without charset conversion */
00371 
00372     if (size_char_out > size_char_in)
00373     {
00374         /* expand string */
00375 
00376         if ((size_char_in == sizeof(short)) && (size_char_out == sizeof(int)))
00377         {            
00378             /* 2 => 4 bytes */
00379 
00380             unsigned short *str1  = (unsigned short *) src;
00381             unsigned int   *str2  = (unsigned int   *) dst;
00382 
00383             if (*str1 == 0)
00384                 return;
00385 
00386             while (char_count--)
00387                 str2[char_count] = (unsigned int) str1[char_count];
00388         }
00389          
00390         else if ((size_char_in == sizeof(char)) && (size_char_out == sizeof(short)))
00391         {            
00392             /* 1 => 2 bytes */
00393 
00394             unsigned char  *str1  = (unsigned char  *) src;
00395             unsigned short *str2  = (unsigned short *) dst;
00396 
00397             if (*str1 == 0)
00398                 return;
00399 
00400             while (char_count--)
00401                 str2[char_count] = (unsigned short) str1[char_count];
00402         }
00403         else if ((size_char_in == sizeof(char)) && (size_char_out == sizeof(int)))
00404         {            
00405             /* 1 => 4 bytes */
00406 
00407             unsigned char *str1  = (unsigned char *) src;
00408             unsigned int  *str2  = (unsigned int  *) dst;
00409          
00410             if (*str1 == 0)
00411                 return;
00412 
00413             while (char_count--)
00414                  str2[char_count] = (unsigned int) str1[char_count];
00415          }
00416     }
00417     else if (size_char_out < size_char_in)
00418     {
00419         /* pack string */
00420 
00421         if ((size_char_in == sizeof(int)) && (size_char_out == sizeof(short)))
00422         {
00423             /* 4 => 2 bytes */
00424 
00425             unsigned int   *str1  = (unsigned int   *) src;
00426             unsigned short *str2 = (unsigned short *) dst;
00427             int i = 0;
00428 
00429             if (*str1 == 0)
00430                 return;
00431 
00432             while (++i < char_count)
00433                 str2[i] = (unsigned short) str1[i];
00434         }
00435         else if ((size_char_in == sizeof(short)) && (size_char_out == sizeof(char)))
00436         {
00437             /* 2 => 1 bytes */
00438 
00439             unsigned short *str1 = (unsigned short *) src;
00440             unsigned char  *str2 = (unsigned char  *) dst;
00441             int i = 0;
00442 
00443             if (*str1 == 0)
00444                 return;
00445 
00446             while (++i < char_count)
00447                 str2[i] = (unsigned char) str1[i];
00448         }
00449         else if ((size_char_in == sizeof(int)) && (size_char_out == sizeof(char)))
00450         {
00451             /* 4 => 1 bytes */
00452 
00453             unsigned int  *str1 = (unsigned int  *) src;
00454             unsigned char *str2 = (unsigned char *) dst;
00455             int i = 0;
00456 
00457             if (*str1 == 0)
00458                 return;
00459 
00460             while (++i < char_count)
00461                 str2[i] = (unsigned char) str1[i];
00462         }
00463     }
00464 }
00465 
00466 /* ------------------------------------------------------------------------ *
00467  * OCI_ConvertString
00468  * ------------------------------------------------------------------------ */
00469 
00470 void OCI_ConvertString(void *str, int char_count, int size_char_in, 
00471                        int size_char_out)
00472 {
00473     /* inplace string packing / expansion */
00474 
00475     OCI_MoveString(str, str, char_count, size_char_in, size_char_out);
00476 }
00477 
00478 /* ------------------------------------------------------------------------ *
00479  *  
00480  * ------------------------------------------------------------------------ */
00481 
00482 void OCI_CopyString(void *src, void *dest, int *size, int size_char_in,
00483                     int size_char_out)
00484 {
00485     if ((src == NULL) || (dest == NULL) || (size == NULL))
00486         return;
00487 
00488     if (size_char_out == size_char_in)
00489     {
00490         memcpy(dest, src, (size_t) *size);
00491         memset((void*) (((char*) dest) + (*size)), 0, size_char_out);
00492     }
00493     else
00494         OCI_GetOutputString(src, dest, size, size_char_in, size_char_out);
00495 }
00496 
00497 /* ------------------------------------------------------------------------ *
00498  * OCI_ReleaseMetaString
00499  * ------------------------------------------------------------------------ */
00500 
00501 void OCI_ReleaseMetaString(void *str)
00502 {
00503     if (str == NULL)
00504         return;
00505 
00506 #ifdef OCI_CHECK_METASTRINGS 
00507 
00508     free(str);
00509 
00510 #endif
00511 }
00512 
00513 /* ------------------------------------------------------------------------ *
00514  * OCI_ReleaseDataString
00515  * ------------------------------------------------------------------------ */
00516 
00517 void OCI_ReleaseDataString(void *str)
00518 {
00519     if (str == NULL)
00520         return;
00521 
00522 #ifdef OCI_CHECK_DATASTRINGS 
00523 
00524     free(str);
00525 
00526 #endif
00527 }
00528 
00529 /* ------------------------------------------------------------------------ *
00530  * OCI_StringFromStringPtr
00531  * ------------------------------------------------------------------------ */
00532 
00533 void * OCI_StringFromStringPtr(OCIString *str, void **buf, int *buflen)
00534 {
00535     void *tmp = NULL;
00536     void *ret = NULL;  
00537   
00538     int olen  = 0;
00539     int osize = 0;
00540     int esize = 0;
00541     int msize = 0;
00542 
00543     OCI_CHECK(buf    == NULL, NULL);
00544     OCI_CHECK(buflen == NULL, NULL);
00545 
00546     tmp = OCIStringPtr(OCILib.env, str);
00547 
00548     if (tmp != NULL)
00549     {
00550 
00551 #if defined(OCI_CHARSET_MIXED)
00552 
00553         /* tmp is ANSI and must be converted to UTF16 */
00554 
00555         esize  = 1;
00556         msize  = (int) sizeof(dtext);
00557         olen   = (int) strlen((char* ) tmp);
00558         osize  = olen * esize;
00559         
00560 #elif defined(OCI_CHECK_DATASTRINGS)
00561 
00562         /* tmp is UTF16 and might be converted to UTF32 on unixes */
00563 
00564         
00565         esize  = (int) sizeof(odtext);
00566         msize  = (int) sizeof(dtext);
00567         olen   = (int) OCI_StringLength(tmp, sizeof(odtext));
00568         osize  = olen * esize;
00569 
00570 #else
00571 
00572     OCI_NOT_USED(esize);
00573 
00574 #endif
00575 
00576         /* do we need to use a buffer */
00577 
00578         if (olen > 0)
00579         {
00580             /* do we need to allocate/reallocate the buffer */
00581             
00582             if ((*buf) == NULL)
00583             {           
00584                 *buflen = (olen+1) * msize;
00585                 *buf    = OCI_MemAlloc(OCI_IPC_STRING, msize, olen+1, FALSE);
00586             }
00587             else if ((*buflen) < ((olen+1) * msize))
00588             {
00589                 *buflen = (olen+1) * msize;
00590                 *buf    = OCI_MemRealloc(*buf, OCI_IPC_STRING, msize, olen+1);
00591             }
00592         }
00593 
00594 #if defined(OCI_CHARSET_MIXED)
00595 
00596         mbstowcs(*buf, tmp, olen + OCI_CVT_CHAR);
00597 
00598         memset( (void*) (((char*) *buf) + (olen*msize)), 0, msize);
00599         
00600         ret = *buf;
00601 
00602 #elif defined(OCI_CHECK_DATASTRINGS)
00603   
00604         OCI_GetOutputDataString(tmp, *buf, &osize);
00605         
00606         memset( (void*) (((char*) *buf) + (osize)), 0, msize);
00607                 
00608         ret = *buf;
00609 
00610 #else
00611 
00612         osize = 0;
00613         ret   = tmp;
00614 
00615 #endif
00616 
00617     }
00618     else
00619     {
00620         ret = tmp;
00621     }
00622 
00623     return ret;
00624 }
00625 
00626 /* ------------------------------------------------------------------------ *
00627  * OCI_StringFromStringPtr
00628  * ------------------------------------------------------------------------ */
00629 
00630 boolean OCI_StringToStringPtr(OCIString **str, OCIError *err, void *value, 
00631                               void **buf, int *buflen)
00632 {
00633     boolean res = TRUE;
00634     void *ostr  = NULL;  
00635     int osize   = 0;
00636 
00637 #ifdef OCI_CHARSET_MIXED
00638 
00639     int olen    = 0;
00640     int esize   = 0;
00641 
00642 #endif
00643 
00644     OCI_CHECK(str    == NULL, FALSE);
00645     OCI_CHECK(buf    == NULL, FALSE);
00646     OCI_CHECK(buflen == NULL, FALSE);
00647 
00648 #ifdef OCI_CHARSET_MIXED
00649 
00650     /* value is UTF16 and must be converted to ANSI */
00651  
00652     esize  = (int) 1;
00653     olen   = (int) dtslen((dtext*) value);
00654     osize  = olen;
00655 
00656     /* do we need to use a buffer */
00657 
00658     if (olen > 0)
00659     {
00660         /* do we need to allocate/reallocate the buffer */
00661 
00662         if ((*buf) == NULL)
00663         {           
00664             *buflen = (olen+1) * esize;
00665             *buf    = OCI_MemAlloc(OCI_IPC_STRING, esize, olen+1, FALSE);
00666 
00667         }
00668         else if ((*buflen) < ((olen+1) * esize))
00669         {
00670             *buflen = (olen+1) * esize;
00671             *buf    = OCI_MemRealloc(*buf, OCI_IPC_STRING, esize, olen+1);
00672         }
00673 
00674     }    
00675     
00676     wcstombs((char *) *buf, (dtext *) value, olen + OCI_CVT_CHAR);
00677 
00678     ostr = *buf;
00679     
00680 #else
00681     
00682     osize  = -1;
00683     ostr   = OCI_GetInputDataString(value, &osize);
00684 
00685 #endif
00686 
00687     OCI_CALL3
00688     (
00689         res, err, 
00690 
00691         OCIStringAssignText(OCILib.env, err, (oratext *) ostr, (ub4) osize, str)
00692     )
00693 
00694     OCI_ReleaseDataString(ostr);
00695 
00696     return res;
00697 }
00698 
00699 /* ************************************************************************ *
00700  *                            PUBLIC FUNCTIONS
00701  * ************************************************************************ */
00702 
00703 /* ------------------------------------------------------------------------ *
00704  * ocistrdup
00705  * ------------------------------------------------------------------------ */
00706 
00707 char * ocistrdup(const char * src)
00708 {
00709     char *dst;
00710 
00711     OCI_CHECK(src == NULL, NULL)
00712 
00713     dst = (char *) malloc((strlen(src) + 1) * sizeof(*dst));
00714 
00715     if (dst != NULL)
00716         strcpy(dst, src);
00717 
00718     return dst;
00719 }
00720 
00721 /* ------------------------------------------------------------------------ *
00722  * ocistrcasecmp
00723  * ------------------------------------------------------------------------ */
00724 
00725 int ocistrcasecmp(const char *str1, const char *str2)
00726 {
00727     if (str1 == NULL && str2 == NULL)
00728         return 0;
00729 
00730     if (str1 == NULL)
00731         return 1;
00732 
00733     if (str2 == NULL)
00734         return -1;
00735 
00736     while (((*str1) != 0) && 
00737            ((*str2) != 0) &&
00738            (tolower((int)(*str1)) == tolower((int)(*str2))))
00739     {
00740         str1++;
00741         str2++;
00742     }
00743 
00744     return (tolower((int) (*str1)) - tolower((int) (*str2)));
00745 }
00746 
00747 /* ------------------------------------------------------------------------ *
00748  * ocisprintf
00749  * ------------------------------------------------------------------------ */
00750 
00751 int ocisprintf(char *str, int size, const char *format, ...)
00752 {
00753     va_list args;
00754     int n;
00755 
00756     va_start(args, format);
00757 
00758     n = vsnprintf(str, (size_t) size, format, args);
00759 
00760     va_end(args);
00761 
00762     return n;
00763 }
00764 
00765 #ifdef OCI_INCLUDE_WCHAR
00766 
00767 /* ------------------------------------------------------------------------ *
00768  * ociwcsdup
00769  * ------------------------------------------------------------------------ */
00770 
00771 wchar_t * ociwcsdup(const wchar_t * src)
00772 {
00773     wchar_t *dst;
00774 
00775     OCI_CHECK(src == NULL, NULL)
00776 
00777     dst = (wchar_t *) malloc((wcslen(src)+1) * sizeof(wchar_t));
00778 
00779     if (dst != NULL)
00780         wcscpy(dst, src);
00781 
00782     return dst;
00783 }
00784 
00785 /* ------------------------------------------------------------------------ *
00786  * ociwcscasecmp
00787  * ------------------------------------------------------------------------ */
00788 
00789 int ociwcscasecmp(const wchar_t *str1, const wchar_t *str2)
00790 {
00791      if (str1 == NULL && str2 == NULL)
00792         return 0;
00793 
00794     if (str1 == NULL)
00795         return 1;
00796 
00797     if (str2 == NULL)
00798         return -1;
00799 
00800     while ((*str1 != 0) && (*str2 != 0) &&
00801            (towlower((wint_t)*str1) == towlower((wint_t)*str2)))
00802     {
00803         str1++;
00804         str2++;
00805     }
00806 
00807     return (towlower((wint_t) *str1) - towlower((wint_t) *str2));
00808 }
00809 
00810 #endif
00811 

Generated on Thu Jul 30 17:41:53 2009 for OCILIB (C Driver for Oracle) by  doxygen 1.5.4