+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// File : $Id: _rb.cpp,v 1.2 2009/03/19 20:00:27 faust Exp $\r
+// Subject : IBPP, internal RB 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
+// * RB == Result Block/Buffer, see Interbase 6.0 C-API\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 <cstring>\r
+\r
+using namespace ibpp_internals;\r
+\r
+char* RB::FindToken(char token)\r
+{\r
+ char* p = mBuffer;\r
+\r
+ while (*p != isc_info_end)\r
+ {\r
+ int len;\r
+\r
+ if (*p == token) return p;\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ p += (len + 3);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+char* RB::FindToken(char token, char subtoken)\r
+{\r
+ char* p = mBuffer;\r
+\r
+ while (*p != isc_info_end)\r
+ {\r
+ int len;\r
+\r
+ if (*p == token)\r
+ {\r
+ // Found token, now find subtoken\r
+ int inlen = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ p += 3;\r
+ while (inlen > 0)\r
+ {\r
+ if (*p == subtoken) return p;\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ p += (len + 3);\r
+ inlen -= (len + 3);\r
+ }\r
+ return 0;\r
+ }\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ p += (len + 3);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+int RB::GetValue(char token)\r
+{\r
+ int value;\r
+ int len;\r
+ char* p = FindToken(token);\r
+\r
+ if (p == 0)\r
+ throw LogicExceptionImpl("RB::GetValue", _("Token not found."));\r
+\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ if (len == 0) value = 0;\r
+ else value = (*gds.Call()->m_vax_integer)(p+3, (short)len);\r
+\r
+ return value;\r
+}\r
+\r
+int RB::GetCountValue(char token)\r
+{\r
+ // Specifically used on tokens like isc_info_insert_count and the like\r
+ // which return detailed counts per relation. We sum up the values.\r
+ int value;\r
+ int len;\r
+ char* p = FindToken(token);\r
+\r
+ if (p == 0)\r
+ throw LogicExceptionImpl("RB::GetCountValue", _("Token not found."));\r
+\r
+ // len is the number of bytes in the following array\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ p += 3;\r
+ value = 0;\r
+ while (len > 0)\r
+ {\r
+ // Each array item is 6 bytes : 2 bytes for the relation_id which\r
+ // we skip, and 4 bytes for the count value which we sum up accross\r
+ // all tables.\r
+ value += (*gds.Call()->m_vax_integer)(p+2, 4);\r
+ p += 6;\r
+ len -= 6;\r
+ }\r
+\r
+ return value;\r
+}\r
+\r
+int RB::GetValue(char token, char subtoken)\r
+{\r
+ int value;\r
+ int len;\r
+ char* p = FindToken(token, subtoken);\r
+\r
+ if (p == 0)\r
+ throw LogicExceptionImpl("RB::GetValue", _("Token/Subtoken not found."));\r
+\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ if (len == 0) value = 0;\r
+ else value = (*gds.Call()->m_vax_integer)(p+3, (short)len);\r
+\r
+ return value;\r
+}\r
+\r
+bool RB::GetBool(char token)\r
+{\r
+ int value;\r
+ char* p = FindToken(token);\r
+\r
+ if (p == 0)\r
+ throw LogicExceptionImpl("RB::GetBool", _("Token not found."));\r
+\r
+ value = (*gds.Call()->m_vax_integer)(p+1, 4);\r
+\r
+ return value == 0 ? false : true;\r
+}\r
+\r
+int RB::GetString(char token, std::string& data)\r
+{\r
+ int len;\r
+ char* p = FindToken(token);\r
+\r
+ if (p == 0)\r
+ throw LogicExceptionImpl("RB::GetString", _("Token not found."));\r
+\r
+ len = (*gds.Call()->m_vax_integer)(p+1, 2);\r
+ data = std::string(p+3, len);\r
+ return len;\r
+}\r
+\r
+void RB::Reset()\r
+{\r
+ delete [] mBuffer;\r
+ mBuffer = new char [mSize];\r
+ memset(mBuffer, 255, mSize);\r
+}\r
+\r
+RB::RB()\r
+{\r
+ mSize = 1024;\r
+ mBuffer = new char [1024];\r
+ memset(mBuffer, 255, mSize);\r
+}\r
+\r
+RB::RB(int Size)\r
+{\r
+ mSize = Size;\r
+ mBuffer = new char [Size];\r
+ memset(mBuffer, 255, mSize);\r
+}\r
+\r
+RB::~RB()\r
+{\r
+ try { delete [] mBuffer; }\r
+ catch (...) { }\r
+}\r
+\r
+//\r
+// EOF\r
+//\r