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: number.c, Vincent Rogier $ 00033 * --------------------------------------------------------------------------------------------- */ 00034 00035 #include "ocilib_internal.h" 00036 00037 /* ********************************************************************************************* * 00038 * PRIVATE FUNCTIONS 00039 * ********************************************************************************************* */ 00040 00041 /* --------------------------------------------------------------------------------------------- * 00042 * OCI_NumberGet 00043 * --------------------------------------------------------------------------------------------- */ 00044 00045 boolean OCI_NumberGet 00046 ( 00047 OCI_Connection *con, 00048 void *number, 00049 uword size, 00050 uword type, 00051 int sqlcode, 00052 void *out_value 00053 ) 00054 { 00055 boolean res = TRUE; 00056 00057 OCI_CHECK(con == NULL, FALSE); 00058 OCI_CHECK(number == NULL, FALSE); 00059 OCI_CHECK(out_value == NULL, FALSE); 00060 00061 #if OCI_VERSION_COMPILE < OCI_10_1 00062 00063 OCI_NOT_USED(sqlcode); 00064 00065 #endif 00066 00067 if (type == OCI_NUM_NUMBER) 00068 { 00069 memcpy(out_value, number, size); 00070 } 00071 else if (type & OCI_NUM_DOUBLE || type & OCI_NUM_FLOAT) 00072 { 00073 00074 #if OCI_VERSION_COMPILE >= OCI_10_1 00075 00076 if ((OCILib.version_runtime >= OCI_10_1) && ((sqlcode != SQLT_VNU))) 00077 { 00078 if (((type & OCI_NUM_DOUBLE) && (sqlcode == SQLT_BDOUBLE)) || 00079 ((type & OCI_NUM_FLOAT ) && (sqlcode == SQLT_BFLOAT ))) 00080 { 00081 memcpy(out_value, number, size); 00082 } 00083 else if (type & OCI_NUM_DOUBLE && sqlcode == SQLT_BFLOAT) 00084 { 00085 *((double *) out_value) = (double) *((float *) number); 00086 } 00087 else if (type & OCI_NUM_FLOAT && sqlcode == SQLT_BDOUBLE) 00088 { 00089 *((float *) out_value) = (float) *((double *) number); 00090 } 00091 } 00092 else 00093 00094 #endif 00095 00096 { 00097 OCI_CALL2 00098 ( 00099 res, con, 00100 00101 OCINumberToReal(con->err, (OCINumber *) number, size, out_value) 00102 ) 00103 } 00104 } 00105 else 00106 { 00107 uword sign = OCI_NUMBER_SIGNED; 00108 00109 if (type & OCI_NUM_UNSIGNED) 00110 { 00111 sign = OCI_NUMBER_UNSIGNED; 00112 } 00113 00114 OCI_CALL2 00115 ( 00116 res, con, 00117 00118 OCINumberToInt(con->err, (OCINumber *) number, size, sign, out_value) 00119 ) 00120 } 00121 00122 return res; 00123 } 00124 00125 /* --------------------------------------------------------------------------------------------- * 00126 * OCI_NumberSet 00127 * --------------------------------------------------------------------------------------------- */ 00128 00129 boolean OCI_NumberSet 00130 ( 00131 OCI_Connection *con, 00132 void *number, 00133 uword size, 00134 uword type, 00135 int sqlcode, 00136 void *in_value 00137 ) 00138 { 00139 boolean res = TRUE; 00140 00141 OCI_CHECK(con == NULL, FALSE); 00142 OCI_CHECK(number == NULL, FALSE); 00143 OCI_CHECK(in_value == NULL, FALSE); 00144 00145 #if OCI_VERSION_COMPILE < OCI_10_1 00146 00147 OCI_NOT_USED(sqlcode); 00148 00149 #endif 00150 00151 if (type & OCI_NUM_DOUBLE || type & OCI_NUM_FLOAT) 00152 { 00153 00154 #if OCI_VERSION_COMPILE >= OCI_10_1 00155 00156 if ((OCILib.version_runtime >= OCI_10_1) && ((sqlcode != SQLT_VNU))) 00157 { 00158 if (((type & OCI_NUM_DOUBLE) && (sqlcode == SQLT_BDOUBLE)) || 00159 ((type & OCI_NUM_FLOAT ) && (sqlcode == SQLT_BFLOAT ))) 00160 { 00161 memcpy(number, in_value, size); 00162 } 00163 else if (type & OCI_NUM_DOUBLE && sqlcode == SQLT_BFLOAT) 00164 { 00165 *((double *) number) = (double) *((float *) in_value); 00166 } 00167 else if (type & OCI_NUM_FLOAT && sqlcode == SQLT_BDOUBLE) 00168 { 00169 *((float *) number) = (float) *((double *) in_value); 00170 } 00171 } 00172 else 00173 00174 #endif 00175 00176 { 00177 OCI_CALL2 00178 ( 00179 res, con, 00180 00181 OCINumberFromReal(con->err, in_value, size, (OCINumber *) number) 00182 ) 00183 } 00184 } 00185 else 00186 { 00187 uword sign = OCI_NUMBER_SIGNED; 00188 00189 if (type & OCI_NUM_UNSIGNED) 00190 { 00191 sign = OCI_NUMBER_UNSIGNED; 00192 } 00193 00194 OCI_CALL2 00195 ( 00196 res, con, 00197 00198 OCINumberFromInt(con->err, in_value, size, sign, (OCINumber *) number) 00199 ) 00200 } 00201 00202 return res; 00203 } 00204 00205 00206 /* --------------------------------------------------------------------------------------------- * 00207 * OCI_NumberFromString 00208 * --------------------------------------------------------------------------------------------- */ 00209 00210 boolean OCI_NumberFromString 00211 ( 00212 OCI_Connection *con, 00213 void *out_value, 00214 uword size, 00215 uword type, 00216 int sqlcode, 00217 const dtext *in_value, 00218 const mtext * fmt 00219 ) 00220 { 00221 boolean res = TRUE; 00222 boolean done = FALSE; 00223 00224 /* For binary types, perfom a C based conversion */ 00225 00226 if (type & OCI_NUM_DOUBLE || type & OCI_NUM_FLOAT) 00227 { 00228 00229 #if OCI_VERSION_COMPILE >= OCI_10_1 00230 00231 if (OCILib.version_runtime >= OCI_10_1) 00232 { 00233 void *ostr1 = NULL; 00234 int osize1 = -1; 00235 00236 fmt = OCI_STRING_FORMAT_NUM_BIN; 00237 00238 ostr1 = OCI_GetInputString((void *) fmt, &osize1, sizeof(mtext), sizeof(dtext)); 00239 00240 if (type & OCI_NUM_DOUBLE) 00241 { 00242 res = (dtscanf(in_value, (dtext *) ostr1, out_value) == 1); 00243 } 00244 else if (type & OCI_NUM_FLOAT) 00245 { 00246 double tmp_value = 0.0; 00247 00248 res = (dtscanf(in_value, (dtext *) ostr1, &tmp_value) == 1); 00249 00250 *((float *) out_value) = (float) tmp_value; 00251 } 00252 00253 done = TRUE; 00254 00255 if (fmt != ostr1) 00256 { 00257 OCI_ReleaseMetaString(ostr1); 00258 } 00259 } 00260 00261 #endif 00262 00263 } 00264 00265 /* use OCINumber conversion if not processed yet */ 00266 00267 if (done == FALSE) 00268 { 00269 void *ostr1 = NULL; 00270 void *ostr2 = NULL; 00271 int osize1 = -1; 00272 int osize2 = -1; 00273 OCINumber number; 00274 00275 if (fmt == NULL) 00276 { 00277 fmt = OCI_GetDefaultFormatNumeric(con); 00278 } 00279 00280 ostr1 = OCI_GetInputString((void *) in_value, &osize1, sizeof(dtext), sizeof(omtext)); 00281 ostr2 = OCI_GetInputMetaString(fmt, &osize2); 00282 00283 memset(&number, 0, sizeof(number)); 00284 00285 OCI_CALL2 00286 ( 00287 res, con, 00288 00289 OCINumberFromText(con->err, (oratext *) ostr1, (ub4) osize1, (oratext *) ostr2, 00290 (ub4) osize2, (oratext *) NULL, (ub4) 0, (OCINumber *) &number) 00291 ) 00292 00293 OCI_ReleaseMetaString(ostr2); 00294 00295 if (in_value != ostr1) 00296 { 00297 OCI_ReleaseMetaString(ostr1); 00298 } 00299 00300 res = res && OCI_NumberGet(con, &number, size, type, sqlcode, out_value); 00301 } 00302 00303 return res; 00304 } 00305 00306 /* --------------------------------------------------------------------------------------------- * 00307 * OCI_NumberToString 00308 * --------------------------------------------------------------------------------------------- */ 00309 00310 boolean OCI_NumberToString 00311 ( 00312 OCI_Connection *con, 00313 void *number, 00314 uword type, 00315 int sqlcode, 00316 dtext *out_value, 00317 int out_value_size, 00318 const mtext * fmt 00319 ) 00320 { 00321 boolean res = TRUE; 00322 boolean done = FALSE; 00323 00324 out_value[0] = 0; 00325 00326 /* For binary types, perfom a C based conversion */ 00327 00328 if (type & OCI_NUM_DOUBLE || type & OCI_NUM_FLOAT) 00329 { 00330 00331 #if OCI_VERSION_COMPILE >= OCI_10_1 00332 00333 if ((OCILib.version_runtime >= OCI_10_1) && ((sqlcode != SQLT_VNU))) 00334 { 00335 void *ostr1 = NULL; 00336 int osize1 = -1; 00337 00338 if (fmt == NULL) 00339 { 00340 fmt = OCI_STRING_FORMAT_NUM_BIN; 00341 } 00342 00343 ostr1 = OCI_GetInputString((void *) fmt, &osize1, sizeof(mtext), sizeof(dtext)); 00344 00345 if (type & OCI_NUM_DOUBLE && sqlcode == SQLT_BDOUBLE) 00346 { 00347 out_value_size = dtsprintf(out_value, out_value_size, (dtext *) ostr1, *((double *) number)); 00348 } 00349 else if (type & OCI_NUM_FLOAT && sqlcode == SQLT_BFLOAT) 00350 { 00351 out_value_size = dtsprintf(out_value, out_value_size, (dtext *) ostr1, *((float *) number)); 00352 } 00353 00354 done = TRUE; 00355 00356 if (fmt != ostr1) 00357 { 00358 OCI_ReleaseMetaString(ostr1); 00359 } 00360 00361 if ((out_value_size) > 0) 00362 { 00363 while (out_value[out_value_size-1] == DT('0')) 00364 { 00365 out_value[out_value_size-1] = 0; 00366 } 00367 00368 out_value--; 00369 } 00370 } 00371 00372 #else 00373 00374 OCI_NOT_USED(sqlcode); 00375 00376 #endif 00377 00378 } 00379 00380 /* use OCINumber conversion if not processed yet */ 00381 00382 if (done == FALSE) 00383 { 00384 void *ostr1 = NULL; 00385 void *ostr2 = NULL; 00386 int osize1 = out_value_size * (int) sizeof(dtext); 00387 int osize2 = -1; 00388 00389 if (fmt == NULL) 00390 { 00391 fmt = OCI_GetDefaultFormatNumeric(con); 00392 } 00393 00394 ostr1 = OCI_GetInputString(out_value, &osize1, sizeof(dtext), sizeof(omtext)); 00395 ostr2 = OCI_GetInputMetaString(fmt, &osize2); 00396 00397 OCI_CALL2 00398 ( 00399 res, con, 00400 00401 OCINumberToText(con->err, (OCINumber *) number, (oratext *) ostr2, 00402 (ub4) osize2, (oratext *) NULL, (ub4) 0, 00403 (ub4 *) &osize1, (oratext *) ostr1) 00404 ) 00405 00406 OCI_GetOutputString(ostr1, out_value, &osize1, sizeof(omtext), sizeof(dtext)); 00407 OCI_ReleaseMetaString(ostr2); 00408 00409 if (out_value != ostr1) 00410 { 00411 OCI_ReleaseMetaString(ostr1); 00412 } 00413 00414 out_value_size = (osize1 / (int) sizeof(dtext)); 00415 } 00416 00417 /* do we need to suppress last '.' or ',' from integers */ 00418 00419 if ((--out_value_size) >= 0) 00420 { 00421 if ((out_value[out_value_size] == DT('.')) || 00422 (out_value[out_value_size] == DT(','))) 00423 { 00424 out_value[out_value_size] = 0; 00425 } 00426 } 00427 00428 return res; 00429 }