]> git.stg.codes - stg.git/blobdiff - stglibs/ibpp.lib/array.cpp
Port to CMake, get rid of os_int.h.
[stg.git] / stglibs / ibpp.lib / array.cpp
diff --git a/stglibs/ibpp.lib/array.cpp b/stglibs/ibpp.lib/array.cpp
deleted file mode 100644 (file)
index 2dc7ab2..0000000
+++ /dev/null
@@ -1,1046 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////\r
-//\r
-//     File    : $Id: array.cpp,v 1.2 2009/03/19 20:00:28 faust Exp $\r
-//     Subject : IBPP, Array class implementation\r
-//\r
-///////////////////////////////////////////////////////////////////////////////\r
-//\r
-//     (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org)\r
-//\r
-//     The contents of this file are subject to the IBPP License (the "License");\r
-//     you may not use this file except in compliance with the License.  You may\r
-//     obtain a copy of the License at http://www.ibpp.org or in the 'license.txt'\r
-//     file which must have been distributed along with this file.\r
-//\r
-//     This software, distributed under the License, is distributed on an "AS IS"\r
-//     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the\r
-//     License for the specific language governing rights and limitations\r
-//     under the License.\r
-//\r
-///////////////////////////////////////////////////////////////////////////////\r
-//\r
-//     COMMENTS\r
-//     * Tabulations should be set every four characters when editing this file.\r
-//\r
-///////////////////////////////////////////////////////////////////////////////\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning(disable: 4786 4996)\r
-#ifndef _DEBUG\r
-#pragma warning(disable: 4702)\r
-#endif\r
-#endif\r
-\r
-#include "_ibpp.h"\r
-\r
-#ifdef HAS_HDRSTOP\r
-#pragma hdrstop\r
-#endif\r
-\r
-#include <math.h>\r
-#include <cstring>\r
-\r
-using namespace ibpp_internals;\r
-\r
-//     (((((((( OBJECT INTERFACE IMPLEMENTATION ))))))))\r
-\r
-void ArrayImpl::Describe(const std::string& table, const std::string& column)\r
-{\r
-       //if (mIdAssigned)\r
-       //      throw LogicExceptionImpl("Array::Lookup", _("Array already in use."));\r
-       if (mDatabase == 0)\r
-               throw LogicExceptionImpl("Array::Lookup", _("No Database is attached."));\r
-       if (mTransaction == 0)\r
-               throw LogicExceptionImpl("Array::Lookup", _("No Transaction is attached."));\r
-\r
-       ResetId();      // Re-use this array object if was previously assigned\r
-\r
-       IBS status;\r
-       (*gds.Call()->m_array_lookup_bounds)(status.Self(), mDatabase->GetHandlePtr(),\r
-               mTransaction->GetHandlePtr(), const_cast<char*>(table.c_str()),\r
-                       const_cast<char*>(column.c_str()), &mDesc);\r
-       if (status.Errors())\r
-               throw SQLExceptionImpl(status, "Array::Lookup",\r
-                       _("isc_array_lookup_bounds failed."));\r
-\r
-       AllocArrayBuffer();\r
-\r
-       mDescribed = true;\r
-}\r
-\r
-void ArrayImpl::SetBounds(int dim, int low, int high)\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::SetBounds", _("Array description not set."));\r
-       if (mDatabase == 0)\r
-               throw LogicExceptionImpl("Array::SetBounds", _("No Database is attached."));\r
-       if (mTransaction == 0)\r
-               throw LogicExceptionImpl("Array::SetBounds", _("No Transaction is attached."));\r
-       if (dim < 0 || dim > mDesc.array_desc_dimensions-1)\r
-               throw LogicExceptionImpl("Array::SetBounds", _("Invalid dimension."));\r
-       if (low > high ||\r
-               low < mDesc.array_desc_bounds[dim].array_bound_lower ||\r
-               low > mDesc.array_desc_bounds[dim].array_bound_upper ||\r
-               high > mDesc.array_desc_bounds[dim].array_bound_upper ||\r
-               high < mDesc.array_desc_bounds[dim].array_bound_lower)\r
-               throw LogicExceptionImpl("Array::SetBounds",\r
-                       _("Invalid bounds. You can only narrow the bounds."));\r
-\r
-       mDesc.array_desc_bounds[dim].array_bound_lower = short(low);\r
-       mDesc.array_desc_bounds[dim].array_bound_upper = short(high);\r
-\r
-       AllocArrayBuffer();\r
-}\r
-\r
-IBPP::SDT ArrayImpl::ElementType()\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::ElementType",\r
-                       _("Array description not set."));\r
-\r
-       IBPP::SDT value;\r
-       switch (mDesc.array_desc_dtype)\r
-       {\r
-               case blr_text :                 value = IBPP::sdString;         break;\r
-               case blr_varying :              value = IBPP::sdString;         break;\r
-               case blr_cstring :              value = IBPP::sdString;         break;\r
-               case blr_short :                value = IBPP::sdSmallint;       break;\r
-               case blr_long :                 value = IBPP::sdInteger;        break;\r
-               case blr_int64 :                value = IBPP::sdLargeint;       break;\r
-               case blr_float :                value = IBPP::sdFloat;          break;\r
-               case blr_double :               value = IBPP::sdDouble;         break;\r
-               case blr_timestamp :    value = IBPP::sdTimestamp;      break;\r
-               case blr_sql_date :             value = IBPP::sdDate;           break;\r
-               case blr_sql_time :             value = IBPP::sdTime;           break;\r
-               default : throw LogicExceptionImpl("Array::ElementType",\r
-                                               _("Found an unknown sqltype !"));\r
-       }\r
-\r
-       return value;\r
-}\r
-\r
-int ArrayImpl::ElementSize()\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::ElementSize",\r
-                       _("Array description not set."));\r
-\r
-       return mDesc.array_desc_length;\r
-}\r
-\r
-int ArrayImpl::ElementScale()\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::ElementScale",\r
-                       _("Array description not set."));\r
-\r
-       return mDesc.array_desc_scale;\r
-}\r
-\r
-int ArrayImpl::Dimensions()\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::Dimensions",\r
-                       _("Array description not set."));\r
-\r
-       return mDesc.array_desc_dimensions;\r
-}\r
-\r
-void ArrayImpl::Bounds(int dim, int* low, int* high)\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::Bounds", _("Array description not set."));\r
-       if (dim < 0 || dim > mDesc.array_desc_dimensions-1)\r
-               throw LogicExceptionImpl("Array::Bounds", _("Invalid dimension."));\r
-       if (low == 0 || high == 0)\r
-               throw LogicExceptionImpl("Array::Bounds", _("Null reference detected."));\r
-\r
-       *low =  mDesc.array_desc_bounds[dim].array_bound_lower;\r
-       *high = mDesc.array_desc_bounds[dim].array_bound_upper;\r
-}\r
-\r
-/*\r
-\r
-COMMENTS\r
-\r
-1)\r
-For an array column of type CHAR(X), the internal type returned or expected is blr_text.\r
-In such case, the byte array received or submitted to get/put_slice is formatted in\r
-elements of X bytes, which correspond to what is reported in array_desc_length.\r
-The elements are not '\0' terminated but are right-padded with spaces ' '.\r
-\r
-2)\r
-For an array column of type VARCHAR(X), the internal type is blr_varying.\r
-The underlying format is rather curious and different than what is used in XSQLDA.\r
-The element size is reported in array_desc_length as X.\r
-Yet each element of the byte array is expected to be of size X+2 (just as if we were\r
-to stuff a short in the first 2 bytes to store the length (as is done with XSQLDA).\r
-No. The string of X characters maximum has to be stored in the chunks of X+2 bytes as\r
-a zero-terminated c-string. Note that the buffer is indeed one byte too large.\r
-Internally, the API probably convert in-place in these chunks the zero-terminated string\r
-to a variable-size string with a short in front and the string data non zero-terminated\r
-behind.\r
-\r
-3)\r
-With Interbase 6.0 and Firebird 1.0 (initial april 2002 release), the int64 support is\r
-broken regarding the arrays. It is not possible to work on arrays using a datatype stored\r
-in an int64, as for instance any NUMERIC(x,0) where x is equal or greater than 10. That's\r
-a bug in the engine, not in IBPP, which has been fixed in june 2002. Engines compiled from\r
-the current Firebird CVS code as of july 2002 are okay. As will be the 1.01 Firebird version.\r
-We have no idea if this is fixed or not in Interbase 6.5 though.\r
-\r
-*/\r
-\r
-void ArrayImpl::ReadTo(IBPP::ADT adtype, void* data, int datacount)\r
-{\r
-       if (! mIdAssigned)\r
-               throw LogicExceptionImpl("Array::ReadTo", _("Array Id not read from column."));\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::ReadTo", _("Array description not set."));\r
-       if (mDatabase == 0)\r
-               throw LogicExceptionImpl("Array::ReadTo", _("No Database is attached."));\r
-       if (mTransaction == 0)\r
-               throw LogicExceptionImpl("Array::ReadTo", _("No Transaction is attached."));\r
-       if (datacount != mElemCount)\r
-               throw LogicExceptionImpl("Array::ReadTo", _("Wrong count of array elements"));\r
-\r
-       IBS status;\r
-       ISC_LONG lenbuf = mBufferSize;\r
-       (*gds.Call()->m_array_get_slice)(status.Self(), mDatabase->GetHandlePtr(),\r
-               mTransaction->GetHandlePtr(), &mId, &mDesc, mBuffer, &lenbuf);\r
-       if (status.Errors())\r
-               throw SQLExceptionImpl(status, "Array::ReadTo", _("isc_array_get_slice failed."));\r
-       if (lenbuf != mBufferSize)\r
-               throw SQLExceptionImpl(status, "Array::ReadTo", _("Internal buffer size discrepancy."));\r
-\r
-       // Now, convert the types and copy values to the user array...\r
-       int len;\r
-       char* src = (char*)mBuffer;\r
-       char* dst = (char*)data;\r
-\r
-       switch (mDesc.array_desc_dtype)\r
-       {\r
-               case blr_text :\r
-                       if (adtype == IBPP::adString)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       strncpy(dst, src, mElemSize);\r
-                                       dst[mElemSize] = '\0';\r
-                                       src += mElemSize;\r
-                                       dst += (mElemSize + 1);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*src == 't' || *src == 'T' || *src == 'y' || *src == 'Y' || *src == '1')\r
-                                               *(bool*)dst = true;\r
-                                       else *(bool*)dst = false;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(bool);\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::ReadTo", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_varying :\r
-                       if (adtype == IBPP::adString)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       len = (int)strlen(src);\r
-                                       if (len > mElemSize-2) len = mElemSize-2;\r
-                                       strncpy(dst, src, len);\r
-                                       dst[len] = '\0';\r
-                                       src += mElemSize;\r
-                                       dst += (mElemSize - 2 + 1);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*src == 't' || *src == 'T' || *src == 'y' || *src == 'Y' || *src == '1')\r
-                                               *(bool*)dst = true;\r
-                                       else *(bool*)dst = false;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(bool);\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::ReadTo", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_short :\r
-                       if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(bool*)dst = (*(short*)src != 0) ? true : false;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(bool);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt16)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(short*)dst = *(short*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(short);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt32)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int*)dst = (int)*(short*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(int);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt64)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = (int64_t)*(short*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(int64_t);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adFloat)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(float*)dst = (float)(*(short*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(float);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adDouble)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst = (double)(*(short*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(double);\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::ReadTo", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_long :\r
-                       if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(bool*)dst = (*(long*)src != 0) ? true : false;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(bool);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt16)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*(long*)src < consts::min16 || *(long*)src > consts::max16)\r
-                                               throw LogicExceptionImpl("Array::ReadTo",\r
-                                                       _("Out of range numeric conversion !"));\r
-                                       *(short*)dst = short(*(long*)src);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(short);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt32)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(long*)dst = *(long*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(long);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt64)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = (int64_t)*(long*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(int64_t);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adFloat)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(float*)dst = (float)(*(long*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(float);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adDouble)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst = (double)(*(long*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(double);\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::ReadTo", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_int64 :\r
-                       if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(bool*)dst = (*(int64_t*)src != 0) ? true : false;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(bool);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt16)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*(int64_t*)src < consts::min16 || *(int64_t*)src > consts::max16)\r
-                                               throw LogicExceptionImpl("Array::ReadTo",\r
-                                                       _("Out of range numeric conversion !"));\r
-                                       *(short*)dst = short(*(int64_t*)src);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(short);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt32)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*(int64_t*)src < consts::min32 || *(int64_t*)src > consts::max32)\r
-                                               throw LogicExceptionImpl("Array::ReadTo",\r
-                                                       _("Out of range numeric conversion !"));\r
-                                       *(long*)dst = (long)*(int64_t*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(long);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt64)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = *(int64_t*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(int64_t);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adFloat)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(float*)dst = (float)(*(int64_t*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(float);\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adDouble)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst = (double)(*(int64_t*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(double);\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::ReadTo", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_float :\r
-                       if (adtype != IBPP::adFloat || mDesc.array_desc_scale != 0)\r
-                               throw LogicExceptionImpl("Array::ReadTo", _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               *(float*)dst = *(float*)src;\r
-                               src += mElemSize;\r
-                               dst += sizeof(float);\r
-                       }\r
-                       break;\r
-\r
-               case blr_double :\r
-                       if (adtype != IBPP::adDouble) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                               _("Incompatible types."));\r
-                       if (mDesc.array_desc_scale != 0)\r
-                       {\r
-                               // Round to scale of NUMERIC(x,y)\r
-                               double divisor = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst = (double)(*(double*)src / divisor);\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(double);\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst = *(double*)src;\r
-                                       src += mElemSize;\r
-                                       dst += sizeof(double);\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case blr_timestamp :\r
-                       if (adtype != IBPP::adTimestamp) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                                               _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               decodeTimestamp(*(IBPP::Timestamp*)dst, *(ISC_TIMESTAMP*)src);\r
-                               src += mElemSize;\r
-                               dst += sizeof(IBPP::Timestamp);\r
-                       }\r
-                       break;\r
-\r
-               case blr_sql_date :\r
-                       if (adtype != IBPP::adDate) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                                               _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               decodeDate(*(IBPP::Date*)dst, *(ISC_DATE*)src);\r
-                               src += mElemSize;\r
-                               dst += sizeof(IBPP::Date);\r
-                       }\r
-                       break;\r
-\r
-               case blr_sql_time :\r
-                       if (adtype != IBPP::adTime) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                                               _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               decodeTime(*(IBPP::Time*)dst, *(ISC_TIME*)src);\r
-                               src += mElemSize;\r
-                               dst += sizeof(IBPP::Time);\r
-                       }\r
-                       break;\r
-\r
-               default :\r
-                       throw LogicExceptionImpl("Array::ReadTo", _("Unknown sql type."));\r
-       }\r
-}\r
-\r
-void ArrayImpl::WriteFrom(IBPP::ADT adtype, const void* data, int datacount)\r
-{\r
-       if (! mDescribed)\r
-               throw LogicExceptionImpl("Array::WriteFrom", _("Array description not set."));\r
-       if (mDatabase == 0)\r
-               throw LogicExceptionImpl("Array::WriteFrom", _("No Database is attached."));\r
-       if (mTransaction == 0)\r
-               throw LogicExceptionImpl("Array::WriteFrom", _("No Transaction is attached."));\r
-       if (datacount != mElemCount)\r
-               throw LogicExceptionImpl("Array::ReadTo", _("Wrong count of array elements"));\r
-\r
-       // Read user data and convert types to the mBuffer\r
-       int len;\r
-       char* src = (char*)data;\r
-       char* dst = (char*)mBuffer;\r
-\r
-       switch (mDesc.array_desc_dtype)\r
-       {\r
-               case blr_text :\r
-                       if (adtype == IBPP::adString)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       len = (int)strlen(src);\r
-                                       if (len > mElemSize) len = mElemSize;\r
-                                       strncpy(dst, src, len);\r
-                                       while (len < mElemSize) dst[len++] = ' ';\r
-                                       src += (mElemSize + 1);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *dst = *(bool*)src ? 'T' : 'F';\r
-                                       len = 1;\r
-                                       while (len < mElemSize) dst[len++] = ' ';\r
-                                       src += sizeof(bool);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::WriteFrom", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_varying :\r
-                       if (adtype == IBPP::adString)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       len = (int)strlen(src);\r
-                                       if (len > mElemSize-2) len = mElemSize-2;\r
-                                       strncpy(dst, src, len);\r
-                                       dst[len] = '\0';\r
-                                       src += (mElemSize - 2 + 1);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(short*)dst = (short)1;\r
-                                       dst[2] = *(bool*)src ? 'T' : 'F';\r
-                                       src += sizeof(bool);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::WriteFrom", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_short :\r
-                       if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(short*)dst = short(*(bool*)src ? 1 : 0);\r
-                                       src += sizeof(bool);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt16)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(short*)dst = *(short*)src;\r
-                                       src += sizeof(short);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt32)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*(long*)src < consts::min16 || *(long*)src > consts::max16)\r
-                                               throw LogicExceptionImpl("Array::WriteFrom",\r
-                                                       _("Out of range numeric conversion !"));\r
-                                       *(short*)dst = (short)*(int*)src;\r
-                                       src += sizeof(int);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt64)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*(int64_t*)src < consts::min16 || *(int64_t*)src > consts::max16)\r
-                                               throw LogicExceptionImpl("Array::WriteFrom",\r
-                                                       _("Out of range numeric conversion !"));\r
-                                       *(short*)dst = (short)*(int64_t*)src;\r
-                                       src += sizeof(int64_t);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adFloat)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(short*)dst =\r
-                                               (short)floor(*(float*)src * multiplier + 0.5);\r
-                                       src += sizeof(float);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adDouble)\r
-                       {\r
-                               // This SQL_SHORT is a NUMERIC(x,y), scale it !\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(short*)dst =\r
-                                               (short)floor(*(double*)src * multiplier + 0.5);\r
-                                       src += sizeof(double);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::WriteFrom", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_long :\r
-                       if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(long*)dst = *(bool*)src ? 1 : 0;\r
-                                       src += sizeof(bool);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt16)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(long*)dst = *(short*)src;\r
-                                       src += sizeof(short);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt32)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(long*)dst = *(long*)src;\r
-                                       src += sizeof(long);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt64)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       if (*(int64_t*)src < consts::min32 || *(int64_t*)src > consts::max32)\r
-                                               throw LogicExceptionImpl("Array::WriteFrom",\r
-                                                       _("Out of range numeric conversion !"));\r
-                                       *(long*)dst = (long)*(int64_t*)src;\r
-                                       src += sizeof(int64_t);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adFloat)\r
-                       {\r
-                               // This SQL_INT is a NUMERIC(x,y), scale it !\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(long*)dst =\r
-                                               (long)floor(*(float*)src * multiplier + 0.5);\r
-                                       src += sizeof(float);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adDouble)\r
-                       {\r
-                               // This SQL_INT is a NUMERIC(x,y), scale it !\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(long*)dst =\r
-                                               (long)floor(*(double*)src * multiplier + 0.5);\r
-                                       src += sizeof(double);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else throw LogicExceptionImpl("Array::WriteFrom", _("Incompatible types."));\r
-                       break;\r
-\r
-               case blr_int64 :\r
-                       if (adtype == IBPP::adBool)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = *(bool*)src ? 1 : 0;\r
-                                       src += sizeof(bool);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt16)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = *(short*)src;\r
-                                       src += sizeof(short);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt32)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = *(long*)src;\r
-                                       src += sizeof(long);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adInt64)\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst = *(int64_t*)src;\r
-                                       src += sizeof(int64_t);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adFloat)\r
-                       {\r
-                               // This SQL_INT is a NUMERIC(x,y), scale it !\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst =\r
-                                               (int64_t)floor(*(float*)src * multiplier + 0.5);\r
-                                       src += sizeof(float);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else if (adtype == IBPP::adDouble)\r
-                       {\r
-                               // This SQL_INT is a NUMERIC(x,y), scale it !\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(int64_t*)dst =\r
-                                               (int64_t)floor(*(double*)src * multiplier + 0.5);\r
-                                       src += sizeof(double);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else\r
-                               throw LogicExceptionImpl("Array::WriteFrom",\r
-                                       _("Incompatible types (blr_int64 and ADT %d)."), (int)adtype);\r
-                       break;\r
-\r
-               case blr_float :\r
-                       if (adtype != IBPP::adFloat || mDesc.array_desc_scale != 0)\r
-                               throw LogicExceptionImpl("Array::WriteFrom", _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               *(float*)dst = *(float*)src;\r
-                               src += sizeof(float);\r
-                               dst += mElemSize;\r
-                       }\r
-                       break;\r
-\r
-               case blr_double :\r
-                       if (adtype != IBPP::adDouble) throw LogicExceptionImpl("Array::WriteFrom",\r
-                                                                               _("Incompatible types."));\r
-                       if (mDesc.array_desc_scale != 0)\r
-                       {\r
-                               // Round to scale of NUMERIC(x,y)\r
-                               double multiplier = consts::dscales[-mDesc.array_desc_scale];\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst =\r
-                                               floor(*(double*)src * multiplier + 0.5) / multiplier;\r
-                                       src += sizeof(double);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               for (int i = 0; i < mElemCount; i++)\r
-                               {\r
-                                       *(double*)dst = *(double*)src;\r
-                                       src += sizeof(double);\r
-                                       dst += mElemSize;\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case blr_timestamp :\r
-                       if (adtype != IBPP::adTimestamp) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                                               _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               encodeTimestamp(*(ISC_TIMESTAMP*)dst, *(IBPP::Timestamp*)src);\r
-                               src += sizeof(IBPP::Timestamp);\r
-                               dst += mElemSize;\r
-                       }\r
-                       break;\r
-\r
-               case blr_sql_date :\r
-                       if (adtype != IBPP::adDate) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                                               _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               encodeDate(*(ISC_DATE*)dst, *(IBPP::Date*)src); \r
-                               src += sizeof(IBPP::Date);\r
-                               dst += mElemSize;\r
-                       }\r
-                       break;\r
-\r
-               case blr_sql_time :\r
-                       if (adtype != IBPP::adTime) throw LogicExceptionImpl("Array::ReadTo",\r
-                                                                                               _("Incompatible types."));\r
-                       for (int i = 0; i < mElemCount; i++)\r
-                       {\r
-                               encodeTime(*(ISC_TIME*)dst, *(IBPP::Time*)src);\r
-                               src += sizeof(IBPP::Time);\r
-                               dst += mElemSize;\r
-                       }\r
-                       break;\r
-\r
-               default :\r
-                       throw LogicExceptionImpl("Array::WriteFrom", _("Unknown sql type."));\r
-       }\r
-\r
-       IBS status;\r
-       ISC_LONG lenbuf = mBufferSize;\r
-       (*gds.Call()->m_array_put_slice)(status.Self(), mDatabase->GetHandlePtr(),\r
-               mTransaction->GetHandlePtr(), &mId, &mDesc, mBuffer, &lenbuf);\r
-       if (status.Errors())\r
-               throw SQLExceptionImpl(status, "Array::WriteFrom", _("isc_array_put_slice failed."));\r
-       if (lenbuf != mBufferSize)\r
-               throw SQLExceptionImpl(status, "Array::WriteFrom", _("Internal buffer size discrepancy."));\r
-}\r
-\r
-IBPP::Database ArrayImpl::DatabasePtr() const\r
-{\r
-       if (mDatabase == 0) throw LogicExceptionImpl("Array::DatabasePtr",\r
-                       _("No Database is attached."));\r
-       return mDatabase;\r
-}\r
-\r
-IBPP::Transaction ArrayImpl::TransactionPtr() const\r
-{\r
-       if (mTransaction == 0) throw LogicExceptionImpl("Array::TransactionPtr",\r
-                       _("No Transaction is attached."));\r
-       return mTransaction;\r
-}\r
-\r
-IBPP::IArray* ArrayImpl::AddRef()\r
-{\r
-       ASSERTION(mRefCount >= 0);\r
-       ++mRefCount;\r
-       return this;\r
-}\r
-\r
-void ArrayImpl::Release()\r
-{\r
-       // Release cannot throw, except in DEBUG builds on assertion\r
-       ASSERTION(mRefCount >= 0);\r
-       --mRefCount;\r
-       try { if (mRefCount <= 0) delete this; }\r
-               catch (...) { }\r
-}\r
-\r
-//     (((((((( OBJECT INTERNAL METHODS ))))))))\r
-\r
-void ArrayImpl::Init()\r
-{\r
-       ResetId();\r
-       mDescribed = false;\r
-       mDatabase = 0;\r
-       mTransaction = 0;\r
-       mBuffer = 0;\r
-       mBufferSize = 0;\r
-}\r
-\r
-void ArrayImpl::SetId(ISC_QUAD* quad)\r
-{\r
-       if (quad == 0)\r
-               throw LogicExceptionImpl("ArrayImpl::SetId", _("Null Id reference detected."));\r
-\r
-       memcpy(&mId, quad, sizeof(mId));\r
-       mIdAssigned = true;\r
-}\r
-\r
-void ArrayImpl::GetId(ISC_QUAD* quad)\r
-{\r
-       if (quad == 0)\r
-               throw LogicExceptionImpl("ArrayImpl::GetId", _("Null Id reference detected."));\r
-\r
-       memcpy(quad, &mId, sizeof(mId));\r
-}\r
-\r
-void ArrayImpl::ResetId()\r
-{\r
-       memset(&mId, 0, sizeof(mId));\r
-       mIdAssigned = false;\r
-}\r
-\r
-void ArrayImpl::AllocArrayBuffer()\r
-{\r
-       // Clean previous buffer if any\r
-       if (mBuffer != 0) delete [] (char*)mBuffer;\r
-       mBuffer = 0;\r
-\r
-       // Computes total number of elements in the array or slice\r
-       mElemCount = 1;\r
-       for (int i = 0; i < mDesc.array_desc_dimensions; i++)\r
-       {\r
-               mElemCount = mElemCount *\r
-                       (mDesc.array_desc_bounds[i].array_bound_upper -\r
-                               mDesc.array_desc_bounds[i].array_bound_lower + 1);\r
-       }\r
-\r
-       // Allocates a buffer for this count of elements\r
-       mElemSize = mDesc.array_desc_length;\r
-       if (mDesc.array_desc_dtype == blr_varying) mElemSize += 2;\r
-       else if (mDesc.array_desc_dtype == blr_cstring) mElemSize += 1;\r
-       mBufferSize = mElemSize * mElemCount;\r
-       mBuffer = (void*) new char[mBufferSize];\r
-}\r
-\r
-void ArrayImpl::AttachDatabaseImpl(DatabaseImpl* database)\r
-{\r
-       if (database == 0) throw LogicExceptionImpl("Array::AttachDatabase",\r
-                       _("Can't attach a 0 Database object."));\r
-\r
-       if (mDatabase != 0) mDatabase->DetachArrayImpl(this);\r
-       mDatabase = database;\r
-       mDatabase->AttachArrayImpl(this);\r
-}\r
-\r
-void ArrayImpl::AttachTransactionImpl(TransactionImpl* transaction)\r
-{\r
-       if (transaction == 0) throw LogicExceptionImpl("Array::AttachTransaction",\r
-                       _("Can't attach a 0 Transaction object."));\r
-\r
-       if (mTransaction != 0) mTransaction->DetachArrayImpl(this);\r
-       mTransaction = transaction;\r
-       mTransaction->AttachArrayImpl(this);\r
-}\r
-\r
-void ArrayImpl::DetachDatabaseImpl()\r
-{\r
-       if (mDatabase == 0) return;\r
-\r
-       mDatabase->DetachArrayImpl(this);\r
-       mDatabase = 0;\r
-}\r
-\r
-void ArrayImpl::DetachTransactionImpl()\r
-{\r
-       if (mTransaction == 0) return;\r
-\r
-       mTransaction->DetachArrayImpl(this);\r
-       mTransaction = 0;\r
-}\r
-\r
-ArrayImpl::ArrayImpl(DatabaseImpl* database, TransactionImpl* transaction)\r
-       : mRefCount(0)\r
-{\r
-       Init();\r
-       AttachDatabaseImpl(database);\r
-       if (transaction != 0) AttachTransactionImpl(transaction);\r
-}\r
-\r
-ArrayImpl::~ArrayImpl()\r
-{\r
-       try { if (mTransaction != 0) mTransaction->DetachArrayImpl(this); }\r
-               catch (...) {}\r
-       try { if (mDatabase != 0) mDatabase->DetachArrayImpl(this); }\r
-               catch (...) {}\r
-       try { if (mBuffer != 0) delete [] (char*)mBuffer; }\r
-               catch (...) {}\r
-}\r
-\r
-//\r
-//     EOF\r
-//\r