summaryrefslogtreecommitdiffstats
path: root/raslib
diff options
context:
space:
mode:
Diffstat (limited to 'raslib')
-rw-r--r--raslib/Makefile.am54
-rw-r--r--raslib/attribute.cc257
-rw-r--r--raslib/attribute.hh134
-rw-r--r--raslib/basetype.cc77
-rw-r--r--raslib/basetype.hh80
-rw-r--r--raslib/collectiontype.cc140
-rw-r--r--raslib/collectiontype.hh108
-rw-r--r--raslib/complex.cc110
-rw-r--r--raslib/complex.hh87
-rw-r--r--raslib/complex.icc1
-rw-r--r--raslib/complextype.cc284
-rw-r--r--raslib/complextype.hh71
-rw-r--r--raslib/complextype.icc1
-rw-r--r--raslib/dlist.cc71
-rw-r--r--raslib/dlist.hh42
-rw-r--r--raslib/endian.cc623
-rw-r--r--raslib/endian.hh118
-rw-r--r--raslib/error.cc888
-rw-r--r--raslib/error.hh583
-rw-r--r--raslib/error.icc74
-rw-r--r--raslib/flatbasetype.cc301
-rw-r--r--raslib/flatbasetype.hh123
-rw-r--r--raslib/itertype.cc97
-rw-r--r--raslib/itertype.hh86
-rw-r--r--raslib/marraytype.cc131
-rw-r--r--raslib/marraytype.hh101
-rw-r--r--raslib/mddtypes.cc416
-rw-r--r--raslib/mddtypes.hh491
-rw-r--r--raslib/memblockvec.cc107
-rw-r--r--raslib/memblockvec.hh84
-rw-r--r--raslib/metaobject.cc81
-rw-r--r--raslib/metaobject.hh77
-rw-r--r--raslib/minterval.cc1055
-rw-r--r--raslib/minterval.hh567
-rw-r--r--raslib/minterval.icc138
-rw-r--r--raslib/mintervaltype.cc80
-rw-r--r--raslib/mintervaltype.hh79
-rw-r--r--raslib/miter.cc33
-rw-r--r--raslib/miter.hh99
-rw-r--r--raslib/miter.icc144
-rw-r--r--raslib/mitera.cc141
-rw-r--r--raslib/mitera.hh92
-rw-r--r--raslib/miterd.cc117
-rw-r--r--raslib/miterd.hh165
-rw-r--r--raslib/miterd.icc166
-rw-r--r--raslib/miterf.hh128
-rw-r--r--raslib/miterf.icc222
-rw-r--r--raslib/odmgtypes.hh204
-rw-r--r--raslib/oid.cc352
-rw-r--r--raslib/oid.hh137
-rw-r--r--raslib/oid.icc62
-rw-r--r--raslib/oidtype.cc80
-rw-r--r--raslib/oidtype.hh79
-rw-r--r--raslib/parseparams.cc283
-rw-r--r--raslib/parseparams.hh116
-rw-r--r--raslib/point.cc372
-rw-r--r--raslib/point.hh165
-rw-r--r--raslib/point.icc54
-rw-r--r--raslib/pointtype.cc81
-rw-r--r--raslib/pointtype.hh81
-rw-r--r--raslib/primitive.cc439
-rw-r--r--raslib/primitive.hh143
-rw-r--r--raslib/primitivetype.cc601
-rw-r--r--raslib/primitivetype.hh147
-rw-r--r--raslib/property.cc99
-rw-r--r--raslib/property.hh77
-rw-r--r--raslib/rm.cc31
-rw-r--r--raslib/rm.hh38
-rw-r--r--raslib/rmdebug.cc430
-rw-r--r--raslib/rmdebug.hh382
-rw-r--r--raslib/rmdebug.icc120
-rw-r--r--raslib/rminit.cc321
-rw-r--r--raslib/rminit.hh181
-rw-r--r--raslib/scalar.cc120
-rw-r--r--raslib/scalar.hh100
-rw-r--r--raslib/shhopt.c485
-rw-r--r--raslib/shhopt.h56
-rw-r--r--raslib/sinterval.cc1018
-rw-r--r--raslib/sinterval.hh451
-rw-r--r--raslib/sinterval.icc76
-rw-r--r--raslib/sintervaltype.cc80
-rw-r--r--raslib/sintervaltype.hh81
-rw-r--r--raslib/storageman.cc133
-rw-r--r--raslib/storageman.hh116
-rw-r--r--raslib/structure.cc282
-rw-r--r--raslib/structure.hh111
-rw-r--r--raslib/structuretype.cc276
-rw-r--r--raslib/structuretype.hh118
-rw-r--r--raslib/template_inst.hh78
-rw-r--r--raslib/test/Makefile192
-rw-r--r--raslib/test/errtxts244
-rw-r--r--raslib/test/test_endian.cc156
-rw-r--r--raslib/test/test_error.cc223
-rw-r--r--raslib/test/test_metaobject.cc332
-rw-r--r--raslib/test/test_minterval.cc118
-rw-r--r--raslib/test/test_miter.cc334
-rw-r--r--raslib/test/test_miterdbin0 -> 241129 bytes
-rw-r--r--raslib/test/test_miterd.cc75
-rw-r--r--raslib/test/test_miterf.cc118
-rw-r--r--raslib/test/test_oid.cc181
-rw-r--r--raslib/test/test_params.cc101
-rw-r--r--raslib/test/test_point.cc90
-rw-r--r--raslib/test/test_rmdebug.cc179
-rw-r--r--raslib/test/test_sinterval.cc164
-rw-r--r--raslib/test/test_timer.cc101
-rw-r--r--raslib/type.cc671
-rw-r--r--raslib/type.hh167
107 files changed, 21226 insertions, 0 deletions
diff --git a/raslib/Makefile.am b/raslib/Makefile.am
new file mode 100644
index 0000000..6760b08
--- /dev/null
+++ b/raslib/Makefile.am
@@ -0,0 +1,54 @@
+# -*-Makefile-*- (for Emacs)
+#
+# This file is part of rasdaman community.
+#
+# Rasdaman community is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rasdaman community is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>.
+#
+# MAKEFILE FOR:
+# module raslib
+#
+# COMMENTS:
+#
+##################################################################
+
+AM_CXXFLAGS=@CLIENTCXXFLAGS@
+AM_LDFLAGS=@CLIENTLDFLAGS@
+
+noinst_LIBRARIES=libraslib.a
+libraslib_a_SOURCES= sinterval.hh dlist.hh point.hh minterval.hh error.hh \
+ rmdebug.hh rminit.hh metaobject.hh type.hh marraytype.hh \
+ basetype.hh primitivetype.hh sintervaltype.hh \
+ collectiontype.hh property.hh attribute.hh mintervaltype.hh \
+ pointtype.hh oidtype.hh structuretype.hh itertype.hh \
+ oid.hh scalar.hh primitive.hh structure.hh miter.hh mddtypes.hh \
+ miterd.hh mitera.hh memblockvec.hh parseparams.hh storageman.hh \
+ endian.hh flatbasetype.hh complex.hh complextype.hh shhopt.h \
+ sinterval.cc dlist.cc point.cc minterval.cc error.cc \
+ rmdebug.cc rminit.cc metaobject.cc type.cc marraytype.cc \
+ basetype.cc primitivetype.cc sintervaltype.cc \
+ collectiontype.cc property.cc attribute.cc mintervaltype.cc \
+ pointtype.cc oidtype.cc structuretype.cc itertype.cc \
+ oid.cc scalar.cc primitive.cc structure.cc miter.cc mddtypes.cc \
+ miterd.cc mitera.cc memblockvec.cc parseparams.cc storageman.cc \
+ endian.cc flatbasetype.cc complex.cc complextype.cc shhopt.c \
+ complex.icc complextype.icc error.icc minterval.icc miterd.icc miterf.icc \
+ miter.icc oid.icc point.icc rmdebug.icc sinterval.icc \
+ rmdebug.hh rm.hh odmgtypes.hh miterf.hh template_inst.hh
+
diff --git a/raslib/attribute.cc b/raslib/attribute.cc
new file mode 100644
index 0000000..6456810
--- /dev/null
+++ b/raslib/attribute.cc
@@ -0,0 +1,257 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#) raslib, r_Attribute: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/attribute.cc,v 1.11 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/attribute.hh"
+#include "raslib/basetype.hh"
+#include "raslib/structuretype.hh"
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+r_Attribute::r_Attribute()
+ : r_Property(),
+ localOffset(0),
+ globalOffset(0)
+ {
+ }
+
+r_Attribute::r_Attribute(const char* newTypeName, const r_Base_Type& newType)
+ : r_Property(newTypeName, newType),
+ localOffset(0),
+ globalOffset(0)
+ {
+ }
+
+r_Attribute::r_Attribute(const r_Attribute& oldObj)
+ : r_Property(oldObj) ,
+ localOffset(oldObj.localOffset),
+ globalOffset(oldObj.globalOffset)
+ {
+ }
+
+const r_Attribute&
+r_Attribute::operator=(const r_Attribute& oldObj)
+ {
+ // Gracefully handle self assignment
+ if (this != &oldObj)
+ {
+ r_Property::operator=(oldObj) ;
+ localOffset = oldObj.localOffset;
+ globalOffset = oldObj.globalOffset;
+ }
+
+ return *this;
+ }
+
+r_Attribute::~r_Attribute()
+ {
+ }
+
+r_Bytes
+r_Attribute::offset() const
+ {
+ return localOffset;
+ }
+
+void
+r_Attribute::set_offset(r_Bytes newOffset)
+ {
+ localOffset = newOffset;
+ }
+
+r_Bytes
+r_Attribute::global_offset() const
+ {
+ return globalOffset;
+ }
+
+void
+r_Attribute::set_global_offset(r_Bytes newOffset)
+ {
+ globalOffset = newOffset;
+ }
+
+void
+r_Attribute::print_status(std::ostream& s) const
+ {
+ type_of().print_status(s);
+ s << " " << name() << std::flush;
+ }
+
+
+
+r_Attribute
+r_Attribute::operator[](unsigned int number) const throw(r_Error)
+ {
+ if (type_of().type_id() != r_Type::STRUCTURETYPE)
+ {
+ RMInit::logOut << "r_Attribute::operator[](" << number << ") not a struct type" << endl;
+ throw r_Error(r_Error::r_Error_TypeInvalid) ;
+ }
+
+ const r_Structure_Type& structValue = (const r_Structure_Type&)type_of();
+
+ return structValue[number];
+ }
+
+
+
+r_Boolean
+r_Attribute::get_boolean(const char* cell) const throw(r_Error)
+ {
+ if (type_of().type_id() != r_Type::BOOL)
+ {
+ RMInit::logOut << "r_Attribute::get_boolean(data) not a boolean" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Boolean*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_Char
+r_Attribute::get_char(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::CHAR)
+ {
+ RMInit::logOut << "r_Attribute::get_char(data) not a char" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Char*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_Octet
+r_Attribute::get_octet(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::OCTET)
+ {
+ RMInit::logOut << "r_Attribute::get_octet(data) not a octet" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Octet*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_Short
+r_Attribute::get_short(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::SHORT)
+ {
+ RMInit::logOut << "r_Attribute::get_short(data) not a short" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Short*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_UShort
+r_Attribute::get_ushort(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::USHORT)
+ {
+ RMInit::logOut << "r_Attribute::get_ushort(data) not a ushort" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_UShort*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_Long
+r_Attribute::get_long(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::LONG)
+ {
+ RMInit::logOut << "r_Attribute::get_long(data) not a long" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Long*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_ULong
+r_Attribute::get_ulong(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::ULONG)
+ {
+ RMInit::logOut << "r_Attribute::get_ulong(data) not a ulong" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_ULong*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_Float
+r_Attribute::get_float(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::FLOAT)
+ {
+ RMInit::logOut << "r_Attribute::get_float(data) not a float" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Float*) (cell+globalOffset) ) ;
+ }
+
+
+
+r_Double
+r_Attribute::get_double(const char* cell) const throw(r_Error)
+ {
+ if (type_of() .type_id() != r_Type::DOUBLE)
+ {
+ RMInit::logOut << "r_Attribute::get_double(data) not a double" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid) ;
+ throw(err) ;
+ }
+
+ return *((r_Double*) (cell+globalOffset) ) ;
+ }
+
+std::ostream &operator<<( std::ostream &str, const r_Attribute &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/attribute.hh b/raslib/attribute.hh
new file mode 100644
index 0000000..1bfed1c
--- /dev/null
+++ b/raslib/attribute.hh
@@ -0,0 +1,134 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: attribute.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Attribute
+ *
+ * COMMENTS:
+ * None
+*/
+
+#ifndef _D_ATTRIBUTE_
+#define _D_ATTRIBUTE_
+
+#include "raslib/property.hh"
+#include "raslib/odmgtypes.hh"
+#include "raslib/mddtypes.hh"
+
+class r_Base_Type;
+class r_Type_Id;
+class r_Error;
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents attributes of structs in the ODMG
+ conformant representation of the RasDaMan type system.
+*/
+
+
+class r_Attribute : public r_Property
+ {
+ public:
+ /// default constructor.
+ /// initialise important attributes to NULL
+ r_Attribute();
+
+ /// constructor getting name and type of attribute.
+ r_Attribute(const char* newTypeName, const r_Base_Type& newType);
+
+ /// copy constructor.
+ r_Attribute(const r_Attribute& oldObj);
+
+ /// assignment operator.
+ const r_Attribute& operator=(const r_Attribute& oldObj);
+
+ /// destructor.
+ virtual ~r_Attribute();
+
+ /// retrieve (local) offset
+ r_Bytes offset() const;
+
+ /// set (local) offset
+ void set_offset(r_Bytes newOffset);
+
+ /// retrieve global offset
+ r_Bytes global_offset() const;
+
+ /// set global offset
+ void set_global_offset(r_Bytes newOffset);
+
+ /// writes state of object to specified stream
+ virtual void print_status(std::ostream& s = std::cout) const;
+
+ /// subscript operator to access attributes of a structured attribute
+ /// throws error when type is not a struct type
+ r_Attribute operator[](unsigned int number) const throw(r_Error);
+
+ //@Man: Type-safe value access methods. In case of type mismatch, an exception is raised.
+ //@{
+ ///
+ r_Boolean get_boolean(const char* cell) const throw(r_Error);
+
+ ///
+ r_Char get_char(const char* cell) const throw(r_Error);
+
+ ///
+ r_Octet get_octet(const char* cell) const throw(r_Error);
+
+ ///
+ r_Short get_short(const char* cell) const throw(r_Error);
+
+ ///
+ r_UShort get_ushort(const char* cell) const throw(r_Error);
+
+ ///
+ r_Long get_long(const char* cell) const throw(r_Error);
+
+ ///
+ r_ULong get_ulong(const char* cell) const throw(r_Error);
+
+ ///
+ r_Float get_float(const char* cell) const throw(r_Error);
+
+ ///
+ r_Double get_double(const char* cell) const throw(r_Error);
+
+ ///
+ //@}
+
+ protected:
+ /// local offset
+ r_Bytes localOffset;
+
+ /// global offset
+ r_Bytes globalOffset;
+ };
+
+//@Doc: write the status of a attribute to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Attribute &type );
+
+#endif
diff --git a/raslib/basetype.cc b/raslib/basetype.cc
new file mode 100644
index 0000000..639073f
--- /dev/null
+++ b/raslib/basetype.cc
@@ -0,0 +1,77 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/basetype.cc,v 1.4 2003/12/27 23:01:21 rasdev Exp $";
+
+#include <ctype.h> // for isalpha()
+#include <string.h> // for strncmp()
+
+#include "raslib/basetype.hh"
+#include "raslib/attribute.hh"
+
+r_Base_Type::r_Base_Type()
+ : r_Type(),
+ typeSize(0)
+ {
+ }
+
+r_Base_Type::r_Base_Type(const char* newTypeName, r_Bytes newTypeSize)
+ : r_Type(newTypeName),
+ typeSize(newTypeSize)
+ {
+ }
+
+r_Base_Type::r_Base_Type(const r_Base_Type& oldObj)
+ : r_Type(oldObj),
+ typeSize(oldObj.typeSize)
+ {
+ }
+
+const r_Base_Type&
+r_Base_Type::operator=(const r_Base_Type& oldObj)
+ {
+ // Gracefully handle self assignment
+ if (this == &oldObj) return *this;
+
+ r_Type::operator=(oldObj);
+ typeSize = oldObj.typeSize;
+
+ return *this;
+ }
+
+r_Base_Type::~r_Base_Type()
+ {
+ }
+
+bool
+r_Base_Type::isBaseType() const
+ {
+ return true;
+ }
+
+r_Bytes
+r_Base_Type::size() const
+ {
+ return typeSize;
+ }
+
diff --git a/raslib/basetype.hh b/raslib/basetype.hh
new file mode 100644
index 0000000..45e7446
--- /dev/null
+++ b/raslib/basetype.hh
@@ -0,0 +1,80 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: basetype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Base_Type
+ *
+ * COMMENTS:
+ * None
+*/
+
+#ifndef _D_BASETYPE_
+#define _D_BASETYPE_
+
+#include "raslib/type.hh"
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/**
+ This class is the superclass of the types r_Structure_Type and r_Primitive_Type in the
+ representation of the RasDaMan type system.
+*/
+
+class r_Base_Type : public r_Type
+ {
+ public:
+ /// default constructor.
+ r_Base_Type();
+
+ /// constructor getting name of basetype.
+ r_Base_Type(const char* newTypeName, r_Bytes newSize);
+
+ /// copy constructor
+ r_Base_Type(const r_Base_Type& oldObj);
+
+ /// assignment operator.
+ const r_Base_Type& operator=(const r_Base_Type& oldObj);
+
+ /// destructor.
+ virtual ~r_Base_Type();
+
+ /// check, if type is a base type (primitive type or structure type).
+ virtual bool isBaseType() const;
+
+ /// retrieve size of the type.
+ r_Bytes size() const;
+
+ /// prints value of a primitive type or values of a structured type
+ virtual void print_value(const char* storage, std::ostream& s = std::cout) const = 0;
+
+ protected:
+ /// storing size of type in bytes
+ r_Bytes typeSize;
+
+ };
+
+#endif
diff --git a/raslib/collectiontype.cc b/raslib/collectiontype.cc
new file mode 100644
index 0000000..035e201
--- /dev/null
+++ b/raslib/collectiontype.cc
@@ -0,0 +1,140 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Collection_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/collectiontype.cc,v 1.6 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/collectiontype.hh"
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+
+r_Collection_Type::r_Collection_Type()
+ : r_Type(),
+ elementType(NULL)
+ {
+ }
+
+r_Collection_Type::r_Collection_Type(r_Type& newElementType)
+ : r_Type(),
+ elementType(newElementType.clone())
+ {
+ }
+
+r_Collection_Type::r_Collection_Type(const r_Collection_Type& oldObj) throw (r_Error)
+ : r_Type(oldObj),
+ elementType(NULL)
+ {
+ if (oldObj.elementType)
+ elementType = oldObj.elementType->clone();
+ else {
+ RMInit::logOut << "r_Collection_Type::r_Collection_Type( oldObj ) the element type is NULL." << endl;
+ throw r_Error(COLLECTIONTYPEHASNOELEMENTTYPE);
+ }
+ }
+
+bool
+r_Collection_Type::isCollectionType() const
+ {
+ return true;
+ }
+
+const r_Collection_Type&
+r_Collection_Type::operator=(const r_Collection_Type& oldObj) throw (r_Error)
+ {
+ // Gracefully handle self assignment
+ if (this == &oldObj)
+ return *this;
+
+ r_Type::operator=(oldObj);
+ delete elementType;
+ elementType = NULL;
+ if (oldObj.elementType)
+ elementType = oldObj.elementType->clone();
+ else {
+ RMInit::logOut << "r_Collection_Type::operator=( oldObj ) the element type is NULL." << endl;
+ throw r_Error(COLLECTIONTYPEHASNOELEMENTTYPE);
+ }
+ return *this;
+ }
+
+const r_Type&
+r_Collection_Type::element_type() const throw (r_Error)
+ {
+ if (elementType == NULL)
+ {
+ RMInit::logOut << "r_Collection_Type::element_type() the element type is NULL." << endl;
+ throw r_Error(COLLECTIONTYPEHASNOELEMENTTYPE);
+ }
+ return *elementType;
+ }
+
+r_Type*
+r_Collection_Type::clone() const
+ {
+ return new r_Collection_Type(*this);
+ }
+
+r_Collection_Type::r_Kind
+r_Collection_Type::kind() const
+ {
+ return SET;
+ }
+
+r_Type::r_Type_Id
+r_Collection_Type::type_id() const
+ {
+ return COLLECTIONTYPE;
+ }
+
+void
+r_Collection_Type::convertToLittleEndian(char* cells, r_Area noCells) const
+ {
+ }
+
+void
+r_Collection_Type::convertToBigEndian(char* cells, r_Area noCells) const
+ {
+ }
+
+void
+r_Collection_Type::print_status(std::ostream& s) const
+ {
+ s << "set< ";
+ elementType->print_status(s);
+ s << " >";
+ }
+
+
+
+r_Collection_Type::~r_Collection_Type()
+ {
+ if (elementType)
+ delete elementType;
+ elementType = NULL;
+ }
+
+std::ostream &operator<<( std::ostream &str, const r_Collection_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/collectiontype.hh b/raslib/collectiontype.hh
new file mode 100644
index 0000000..9e33106
--- /dev/null
+++ b/raslib/collectiontype.hh
@@ -0,0 +1,108 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: collectiontype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Collection_Type
+ *
+ * COMMENTS:
+ * None
+*/
+
+#ifndef _D_COLLECTION_TYPE_
+#define _D_COLLECTION_TYPE_
+
+#include "raslib/type.hh"
+class r_Error;
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents the collection type in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+
+class r_Collection_Type : public r_Type
+ {
+ public:
+ /// Set type in the only one needed right now.
+ typedef enum { SET } r_Kind;
+
+ /// copy constructor
+ /// the exception is only raised when the element type of the copied type is NULL.
+ /// (this can not happen)
+ r_Collection_Type(const r_Collection_Type&) throw (r_Error);
+
+ /// constructor getting element type
+ r_Collection_Type(r_Type& newType);
+
+ /// returns identifier SET of enumeration r_Kind
+ r_Kind kind() const;
+
+ /// assignment operator
+ /// the exception is only raised when the element type of the copied type is NULL.
+ /// (this can not happen)
+ const r_Collection_Type& operator=(const r_Collection_Type& oldObj) throw (r_Error);
+
+ /// get element type
+ /// the exception is only raised when the element type of the copied type is NULL.
+ /// (this can not happen)
+ const r_Type& element_type() const throw (r_Error);
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ virtual bool isCollectionType() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status(std::ostream& s = std::cout) const;
+
+ /// destructor
+ ~r_Collection_Type();
+
+ protected:
+ /// default constructor
+ /// no one should use that
+ r_Collection_Type();
+
+ /// element type
+ r_Type* elementType;
+ };
+
+//@Doc: write the status of a collection type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Collection_Type &type );
+
+#endif
+
diff --git a/raslib/complex.cc b/raslib/complex.cc
new file mode 100644
index 0000000..9b8ed2e
--- /dev/null
+++ b/raslib/complex.cc
@@ -0,0 +1,110 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+#include "raslib/complex.hh"
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+#include "raslib/complextype.hh"
+
+r_Complex::r_Complex(const char* newBuffer, const r_Complex_Type* newType)
+ : r_Primitive(newBuffer, newType)
+ {
+ }
+
+r_Complex::r_Complex(const r_Complex& obj)
+ : r_Primitive(obj)
+ {
+ }
+
+r_Complex::~r_Complex()
+ {
+ }
+
+r_Scalar*
+r_Complex::clone() const
+ {
+ return new r_Complex(*this);
+ }
+
+const r_Complex&
+r_Complex::operator=(const r_Complex& obj)
+ {
+ r_Primitive::operator=(obj);
+ return *this;
+ }
+
+r_Double
+r_Complex::get_re() const throw (r_Error)
+ {
+ if (!get_buffer() || !valueType || !valueType->isComplexType())
+ {
+ RMInit::logOut << "r_Complex::get_re() value type is not a complex, not initialised or not buffered" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid);
+ throw err;
+ }
+ return ((r_Complex_Type *)valueType)->get_re(get_buffer());
+ }
+
+r_Double
+r_Complex::get_im() const throw (r_Error)
+ {
+ if(!get_buffer() || !valueType || !valueType->isComplexType())
+ {
+ RMInit::logOut << "r_Complex::get_im() value type is not a complex, not initialised or not buffered" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid);
+ throw err;
+ }
+ return ((r_Complex_Type *)valueType)->get_im(get_buffer());
+ }
+
+void
+r_Complex::set_re(r_Double re) throw (r_Error)
+ {
+ if (!valueType || !valueType->isComplexType())
+ {
+ RMInit::logOut << "r_Complex::set_re(" << re << ") value type is not a complex or not initialised" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid);
+ throw err;
+ }
+ ((r_Complex_Type *)valueType)->set_re((char*)get_buffer(), re);
+ }
+
+void
+r_Complex::set_im(r_Double im) throw (r_Error)
+ {
+ if(!valueType || !valueType->isComplexType())
+ {
+ RMInit::logOut << "r_Complex::get_im() value type is not a complex or not initialised" << endl;
+ r_Error err(r_Error::r_Error_TypeInvalid);
+ throw err;
+ }
+ ((r_Complex_Type *)valueType)->set_im((char*)get_buffer(), im);
+ }
+
+
+bool
+r_Complex::isComplex() const
+ {
+ return true;
+ }
+
diff --git a/raslib/complex.hh b/raslib/complex.hh
new file mode 100644
index 0000000..c67da82
--- /dev/null
+++ b/raslib/complex.hh
@@ -0,0 +1,87 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: complex.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Complex
+ *
+ * COMMENTS:
+ * The class represents a complex type value.
+ *
+*/
+
+#ifndef _D_COMPLEX_
+#define _D_COMPLEX_
+
+#include <iostream>
+class r_Error;
+class r_Complex_Type;
+
+#include "raslib/odmgtypes.hh"
+#include "raslib/mddtypes.hh"
+#include "raslib/primitive.hh"
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class \Ref{r_Complex} represents a complex type value.
+
+*/
+
+
+class r_Complex: public r_Primitive
+ {
+ public:
+
+ explicit
+ /// constructs a scalar type value
+ r_Complex(const char* newBuffer, const r_Complex_Type* newType);
+
+ /// copy constructor
+ r_Complex(const r_Complex& obj);
+
+ /// destructor
+ ~r_Complex();
+
+ virtual bool isComplex() const;
+
+ /// clone operator
+ virtual r_Scalar* clone() const;
+
+ /// operator for assigning a primitive
+ virtual const r_Complex& operator =(const r_Complex&);
+
+ r_Double get_re() const throw(r_Error);
+ r_Double get_im() const throw(r_Error);
+
+ void set_re(r_Double) throw(r_Error);
+ void set_im(r_Double) throw(r_Error);
+
+ };
+
+
+#endif
+
diff --git a/raslib/complex.icc b/raslib/complex.icc
new file mode 100644
index 0000000..bab562e
--- /dev/null
+++ b/raslib/complex.icc
@@ -0,0 +1 @@
+//this is moved to complex.cc
diff --git a/raslib/complextype.cc b/raslib/complextype.cc
new file mode 100644
index 0000000..e2b59b3
--- /dev/null
+++ b/raslib/complextype.cc
@@ -0,0 +1,284 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+#include <iomanip>
+#include <string>
+#include <cstring>
+
+#include "raslib/complextype.hh"
+#include "raslib/endian.hh"
+#include "raslib/rmdebug.hh"
+#include "raslib/error.hh"
+
+r_Complex_Type::r_Complex_Type()
+ : r_Primitive_Type(),
+ imOff(0)
+ {
+ }
+
+r_Complex_Type::r_Complex_Type(const char* newTypeName, const r_Type::r_Type_Id newTypeId)
+ : r_Primitive_Type(newTypeName, newTypeId)
+ {
+ imOff = 0;
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ imOff = sizeof(r_Float);
+ break;
+ case COMPLEXTYPE2:
+ imOff = sizeof(r_Double);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "r_Complex_Type(...) bad typeId " << typeId);
+ break;
+ }
+ }
+
+r_Complex_Type::~r_Complex_Type()
+ {
+ }
+
+r_Complex_Type::r_Complex_Type(const r_Complex_Type& oldObj)
+ : r_Primitive_Type(oldObj),
+ imOff(oldObj.imOff)
+ {
+ }
+
+const r_Complex_Type&
+r_Complex_Type::operator=(const r_Complex_Type& oldObj)
+ {
+ if (this == &oldObj)
+ return *this;
+
+ r_Primitive_Type::operator =(oldObj);
+ imOff = oldObj.imOff;
+ return *this;
+ }
+
+r_Type*
+r_Complex_Type::clone() const
+ {
+ return new r_Complex_Type(*this);
+ }
+
+r_Double
+ r_Complex_Type::get_re(const char* cell) const throw(r_Error)
+ {
+ double res = 0;
+
+ if( (typeId != r_Type::COMPLEXTYPE1) &&
+ (typeId != r_Type::COMPLEXTYPE2) )
+ {
+ RMInit::logOut << "r_Complex_Type::get_re(cell) type not a complex1 or complex2" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ res = *(r_Float*)cell;
+ break;
+ case COMPLEXTYPE2:
+ res = *(r_Double *)cell;
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "get_re(...) bad typeId " << typeId);
+ break;
+ }
+ return res;
+ }
+
+r_Double
+r_Complex_Type::get_im(const char* cell) const throw(r_Error)
+ {
+ double res = 0;
+
+ if( (typeId != r_Type::COMPLEXTYPE1) &&
+ (typeId != r_Type::COMPLEXTYPE2) )
+ {
+ RMInit::logOut << "r_Complex_Type::get_im(cell) type not a complex1 or complex2" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ res = *(r_Float*)(cell + imOff);
+ break;
+ case COMPLEXTYPE2:
+ res = *(r_Double*)(cell + imOff);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "get_im(...) bad typeId " << typeId);
+ break;
+ }
+ return res;
+ }
+
+
+
+
+void
+r_Complex_Type::set_re(char* cell, r_Double re) throw(r_Error)
+ {
+ r_Float ref=0.;
+ if( (typeId != r_Type::COMPLEXTYPE1) &&
+ (typeId != r_Type::COMPLEXTYPE2) )
+ {
+ RMInit::logOut << "r_Complex_Type::set_re(cell, re) type not a complex1 or complex2" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ ref=re;
+ memmove(cell, &ref, imOff);
+ break;
+ case COMPLEXTYPE2:
+ memmove(cell, &re, imOff);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "set_re(...) bad typeId " << typeId);
+ break;
+ }
+ }
+
+void
+r_Complex_Type::set_im(char* cell, r_Double im) throw(r_Error)
+ {
+ r_Float imf= 0.;
+
+ if( (typeId != r_Type::COMPLEXTYPE1) &&
+ (typeId != r_Type::COMPLEXTYPE2) )
+ {
+ RMInit::logOut << "r_Complex_Type::set_im(cell, im) type not a complex1 or complex2" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ imf=im;
+ memmove((cell + imOff), &imf, imOff);
+ break;
+ case COMPLEXTYPE2:
+ memmove((cell + imOff), &im, imOff);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "set_im(...) bad typeId " << typeId);
+ break;
+ }
+ }
+
+
+void
+r_Complex_Type::print_status(std::ostream& s) const
+ {
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ s << "complex(float, float)";
+ break;
+ case COMPLEXTYPE2:
+ s << "complex(double, double)";
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "print_status(...) bad typeId " << typeId);
+ break;
+ }
+ }
+
+void
+r_Complex_Type::print_value(const char* storage, std::ostream& s) const
+ {
+ s << "(" << get_re(storage) << ", " << get_im(storage) << ")";
+ }
+
+void
+r_Complex_Type::convertToLittleEndian(char* cells, r_Area noCells) const
+ {
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ for (r_Area i = 0; i < noCells; ++i)
+ {
+ *(r_Float*)(cells + i * typeSize) = r_Endian::swap((r_Float)get_re(cells + i * typeSize));
+ *(r_Float*)(cells + i * typeSize + imOff) = r_Endian::swap((r_Float)get_im(cells + i * typeSize));
+ }
+ break;
+
+ case COMPLEXTYPE2:
+ for (r_Area i = 0; i < noCells; ++i)
+ {
+ *(r_Double*)(cells + i * typeSize) = r_Endian::swap(get_re(cells + i * typeSize));
+ *(r_Double*)(cells + i * typeSize + imOff) = r_Endian::swap(get_im(cells + i * typeSize));
+ }
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "convertToLittleEndian(...) bad typeId " << typeId);
+ break;
+ }
+ }
+
+void
+r_Complex_Type::convertToBigEndian(char* cells, r_Area noCells) const
+ {
+ switch (typeId)
+ {
+ case COMPLEXTYPE1:
+ for (r_Area i = 0; i < noCells; ++i)
+ {
+ *(r_Float*)(cells + i * typeSize) = r_Endian::swap((r_Float)get_re(cells + i * typeSize));
+ *(r_Float*)(cells + i * typeSize + imOff) = r_Endian::swap((r_Float)get_im(cells + i * typeSize));
+ }
+ break;
+ case COMPLEXTYPE2:
+ for (r_Area i = 0; i < noCells; ++i)
+ {
+ *(r_Double*)(cells + i * typeSize) = r_Endian::swap(get_re(cells + i * typeSize));
+ *(r_Double*)(cells + i * typeSize + imOff) = r_Endian::swap(get_im(cells + i * typeSize));
+ }
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Complex_Type", "convertToBigEndian(...) bad typeId " << typeId);
+ break;
+ }
+ }
+
+bool
+r_Complex_Type::isComplexType() const
+ {
+ return true;
+ }
+
+std::ostream &operator<<( std::ostream &str, const r_Complex_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/complextype.hh b/raslib/complextype.hh
new file mode 100644
index 0000000..a496384
--- /dev/null
+++ b/raslib/complextype.hh
@@ -0,0 +1,71 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: complextype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Complex_Type
+ *
+ * COMMENTS:
+ * None
+*/
+
+#ifndef _D_COMPLEXTYPE_TYPE_
+#define _D_COMPLEXTYPE_TYPE_
+
+#include "raslib/primitivetype.hh"
+#include "raslib/odmgtypes.hh"
+#include "raslib/mddtypes.hh"
+
+class r_Complex_Type : public r_Primitive_Type
+ {
+ public:
+ r_Complex_Type();
+ r_Complex_Type(const char* newTypeName, const r_Type::r_Type_Id newTypeId);
+ r_Complex_Type(const r_Complex_Type& oldObj);
+ const r_Complex_Type& operator=(const r_Complex_Type& oldObj);
+ virtual ~r_Complex_Type();
+
+ virtual r_Type* clone() const;
+ virtual void print_status(std::ostream& s = std::cout) const;
+ virtual void print_value(const char* storage, std::ostream& s = std::cout) const;
+
+ r_Double get_re(const char* cell) const throw(r_Error);
+ r_Double get_im(const char* cell) const throw(r_Error);
+
+ void set_re(char* cell, r_Double re) throw(r_Error);
+ void set_im(char* cell, r_Double im) throw(r_Error);
+
+
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+ virtual bool isComplexType() const;
+
+ private:
+ r_Bytes imOff;
+ };
+
+//@Doc: write the status of a complex type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Complex_Type &type );
+
+#endif
diff --git a/raslib/complextype.icc b/raslib/complextype.icc
new file mode 100644
index 0000000..9bbb3dd
--- /dev/null
+++ b/raslib/complextype.icc
@@ -0,0 +1 @@
+//this is moved to complextype.cc
diff --git a/raslib/dlist.cc b/raslib/dlist.cc
new file mode 100644
index 0000000..9641580
--- /dev/null
+++ b/raslib/dlist.cc
@@ -0,0 +1,71 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+#include <iostream>
+#include <vector>
+#include "raslib/dlist.hh"
+#include "raslib/minterval.hh"
+
+template <class T>
+std::ostream& operator<< (std::ostream& os, const std::vector<T>& list)
+{
+ os << "[ ";
+ for (typename std::vector<T>::const_iterator it = list.begin(); it != list.end(); it++)
+ os << (*it) << " ";
+ os << "]";
+ return os;
+}
+
+template <class T>
+std::ostream& operator<< (const std::vector<T>& list, std::ostream& os)
+{
+ os << "[ ";
+ for (typename std::vector<T>::const_iterator it = list.begin(); it != list.end(); it++)
+ os << (*it) << " ";
+ os << "]";
+ return os;
+}
+
+#if defined(SOLARIS) && ! defined(EARLY_TEMPLATE)
+//this is here to get around a template instantiation problem on sun
+template <>
+std::ostream& operator<< (std::ostream& os, const std::vector<r_Minterval>& list)
+{
+ os << "[ ";
+ for (typename std::vector<r_Minterval>::const_iterator it = list.begin(); it != list.end(); it++)
+ os << (*it) << " ";
+ os << "]";
+ return os;
+}
+
+template <>
+std::ostream& operator<< (const std::vector<r_Minterval>& list, std::ostream& os)
+{
+ os << "[ ";
+ for (typename std::vector<r_Minterval>::const_iterator it = list.begin(); it != list.end(); it++)
+ os << (*it) << " ";
+ os << "]";
+ return os;
+}
+
+#endif
diff --git a/raslib/dlist.hh b/raslib/dlist.hh
new file mode 100644
index 0000000..ea794e3
--- /dev/null
+++ b/raslib/dlist.hh
@@ -0,0 +1,42 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+#ifndef _DLIST_H_
+#define _DLIST_H_
+#include <iostream>
+#include <vector>
+
+template <class T>
+std::ostream& operator<< (std::ostream& os, const std::vector<T>& list);
+
+template <class T>
+std::ostream& operator<< (const std::vector<T>& list, std::ostream& os);
+
+#ifdef EARLY_TEMPLATE
+#ifdef __EXECUTABLE__
+#include "raslib/dlist.cc"
+#endif
+#endif
+
+#endif
+
diff --git a/raslib/endian.cc b/raslib/endian.cc
new file mode 100644
index 0000000..45837a1
--- /dev/null
+++ b/raslib/endian.cc
@@ -0,0 +1,623 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: endian.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Endian
+ *
+ * COMMENTS:
+ * None
+*/
+
+#include <string.h>
+
+
+#include "raslib/endian.hh"
+#include "raslib/rmdebug.hh"
+#include "raslib/minterval.hh"
+#include "raslib/primitivetype.hh"
+#include "raslib/structuretype.hh"
+#include "raslib/miter.hh"
+
+
+
+
+/*
+ * Inline code used in several places in the r_Endian class
+ */
+
+static inline r_Octet eswap( r_Octet val )
+{
+ return val;
+}
+
+static inline void eswap( r_Octet val, void *dest )
+{
+ r_Char *d = (r_Char *)dest;
+ *d = val;
+}
+
+static inline r_Short eswap( r_Short val )
+{
+ return (r_Short)(((val & 0xff) << 8) | ((val >> 8) & 0xff));
+}
+
+static inline r_UShort eswap( r_UShort val )
+{
+ return (r_UShort)(((val & 0xff) << 8) | ((val >> 8) & 0xff));
+}
+
+static inline void eswap( r_Short val, void *dest )
+{
+ r_Short *d = (r_Short *)dest;
+ *d = eswap(val);
+}
+
+static inline void eswap( r_UShort val, void *dest )
+{
+ r_UShort *d = (r_UShort *)dest;
+ *d = eswap(val);
+}
+
+static inline r_Long eswap( r_Long val )
+{
+ return (r_Long)(((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val >> 8) & 0xff00) | ((val >> 24) & 0xff));
+}
+
+static inline r_ULong eswap( r_ULong val )
+{
+ return (r_ULong)(((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val >> 8) & 0xff00) | ((val >> 24) & 0xff));
+}
+
+static inline void eswap( r_Long val, void *dest )
+{
+ r_Long *d = (r_Long *)dest;
+ *d = eswap(val);
+}
+
+static inline void eswap( r_ULong val, void *dest )
+{
+ r_ULong *d = (r_ULong *)dest;
+ *d = eswap(val);
+}
+
+/*
+these types are not supported
+static inline long eswap( long val )
+{
+ return (long)(((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val >> 8) & 0xff00) | ((val >> 24) & 0xff));
+}
+
+static inline r_ULong eswap( r_ULong val )
+{
+ return (r_ULong)(((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val >> 8) & 0xff00) | ((val >> 24) & 0xff));
+}
+
+static inline void eswap( long val, void *dest )
+{
+ long *d = (long *)dest;
+ *d = eswap(val);
+}
+
+static inline void eswap( r_ULong val, void *dest )
+{
+ r_ULong *d = (r_ULong *)dest;
+ *d = eswap(val);
+}
+*/
+
+static inline r_Float eswap( r_Float val )
+{
+ r_Long *ptr = (r_Long*)&val;
+ r_Float result;
+
+ eswap(*ptr, &result);
+
+ return result;
+}
+
+static inline void eswap( r_Float val, void *dest )
+{
+ r_Long *ptr = (r_Long*)&val;
+
+ eswap(*ptr, dest);
+}
+
+
+#ifndef __GNUG__
+inline
+#endif
+static r_Double eswap( r_Double val )
+{
+ r_Long *ptr = (r_Long*)&val;
+ r_Double result;
+ eswap(ptr[0], ((r_Octet*)&result)+sizeof(r_Long));
+ eswap(ptr[1], (r_Octet*)&result);
+/*
+#ifndef DECALPHA
+ eswap(ptr[0], ((r_Octet*)&result)+sizeof(long));
+ eswap(ptr[1], (r_Octet*)&result);
+#else
+ eswap(*ptr, &result);
+#endif
+*/
+ return result;
+}
+
+#ifndef __GNUG__
+inline
+#endif
+static void eswap( r_Double val, void *dest )
+{
+ r_Long *ptr = (r_Long*)&val;
+ eswap(ptr[0], ((r_Octet*)dest)+sizeof(r_Long));
+ eswap(ptr[1], dest);
+/*
+#ifndef DECALPHA
+ eswap(ptr[0], ((r_Octet*)dest)+sizeof(long));
+ eswap(ptr[1], dest);
+#else
+ eswap(*ptr, dest);
+#endif
+*/
+}
+
+
+/*
+ * Template functions used throughout the code
+ */
+
+// template for special linear iteration
+template<class T>
+void swap_array_templ( r_Bytes size, T *dest, const T *src)
+{
+ const T *sptr = src;
+ T *dptr = dest;
+ r_Bytes ctr;
+
+ for (ctr = 0; ctr < size; ctr += sizeof(T), sptr++, dptr++)
+ eswap(*sptr, dptr);
+}
+
+
+// template for identical domains for src and dest
+template<class T>
+void swap_array_templ(r_Miter &iter, T *destBase, const T *srcBase)
+{
+ while (!iter.isDone())
+ {
+ const T *src = (const T*)iter.nextCell();
+ eswap(*src, destBase + (src - srcBase));
+ }
+}
+
+
+// template for generic iteration (src is just a dummy here)
+template<class T>
+void swap_array_templ(r_Miter &siter, r_Miter &diter, const T *srcBase)
+{
+ while (!siter.isDone())
+ {
+ const T *src = (const T*)siter.nextCell();
+ T *dest = (T*)diter.nextCell();
+ eswap(*src, dest);
+ }
+}
+
+// force the instantiations; we only need the templates r_Longernally anyway
+template void swap_array_templ(r_Bytes, r_Short *, const r_Short *);
+template void swap_array_templ(r_Bytes, r_UShort *, const r_UShort *);
+template void swap_array_templ(r_Bytes, r_Long *, const r_Long *);
+template void swap_array_templ(r_Bytes, r_ULong *, const r_ULong *);
+/*
+template void swap_array_templ(r_Bytes, long *, const long *);
+template void swap_array_templ(r_Bytes, r_ULong *, const r_ULong *);
+*/
+template void swap_array_templ(r_Bytes, r_Float *, const r_Float *);
+template void swap_array_templ(r_Bytes, r_Double *, const r_Double *);
+template void swap_array_templ(r_Miter &, r_Octet *, const r_Octet *);
+template void swap_array_templ(r_Miter &, r_Short *, const r_Short *);
+template void swap_array_templ(r_Miter &, r_Long *, const r_Long *);
+template void swap_array_templ(r_Miter &, r_Float *, const r_Float *);
+template void swap_array_templ(r_Miter &, r_Double *, const r_Double *);
+template void swap_array_templ(r_Miter &, r_Miter &, const r_Octet *);
+template void swap_array_templ(r_Miter &, r_Miter &, const r_Short *);
+template void swap_array_templ(r_Miter &, r_Miter &, const r_Long *);
+template void swap_array_templ(r_Miter &, r_Miter &, const r_Float *);
+template void swap_array_templ(r_Miter &, r_Miter &, const r_Double *);
+
+
+
+
+
+/*
+ * r_Endian members
+ */
+
+r_Short r_Endian::swap( r_Short val )
+{
+ return eswap(val);
+}
+
+r_UShort r_Endian::swap( r_UShort val )
+{
+ return eswap(val);
+}
+
+r_Long r_Endian::swap( r_Long val )
+{
+ return eswap(val);
+}
+
+r_ULong r_Endian::swap( r_ULong val )
+{
+ return eswap(val);
+}
+/*
+long r_Endian::swap( long val )
+{
+ return eswap(val);
+}
+
+r_ULong r_Endian::swap( r_ULong val )
+{
+ return eswap(val);
+}
+*/
+r_Float r_Endian::swap( r_Float val )
+{
+ return eswap(val);
+}
+
+r_Double r_Endian::swap( r_Double val )
+{
+ return eswap(val);
+}
+
+
+r_Endian::r_Endianness r_Endian::get_endianness( void )
+{
+#ifdef LITTLE_ENDIAN
+ return r_Endian_Little;
+#else
+ return r_Endian_Big;
+#endif
+}
+
+
+
+/*
+ * Simplest array swapping: linear buffer filled with atomic type
+ */
+
+void r_Endian::swap_array( const r_Primitive_Type *type, r_Bytes size, const void *src, void *dest )
+{
+ switch (type->type_id())
+ {
+ case r_Primitive_Type::BOOL:
+ case r_Primitive_Type::CHAR:
+ case r_Primitive_Type::OCTET:
+ if (src != (const void*)dest)
+ {
+ // change of endianness on 1 byte data is a NULL operation.
+ // if src and dest differ, we have to _copy_, though.
+ memcpy(dest, src, size);
+ }
+ break;
+ case r_Primitive_Type::SHORT:
+ swap_array_templ(size, (r_Short*)dest, (const r_Short*)src);
+ break;
+ case r_Primitive_Type::USHORT:
+ swap_array_templ(size, (r_UShort*)dest, (const r_UShort*)src);
+ break;
+ case r_Primitive_Type::LONG:
+ swap_array_templ(size, (r_Long*)dest, (const r_Long*)src);
+ break;
+ case r_Primitive_Type::ULONG:
+ swap_array_templ(size, (r_ULong*)dest, (const r_ULong*)src);
+ break;
+ case r_Primitive_Type::FLOAT:
+ case r_Primitive_Type::COMPLEXTYPE1:
+ swap_array_templ(size, (r_Float*)dest, (const r_Float*)src);
+ break;
+ case r_Primitive_Type::DOUBLE:
+ case r_Primitive_Type::COMPLEXTYPE2:
+ swap_array_templ(size, (r_Double*)dest, (const r_Double*)src);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Endian", "swap_array(type, size, src, dest) bad typeId " << type->type_id());
+ break;
+ }
+}
+
+
+/*
+ * Same functionality as function above, but with the types given implicitly
+ * by the parameters
+ */
+
+// Dummies, but useful when templates are used
+void r_Endian::swap_array( r_Bytes size, const r_Octet *src, r_Octet *dest )
+{
+}
+
+void r_Endian::swap_array( r_Bytes size, const r_Char *src, r_Char *dest )
+{
+}
+
+// Here go the real ones...
+void r_Endian::swap_array( r_Bytes size, const r_Short *src, r_Short *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+
+void r_Endian::swap_array( r_Bytes size, const r_UShort *src, r_UShort *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+
+void r_Endian::swap_array( r_Bytes size, const r_Long *src, r_Long *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+
+void r_Endian::swap_array( r_Bytes size, const r_ULong *src, r_ULong *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+/*
+void r_Endian::swap_array( r_Bytes size, const long *src, long *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+
+void r_Endian::swap_array( r_Bytes size, const r_ULong *src, r_ULong *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+*/
+void r_Endian::swap_array( r_Bytes size, const r_Float *src, r_Float *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+
+void r_Endian::swap_array( r_Bytes size, const r_Double *src, r_Double *dest )
+{
+ swap_array_templ(size, dest, src);
+}
+
+
+/*
+ * Same functionality as above, but with the type size given as parameter
+ */
+
+void r_Endian::swap_array( r_Bytes size, r_Bytes tsize, const void *src, void *dest )
+{
+ switch (tsize)
+ {
+ case 2:
+ swap_array_templ(size, (r_Short*)dest, (const r_Short*)src);
+ break;
+ case 4:
+ swap_array_templ(size, (r_Long*)dest, (const r_Long*)src);
+ break;
+ case 8:
+ case 16: // complexd
+ swap_array_templ(size, (r_Double*)dest, (const r_Double*)src);
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+/*
+ * ``Half-generic'': array with arbitrary total domain and iteration
+ * domain, but same domains for src and dest
+ */
+void r_Endian::swap_array( const r_Primitive_Type *type, const r_Minterval &srcDom, const r_Minterval &srcIterDom, const void *src, void *dest, r_ULong step )
+{
+ if ((srcDom == srcIterDom) && (step == type->size()))
+ {
+ r_ULong size = step * srcDom.cell_count();
+
+ swap_array(type, size, src, dest);
+ }
+ else
+ {
+ r_Miter iter(&srcIterDom, &srcDom, step, (const char*)src);
+
+ switch (type->type_id())
+ {
+ case r_Primitive_Type::BOOL:
+ case r_Primitive_Type::CHAR:
+ case r_Primitive_Type::OCTET:
+ if (src != (const void*)dest)
+ {
+ swap_array_templ(iter, (r_Octet*)dest, (const r_Octet*)src);
+ }
+ break;
+ case r_Primitive_Type::SHORT:
+ swap_array_templ(iter, (r_Short*)dest, (const r_Short*)src);
+ break;
+ case r_Primitive_Type::USHORT:
+ swap_array_templ(iter, (r_UShort*)dest, (const r_UShort*)src);
+ break;
+ case r_Primitive_Type::LONG:
+ swap_array_templ(iter, (r_Long*)dest, (const r_Long*)src);
+ break;
+ case r_Primitive_Type::ULONG:
+ swap_array_templ(iter, (r_ULong*)dest, (const r_ULong*)src);
+ break;
+ case r_Primitive_Type::FLOAT:
+ case r_Primitive_Type::COMPLEXTYPE1:
+ swap_array_templ(iter, (r_Float*)dest, (const r_Float*)src);
+ break;
+ case r_Primitive_Type::DOUBLE:
+ case r_Primitive_Type::COMPLEXTYPE2:
+ swap_array_templ(iter, (r_Double*)dest, (const r_Double*)src);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Endian", "swap_array(type, srcdom, srciterdom, src, dest, step) bad typeId " << type->type_id());
+ break;
+ }
+ }
+}
+
+
+static void swap_array_struct( const r_Structure_Type *structType, const r_Minterval &srcDom, const r_Minterval &srcIterDom, const void *src, void *dest, r_ULong step )
+{
+ r_Structure_Type::attribute_iterator iter(structType->defines_attribute_begin());
+
+ while (iter != structType->defines_attribute_end())
+ {
+ r_Type *newType = (*iter).type_of().clone();
+ const void *srcPtr = (const void*)(((const r_Octet*)src) + (*iter).offset());
+ void *destPtr = (void*)(((r_Octet*)dest) + (*iter).offset());
+ if (newType->isStructType())
+ swap_array_struct((const r_Structure_Type*)newType, srcDom, srcIterDom, srcPtr, destPtr, step);
+ else
+ r_Endian::swap_array((const r_Primitive_Type*)newType, srcDom, srcIterDom, srcPtr, destPtr, step);
+ delete newType;
+ iter++;
+ }
+}
+
+
+void r_Endian::swap_array( const r_Base_Type *type, const r_Minterval &srcDom, const r_Minterval &srcIterDom, const void *src, void *dest )
+{
+ if (type->isStructType())
+ swap_array_struct((const r_Structure_Type*)type, srcDom, srcIterDom, src, dest, type->size());
+ else
+ swap_array((const r_Primitive_Type*)type, srcDom, srcIterDom, src, dest, type->size());
+}
+
+
+
+
+/*
+ * Fully generic: different total domain and iteration domain for both
+ * src and dest. Beware that the number of cells in the iteration domains
+ * for src and dest must be identical!
+ */
+
+void r_Endian::swap_array( const r_Primitive_Type *type, const r_Minterval &srcDom, const r_Minterval &srcIterDom, const r_Minterval &destDom, const r_Minterval &destIterDom, const void *src, void *dest, r_ULong step )
+{
+ /// check if the whole thing reduces to a linear scan
+ if ((srcDom == srcIterDom) && (step == type->size()))
+ {
+ r_ULong size = step * srcDom.cell_count();
+
+ swap_array(type, size, src, dest);
+ }
+ /// no, generic code...
+ else
+ {
+ r_Miter siter(&srcIterDom, &srcDom, (r_Long)step, (const char*)src);
+ r_Miter diter(&destIterDom, &destDom, (r_Long)step, (const char*)dest);
+
+ switch (type->type_id())
+ {
+ case r_Primitive_Type::BOOL:
+ case r_Primitive_Type::CHAR:
+ case r_Primitive_Type::OCTET:
+ if (src != (const void*)dest)
+ {
+ swap_array_templ(siter, diter, (const r_Octet*)src);
+ }
+ break;
+ case r_Primitive_Type::SHORT:
+ swap_array_templ(siter, diter, (const r_Short*)src);
+ break;
+ case r_Primitive_Type::USHORT:
+ swap_array_templ(siter, diter, (const r_UShort*)src);
+ break;
+ case r_Primitive_Type::LONG:
+ swap_array_templ(siter, diter, (const r_Long*)src);
+ break;
+ case r_Primitive_Type::ULONG:
+ swap_array_templ(siter, diter, (const r_ULong*)src);
+ break;
+ case r_Primitive_Type::FLOAT:
+ case r_Primitive_Type::COMPLEXTYPE1:
+ swap_array_templ(siter, diter, (const r_Float*)src);
+ break;
+ case r_Primitive_Type::DOUBLE:
+ case r_Primitive_Type::COMPLEXTYPE2:
+ swap_array_templ(siter, diter, (const r_Double*)src);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Endian", "swap_array(type, srcdom, srciterdom, destdom, destiterdom, src, dest, step) bad typeId " << type->type_id());
+ break;
+ }
+ }
+}
+
+
+static void swap_array_struct( const r_Structure_Type *structType, const r_Minterval &srcDom, const r_Minterval &srcIterDom, const r_Minterval &destDom, const r_Minterval &destIterDom, const void *src, void *dest, r_ULong step)
+{
+ r_Structure_Type::attribute_iterator iter(structType->defines_attribute_begin());
+
+ while (iter != structType->defines_attribute_end())
+ {
+ r_Type *newType = (*iter).type_of().clone();
+ const void *srcPtr = (const void*)(((const r_Octet*)src) + (*iter).offset());
+ void *destPtr = (void*)(((r_Octet*)dest) + (*iter).offset());
+ if (newType->isStructType())
+ swap_array_struct((const r_Structure_Type*)newType, srcDom, srcIterDom, destDom, destIterDom, srcPtr, destPtr, step);
+ else
+ r_Endian::swap_array((const r_Primitive_Type*)newType, srcDom, srcIterDom, destDom, destIterDom, srcPtr, destPtr, step);
+ delete newType;
+ iter++;
+ }
+}
+
+void r_Endian::swap_array( const r_Base_Type *type, const r_Minterval &srcDom, const r_Minterval &srcIterDom, const r_Minterval &destDom, const r_Minterval &destIterDom, const void *src, void *dest )
+{
+ if (type->isStructType())
+ swap_array_struct((const r_Structure_Type*)type, srcDom, srcIterDom, destDom, destIterDom, src, dest, type->size());
+ else
+ swap_array((const r_Primitive_Type*)type, srcDom, srcIterDom, destDom, destIterDom, src, dest, type->size());
+}
+
+std::ostream& operator<<(std::ostream& s, r_Endian::r_Endianness& e)
+{
+ switch(e) {
+ case r_Endian::r_Endian_Little:
+ s << "Little_Endian";
+ break;
+ case r_Endian::r_Endian_Big:
+ s << "Big_Endian";
+ break;
+ default:
+ s << "Unkown r_Endiannes";
+ break;
+ }
+ return s;
+}
diff --git a/raslib/endian.hh b/raslib/endian.hh
new file mode 100644
index 0000000..fb8e0ff
--- /dev/null
+++ b/raslib/endian.hh
@@ -0,0 +1,118 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: endian.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Endian
+ *
+ * COMMENTS:
+ * None
+*/
+
+#ifndef _R_ENDIANTOOLS_HH_
+#define _R_ENDIANTOOLS_HH_
+
+#include <iostream>
+
+class r_Minterval;
+class r_Base_Type;
+class r_Primitive_Type;
+#include "raslib/odmgtypes.hh"
+#include "raslib/mddtypes.hh"
+
+//@ManMemo: Module {\bf raslib}
+
+/*@Doc:
+ Class to check the endianness of the host machine and to
+ swap the endianness of types and arrays. Don't instantiate,
+ static members only.
+*/
+
+class r_Endian
+{
+ public:
+ /// endianness identifiers
+ enum r_Endianness {
+ r_Endian_Big,
+ r_Endian_Little
+ };
+
+ /// swap endianness of atomic types
+ static r_Short swap( r_Short val );
+ static r_UShort swap( r_UShort val );
+ static r_Long swap( r_Long val );
+ static r_ULong swap( r_ULong val );
+ static r_Float swap( r_Float val );
+ static r_Double swap( r_Double val );
+
+ /// query host machine's endianness
+ static r_Endianness get_endianness( void );
+
+ /// change the endianness of a linear array of size <size> and type <type>
+ static void swap_array( const r_Primitive_Type *type, r_Bytes size, const void *src, void *dest );
+
+ /// change the endianness of a linear array of size <size>, type implicit
+ static void swap_array( r_Bytes size, const r_Octet *src, r_Octet *dest ); // dummy
+ static void swap_array( r_Bytes size, const r_Char *src, r_Char *dest ); // dummy
+ static void swap_array( r_Bytes size, const r_Short *src, r_Short *dest );
+ static void swap_array( r_Bytes size, const r_UShort *src, r_UShort *dest );
+ static void swap_array( r_Bytes size, const r_Long *src, r_Long *dest );
+ static void swap_array( r_Bytes size, const r_ULong *src, r_ULong *dest );
+ static void swap_array( r_Bytes size, const r_Float *src, r_Float *dest );
+ static void swap_array( r_Bytes size, const r_Double *src, r_Double *dest );
+
+ /// change the endianness of a linear array of size <size> with type size <tsize>
+ static void swap_array( r_Bytes size, r_Bytes tsize, const void *src, void *dest);
+
+ /// change the endianness of one type member of an array for identical domains
+ /// for src and dest; step is the increment between cells
+ static void swap_array( const r_Primitive_Type *type, const r_Minterval &srcDom,
+ const r_Minterval &srcIterDom, const void *src, void *dest,
+ r_ULong step );
+
+ /// change the endianness of the entire tile for identical domains for src and dest
+ static void swap_array( const r_Base_Type *type, const r_Minterval &srcDom,
+ const r_Minterval &srcIterDom, const void *src, void *dest );
+
+ /// change the endianness of one type member of an array for the generic case;
+ /// step is the increment between cells.
+ static void swap_array( const r_Primitive_Type *type, const r_Minterval &srcDom,
+ const r_Minterval &srcIterDom, const r_Minterval &destDom,
+ const r_Minterval &destIterDom, const void *src, void *dest,
+ r_ULong step );
+
+ /// change the endianness of the entire tile for the generic case
+ static void swap_array( const r_Base_Type *type, const r_Minterval &srcDom,
+ const r_Minterval &srcIterDom, const r_Minterval &destDom,
+ const r_Minterval &destIterDom, const void *src, void *dest );
+};
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for enum of type {\tt const} \Ref{r_Minterval}.
+ */
+ extern std::ostream& operator<<( std::ostream& s, r_Endian::r_Endianness& e );
+
+
+#endif
diff --git a/raslib/error.cc b/raslib/error.cc
new file mode 100644
index 0000000..1ccc3cc
--- /dev/null
+++ b/raslib/error.cc
@@ -0,0 +1,888 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/***
+ * SOURCE: error.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Error
+ *
+ * COMMENTS:
+ * - in general, string should be used instead of dynamic char* mgmnt
+ * - r_Error specializations must not use int literals
+ * - freeTextTable() does not free strings -> mem leak
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Error: $Id: error.cc,v 1.60 2005/09/03 20:35:12 rasdev Exp $";
+
+using namespace std;
+
+using namespace std;
+
+#include "mymalloc/mymalloc.h"
+
+#include "raslib/error.hh"
+#include "raslib/rmdebug.hh"
+#include "debug.hh"
+
+
+#include <string.h>
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+
+#include <fstream>
+#include <string>
+#include <utility>
+#include <list>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+using std::endl;
+using std::ends;
+using std::ios;
+using std::ostrstream;
+
+r_Error::errorInfo* r_Error::textList = NULL;
+
+r_Error::r_Error()
+ : theKind(r_Error_General),
+ errorText(0),
+ errorNo(0)
+ {
+ resetErrorText();
+ }
+
+r_Error::r_Error(const r_Error& err)
+ : errorText(0),
+ errorNo(err.errorNo),
+ theKind(err.theKind)
+ {
+ if (err.errorText)
+ {
+ errorText = new char[ strlen(err.errorText)+1 ];
+ strcpy(errorText, err.errorText);
+ }
+ }
+
+r_Error::r_Error(kind the_kind, unsigned int newErrorNo)
+ : errorText(0),
+ theKind(the_kind),
+ errorNo(newErrorNo)
+ {
+ resetErrorText();
+ }
+
+r_Error::~r_Error() throw()
+ {
+ if (errorText)
+ delete[] errorText;
+ }
+
+
+
+const char*
+r_Error::what() const throw ()
+ {
+ return (const char*)errorText;
+ }
+
+
+
+const r_Error&
+r_Error::operator=(const r_Error& obj)
+ {
+ if (this != &obj)
+ {
+ if (errorText)
+ {
+ delete[] errorText;
+ errorText = NULL;
+ }
+
+ theKind = obj.theKind;
+ errorNo = obj.errorNo;
+
+ if (obj.errorText)
+ {
+ errorText = new char[ strlen(obj.errorText)+1 ];
+ strcpy(errorText, obj.errorText);
+ }
+ }
+
+ return *this;
+ }
+
+char*
+r_Error::serialiseError()
+ {
+ // default implementation for errors not of kind r_Error_SerialisableException
+ char* retVal = NULL;
+ char buf[80]; // should be enough for two numbers
+
+ sprintf(buf, "%d\t%d", theKind, errorNo);
+ retVal = (char*)mymalloc(strlen(buf) + 1);
+ strcpy(retVal, buf);
+ return retVal;
+ }
+
+
+r_Error*
+r_Error::getAnyError(char* serErr)
+{
+ r_Error* retVal = NULL;
+ char* currChar = NULL;
+ kind newTheKind;
+ unsigned int newErrNum = 0;
+ // first read the attributes of r_Error to find out which subclass it is
+ // (stored in errNum).
+ newTheKind = (r_Error::kind)strtol(serErr, &currChar, 10);
+ newErrNum = strtol(currChar+1, &currChar, 10);
+
+ if (newTheKind != r_Error_SerialisableException)
+ {
+ retVal = new r_Error(newTheKind, newErrNum);
+ }
+ else
+ {
+ // add new serialisable errors to this case!
+ switch (newErrNum)
+ {
+ case 206:
+ retVal = new r_Ebase_dbms(newTheKind, newErrNum, currChar+1);
+ break;
+ }
+ }
+ return retVal;
+}
+
+//
+// --- error text file table maintenance ---------------------------------
+//
+
+/*
+ * list of error codes, contining numerical error code, error flag char
+ * (warning or error), and error text.
+ * It is modelled as nested pairs to allow using standard classes.
+ * Filled from file.
+ */
+list<pair<pair<int,char>, char*> > errorTexts;
+
+/// has error text file been loaded, i.e., is table filled?
+bool errorTextsLoaded = false;
+
+void
+initTextTable()
+{
+ char errorFileName[FILENAME_MAX]; // error file path/name
+ std::ifstream errortexts;
+ string line; // current input line read from file
+ char errKind;
+ int errNo;
+ char errText[1000];
+ unsigned int numOfEntries = 0;
+ int result; // sscanf() result
+
+ // determine file name; use path if env var is set
+ strcpy( errorFileName, "" );
+ const char* rmanHome = getenv( RASDAMAN_PATH_VARNAME );
+ if (rmanHome)
+ {
+ strcat(errorFileName, rmanHome);
+ strcat(errorFileName, ERRORTEXXT_PATH );
+ strcat(errorFileName, "/" );
+ } else {
+ strcat(errorFileName, SHARE_DATA_DIR);
+ strcat(errorFileName, "/");
+ }
+ strcat(errorFileName, ERRORTEXT_FILE );
+ // RMInit::logOut << "using error text file: " << errorFileName << endl;
+
+ // errortexts.open(errorFileName, ios::nocreate | ios::in);
+ errortexts.open(errorFileName, ios::in);
+
+ // In case the file 'errtxts' can't be found
+#ifdef __VISUALC__
+ if (!errortexts.is_open())
+#else
+ if (!errortexts)
+#endif
+ {
+ r_Error::textList = NULL;
+ RMInit::logOut << "No error texts file found at: " << errorFileName << endl;
+ }
+ else // File errtxts found
+ {
+ // read entries from file
+ numOfEntries = 0; // just for displaying, currently not used otherwise
+ while ( ! errortexts.eof() )
+ {
+ getline( errortexts, line );
+ char *errText = (char*) mymalloc( line.length() + 1 );
+ if (errText == NULL)
+ {
+ RMInit::logOut << "Fatal error: cannot allocate error text table line #" << numOfEntries << endl;
+ throw r_Error( r_Error::r_Error_MemoryAllocation );
+ }
+ // general line format is (aside of comments and empty lines): ddd^f^text...
+ result = sscanf( line.c_str(), "%d^%c^%[^\n]s\n", &errNo, &errKind, errText );
+ if (result == 3) // consider only lines that match given structure
+ {
+ errorTexts.push_back( pair<pair<int,char>,char*> (pair<int,char>( errNo, errKind ), errText) );
+ numOfEntries++;
+ }
+ }
+ // RMInit::logOut << "number of error texts loaded: " << numOfEntries << endl;
+ errorTextsLoaded = true;
+ }
+ errortexts.close();
+}
+
+
+
+void
+freeTextTable()
+{
+ list<pair<pair<int,char>, char*> >::iterator iter = errorTexts.begin();
+ list<pair<pair<int,char>, char*> >::iterator end = errorTexts.end();
+
+ if (errorTextsLoaded) // have we initialized the table previously?
+ { // yes -> free each string
+#if 0 // doesn't work yet
+ while ( iter != NULL && iter != end )
+ {
+ cout << "freeing " << iter->second << endl << flush;
+ free( iter->second );
+ iter->second = NULL;
+ // delete[] iter->second;
+ }
+#endif
+ errorTexts.clear(); // now clear list itself
+ }
+}
+
+
+
+r_Error::r_Error(unsigned int errorno)
+ : errorText(NULL),
+ theKind(r_Error_General),
+ errorNo(errorno)
+{
+ resetErrorText();
+}
+
+
+
+void
+r_Error::setErrorTextOnKind()
+ {
+ char buffer[256];
+
+ switch (theKind)
+ {
+ case r_Error_General :
+ strcpy(buffer, " ODMG General");
+ break;
+
+ case r_Error_DatabaseClassMismatch :
+ strcpy(buffer, "Database Class Mismatch");
+ break;
+
+ case r_Error_DatabaseClassUndefined :
+ strcpy(buffer, "Database Class Undefined");
+ break;
+
+ case r_Error_DatabaseClosed :
+ strcpy(buffer, "Database Closed");
+ break;
+
+ case r_Error_DatabaseOpen :
+ strcpy(buffer, "Database Open");
+ break;
+
+ case r_Error_DateInvalid :
+ strcpy(buffer, "Date Invalid");
+ break;
+
+ case r_Error_IteratorExhausted :
+ strcpy(buffer, "Iterator Exhausted");
+ break;
+
+ case r_Error_NameNotUnique :
+ strcpy(buffer, "Name Not Unique");
+ break;
+
+ case r_Error_QueryParameterCountInvalid :
+ strcpy(buffer, "Query Parameter Count Invalid");
+ break;
+
+ case r_Error_QueryParameterTypeInvalid :
+ strcpy(buffer, "Query Parameter Type Invalid");
+ break;
+
+ case r_Error_RefInvalid :
+ strcpy(buffer, "Ref Invalid");
+ break;
+
+ case r_Error_RefNull :
+ strcpy(buffer, "Ref Null");
+ break;
+
+ case r_Error_TimeInvalid :
+ strcpy(buffer, "Time Invalid");
+ break;
+
+ case r_Error_TimestampInvalid :
+ strcpy(buffer, "Timestamp Invalid");
+ break;
+
+ case r_Error_TransactionOpen :
+ strcpy(buffer, "Transaction Open");
+ break;
+
+ case r_Error_TransactionNotOpen :
+ strcpy(buffer, "Transaction Not Open");
+ break;
+
+ case r_Error_TypeInvalid :
+ strcpy(buffer, "Type Invalid");
+ break;
+
+ case r_Error_DatabaseUnknown :
+ strcpy(buffer, "Database Unknown");
+ break;
+
+ case r_Error_TransferFailed :
+ strcpy(buffer, "Transfer Failed");
+ break;
+
+ case r_Error_HostInvalid :
+ strcpy(buffer, "Host Invalid");
+ break;
+
+ case r_Error_ServerInvalid :
+ strcpy(buffer, "Server Invalid");
+ break;
+
+ case r_Error_ClientUnknown :
+ strcpy(buffer, "Client Unknown");
+ break;
+
+ case r_Error_ObjectUnknown :
+ strcpy(buffer, "Object Unknown");
+ break;
+
+ case r_Error_ObjectInvalid :
+ strcpy(buffer, "Object Invalid");
+ break;
+
+ case r_Error_QueryExecutionFailed :
+ strcpy(buffer, "Query Execution Failed");
+ break;
+
+ case r_Error_BaseDBMSFailed :
+ strcpy(buffer, "Base DBMS Failed");
+ break;
+
+ case r_Error_CollectionElementTypeMismatch :
+ strcpy(buffer, "Collection Element Type Mismatch");
+ break;
+
+ case r_Error_CreatingOIdFailed :
+ strcpy(buffer, "Creation of OID failed");
+ break;
+
+ case r_Error_TransactionReadOnly :
+ strcpy(buffer, "Transaction is read only");
+ break;
+
+ case r_Error_LimitsMismatch :
+ strcpy(buffer, "Limits reported to an object mismatch");
+ break;
+
+ case r_Error_NameInvalid :
+ strcpy(buffer, "Name Invalid");
+ break;
+
+ case r_Error_FeatureNotSupported :
+ strcpy(buffer, "Feature is not supported");
+ break;
+
+ case r_Error_AccesDenied:
+ strcpy(buffer, "Access denied");
+ break;
+
+ case r_Error_MemoryAllocation:
+ strcpy(buffer, "Memory allocation failed");
+ break;
+
+ default:
+ strcpy(buffer, "not specified");
+ break;
+ }
+
+ if (errorText)
+ delete[] errorText;
+
+ char preText[] = "Exception: ";
+
+ errorText = new char[strlen(preText) + strlen(buffer) + 1];
+ strcpy(errorText, preText);
+ strcat(errorText, buffer);
+ }
+
+
+
+void
+r_Error::setErrorTextOnNumber()
+{
+ char *result = NULL; // ptr to error text constructed
+
+ // delete old error text, if any
+ if (errorText)
+ {
+ delete[] errorText;
+ errorText = 0;
+ }
+
+ // has list been built earlier?
+ if (errorTextsLoaded)
+ { // yes, we have a list -> search
+ // search through list to find entry
+ list<pair<pair<int,char>, char*> >::iterator iter = errorTexts.begin();
+ list<pair<pair<int,char>, char*> >::iterator end = errorTexts.end();
+ bool found = false;
+ while ( iter != end && ! found )
+ {
+ if (iter->first.first == errorNo)
+ found = true;
+ else
+ iter++;
+ }
+
+ if (found)
+ result = iter->second;
+ else
+ result = "(no explanation text available for this error code.)";
+ }
+ else // no, there is no spoon -err- list
+ result = "(no explanation text available - cannot find/load file with standard error messages.)";
+
+ errorText = new char[strlen(result) + 1];
+ if (errorText == NULL)
+ {
+ RMInit::logOut << "Error: cannot allocate error text." << endl;
+ throw r_Error( r_Error::r_Error_MemoryAllocation );
+ }
+ else
+ strcpy(errorText, result);
+
+ return;
+}
+
+
+
+void
+r_Error::setTextParameter(const char* parameterName, int value)
+ {
+ // convert long value to string
+ char valueString[256];
+ ostrstream valueStream(valueString, sizeof(valueString) );
+ valueStream << value << ends;
+
+ setTextParameter(parameterName, valueString);
+ }
+
+
+
+void
+r_Error::setTextParameter(const char* parameterName, const char* value)
+ {
+ if (errorText)
+ {
+ // locate the next matching parameter in the query string
+ char* paramStart = strstr(errorText, parameterName);
+
+ if (paramStart)
+ {
+ // allocate a new query string and fill it
+ char* paramEnd = NULL;
+ int paramLength = 0;
+ char* tmpText = NULL;
+ int newLength = 0;
+
+ tmpText = errorText;
+ paramLength = strlen(parameterName);
+ paramEnd = paramStart + paramLength;
+ newLength = strlen(tmpText) - paramLength + strlen(value) + 1;
+ errorText = new char[newLength];
+
+ *paramStart = '\0';
+
+ ostrstream queryStream(errorText, newLength);
+ queryStream << tmpText << value << paramEnd << ends;
+
+ delete[] tmpText;
+ }
+ }
+ }
+
+
+
+void
+r_Error::resetErrorText()
+ {
+ // If no error number is specified use the error kind for the text.
+ if (errorNo)
+ setErrorTextOnNumber();
+ else
+ setErrorTextOnKind();
+ }
+
+
+
+r_Eno_interval::r_Eno_interval()
+ : r_Error(201)
+ {
+ TALK( "r_Error::resetErrorText() - code 201" );
+ resetErrorText();
+ }
+
+
+
+r_Eindex_violation::r_Eindex_violation(r_Range dlow, r_Range dhigh, r_Range dindex)
+ : r_Error(202), low(dlow), high(dhigh), index(dindex)
+ {
+ TALK( "r_Error::r_Eindex_violation() - code 202" );
+ resetErrorText();
+ }
+
+
+
+void
+r_Eindex_violation::resetErrorText()
+ {
+ setErrorTextOnNumber();
+
+ setTextParameter("$low", low );
+ setTextParameter("$high", high );
+ setTextParameter("$index", index);
+ }
+
+
+
+r_Edim_mismatch::r_Edim_mismatch(r_Dimension pdim1, r_Dimension pdim2)
+ : r_Error(203), dim1(pdim1), dim2(pdim2)
+ {
+ TALK( "r_Error::r_Edim_mismatch() - code 203; dim1=" << pdim1 << ", dim2=" << pdim2 );
+ resetErrorText();
+ }
+
+
+
+void
+r_Edim_mismatch::resetErrorText()
+ {
+ setErrorTextOnNumber();
+
+ setTextParameter("$dim1", dim1);
+ setTextParameter("$dim2", dim2);
+ }
+
+
+
+r_Einit_overflow::r_Einit_overflow()
+ : r_Error(204)
+ {
+ TALK( "r_Error::r_Einit_overflow() - code 204" );
+ resetErrorText();
+ }
+
+
+
+r_Eno_cell::r_Eno_cell()
+ : r_Error(205)
+ {
+ TALK( "r_Error::r_Eno_cell() - code 205" );
+ resetErrorText();
+ }
+
+
+
+r_Equery_execution_failed::r_Equery_execution_failed(unsigned int errorno, unsigned int lineno, unsigned int columnno, const char* initToken)
+ : r_Error(errorno),
+ lineNo(lineno),
+ columnNo(columnno)
+ {
+ TALK( "r_Error::r_Equery_execution_failed() - errorno=" << errorno );
+
+ token = new char[strlen(initToken)+1];
+ strcpy(token, initToken);
+
+ resetErrorText();
+ }
+
+
+
+r_Equery_execution_failed::r_Equery_execution_failed(const r_Equery_execution_failed &err)
+ : r_Error(err),
+ lineNo(0),
+ columnNo(0)
+ {
+ TALK( "r_Error::r_Equery_execution_failed()" );
+
+ lineNo = err.lineNo;
+ columnNo = err.columnNo;
+
+ token = new char[strlen(err.token)+1];
+ strcpy(token, err.token);
+ }
+
+
+
+r_Equery_execution_failed::~r_Equery_execution_failed() throw()
+ {
+ if (token)
+ delete[] token;
+ }
+
+
+
+void
+r_Equery_execution_failed::resetErrorText()
+ {
+ setErrorTextOnNumber();
+
+ setTextParameter("$errorNo", errorNo);
+ setTextParameter("$lineNo", lineNo);
+ setTextParameter("$columnNo", columnNo);
+ setTextParameter("$token", token);
+ }
+
+
+
+r_Elimits_mismatch::r_Elimits_mismatch(r_Range lim1, r_Range lim2)
+ : r_Error(r_Error_LimitsMismatch), i1(lim1), i2(lim2)
+ {
+ TALK( "r_Error::r_Elimits_mismatch() - lim1=" << lim1 << ", lim2=" << lim2 );
+ resetErrorText();
+ }
+
+
+
+void
+r_Elimits_mismatch::resetErrorText()
+ {
+ setErrorTextOnNumber();
+
+ setTextParameter("$dim1", i1);
+ setTextParameter("$dim2", i2);
+ }
+
+/* ------------------------------------------------------------------
+ class r_Ebase_dbms
+ ------------------------------------------------------------------ */
+
+r_Ebase_dbms::r_Ebase_dbms(const long& newDbmsErrNum, const char* newDbmsErrTxt)
+ : r_Error(r_Error_SerialisableException, 206),
+ dbmsErrNum(newDbmsErrNum),
+ whatTxt(0)
+{
+ TALK( "r_Error::r_Ebase_dbms() code 206 - " << newDbmsErrTxt );
+ baseDBMS = strdup("Error in base DBMS, error number: ");
+ dbmsErrTxt = strdup(newDbmsErrTxt);
+ buildWhat();
+}
+
+r_Ebase_dbms::r_Ebase_dbms(const r_Ebase_dbms& obj)
+ : r_Error(obj),
+ dbmsErrNum(0),
+ whatTxt(0)
+{
+ TALK( "r_Error::r_Ebase_dbms()" );
+
+ dbmsErrNum = obj.dbmsErrNum;
+ if (obj.baseDBMS)
+ {
+ baseDBMS = (char*)mymalloc(strlen(obj.baseDBMS) + 1);
+ strcpy(baseDBMS, obj.baseDBMS);
+ }
+ else
+ {
+ baseDBMS = 0;
+ }
+ if (obj.dbmsErrTxt)
+ {
+ dbmsErrTxt = (char*)mymalloc(strlen(obj.dbmsErrTxt) + 1);
+ strcpy(dbmsErrTxt, obj.dbmsErrTxt);
+ }
+ else
+ {
+ dbmsErrTxt = 0;
+ }
+ buildWhat();
+}
+
+// r_Ebase_dbms: constructor receiving kind, errno, and descriptive string
+// NB: the string must have the format "<kind>\t<errno>\t<text>"
+// (currently the only location where this is used is getAnyError() above)
+r_Ebase_dbms::r_Ebase_dbms(kind newTheKind, unsigned long newErrNum, const char* myStr)
+ : r_Error(newTheKind, newErrNum), whatTxt(0)
+{
+ TALK( "r_Error::r_Ebase_dbms() - kind=" << newTheKind );
+
+ // as the const char* cannot be passed to strtol() - this was a bug anyway -
+ // we copy the string. Efficiency is not a concern here. -- PB 2005-jan-14
+ // const char* currChar = myStr;
+ char* tmpBuf = NULL; // temp copy of myStr
+ char* currChar = NULL; // ptr iterating over tmpBuf
+ tmpBuf = strdup( myStr );
+ currChar = tmpBuf; // initialize char ptr to begin of buffer
+
+ // read the attributes of r_Ebase_dbms from the string already partially parsed by
+ // r_Error::getAnyError(char* serErr)
+ dbmsErrNum = strtol(currChar, &currChar, 10);
+ // of course \t is part of the string, so we trick a little
+ char* tmpPtr = strchr(((char*)currChar)+1, '\t');
+ if (tmpPtr==NULL) // no trailing information found?
+ {
+ baseDBMS = strdup( "unknown" );
+ dbmsErrTxt = strdup( "unknown" );
+ }
+ else // yes -> analyse it
+ {
+ *tmpPtr = '\0'; // terminate item for strdup()
+ baseDBMS = strdup(currChar+1); // extract item (db name) from string
+ *tmpPtr = '\t'; // re-substitute EOS with tab
+ currChar = strchr(currChar+1, '\t'); // search for tab as item delimiter
+ dbmsErrTxt = strdup(currChar+1); // extract final item which is error text
+ }
+ buildWhat();
+
+ free( tmpBuf ); // allocated in strdup() -- PB 2005-jan-14
+}
+
+r_Ebase_dbms::~r_Ebase_dbms() throw()
+{
+ if (whatTxt)
+ free(whatTxt);
+ if (dbmsErrTxt)
+ free(dbmsErrTxt);
+ if (baseDBMS)
+ free(baseDBMS);
+}
+
+const r_Ebase_dbms&
+r_Ebase_dbms::operator=(const r_Ebase_dbms& obj)
+{
+ if (this != &obj)
+ {
+ dbmsErrNum = obj.dbmsErrNum;
+
+ if (obj.baseDBMS)
+ {
+ if (baseDBMS) free(baseDBMS);
+ baseDBMS = (char*)mymalloc(strlen(obj.baseDBMS) + 1);
+ strcpy(baseDBMS, obj.baseDBMS);
+ }
+ else
+ {
+ baseDBMS = 0;
+ }
+ if (obj.dbmsErrTxt)
+ {
+ if (dbmsErrTxt) free(dbmsErrTxt);
+ dbmsErrTxt = (char*)mymalloc(strlen(obj.dbmsErrTxt) + 1);
+ strcpy(dbmsErrTxt, obj.dbmsErrTxt);
+ }
+ else
+ {
+ dbmsErrTxt = 0;
+ }
+ buildWhat();
+ }
+ return *this;
+ }
+
+void
+r_Ebase_dbms::buildWhat()
+{
+ // Ok, we have to build the error message for this class. The problem is that ressource
+ // allocation is involved here!
+ if(whatTxt)
+ free(whatTxt);
+ // assumes 10 digits for errNum
+ whatTxt = (char*)mymalloc(strlen(baseDBMS) + strlen(dbmsErrTxt) + 12);
+ strcpy(whatTxt, baseDBMS);
+ sprintf(whatTxt + strlen(whatTxt), "%d\n", dbmsErrNum);
+ strcat(whatTxt, dbmsErrTxt);
+}
+
+const char*
+r_Ebase_dbms::what() const throw()
+{
+ return whatTxt;
+}
+
+char*
+r_Ebase_dbms::serialiseError()
+{
+ char* tmpRes = r_Error::serialiseError();
+ char buf[40];
+ char* retVal;
+
+ sprintf(buf, "\t%d\t", dbmsErrNum);
+ retVal = (char*)mymalloc(strlen(tmpRes) + strlen(buf) + strlen(baseDBMS) + strlen(dbmsErrTxt) + 2);
+ strcpy(retVal, tmpRes);
+ strcat(retVal, buf);
+ strcat(retVal, baseDBMS);
+ strcat(retVal, "\t");
+ strcat(retVal, dbmsErrTxt);
+
+ free(tmpRes);
+ return retVal;
+}
+
+r_Eno_permission::r_Eno_permission()
+:r_Error(r_Error_AccesDenied,NO_PERMISSION_FOR_OPERATION)
+{
+ TALK( "r_Error::r_Eno_permission()" );
+ resetErrorText();
+}
+
+
+r_Ememory_allocation::r_Ememory_allocation(): r_Error(r_Error_MemoryAllocation, 66) // 66 is: mem alloc failed
+{
+ TALK( "r_Error::r_Ememory_allocation() - code 66" );
+ resetErrorText();
+}
+
+r_Ecapability_refused::r_Ecapability_refused()
+:r_Error(r_Error_AccesDenied,CAPABILITY_REFUSED)
+{
+ TALK( "r_Error::r_Ecapability_refused()" );
+ resetErrorText();
+}
+
diff --git a/raslib/error.hh b/raslib/error.hh
new file mode 100644
index 0000000..074c37d
--- /dev/null
+++ b/raslib/error.hh
@@ -0,0 +1,583 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: error.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Error
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_ERROR_
+#define _D_ERROR_
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class implements partially the \Ref{r_Error} class of the
+ C++ binding of ODMG-93 v.1.2. It extends exception
+ handling through deriving special classes for MDD specific
+ errors.
+
+ In future, \Ref{r_Error} should be derived from the class exception
+ defined in the C++ standard.
+
+ The class allows the specification of an error number. The error number
+ is used as an index to a generic textual description of the error which
+ is read by {\tt setErrorTextOnNumber()}. Error text is loaded from a
+ text file by the friend method {\tt initTextTable()} which has to be
+ invoked at the beginning of the application. The table can be freed again
+ using {\tt freeTextTable()}.
+ The parameters in the generic text are substituted using {\tt setTextParameter()}.
+
+ If no error number is specified, the error kind is used as error text.
+
+ Attention: The content of an error object is not supposed to be changed after
+ creation because the error text is initialized only in the constructor. Therefore,
+ just read methods for error parameters are supported.
+
+ A standard error text file is read by {\tt initTextTable()}. The location and file
+ name expected is defined here. Ideally all programs using this mechanism should
+ include error.hh to use the same settings.
+*/
+
+#ifdef __VISUALC__
+#pragma warning( disable : 4290 )
+#endif
+
+#include <exception>
+
+#include "raslib/mddtypes.hh"
+
+/*
+ * error text file ------------------
+ */
+
+/// name of variable which should contain path to rasdaman home dir
+#define RASDAMAN_PATH_VARNAME "RMANHOME"
+
+/// relative path to error text file, starting from $RMANHOME
+#define ERRORTEXXT_PATH "/bin"
+
+/// error text file name
+#define ERRORTEXT_FILE "errtxts"
+
+/* end error text file ------------------ */
+
+class r_Error : public std::exception
+{
+ public:
+
+ /// error information
+ struct errorInfo {
+ int num;
+ char kind;
+ char* text;
+ };
+
+ /// error kinds
+ enum kind { r_Error_General,
+ r_Error_DatabaseClassMismatch,
+ r_Error_DatabaseClassUndefined,
+ r_Error_DatabaseClosed,
+ r_Error_DatabaseOpen,
+ r_Error_DateInvalid,
+ r_Error_IteratorExhausted,
+ r_Error_NameNotUnique,
+ r_Error_QueryParameterCountInvalid,
+ r_Error_QueryParameterTypeInvalid,
+ r_Error_RefInvalid,
+ r_Error_RefNull,
+ r_Error_TimeInvalid,
+ r_Error_TimestampInvalid,
+ r_Error_TransactionOpen,
+ r_Error_TransactionNotOpen,
+ r_Error_TypeInvalid,
+
+ r_Error_OIdInvalid,
+ r_Error_OIdNotUnique,
+
+ r_Error_DatabaseUnknown,
+ r_Error_TransferFailed,
+ r_Error_HostInvalid,
+ r_Error_ServerInvalid,
+ r_Error_RpcInterfaceIncompatible,
+ r_Error_ClientUnknown,
+ r_Error_ObjectUnknown,
+ r_Error_ObjectInvalid,
+
+ r_Error_QueryExecutionFailed,
+ r_Error_BaseDBMSFailed,
+ r_Error_CollectionElementTypeMismatch,
+ r_Error_CreatingOIdFailed,
+ r_Error_TransactionReadOnly,
+
+ r_Error_LimitsMismatch,
+ r_Error_NameInvalid,
+ r_Error_FeatureNotSupported,
+ // r_Error_SerialisableException is used for subclasses which can be serialised
+ // as strings for client / server transfer
+ r_Error_SerialisableException,
+
+ r_Error_AccesDenied,
+ r_Error_SystemOverloaded,
+
+ r_Error_MemoryAllocation
+
+ };
+
+ /// default constructor
+ r_Error();
+
+ /// copy constructor
+ r_Error( const r_Error& );
+
+ /// constructor getting the kind
+ r_Error( kind the_kind, unsigned int newErrorNo = 0 );
+
+ /// constructor getting an error number
+ r_Error( unsigned int errorno );
+
+ /// destructor
+ virtual ~r_Error() throw();
+
+ /// get an error description
+ virtual const char* what() const throw();
+
+ /// assignment operator
+ const r_Error& operator=( const r_Error& obj );
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ inline kind get_kind() const;
+ ///
+ inline unsigned int get_errorno() const;
+ ///
+ //@}
+
+ /// used to transfer exceptions of kind r_Error_SerialisableException to the client.
+ virtual char* serialiseError();
+ /*@Doc:
+ The char* returned is allocated with malloc (for potential RPC transfer) and has
+ to be freed by the caller.
+ */
+
+ /// This function parses a serialised error.
+ static r_Error* getAnyError(char* serErr);
+ /*@Doc:
+ Useful results can only be expected for errors of kind r_Error_SerialisableException.
+ */
+
+ /// read error text file into text table
+ friend void initTextTable();
+
+ /// free the text table again
+ friend void freeTextTable();
+
+ /// replace the specified parameter by the integer value
+ void setTextParameter( const char* parameterName, int value );
+
+ /// replace the specified parameter by the string value
+ void setTextParameter( const char* parameterName, const char* value );
+
+ protected:
+ /// set error text according to the actual error kind
+ void setErrorTextOnKind();
+
+ /// set error text according to the actual error number
+ void setErrorTextOnNumber();
+
+ /// reset error text
+ virtual void resetErrorText();
+ /**
+ The virtual method is redefined in each subclass which supports text parameters.
+ Usually it is invoked in the constructor of the subclass.
+ */
+
+ /// attribute storing the error description text
+ char* errorText;
+
+ /// attribute storing the error kind
+ kind theKind;
+
+ /// attribute storing the number of the error
+ unsigned int errorNo;
+
+ private:
+ static errorInfo *textList;
+};
+
+
+/* Modified by Constantin Jucovschi */
+/* Added the definition of the initTextTable() and freeTextTable()*/
+ void initTextTable();
+ void freeTextTable();
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class represents an array object saying that the
+ result is no interval.
+
+*/
+
+class r_Eno_interval : public r_Error
+{
+ public:
+ /// default constructor
+ r_Eno_interval();
+};
+
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class represents an array object saying that the
+ specified index is not within the bounds.
+
+*/
+
+class r_Eindex_violation : public r_Error
+{
+ public:
+ /// constructor getting lower and upper bound, and the index
+ r_Eindex_violation( r_Range dlow, r_Range dhigh, r_Range dindex );
+
+ protected:
+ /// reset error text
+ virtual void resetErrorText();
+
+ private:
+ /// lower bound
+ r_Range low;
+ /// upper bound
+ r_Range high;
+ /// index which caused the error
+ r_Range index;
+};
+
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class represents an array object saying that the
+ dimensionalies of two objects do not match.
+
+*/
+
+class r_Edim_mismatch : public r_Error
+{
+ public:
+ /// constructor getting two dimensionalities
+ r_Edim_mismatch( r_Dimension pdim1, r_Dimension pdim2 );
+
+ protected:
+ /// reset error text
+ virtual void resetErrorText();
+
+ private:
+ /// first dimensionality
+ r_Dimension dim1;
+ /// second dimensionality
+ r_Dimension dim2;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class represents an error object saying that an
+ initialization overflow occured. This happens f.e. if the
+ stream input operator is invoked more often than the
+ object has dimensions.
+
+*/
+
+class r_Einit_overflow : public r_Error
+{
+ public:
+ /// default constructor
+ r_Einit_overflow();
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class represents an error object saying that the
+ result is no cell. This happens f.e. if the cast operator
+ for casting to the base type of class \Ref{r_Marray} is invoked
+ on an object which is not 'zero-dimensional'.
+
+*/
+
+class r_Eno_cell : public r_Error
+{
+ public:
+ /// default constructor
+ r_Eno_cell();
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ The class is used for errors occuring through query execution. In most cases, the position which
+ caused the error can be fixed. This position is specified by line number, column number, and
+ the token which is involved.
+ Additionally, the class is generic concerning the error type. Different error types can be specified
+ by stating the error number.
+
+*/
+
+class r_Equery_execution_failed : public r_Error
+{
+ public:
+ /// default constructor
+ r_Equery_execution_failed( unsigned int errorno, unsigned int lineno, unsigned int columnno, const char* token );
+
+ /// copy constructor
+ r_Equery_execution_failed( const r_Equery_execution_failed &err );
+
+ /// destructor
+ ~r_Equery_execution_failed() throw();
+
+ //@Man: Read methods:
+ //@{
+ ///
+ inline unsigned int get_lineno() const;
+ ///
+ inline unsigned int get_columnno() const;
+ ///
+ inline const char* get_token() const;
+ ///
+ //@}
+
+ protected:
+ /// reset error text
+ virtual void resetErrorText();
+
+ private:
+ /// line number in which the error is caused
+ unsigned int lineNo;
+
+ /// column number which caused the error or is near to the error position
+ unsigned int columnNo;
+
+ /// token which caused the error or is near to the error position
+ char* token;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ This class represents an error when the limits reported on the same
+ object (array) by two sources do not match (at least in one end).
+*/
+
+class r_Elimits_mismatch : public r_Error
+{
+ public:
+ /// constructor getting two limits on the same interval
+ r_Elimits_mismatch( r_Range lim1, r_Range lim2 );
+
+ protected:
+ /// reset error text
+ virtual void resetErrorText();
+
+ private:
+ /// first interval
+ r_Range i1;
+ /// second interval
+ r_Range i2;
+};
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents an error in the base DBMS. It stores the error
+ number in the base DBMS and the error text of the base DBMS. The
+ interpretation of the error is specific for the base DBMS. The
+ errtxt mechanism of RasDaMan is not used, instead what() returns the
+ error of the base DBMS. Note that the const char* parameters of the
+ constructor are not copied, but the pointers are stored. They are
+ never freed (to enable use of constants).
+*/
+
+class r_Ebase_dbms : public r_Error
+{
+public:
+ /// constructor.
+ r_Ebase_dbms( const long& newErrNum, const char* newErrTxt );
+
+ /// copy constructor
+ r_Ebase_dbms( const r_Ebase_dbms& oldErr );
+
+ /// constructor reading from a char* containing serialised representation.
+ r_Ebase_dbms( kind newTheKind, unsigned long newErrNum, const char* myStr );
+
+ /// destructor
+ ~r_Ebase_dbms() throw();
+
+ /// assignment operator
+ const r_Ebase_dbms& operator=( const r_Ebase_dbms& obj );
+
+ // overloads from r_Error
+ virtual const char* what() const throw();
+ virtual char* serialiseError();
+
+private:
+
+ /// build what text
+ void buildWhat();
+ /// the name of the base DBMS.
+ char* baseDBMS;
+ /// error number of the base DBMS.
+ long dbmsErrNum;
+ /// error text of the base DBMS.
+ char* dbmsErrTxt;
+ /// used as return value for what()
+ char* whatTxt;
+};
+
+class r_Eno_permission : public r_Error
+ {
+ public:
+ r_Eno_permission();
+
+ };
+
+class r_Ecapability_refused : public r_Error
+ {
+ public:
+ r_Ecapability_refused();
+
+ };
+
+class r_Ememory_allocation: public r_Error {
+public:
+ r_Ememory_allocation();
+};
+
+#define MEMMORYALLOCATIONERROR 66
+#define INTERNALDLPARSEERROR 100
+#define NOPOINT 200
+#define RASTYPEUNKNOWN 209
+#define BASETYPENOTSUPPORTED 210
+#define RPCCOMMUNICATIONFAILURE 212
+#define SYSTEM_COLLECTION_NOT_WRITABLE 216
+#define SYSTEM_COLLECTION_HAS_NO_OID 217
+#define CONVERSIONFORMATNOTSUPPORTED 218
+#define TILESIZETOOSMALL 219
+#define STORAGERLAYOUTINCOMPATIBLEWITHGMARRAY 220
+#define DOMAINUNINITIALISED 221
+#define NOTANMARRAYTYPE 222
+#define RCINDEXWITHINCOMPATIBLEMARRAYTYPE 223
+#define TILECONFIGMARRAYINCOMPATIBLE 224
+#define RCINDEXWITHOUTREGULARTILING 225
+#define UDFBODYTOOLARGE 226
+#define POLYGONWRONGPOINTDIMENSION 227
+#define POLYGONWRONGINITSTRING 228
+#define QUERYPARAMETERINVALID 229
+#define ILLEGALARGUMENT 230
+#define MARRAYHASNOBASETYPE 231
+#define INTERVALOPEN 232
+#define INTERVALSWITHDIFFERENTDIMENSION 233
+#define TILINGPARAMETERNOTCORRECT 234
+#define CONNECTIONCLOSED 235
+#define COMPRESSIONFAILED 236
+#define CLIENTCOMMUICATIONFAILURE 237
+#define BASETYPENOTSUPPORTEDBYOPERATION 238
+#define OVERLAYPATTERNTOOSMALL 239
+#define INSERTINTORCINDEX 240
+#define NOTILINGDEFINED 241
+#define UNSATIFIEDMDDCONSTANT 373
+#define DATABASE_EXISTS 708
+#define NO_PERMISSION_FOR_OPERATION 803
+#define CAPABILITY_REFUSED 804
+#define DATABASE_INCONSISTENT 1000
+#define DATABASE_INCOMPATIBLE 1001
+#define ZERO_LENGTH_BLOB 1002
+#define TILE_CONTAINER_NOT_FOUND 1003
+#define INDEX_OF_MDD_IS_NULL 1004
+#define STORAGE_OF_MDD_IS_NULL 1005
+#define UNKNOWN_INDEX_TYPE 1006
+#define ILLEGAL_INDEX_TYPE 1007
+#define COLLTYPE_NULL 1008
+#define MDD_NOT_VALID 1009
+#define MDDTYPE_NULL 1010
+#define ILLEGALSTATEREACHED 1011
+#define COLLECTIONTYPEISNULL 1012
+#define TYPENAMEISTOOLONG 1013
+#define INVALIDOBJECTNAME 1014
+#define DATABASE_OPEN 2000
+#define INVALID_OIDTYPE 2001
+#define STRUCTTYPE_ELEMENT_UNKNOWN 2002
+#define STRUCTTYPE_ELEMENT_OUT_OF_BOUNDS 2003
+#define TRANSIENT_INDEX_USED_AS_PERSISTENT 2004
+#define TILE_MULTIPLE_TIMES_RETRIEVED 2005
+#define TILE_NOT_INSERTED_INTO_INDEX 2006
+#define TRANSIENT_INDEX_OUT_OF_BOUNDS 2007
+#define MDD_EXISTS_MULTIPLE_TIMES 2008
+#define DATA_NOT_INSERTED_COMPLETELY 2009
+#define CONVERSION_RETURNED_WRONG_TYPE 2010
+#define COLLECTIONTYPEHASNOELEMENTTYPE 2011
+#define MARRAYTYPEHASNOELEMENTTYPE 2012
+#define PROPERTYTYPEHASNOELEMENTTYPE 2013
+#define SCALARWASPASSEDNULLTYPE 2014
+#define INDEXNOTFOUNDINPARENT 2015
+#define INDEXEXHAUSTEDAREA 2016
+#define LAYOUTALGORITHMPROBLEM 2017
+#define OBJECTDOESNOTSUPPORTSWAPING 2018
+#define ERRORDURINGSWAPING 2019
+#define BINARYEXPORTNOTSUPPORTEDFOROBJECT 2020
+#define BINARYIMPORTNOTSUPPORTEDFOROBJECT 2021
+#define OPERANDSRESULTTYPESNOMATCH 2022
+#define TRYINGTOINFERHOOKFROMNULLNODE 2023
+#define QTNODETYPEPARENTDOESNOTEXIST 2024
+
+#include "raslib/error.icc"
+
+#endif
diff --git a/raslib/error.icc b/raslib/error.icc
new file mode 100644
index 0000000..20aaa4f
--- /dev/null
+++ b/raslib/error.icc
@@ -0,0 +1,74 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INLINE SOURCE: error.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_Error
+ *
+ * COMMENTS:
+ *
+*/
+
+
+inline r_Error::kind
+r_Error::get_kind() const
+{
+ return theKind;
+}
+
+
+
+inline unsigned int
+r_Error::get_errorno() const
+{
+ return errorNo;
+}
+
+
+
+inline unsigned int
+r_Equery_execution_failed::get_lineno() const
+{
+ return lineNo;
+}
+
+
+
+inline unsigned int
+r_Equery_execution_failed::get_columnno() const
+{
+ return columnNo;
+}
+
+
+
+inline const char*
+r_Equery_execution_failed::get_token() const
+{
+ return token;
+}
+
+
+
+
diff --git a/raslib/flatbasetype.cc b/raslib/flatbasetype.cc
new file mode 100644
index 0000000..13adbd3
--- /dev/null
+++ b/raslib/flatbasetype.cc
@@ -0,0 +1,301 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: flatbasetype.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Flat_Base_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#include <iostream>
+#include <stdio.h>
+
+#include "raslib/primitivetype.hh"
+#include "raslib/structuretype.hh"
+#include "raslib/flatbasetype.hh"
+#include "raslib/error.hh"
+#include "raslib/rminit.hh"
+
+
+r_Flat_Base_Type::r_Flat_Base_Type( void )
+{
+ init_shared();
+}
+
+
+r_Flat_Base_Type::r_Flat_Base_Type( const r_Base_Type *type )
+{
+ init_shared();
+ process_type(type);
+}
+
+
+r_Flat_Base_Type::r_Flat_Base_Type( const r_Flat_Base_Type &src )
+{
+ init_shared();
+ copy_flat_type(src);
+}
+
+
+r_Flat_Base_Type::~r_Flat_Base_Type( void )
+{
+ free_type_data();
+}
+
+
+unsigned int r_Flat_Base_Type::get_num_types( void ) const
+{
+ return numPrimTypes;
+}
+
+
+const r_Primitive_Type *r_Flat_Base_Type::type( unsigned int num ) const throw (r_Eindex_violation)
+{
+ if (num < numPrimTypes)
+ {
+ return primTypes[num];
+ }
+ else {
+ RMInit::logOut << "r_Flat_Base_Type::type(" << num << ") index out of bounds (" << numPrimTypes - 1 << ")" << endl;
+ throw r_Eindex_violation(0, numPrimTypes - 1, num);
+ }
+}
+
+
+const r_Primitive_Type *r_Flat_Base_Type::operator[]( unsigned int num ) const throw (r_Eindex_violation)
+{
+ if (num < numPrimTypes)
+ {
+ return primTypes[num];
+ }
+ else {
+ RMInit::logOut << "r_Flat_Base_Type::operator[](" << num << ") index out of bounds (" << numPrimTypes - 1 << ")" << endl;
+ throw r_Eindex_violation(0, numPrimTypes - 1, num);
+ }
+}
+
+
+unsigned int r_Flat_Base_Type::offset( unsigned int num ) const throw (r_Eindex_violation)
+{
+ if (num < numPrimTypes)
+ {
+ return offsets[num];
+ }
+ else {
+ RMInit::logOut << "r_Flat_Base_Type::offset(" << num << ") index out of bounds (" << numPrimTypes - 1 << ")" << endl;
+ throw r_Eindex_violation(0, numPrimTypes - 1, num);
+ }
+}
+
+
+r_Bytes r_Flat_Base_Type::size( void ) const
+{
+ return typeSize;
+}
+
+
+r_Flat_Base_Type &r_Flat_Base_Type::operator=( const r_Flat_Base_Type &src )
+{
+ free_type_data();
+ copy_flat_type(src);
+ return (*this);
+}
+
+
+r_Flat_Base_Type &r_Flat_Base_Type::operator=( const r_Base_Type *type )
+{
+ free_type_data();
+ process_type(type);
+ return (*this);
+}
+
+
+bool r_Flat_Base_Type::operator==( const r_Flat_Base_Type &src ) const
+{
+ if (numPrimTypes == src.numPrimTypes)
+ {
+ unsigned int i;
+ for (i=0; i<numPrimTypes; i++)
+ {
+ if (primTypes[i]->type_id() != src.primTypes[i]->type_id())
+ break;
+ }
+ if (i >= numPrimTypes)
+ return true;
+ }
+ return false;
+}
+
+
+void r_Flat_Base_Type::init_shared( void )
+{
+ typeSize = 0;
+ numPrimTypes = 0;
+ primTypes = NULL;
+ offsets = NULL;
+}
+
+
+void r_Flat_Base_Type::free_type_data( void )
+{
+ if (primTypes != NULL)
+ {
+ for (unsigned int i=0; i<numPrimTypes; i++)
+ delete primTypes[i];
+ delete [] primTypes;
+ primTypes = NULL;
+ }
+
+ if (offsets != NULL)
+ {
+ delete [] offsets;
+ offsets = NULL;
+ }
+ numPrimTypes = 0;
+}
+
+
+void r_Flat_Base_Type::process_type( const r_Base_Type *type )
+{
+ typeSize = type->size();
+
+ if (type->isStructType())
+ {
+ const r_Structure_Type *stype = (const r_Structure_Type*)type;
+ numPrimTypes = parse_structure_type(stype, 0, 0);
+ primTypes = new r_Primitive_Type*[numPrimTypes];
+ offsets = new unsigned int[numPrimTypes];
+ parse_structure_type(stype, 0, 0);
+ }
+ else
+ {
+ numPrimTypes = 1;
+ primTypes = new r_Primitive_Type*[1];
+ offsets = new unsigned int[1];
+ parse_primitive_type((r_Primitive_Type*)(type->clone()), 0, 0);
+ }
+}
+
+
+void r_Flat_Base_Type::copy_flat_type( const r_Flat_Base_Type &src )
+{
+ typeSize = src.typeSize;
+
+ if (src.numPrimTypes == 0)
+ {
+ numPrimTypes = 0;
+ primTypes = NULL;
+ offsets = NULL;
+ }
+ else
+ {
+ numPrimTypes = src.numPrimTypes;
+ primTypes = new r_Primitive_Type*[numPrimTypes];
+ offsets = new unsigned int[numPrimTypes];
+ for (unsigned int i=0; i<numPrimTypes; i++)
+ {
+ primTypes[i] = (r_Primitive_Type*)(src.primTypes[i]->clone());
+ offsets[i] = src.offsets[i];
+ }
+ }
+}
+
+
+void r_Flat_Base_Type::parse_primitive_type( r_Primitive_Type *type, unsigned int num, unsigned int off )
+{
+ if (primTypes == NULL)
+ {
+ delete type;
+ }
+ else
+ {
+ primTypes[num] = type;
+ offsets[num] = off;
+ //cout << "TYPE "; type->print_status(); cout << ", NUM " << num << ", OFF " << off << endl;
+ }
+}
+
+
+unsigned int r_Flat_Base_Type::parse_structure_type( const r_Structure_Type *type, unsigned int num, unsigned int off )
+{
+ r_Structure_Type::attribute_iterator iter(type->defines_attribute_begin());
+ unsigned int numPrim = 0;
+
+ while (iter != type->defines_attribute_end())
+ {
+ r_Type *newType = (*iter).type_of().clone();
+ if (newType->isStructType())
+ {
+ numPrim += parse_structure_type((const r_Structure_Type*)newType, num + numPrim, off + (*iter).offset());
+ delete newType;
+ }
+ else
+ {
+ parse_primitive_type((r_Primitive_Type*)newType, num + numPrim, off + (*iter).offset());
+ numPrim++;
+ }
+ iter++;
+ }
+
+ return numPrim;
+}
+
+
+void r_Flat_Base_Type::print_status( std::ostream &str ) const
+{
+ if (numPrimTypes == 0)
+ {
+ str << "<nn>";
+ }
+ else
+ {
+ str << typeSize << ':';
+ if (numPrimTypes == 1)
+ {
+ primTypes[0]->print_status(str);
+ }
+ else
+ {
+ unsigned int i;
+ str << '{'; primTypes[0]->print_status(str); str << '(' << offsets[0] << ')';
+ for (i=1; i<numPrimTypes; i++)
+ {
+ str << ", ";
+ primTypes[i]->print_status(str);
+ str << '(' << offsets[i] << ')';
+ }
+ str << '}';
+ }
+ }
+}
+
+
+
+std::ostream &operator<<( std::ostream &str, const r_Flat_Base_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/flatbasetype.hh b/raslib/flatbasetype.hh
new file mode 100644
index 0000000..c92b4b1
--- /dev/null
+++ b/raslib/flatbasetype.hh
@@ -0,0 +1,123 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: flatbasetype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Flat_Base_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _FLAT_BASE_TYPE_HH_
+#define _FLAT_BASE_TYPE_HH_
+
+#include <iostream>
+
+#include "raslib/error.hh"
+
+class r_Base_Type;
+class r_Primitive_Type;
+class r_Structure_Type;
+
+//@ManMemo: Module {\bf raslib}
+
+
+/*@Doc:
+ This class can be used to get a more convenient view on a structured
+ base type. It eliminates all hierarchies and gives you the primitive
+ types only which can be iterated over with a normal linear loop. Used
+ in e.g. the compression module. Note that this is not a regular member
+ of the r_Type hierarchy!
+*/
+
+class r_Flat_Base_Type
+{
+ public:
+ /// default constructor, shouldn't be used
+ r_Flat_Base_Type( void );
+ /// constructor receiving the (hierarchical) base type
+ r_Flat_Base_Type( const r_Base_Type *type );
+ /// copy constructor
+ r_Flat_Base_Type( const r_Flat_Base_Type &src );
+ /// destructor
+ ~r_Flat_Base_Type( void );
+
+ /// return number of primitive types
+ unsigned int get_num_types( void ) const;
+ /// return pointer to primitive type num
+ /// index violation is thrown if higher index is requested than available
+ const r_Primitive_Type *type( unsigned int num ) const throw (r_Eindex_violation);
+ /// operator returns pointer to primitive type num or NULL if invalid
+ /// index violation is thrown if higher index is requested than available
+ const r_Primitive_Type *operator[]( unsigned int num ) const throw (r_Eindex_violation);
+ /// return offset of primitive type num
+ /// index violation is thrown if higher index is requested than available
+ unsigned int offset( unsigned int num ) const throw (r_Eindex_violation);
+ /// return size of entire type
+ r_Bytes size( void ) const;
+ /// assignment of another flat type
+ r_Flat_Base_Type &operator=( const r_Flat_Base_Type &src );
+ /// assignment of a base type
+ r_Flat_Base_Type &operator=( const r_Base_Type *type );
+ /// equality
+ bool operator==( const r_Flat_Base_Type &src ) const;
+ /// print status to a stream
+ void print_status( std::ostream &str ) const;
+
+
+ protected:
+ /// shared init code
+ void init_shared( void );
+ /// process a base type
+ void process_type( const r_Base_Type *type );
+ /// copy another flat type
+ void copy_flat_type( const r_Flat_Base_Type &type );
+ /// free type-specific data (destructor, assignment)
+ void free_type_data( void );
+
+ /// parse a structure type and return number of primitive types contained therein
+ unsigned int parse_structure_type( const r_Structure_Type *type, unsigned int number,
+ unsigned int offset );
+ /// parse a primitive type
+ void parse_primitive_type( r_Primitive_Type *type, unsigned int number,
+ unsigned int offset );
+
+ /// the number of primitive types
+ unsigned int numPrimTypes;
+ /// the total size of the entire type
+ r_Bytes typeSize;
+ /// the primitive types
+ r_Primitive_Type **primTypes;
+ /// the corresponding offsets
+ unsigned int *offsets;
+};
+
+
+//@ManMemo: Module {\bf raslib}
+
+//@Doc: write the status of a flat base type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Flat_Base_Type &type );
+
+#endif
diff --git a/raslib/itertype.cc b/raslib/itertype.cc
new file mode 100644
index 0000000..c277c24
--- /dev/null
+++ b/raslib/itertype.cc
@@ -0,0 +1,97 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+#include "raslib/itertype.hh"
+#include <stdlib.h>
+
+template<class T>
+r_IterType<T>::r_IterType() : lastElem(NULL), myElems(NULL), currPos(0)
+{
+}
+
+template<class T>
+r_IterType<T>::r_IterType(T* newLastElem, T* newElems)
+ : lastElem(newLastElem), myElems(newElems), currPos(newElems)
+{
+}
+
+template<class T>
+r_IterType<T>::r_IterType(T* newLastElem, T* newElems, T* newCurrPos)
+ : lastElem(newLastElem), myElems(newElems), currPos(newCurrPos)
+{
+}
+
+template<class T>
+r_IterType<T>::r_IterType( const r_IterType<T>& iter )
+ : lastElem(iter.lastElem), myElems(iter.myElems), currPos(iter.currPos)
+{
+}
+
+template<class T>
+r_IterType<T>::~r_IterType()
+{
+ // nothing to do, memory management is done by r_Attribute.
+}
+
+template<class T> r_IterType<T>&
+r_IterType<T>::operator=( const r_IterType<T>& iter )
+{
+ lastElem = iter.lastElem;
+ myElems = iter.myElems;
+ currPos = iter.currPos;
+ return *this;
+}
+
+template<class T> bool
+r_IterType<T>::operator==( const r_IterType<T>& otherIter )
+{
+ return currPos == otherIter.currPos;
+}
+
+template<class T> bool
+r_IterType<T>::operator!=( const r_IterType<T>& otherIter )
+{
+ return currPos != otherIter.currPos;
+}
+
+template<class T> r_IterType<T>&
+r_IterType<T>::operator++()
+{
+ currPos++;
+ return *this;
+}
+
+template<class T> r_IterType<T>
+r_IterType<T>::operator++( int )
+{
+ r_IterType<T> result( *this );
+ operator++();
+ return result;
+}
+
+template<class T> T
+r_IterType<T>::operator*()
+{
+ return *currPos;
+}
+
diff --git a/raslib/itertype.hh b/raslib/itertype.hh
new file mode 100644
index 0000000..daabc0f
--- /dev/null
+++ b/raslib/itertype.hh
@@ -0,0 +1,86 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: itertype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_IterType
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_ITER_TYPE_
+#define _D_ITER_TYPE_
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class realizes the iterator used to access
+ single elements of \Ref{r_Structure_Type}.
+*/
+
+template <class T>
+class r_IterType
+{
+public:
+ /// default constructor
+ r_IterType();
+ /// constructor used in r_Structure_Type
+ r_IterType( T* newLastElem, T* newElems );
+ /// constructor used in r_Structure_Type
+ r_IterType( T* newLastElem, T* newElems, T* newCurrPos );
+ /// copy constructor
+ r_IterType( const r_IterType<T>& iter );
+ /// destructor
+ ~r_IterType();
+ /// assignment operator
+ r_IterType<T>& operator=( const r_IterType<T>& iter );
+ /// equal comparison: equal if they point to the same element.
+ bool operator==( const r_IterType<T>& otherIter );
+ /// no equal comparison: not equal if they point to different elements
+ bool operator!=( const r_IterType<T>& otherIter );
+ /// prefix incrementor
+ r_IterType<T>& operator++();
+ /// postfix incrementor
+ r_IterType<T> operator++( int );
+ /// the dereference operator gets the actual element
+ T operator*();
+
+protected:
+ T* lastElem;
+ T* myElems;
+ T* currPos;
+};
+
+#ifdef EARLY_TEMPLATE
+#ifdef __EXECUTABLE__
+#ifdef __VISUALC__
+#include "itertype.cpp"
+#else
+#include "itertype.cc"
+#endif
+#endif
+#endif
+
+#endif
diff --git a/raslib/marraytype.cc b/raslib/marraytype.cc
new file mode 100644
index 0000000..ace70aa
--- /dev/null
+++ b/raslib/marraytype.cc
@@ -0,0 +1,131 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Marray_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/marraytype.cc,v 1.7 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/marraytype.hh"
+#include "raslib/basetype.hh"
+#include "raslib/error.hh"
+#include "raslib/rminit.hh"
+
+r_Marray_Type::r_Marray_Type()
+ : r_Type(),
+ baseType(NULL)
+ {
+ }
+
+r_Marray_Type::r_Marray_Type(const r_Base_Type& newBaseType)
+ : r_Type(),
+ baseType((r_Base_Type*)newBaseType.clone())
+ {
+ }
+
+r_Marray_Type::r_Marray_Type(const r_Marray_Type& oldObj) throw (r_Error)
+ : r_Type(oldObj)
+ {
+ if (oldObj.baseType)
+ baseType = (r_Base_Type*)oldObj.baseType->clone();
+ else {
+ RMInit::logOut << "r_Marray_Type::r_Marray_Type( oldObj ) the element type is NULL." << endl;
+ throw r_Error(MARRAYTYPEHASNOELEMENTTYPE);
+ }
+ }
+
+const r_Marray_Type&
+r_Marray_Type::operator=(const r_Marray_Type& oldObj) throw (r_Error)
+ {
+ // Gracefully handle self assignment
+ if (this == &oldObj)
+ return *this;
+
+ r_Type::operator=(oldObj);
+ if (baseType)
+ {
+ delete baseType;
+ baseType = 0;
+ }
+
+ if (oldObj.baseType)
+ baseType = (r_Base_Type*)oldObj.baseType->clone();
+ else {
+ RMInit::logOut << "r_Marray_Type::operator=( oldObj ) the element type is NULL." << endl;
+ throw r_Error(MARRAYTYPEHASNOELEMENTTYPE);
+ }
+
+ return *this;
+ }
+
+bool
+r_Marray_Type::isMarrayType() const
+ {
+ return true;
+ }
+
+const r_Base_Type&
+r_Marray_Type::base_type() const
+ {
+ return *baseType;
+ }
+
+r_Type*
+r_Marray_Type::clone() const
+ {
+ return new r_Marray_Type(*this);
+ }
+
+r_Type::r_Type_Id
+r_Marray_Type::type_id() const
+ {
+ return MARRAYTYPE;
+ }
+
+void
+r_Marray_Type::convertToLittleEndian(char* cells, r_Area noCells) const
+ {
+ }
+
+void
+r_Marray_Type::convertToBigEndian(char* cells, r_Area noCells) const
+ {
+ }
+
+void
+r_Marray_Type::print_status(std::ostream& s) const
+ {
+ s << "marray< ";
+ baseType->print_status(s);
+ s << " >";
+ }
+
+r_Marray_Type::~r_Marray_Type()
+ {
+ if (baseType)
+ delete baseType;
+ }
+
+std::ostream &operator<<( std::ostream &str, const r_Marray_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
+ \ No newline at end of file
diff --git a/raslib/marraytype.hh b/raslib/marraytype.hh
new file mode 100644
index 0000000..9876acf
--- /dev/null
+++ b/raslib/marraytype.hh
@@ -0,0 +1,101 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: marraytype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Marray_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_MARRAY_TYPE_
+#define _D_MARRAY_TYPE_
+
+#include "raslib/type.hh"
+
+class r_Base_Type;
+class r_Error;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents the marray type in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+
+class r_Marray_Type : public r_Type
+ {
+ public:
+ /// constructor getting basetype
+ r_Marray_Type(const r_Base_Type&);
+
+ /// copy constructor
+ /// if base type is NULL an exception will be raised.
+ /// this is possible
+ r_Marray_Type(const r_Marray_Type&) throw (r_Error);
+
+ /// assignment operator
+ /// if base type is NULL an exception will be raised.
+ /// this is possible
+ const r_Marray_Type& operator=(const r_Marray_Type&) throw (r_Error);
+
+ bool isMarrayType() const;
+
+ /// get base type
+ const r_Base_Type& base_type() const;
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status(std::ostream& s = std::cout) const;
+
+ /// destructor
+ ~r_Marray_Type();
+
+ protected:
+ /// default constructor
+ /// should be used by noone
+ r_Marray_Type();
+
+ /// base type
+ r_Base_Type* baseType;
+ };
+
+//@Doc: write the status of a marray type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Marray_Type &type );
+
+#endif
+
diff --git a/raslib/mddtypes.cc b/raslib/mddtypes.cc
new file mode 100644
index 0000000..4d7ec39
--- /dev/null
+++ b/raslib/mddtypes.cc
@@ -0,0 +1,416 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: mddtypes.cc
+ *
+ * MODULE: raslib
+ * CLASS:
+ *
+ * COMMENTS:
+ *
+*/
+
+
+static const char rcsid[] = "@(#)raslib, mddtypes: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/mddtypes.cc,v 1.26 2005/09/03 20:33:10 rasdev Exp $";
+
+
+
+#ifdef AIX
+ #include <strings.h>
+#else
+ #include <string.h>
+#endif
+
+#include "raslib/mddtypes.hh"
+#include "raslib/rminit.hh"
+
+
+/*
+ * The names of all data formats
+ */
+const char *format_name_array = "Array";
+const char *format_name_tiff = "TIFF";
+const char *format_name_jpeg = "JPEG";
+const char *format_name_hdf = "HDF";
+const char *format_name_cvs = "CVS";
+const char *format_name_png = "PNG";
+const char *format_name_zlib = "ZLib";
+const char *format_name_auto_compression = "AutoCompression";
+const char *format_name_bmp = "BMP";
+const char *format_name_ppm = "PPM";
+const char *format_name_rle = "RLE";
+const char *format_name_wavelet_haar = "HaarWavelet";
+const char *format_name_wavelet_daubechies = "DaubechiesWavelet";
+const char *format_name_sep_zlib = "SepZLib";
+const char *format_name_sep_rle = "SepRLE";
+const char *format_name_wavelet_daub6 = "Daubechies6Wavelet";
+const char *format_name_wavelet_daub8 = "Daubechies8Wavelet";
+const char *format_name_wavelet_daub10 = "Daubechies10Wavelet";
+const char *format_name_wavelet_daub12 = "Daubechies12Wavelet";
+const char *format_name_wavelet_daub14 = "Daubechies14Wavelet";
+const char *format_name_wavelet_daub16 = "Daubechies16Wavelet";
+const char *format_name_wavelet_daub18 = "Daubechies18Wavelet";
+const char *format_name_wavelet_daub20 = "Daubechies20Wavelet";
+const char *format_name_wavelet_least8 = "LeastAsym8Wavelet";
+const char *format_name_wavelet_least10 = "LeastAsym10Wavelet";
+const char *format_name_wavelet_least12 = "LeastAsym12Wavelet";
+const char *format_name_wavelet_least14 = "LeastAsym14Wavelet";
+const char *format_name_wavelet_least16 = "LeastAsym16Wavelet";
+const char *format_name_wavelet_least18 = "LeastAsym18Wavelet";
+const char *format_name_wavelet_least20 = "LeastAsym20Wavelet";
+const char *format_name_wavelet_coiflet6 = "Coiflet6Wavelet";
+const char *format_name_wavelet_coiflet12 = "Coiflet12Wavelet";
+const char *format_name_wavelet_coiflet18 = "Coiflet18Wavelet";
+const char *format_name_wavelet_coiflet24 = "Coiflet24Wavelet";
+const char *format_name_wavelet_coiflet30 = "Coiflet30Wavelet";
+const char *format_name_vff = "VFF";
+const char *format_name_wavelet_qhaar = "QHaarWavelet";
+const char *format_name_tor = "TOR";
+const char *format_name_dem = "DEM";
+const char *format_name_pack_bits = "PACKBITS";
+const char *format_name_ecw = "ECW";
+const char *format_name_tmc = "TMC";
+const char *format_name_ntf = "NTF";
+
+const char *all_data_format_names[r_Data_Format_NUMBER] = {
+ format_name_array,
+ format_name_tiff,
+ format_name_jpeg,
+ format_name_cvs,
+ format_name_hdf,
+ format_name_png,
+ format_name_zlib,
+ format_name_auto_compression,
+ format_name_bmp,
+ format_name_rle,
+ format_name_wavelet_haar,
+ format_name_wavelet_daubechies,
+ format_name_sep_zlib,
+ format_name_sep_rle,
+ format_name_wavelet_daub6,
+ format_name_wavelet_daub8,
+ format_name_wavelet_daub10,
+ format_name_wavelet_daub12,
+ format_name_wavelet_daub14,
+ format_name_wavelet_daub16,
+ format_name_wavelet_daub18,
+ format_name_wavelet_daub20,
+ format_name_wavelet_least8,
+ format_name_wavelet_least10,
+ format_name_wavelet_least12,
+ format_name_wavelet_least14,
+ format_name_wavelet_least16,
+ format_name_wavelet_least18,
+ format_name_wavelet_least20,
+ format_name_wavelet_coiflet6,
+ format_name_wavelet_coiflet12,
+ format_name_wavelet_coiflet18,
+ format_name_wavelet_coiflet24,
+ format_name_wavelet_coiflet30,
+ format_name_vff,
+ format_name_wavelet_qhaar,
+ format_name_ppm,
+ format_name_tor,
+ format_name_dem,
+ format_name_pack_bits,
+ format_name_ecw,
+ format_name_tmc,
+ format_name_ntf
+};
+
+
+const char *get_name_from_data_format( r_Data_Format fmt )
+{
+ unsigned int idx = (unsigned int)fmt;
+
+ if (idx >= (unsigned int)r_Data_Format_NUMBER)
+ return "???";
+
+ return all_data_format_names[idx];
+}
+
+
+r_Data_Format get_data_format_from_name( const char *name )
+{
+ if(!name) {
+ RMInit::logOut << "get_data_format_from_name(" << (name?name: "NULL") << ")" << endl;
+ return r_Data_Format_NUMBER;
+ }
+
+ unsigned int i=r_Data_Format_NUMBER;
+
+ for (i=0; i<(unsigned int)r_Data_Format_NUMBER; i++)
+ {
+ if (strcasecmp(name, all_data_format_names[i]) == 0)
+ break;
+ }
+ return (r_Data_Format)i;
+}
+
+
+
+std::ostream& operator<<( std::ostream& s, r_Data_Format& d )
+{
+ s << (const r_Data_Format)d;
+ return s;
+}
+
+std::ostream& operator<<( std::ostream& s, const r_Data_Format& d )
+{
+ s << get_name_from_data_format(d);
+
+ return s;
+}
+
+const char* scale_function_name_subsampling = "subsampling";
+const char* scale_function_name_bitaggregation = "bitaggregation";
+
+const char* all_scale_function_names[r_Scale_Function_NUMBER] = {
+ scale_function_name_subsampling,
+ scale_function_name_bitaggregation
+ };
+
+const char *get_name_from_scale_function(r_Scale_Function fmt)
+{
+ unsigned int idx = (unsigned int)fmt;
+
+ if (idx >= (unsigned int)r_Scale_Function_NUMBER)
+ return "???";
+
+ return all_scale_function_names[idx];
+}
+
+
+r_Scale_Function get_scale_function_from_name(const char *name)
+{
+ if(!name) {
+ RMInit::logOut << "get_scale_function_from_name(" << (name?name: "NULL") << ")" << endl;
+ return r_Scale_Function_NUMBER;
+ }
+
+ unsigned int i=r_Scale_Function_NUMBER;
+
+ for (i=0; i<(unsigned int)r_Scale_Function_NUMBER; i++)
+ {
+ if (strcasecmp(name, all_scale_function_names[i]) == 0)
+ break;
+ }
+ return (r_Scale_Function)i;
+}
+
+std::ostream& operator<<( std::ostream& s, const r_Scale_Function& d )
+{
+ s << get_name_from_scale_function(d);
+
+ return s;
+}
+
+/*
+ * The names of all index type
+ */
+
+const char *index_name_auto="auto";
+const char *index_name_directory="dir";
+const char *index_name_regdirectory="rdir";
+const char *index_name_rplustree="nrp";
+const char *index_name_regrplustree="rnrp";
+const char *index_name_tilecontainer="tc";
+const char *index_name_regcomputed="rc";
+
+const char *all_index_type_names[r_Index_Type_NUMBER] = {
+ index_name_auto,
+ index_name_directory,
+ index_name_regdirectory,
+ index_name_rplustree,
+ index_name_regrplustree,
+ index_name_tilecontainer,
+ index_name_regcomputed
+ };
+
+const char *get_name_from_index_type( r_Index_Type it )
+{
+ unsigned int idx = (unsigned int)it;
+
+ if (idx >= (unsigned int)r_Index_Type_NUMBER)
+ return "UNKNOWN r_Index_Type";
+
+ if (idx == (unsigned int)r_Invalid_Index)
+ return "r_Invalid_Index";
+
+ return all_index_type_names[idx];
+}
+
+r_Index_Type get_index_type_from_name( const char *name )
+{
+ if(!name) {
+ RMInit::logOut << "get_index_type_from_name(" << (name?name: "NULL") << ")" << endl;
+ return r_Index_Type_NUMBER;
+ }
+
+ unsigned int i=r_Index_Type_NUMBER;
+
+ for (i=0; i<(unsigned int)r_Index_Type_NUMBER; i++)
+ {
+ if (strcasecmp(name, all_index_type_names[i]) == 0)
+ break;
+ }
+ return (r_Index_Type)i;
+}
+
+
+std::ostream& operator<<( std::ostream& s, r_Index_Type d )
+{
+ switch( d )
+ {
+ case r_Invalid_Index:
+ s << "r_Invalid_Index";
+ break;
+ case r_Auto_Index:
+ s << "r_Auto_Index";
+ break;
+ case r_Directory_Index:
+ s << "r_Directory_Index";
+ break;
+ case r_Reg_Directory_Index:
+ s << "r_Reg_Directory_Index";
+ break;
+ case r_RPlus_Tree_Index:
+ s << "r_RPlus_Tree_Index";
+ break;
+ case r_Reg_RPlus_Tree_Index:
+ s << "r_Reg_RPlus_Tree_Index";
+ break;
+ case r_Tile_Container_Index:
+ s << "r_Tile_Container_Index";
+ break;
+ case r_Reg_Computed_Index:
+ s << "r_Reg_Computed_Index";
+ break;
+ default:
+ s << "UNKNOWN r_Index_Type " << d;
+ break;
+ }
+
+ return s;
+}
+
+/*
+ * The names of all tiling schemes
+ */
+
+const char *tiling_name_notiling = "NoTiling";
+const char *tiling_name_regulartiling = "RegularTiling";
+const char *tiling_name_statisticaltiling = "StatisticalTiling";
+const char *tiling_name_interesttiling = "InterestTiling";
+const char *tiling_name_alignedtiling = "AlignedTiling";
+const char *tiling_name_directionaltiling = "DirectionalTiling";
+const char *tiling_name_sizetiling = "SizeTiling";
+
+const char *all_tiling_scheme_names[r_Tiling_Scheme_NUMBER] = {
+ tiling_name_notiling,
+ tiling_name_regulartiling,
+ tiling_name_statisticaltiling,
+ tiling_name_interesttiling,
+ tiling_name_alignedtiling,
+ tiling_name_directionaltiling,
+ tiling_name_sizetiling
+ };
+
+const char *get_name_from_tiling_scheme( r_Tiling_Scheme ts )
+{
+ unsigned int idx = (unsigned int)ts;
+
+ if (idx >= (unsigned int)r_Tiling_Scheme_NUMBER)
+ return "UNKNOWN r_Tiling_Scheme";
+
+ return all_tiling_scheme_names[idx];
+}
+
+r_Tiling_Scheme get_tiling_scheme_from_name( const char *name )
+{
+ if(!name) {
+ RMInit::logOut << "get_tiling_scheme_from_name(" << (name?name: "NULL") << ")" << endl;
+ return r_Tiling_Scheme_NUMBER;
+ }
+
+ unsigned int i=r_Tiling_Scheme_NUMBER;
+
+ for (i=0; i<(unsigned int)r_Tiling_Scheme_NUMBER; i++)
+ {
+ if (strcasecmp(name, all_tiling_scheme_names[i]) == 0)
+ break;
+ }
+ return (r_Tiling_Scheme)i;
+}
+
+std::ostream& operator<<(std::ostream& s, r_Tiling_Scheme d)
+{
+ s << get_name_from_tiling_scheme(d);
+ return s;
+}
+
+std::ostream& operator<<( std::ostream& s, const r_Clustering_Scheme d )
+{
+ switch( d )
+ {
+ case r_Insertion_Order_Clustering:
+ s << "r_Insertion_Order_Clustering";
+ break;
+ case r_Coords_Order_Clustering:
+ s << "r_Coords_Order_Clustering";
+ break;
+ case r_Index_Cluster_Clustering:
+ s << "r_Index_Cluster_Clustering";
+ break;
+ case r_Based_Cluster_Stat_Clustering:
+ s << "r_Based_Cluster_Stat_Clustering";
+ break;
+ default:
+ s << "UNKNOWN r_Clustering_Scheme " << d;
+ break;
+ }
+
+ return s;
+}
+
+
+#ifdef __VISUALC__
+#include <ctype.h>
+int strcasecmp(const char *s1, const char *s2)
+{
+ const char *b, *d;
+
+ b = s1; d = s2;
+ while ((*b != '\0') && (*d != '\0'))
+ {
+ if (tolower((unsigned int)*b) != tolower((unsigned int)*d))
+ break;
+ b++; d++;
+ }
+ if ((*b == '\0') && (*d == '\0'))
+ return 0;
+ if (tolower((unsigned int)*b) < tolower((unsigned int)*d))
+ return -1;
+ return 1;
+}
+#endif
diff --git a/raslib/mddtypes.hh b/raslib/mddtypes.hh
new file mode 100644
index 0000000..f8fb310
--- /dev/null
+++ b/raslib/mddtypes.hh
@@ -0,0 +1,491 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: mddtypes.hh
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ * The file cotains MDD type definitions.
+ *
+ * COMMENTS:
+ * - always append new data formats to remain compatible with earlier compiled code
+ *
+*/
+
+#ifndef _D_MDDTYPES_
+#define _D_MDDTYPES_
+
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <sstream>
+#endif
+
+//typedef unsigned int uint32;
+//typedef int int32;
+
+//@Man: r_Bytes
+//@Type: typedef
+//@Args: as unsigned int
+//@Memo: Module: {\bf raslib}.
+
+typedef unsigned int r_Bytes;
+
+/**
+ {\tt typedef unsigned int r_Bytes;}
+
+ The typedef \Ref{r_Bytes} is used as type for the number of bytes in an tile or mdd or type.
+*/
+
+//@Man: r_Ptr
+//@Type: typedef
+//@Args: as unsigned long
+//@Memo: Module: {\bf raslib}.
+
+typedef unsigned long r_Ptr;
+
+/**
+ {\tt typedef unsigned long r_Ptr;}
+
+ The typedef \Ref{r_Ptr} was introduced to handle correctly convertions from
+ pointers to integer variables on 64bit architectures.
+*/
+
+
+
+//@Man: r_Area
+//@Type: typedef
+//@Args: as unsigned int
+//@Memo: Module: {\bf raslib}.
+
+typedef unsigned int r_Area;
+
+/**
+ {\tt typedef unsigned int r_Area;}
+
+ The typedef \Ref{r_Area} is used as type for the number of cells in an mdd object or tile.
+*/
+
+
+
+//@Man: r_Range
+//@Type: typedef
+//@Args: as int
+//@Memo: Module: {\bf raslib}.
+
+typedef int r_Range;
+
+/**
+ {\tt typedef int r_Range;}
+
+ The typedef \Ref{r_Range} is used as type for the point set
+ of one dimension of a spatial domain. This means that lower
+ and upper bounds of \Ref{r_Sinterval}, the projection value,
+ and the cooridnate values of \Ref{r_Point} are of this type.
+*/
+
+
+
+//@Man: r_Dimension
+//@Type: typedef
+//@Args: as unsigned int
+//@Memo: Module: {\bf raslib}.
+
+typedef unsigned int r_Dimension;
+
+/**
+ {\tt typedef unsigned int r_Dimension;}
+
+ This is used as type for the number of dimensions in
+ \Ref{r_Point} and \Ref{r_Minterval}.
+*/
+
+
+//@Man: r_Data_Format
+//@Type: enum
+//@Args:
+//@Memo: Module: {\bf raslib}.
+
+enum r_Data_Format
+{
+ r_Array,
+ r_TIFF,
+ r_JPEG,
+ r_HDF,
+ r_CSV,
+ r_PNG,
+ r_ZLib,
+ r_Auto_Compression,
+ r_BMP,
+ r_RLE,
+ r_Wavelet_Haar,
+ r_Wavelet_Daubechies, // = Daubechies 4 tap
+ r_Sep_ZLib,
+ r_Sep_RLE,
+ r_Wavelet_Daub6,
+ r_Wavelet_Daub8,
+ r_Wavelet_Daub10,
+ r_Wavelet_Daub12,
+ r_Wavelet_Daub14,
+ r_Wavelet_Daub16,
+ r_Wavelet_Daub18,
+ r_Wavelet_Daub20,
+ r_Wavelet_Least8,
+ r_Wavelet_Least10,
+ r_Wavelet_Least12,
+ r_Wavelet_Least14,
+ r_Wavelet_Least16,
+ r_Wavelet_Least18,
+ r_Wavelet_Least20,
+ r_Wavelet_Coiflet6,
+ r_Wavelet_Coiflet12,
+ r_Wavelet_Coiflet18,
+ r_Wavelet_Coiflet24,
+ r_Wavelet_Coiflet30,
+ r_VFF,
+ r_Wavelet_QHaar,
+ r_PPM,
+ r_TOR,
+ r_DEM,
+ r_Pack_Bits,
+ r_ECW,
+ r_TMC,
+ r_NTF,
+ r_Data_Format_NUMBER
+};
+
+/**
+ {\tt enum r_Data_Format}
+
+ \begin{tabular}{lll}
+ {\ttr_Array} && no compression, row-major memory representation\\
+
+ {\ttr_TIFF} && TIFF format (see \Ref{r_Conv_TIFF})\\
+ {\ttr_JPEG} && JPEG format (see \Ref{r_Conv_JPEG})\\
+ {\ttr_HDF} && HDF format (see \Ref{r_Conv_HDF})\\
+ {\ttr_PNG} && PNG format (see \Ref{r_Conv_PNG})\\
+ {\ttr_BMP} && BMP format (see \Ref{r_Conv_BMP})\\
+ {\ttr_VFF} && VFF format (see \Ref{r_Conv_VFF})\\
+ {\ttr_PPM} && PPM format (see \Ref{r_Conv_PPM})\\
+ {\ttr_TOR} && TOR format (see \Ref{r_Conv_TOR})\\
+ {\ttr_DEM} && DEM format (see \Ref{r_Conv_DEM})\\
+ {\ttr_ECW} && ECW format (see \Ref{r_Conv_ECW})\\
+ {\ttr_NTF} && NITF format (see \Ref{r_Conv_NTF})\\
+
+ {\ttr_Auto_Compression} && automatic compression\\
+ {\ttr_ZLib} && ZLIB compresion (see \Ref{r_Tile_Comp_RLE})\\
+ {\ttr_Pack_Bits} && Packbits rle compresion (see \Ref{r_Tile_Comp_Packbits})\\
+ {\ttr RLE} && RLE compression (see \Ref{r_Tile_Comp_RLE})\\
+ {\ttr_Wavelet_Haar} && Haar Wavelet compression (see \Ref{r_Haar_Wavelet_Compression})\\
+ {\ttr_Wavelet_Daubechies} && Daubechies 4-tap Wavelet compression (see \Ref{r_Daubechies_Wavelet_Compression})\\
+ {\ttr_Sep_ZLib} && ZLIB compression, compress base types separately (see \Ref{r_Tile_Separate_ZLIB})\\
+ {\ttr_Sep_RLE} && RLE compression, compress base types separately (see \Ref{r_Tile_Separate_RLE})\\
+ {\ttr_Wavelet_Daub<n>} && Daubechies n-tap Wavelet compression, n=6,8,...,18,20 (see \Ref{r_Ortho_Wavelet_Factory})\\
+ {\ttr_Wavelet_Least<n>} && Least asymmetric n-tap Wavelet comp., n=8,10,...,18,20 (see \Ref{r_Ortho_Wavelet_Factory})\\
+ {\ttr_Wavelet_Coiflet<n>} && Coiflet n-tap Wavelet compression, n=6,12,18,24,30 (see \Ref{r_Ortho_Wavelet_Factory})\\
+ {\ttr_Wavelet_QHaar} && Lossy Haar Wavelet compression (see \Ref{r_Haar_QWavelet_Compression})\\
+
+ \end{tabular}
+*/
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ The names of all data types, to avoid redundant storage and inconsistencies.
+ The variable name convention is the prefix format_name_ followed by the name
+ of the data format in lower case without the r_ prefix, i.e. for r_Wavelet_Haar
+ format_name_wavelet_haar.
+ In addition there's an array of names all_data_format_names where the data format
+ can be used as index to get the name.
+*/
+
+extern const char *format_name_array;
+extern const char *format_name_tiff;
+extern const char *format_name_jpeg;
+extern const char *format_name_hdf;
+extern const char *format_name_png;
+extern const char *format_name_zlib;
+extern const char *format_name_auto_compression;
+extern const char *format_name_bmp;
+extern const char *format_name_ppm;
+extern const char *format_name_rle;
+extern const char *format_name_wavelet_haar;
+extern const char *format_name_wavelet_daubechies;
+extern const char *format_name_sep_zlib;
+extern const char *format_name_sep_rle;
+extern const char *format_name_wavelet_daub6;
+extern const char *format_name_wavelet_daub8;
+extern const char *format_name_wavelet_daub10;
+extern const char *format_name_wavelet_daub12;
+extern const char *format_name_wavelet_daub14;
+extern const char *format_name_wavelet_daub16;
+extern const char *format_name_wavelet_daub18;
+extern const char *format_name_wavelet_daub20;
+extern const char *format_name_wavelet_least8;
+extern const char *format_name_wavelet_least10;
+extern const char *format_name_wavelet_least12;
+extern const char *format_name_wavelet_least14;
+extern const char *format_name_wavelet_least16;
+extern const char *format_name_wavelet_least18;
+extern const char *format_name_wavelet_least20;
+extern const char *format_name_wavelet_coiflet6;
+extern const char *format_name_wavelet_coiflet12;
+extern const char *format_name_wavelet_coiflet18;
+extern const char *format_name_wavelet_coiflet24;
+extern const char *format_name_wavelet_coiflet30;
+extern const char *format_name_vff;
+extern const char *format_name_tor;
+extern const char *format_name_dem;
+extern const char *format_name_pack_bits;
+extern const char *format_name_wavelet_qhaar;
+extern const char *format_name_tmc;
+extern const char *format_name_ntf;
+
+extern const char *all_data_format_names[r_Data_Format_NUMBER];
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a data format name for a data format
+*/
+const char *get_name_from_data_format( r_Data_Format fmt );
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a data format for a data format name
+*/
+r_Data_Format get_data_format_from_name ( const char *name );
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Data_Format}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Data_Format& d );
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type \Ref{r_Data_Format}.
+*/
+extern std::ostream& operator<<( std::ostream& s, r_Data_Format& d );
+
+//@Man: r_Scale_Function
+//@Type: enum
+//@Args:
+//@Memo: Module: {\bf raslib}.
+
+enum r_Scale_Function {
+ r_SubSampling,
+ r_BitAggregation,
+ r_Scale_Function_NUMBER
+ };
+
+extern const char *scale_function_name_subsampling;
+extern const char *scale_function_name_bitaggregation;
+
+extern const char *all_scale_function_names[r_Scale_Function_NUMBER];
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a scale function name for a scale function
+*/
+const char *get_name_from_scale_function(r_Scale_Function func);
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a scale function from a scale function name
+*/
+r_Scale_Function get_scale_function_from_name(const char *name);
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Scale_Function}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Scale_Function& d );
+
+
+//@Man: r_Index_Type
+//@Type: enum
+//@Args:
+//@Memo: Module: {\bf raslib}.
+
+enum r_Index_Type
+ {
+ r_Invalid_Index = -1,
+ r_Auto_Index = 0,
+ r_Directory_Index = 1,
+ r_Reg_Directory_Index = 2,
+ r_RPlus_Tree_Index = 3,
+ r_Reg_RPlus_Tree_Index = 4,
+ r_Tile_Container_Index = 5,
+ r_Reg_Computed_Index = 6,
+ r_Index_Type_NUMBER = 7
+ };
+
+extern std::ostream& operator<<(std::ostream& in, r_Index_Type type);
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ The names of all index type, to avoid redundant storage and inconsistencies.
+ The variable name convention is the prefix index_name_ followed by the name
+ of the index type in lower case without the r_ prefix, i.e. for r_Auto_Index
+ index_name_auto.
+ In addition there's an array of names all_index_type_names where the index type
+ can be used as index to get the name.
+*/
+
+extern const char *index_name_auto;
+extern const char *index_name_directory;
+extern const char *index_name_regdirectory;
+extern const char *index_name_rplustree;
+extern const char *index_name_regrplustree;
+extern const char *index_name_tilecontainer;
+extern const char *index_name_regcomputed;
+
+extern const char *all_index_type_names[r_Index_Type_NUMBER];
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a index type name for a index type
+*/
+const char *get_name_from_index_type( r_Index_Type it );
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a index type for a index type name
+*/
+r_Index_Type get_index_type_from_name ( const char *name );
+
+//@Man: r_Tiling_Scheme
+//@Type: enum
+//@Args:
+//@Memo: Module: {\bf raslib}.
+
+enum r_Tiling_Scheme
+ {
+ r_NoTiling = 0,
+ r_RegularTiling = 1,
+ r_StatisticalTiling = 2,
+ r_InterestTiling = 3,
+ r_AlignedTiling = 4,
+ r_DirectionalTiling = 5,
+ r_SizeTiling = 6,
+ r_Tiling_Scheme_NUMBER = 7
+ };
+/**
+ Tiling of the object:
+
+ \begin{tabular}{lll}
+ NoTiling && no tiling is done unless the object is too big;
+ in that case, tiling is done along the first direction only;
+ for objects which are to be accessed always as a whole \\
+ {\bf Aligned} && aligned tiling, needs tileConfig \\
+ LowVariationAreas && according to areas of low cell value variation \\
+ BasedTilesStat && based on statistics regarding access to this MDD object
+ \end{tabular}
+
+ In addition, it is possible to have a tiling according to areas of
+ interest, {\bf AreasInterest} mode.
+ The {\tt AreasInterest} mode is indicated by a non - null value of the
+ {\tt areasInterestPath} attribute.
+ This mode is not an alternative mode in {\tt TilingScheme} because it is
+ compatible with the other modes. For instance, an aligned tiling may be
+ adopted outside the areas of interest.
+ */
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ The names of all tiling schems, to avoid redundant storage and inconsistencies.
+ The variable name convention is the prefix tiling_name_ followed by the name
+ of the tiling scheme in lower case without the r_ prefix, i.e. for r_SizeTiling
+ tiling_name_sizetiling.
+ In addition there's an array of names all_tiling_scheme_names where the tile scheme
+ can be used as index to get the name.
+*/
+
+extern const char *tiling_name_notiling;
+extern const char *tiling_name_regulartiling;
+extern const char *tiling_name_statisticaltiling;
+extern const char *tiling_name_interesttiling;
+extern const char *tiling_name_alignedtiling;
+extern const char *tiling_name_directionaltiling;
+extern const char *tiling_name_sizetiling;
+
+extern const char *all_tiling_scheme_names[r_Tiling_Scheme_NUMBER];
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a tiling scheme name for a tiling scheme
+*/
+const char *get_name_from_tiling_scheme( r_Tiling_Scheme ts );
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Get a tiling scheme for a tiling scheme name
+*/
+r_Tiling_Scheme get_tiling_scheme_from_name ( const char *name );
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Tiling_Scheme}.
+*/
+extern std::ostream& operator<<(std::ostream& in, r_Tiling_Scheme type);
+
+//@Man: r_Clustering_Scheme
+//@Type: enum
+//@Args:
+//@Memo: Module: {\bf raslib}.
+enum r_Clustering_Scheme
+ {
+ r_Insertion_Order_Clustering = 1,
+ r_Coords_Order_Clustering = 2,
+ r_Index_Cluster_Clustering = 3,
+ r_Based_Cluster_Stat_Clustering = 4
+ };
+ /**
+ Clustering of the Tiles according to:
+
+ \begin{tabular}{lll}
+ {\bf InsertionOrder } && the order of insertion of the tiles \\
+ CoordsOrder && the coordinates of the tiles \\
+ IndexCluster && the index structure \\
+ BasedClusterStat && statistics about access to the object
+ \end{tabular}
+
+ There is the additional {\bf PathCluster} mode, where clustering is
+ done according to a path of access to areas of interest.
+ The {\tt PathCluster} mode is indicated by setting the {\tt pathCluster}
+ attribute and a non - null value of the {\tt areasInterest}.
+ This mode is not an alternative mode in {\tt ClusteringScheme} because
+ it is compatible with the other modes.
+ */
+extern std::ostream& operator<<(std::ostream& in, r_Clustering_Scheme type);
+
+#ifdef __VISUALC__
+extern int strcasecmp( const char *str1, const char *str2 );
+#endif
+
+#endif
diff --git a/raslib/memblockvec.cc b/raslib/memblockvec.cc
new file mode 100644
index 0000000..9cffc51
--- /dev/null
+++ b/raslib/memblockvec.cc
@@ -0,0 +1,107 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: memblockvec.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Memory_Block_Vector
+ *
+ * COMMENTS:
+ *
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "raslib/memblockvec.hh"
+
+
+r_Memory_Block_Vector::r_Memory_Block_Vector( r_Bytes bsize, unsigned int gran )
+{
+ blockSize = bsize;
+ granularity = gran;
+
+ numBlocks = 0; maxBlocks = granularity;
+ blocks = new void*[granularity];
+}
+
+r_Memory_Block_Vector::~r_Memory_Block_Vector( void )
+{
+ free_data();
+ delete [] blocks;
+}
+
+void* r_Memory_Block_Vector::operator[]( unsigned int idx ) const
+{
+ if (idx >= numBlocks)
+ return NULL;
+
+ return blocks[idx];
+}
+
+void* r_Memory_Block_Vector::add( void )
+{
+ if (numBlocks >= maxBlocks)
+ {
+ void** newBlocks = new void*[maxBlocks + granularity];
+ memcpy(newBlocks, blocks, numBlocks * sizeof(void*));
+ delete [] blocks; blocks = newBlocks;
+ maxBlocks += granularity;
+ }
+ blocks[numBlocks++] = (void*)(new char[blockSize]);
+ return blocks[numBlocks-1];
+}
+
+void r_Memory_Block_Vector::free_data( void )
+{
+ unsigned int i;
+
+ for (i=0; i<numBlocks; i++)
+ {
+ delete [] blocks[i];
+ blocks[i] = NULL;
+ }
+ numBlocks = 0;
+}
+
+r_Bytes r_Memory_Block_Vector::get_size( r_Bytes lastFill ) const
+{
+ return (numBlocks == 0) ? 0 : (numBlocks-1)*blockSize + lastFill;
+}
+
+void r_Memory_Block_Vector::copy_data( void* dest, r_Bytes lastFill ) const
+{
+ unsigned int i;
+ void* destPtr = dest;
+
+ if (numBlocks == 0) return;
+
+ for (i=0; i<numBlocks-1; i++)
+ {
+ memcpy(destPtr, blocks[i], blockSize);
+ destPtr = (void*)(((char*)destPtr) + blockSize);
+ }
+ memcpy(destPtr, blocks[numBlocks-1], lastFill);
+}
diff --git a/raslib/memblockvec.hh b/raslib/memblockvec.hh
new file mode 100644
index 0000000..c026614
--- /dev/null
+++ b/raslib/memblockvec.hh
@@ -0,0 +1,84 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: memblockvec.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Memory_Block_Vector
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _MEMORY_BLOCK_VECTOR_H_
+#define _MEMORY_BLOCK_VECTOR_H_
+
+#include "raslib/mddtypes.hh"
+
+
+//@ManMemo: Module {\bf raslib}
+
+/*@Doc:
+ Auxiliary class, realizes a set of memory blocks of equal size that can
+ be extended to any size. Used by some children of r_LinCompStream.
+*/
+
+class r_Memory_Block_Vector
+{
+public:
+ /// constructor, receiving the size of each memory block and the granularity
+ /// for extending the number of blocks.
+ r_Memory_Block_Vector( r_Bytes bsize=4096, unsigned int gran=8 );
+ /// destructor
+ ~r_Memory_Block_Vector( void );
+ /// return number of blocks
+ inline unsigned int get_number( void ) const {return numBlocks;}
+ /// return block size
+ inline r_Bytes get_block_size( void ) const {return blockSize;}
+ /// return granularity
+ inline unsigned int get_granularity( void ) const {return granularity;}
+ /// get a block
+ void* operator[]( unsigned int idx ) const;
+ /// add a new block and return a pointer to it
+ void* add( void );
+ /// free all blocks (but not the vector, call the destructor for that)
+ void free_data( void );
+ /// get number of bytes stored. lastFill is the number of bytes used
+ /// in the last block
+ r_Bytes get_size( r_Bytes lastFill ) const;
+ /// Copy the data stored in blocks into linear memory. lastFill is the
+ /// number of bytes in the last block
+ void copy_data( void* dest, r_Bytes lastFill ) const;
+
+protected:
+ /// the array of memory block pointers
+ void** blocks;
+ unsigned int numBlocks;
+ unsigned int maxBlocks;
+ /// the size of the blocks
+ r_Bytes blockSize;
+ /// the granularity
+ unsigned int granularity;
+};
+
+#endif
diff --git a/raslib/metaobject.cc b/raslib/metaobject.cc
new file mode 100644
index 0000000..844aa48
--- /dev/null
+++ b/raslib/metaobject.cc
@@ -0,0 +1,81 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+#include "mymalloc/mymalloc.h"
+static const char rcsid[] = "@(#)raslib, r_Meta_Object: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/metaobject.cc,v 1.7 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/metaobject.hh"
+
+#include <stdlib.h> // OSF1 has the definition for malloc here
+#include <malloc.h>
+#include <string.h>
+
+r_Meta_Object::r_Meta_Object()
+ : typeName(NULL)
+{
+}
+
+r_Meta_Object::r_Meta_Object( const char* newTypeName )
+{
+ typeName = (char*)mymalloc(strlen(newTypeName) + 1);
+ strcpy(typeName, newTypeName);
+}
+
+r_Meta_Object::r_Meta_Object( const r_Meta_Object& oldObj )
+ : typeName(NULL)
+{
+ if( oldObj.typeName )
+ {
+ typeName = (char*)mymalloc(strlen(oldObj.typeName) + 1);
+ strcpy(typeName, oldObj.typeName);
+ }
+}
+
+const r_Meta_Object&
+r_Meta_Object::operator=( const r_Meta_Object& oldObj )
+{
+ // Gracefully handle self assignment
+ if (this == &oldObj) return *this;
+
+ free(typeName);
+ typeName = NULL;
+ if( oldObj.typeName )
+ {
+ typeName = (char*)mymalloc(strlen(oldObj.typeName) + 1);
+ strcpy(typeName, oldObj.typeName);
+ }
+
+ return *this;
+}
+
+r_Meta_Object::~r_Meta_Object()
+{
+ if(typeName)
+ free(typeName);
+}
+
+const char*
+r_Meta_Object::name() const
+{
+ return typeName;
+}
diff --git a/raslib/metaobject.hh b/raslib/metaobject.hh
new file mode 100644
index 0000000..634ea98
--- /dev/null
+++ b/raslib/metaobject.hh
@@ -0,0 +1,77 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: metaobject.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Meta_Object
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_META_OBJECT_
+#define _D_META_OBJECT_
+
+#include <iostream>
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <sstream> // for istrstream
+#endif
+
+#include "raslib/error.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class the superclass for all classes in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+class r_Meta_Object
+{
+public:
+ /// default constructor.
+ r_Meta_Object();
+ /// constructor getting name of type.
+ r_Meta_Object( const char* newTypeName );
+ /// copy constructor
+ r_Meta_Object( const r_Meta_Object& oldObj );
+ /// assignment operator.
+ const r_Meta_Object& operator=( const r_Meta_Object& oldObj );
+ /// destructor.
+ virtual ~r_Meta_Object();
+
+ /// retrieve name of the type.
+ const char* name() const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const = 0;
+
+protected:
+ char* typeName;
+};
+
+#endif
diff --git a/raslib/minterval.cc b/raslib/minterval.cc
new file mode 100644
index 0000000..311c8e9
--- /dev/null
+++ b/raslib/minterval.cc
@@ -0,0 +1,1055 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: Minterval.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Minterval
+ *
+ * COMMENTS:
+ *
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Minterval: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/minterval.cc,v 1.54 2005/09/03 20:31:22 rasdev Exp $";
+
+using namespace std;
+
+using namespace std;
+
+#include "raslib/rmdebug.hh"
+#include "raslib/minterval.hh"
+#include "raslib/odmgtypes.hh"
+#include "raslib/dlist.hh"
+#include "mymalloc/mymalloc.h"
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+
+r_Minterval::r_Minterval(r_Dimension dim)
+ : dimensionality(dim),
+ streamInitCnt(0),
+ intervals(NULL)
+ {
+ RMDBGONCE(20, RMDebug::module_raslib, "r_Minterval", "r_Minterval(r_Dimension), this=" << (long)this)
+ intervals = new r_Sinterval[ dimensionality ];
+ }
+
+void
+r_Minterval::constructorinit(char* mIntStr) throw(r_Eno_interval)
+{
+
+ if(!mIntStr)
+ {
+ RMInit::logOut << "r_Minterval::r_Minterval(" << (mIntStr?mIntStr:"NULL") << ")" << endl;
+ throw r_Eno_interval();
+ }
+
+ char* p = NULL; // for counting ','
+ // for parsing the string
+ std::istrstream str(mIntStr, strlen(mIntStr) + 1);
+ char c = 0;
+ r_Sinterval sint;
+ r_Range b = 0; // bound for Sinterval
+
+ if (intervals != NULL)
+ {
+ delete intervals;
+ intervals = NULL;
+ }
+
+ // calculate dimensionality
+ p = mIntStr;
+ while(p = strchr(++p, ','))
+ dimensionality++;
+
+ // allocate space for intervals
+ intervals = new r_Sinterval[ dimensionality ];
+
+ // check for left bracket '['
+ str >> c;
+ if (c != '[')
+ {
+ // error, should perhaps raise exception
+ dimensionality = 0;
+ delete[] intervals;
+ intervals = NULL;
+ RMInit::logOut << "r_Minterval::r_Minterval(" << mIntStr << "): the string doesn't have pattern [a:b,c:d]" << endl;
+ throw r_Eno_interval();
+ }
+
+ // for each dimension: get sinterval
+ for (r_Dimension i=0; i<dimensionality; i++)
+ {
+ // --- evaluate lower bound ------------------------------
+ str >> c; // test read first char
+ if (c == '*') // low bound is '*'
+ sint.set_low('*');
+ else // low bound must be a number
+ {
+ str.putback(c);
+ str >> b; // read type r_Range
+ if ( ! str ) // check for proper int recognition
+ {
+ RMInit::logOut << "minterval constructor failed on dim " << i << ", lo" << endl << flush;
+ throw r_Eno_interval();
+ }
+ sint.set_low(b); // store lo bound
+ }
+
+ // --- check for ':' between lower and upper bound -------
+ str >> c;
+ if (c != ':')
+ {
+ // error
+ dimensionality = 0;
+ delete[] intervals;
+ intervals = NULL;
+ RMInit::logOut << "r_Minterval::r_Minterval(" << mIntStr << "): missing ':', string not like [a:b,c:d]" << endl;
+ throw r_Eno_interval();
+ }
+
+ // --- evaluate upper bound ------------------------------
+ str >> c;
+ if (c == '*')
+ sint.set_high('*');
+ else
+ {
+ str.putback(c);
+ str >> b;
+ if ( ! str )
+ {
+ RMInit::logOut << "minterval constructor failed on dim " << i << ", hi" << endl << flush;
+ throw r_Eno_interval();
+ }
+ sint.set_high(b);
+ }
+ str >> c;
+
+ // --- next dimension needs either ',' separator or ']' end tag
+ if (i != dimensionality-1 && c != ',' || i == dimensionality-1 && c != ']')
+ {
+ dimensionality = 0;
+ delete[] intervals;
+ intervals = NULL;
+ RMInit::logOut << "r_Minterval::r_Minterval(" << mIntStr << "): missing ',' or ']', string not like [a:b,c:d]" << endl;
+ throw r_Eno_interval();
+ }
+
+ intervals[i] = sint;
+
+ sint.set_interval('*','*');
+ }
+}
+
+r_Minterval::r_Minterval(char* mIntStr) throw(r_Eno_interval)
+ : dimensionality(1),
+ streamInitCnt(0),
+ intervals(NULL)
+ {
+ RMDBGONCE(20, RMDebug::module_raslib, "r_Minterval", "r_Minterval(char*), this=" << (long)this)
+ constructorinit(mIntStr);
+ }
+
+r_Minterval::r_Minterval(const char* mIntStr) throw(r_Eno_interval)
+ : dimensionality(1),
+ streamInitCnt(0),
+ intervals(NULL)
+ {
+ RMDBGONCE(20, RMDebug::module_raslib, "r_Minterval", "r_Minterval(char*), this=" << (long)this)
+ char* temp = (char*)mymalloc((1 + strlen(mIntStr)) * sizeof(char));
+ strcpy(temp, mIntStr);
+
+ try
+ {
+ constructorinit(temp);
+ free(temp);
+ }
+ catch(r_Error err)
+ {
+ free(temp);
+ throw;
+ }
+
+ temp = 0;
+ }
+
+r_Minterval&
+r_Minterval::operator<<(const r_Sinterval& newInterval) throw(r_Einit_overflow)
+ {
+ if (streamInitCnt >= dimensionality)
+ {
+ RMInit::logOut << "r_Minterval::operator<<(" << newInterval << ") domain is already full" << endl;
+ throw r_Einit_overflow();
+ }
+
+ intervals[streamInitCnt++] = newInterval;
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::operator<<(r_Range p) throw(r_Einit_overflow)
+ {
+ if (streamInitCnt >= dimensionality)
+ {
+ RMInit::logOut << "r_Minterval::operator<<(" << p << ") domain is already full" << endl;
+ throw r_Einit_overflow();
+ }
+
+ intervals[streamInitCnt++] = r_Sinterval(p, p);
+ return *this;
+ }
+
+r_Minterval::r_Minterval()
+ : dimensionality(0),
+ streamInitCnt(0),
+ intervals(NULL)
+ {
+ RMDBGONCE(20, RMDebug::module_raslib, "r_Minterval", "r_Minterval(), this=" << this)
+ }
+
+//cannot use the initialise function because it will crash
+r_Minterval::r_Minterval(const r_Minterval& minterval)
+ : dimensionality(0),
+ streamInitCnt(0),
+ intervals(NULL)
+ {
+ RMDBGONCE(20, RMDebug::module_raslib, "r_Minterval", "r_Minterval(const r_Minterval&), this=" << this)
+ dimensionality = minterval.dimensionality;
+ streamInitCnt = minterval.streamInitCnt;
+ if(minterval.intervals)
+ {
+ intervals = new r_Sinterval[dimensionality];
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i] = minterval[i];
+ }
+ }
+
+r_Minterval::~r_Minterval()
+ {
+ RMDBGONCE(20, RMDebug::module_raslib, "r_Minterval", "~r_Minterval(), this=" << this)
+ r_deactivate();
+ }
+
+void
+r_Minterval::r_deactivate()
+ {
+ if (intervals)
+ {
+ delete[] intervals;
+ intervals = NULL;
+ }
+ }
+
+bool
+r_Minterval::intersects_with(const r_Minterval& minterval) const
+ {
+ bool result = true;
+
+ if (dimensionality != minterval.dimension())
+ {
+ RMInit::logOut << "r_Minterval::intersects_with(" << minterval << ") do not share the same dimension" << endl;
+ return false;
+ }
+
+ // none of the interval pairs are allowed to be disjoint
+ for (r_Dimension i=0; i<dimensionality && result; i++)
+ {
+ if (!intervals[i].intersects_with(minterval[i]))
+ {
+ result = false;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+#ifndef OPT_INLINE
+r_Sinterval
+r_Minterval::operator[](r_Dimension i) const
+ {
+ if (i < 0 || i >= dimensionality)
+ {
+ RMInit::logOut << "r_Minterval:::operator[](" << i << ") const index out of bounds (" << dimensionality << ")" << endl;
+ throw r_Eindex_violation(0, dimensionality-1, i);
+ }
+
+ return intervals[i];
+ }
+
+r_Sinterval&
+r_Minterval::operator[](r_Dimension i)
+ {
+ if (i < 0 || i >= dimensionality)
+ {
+ RMInit::logOut << "r_Minterval:::operator[](" << i << ") index out of bounds (" << dimensionality << ")" << endl;
+ throw r_Eindex_violation(0, dimensionality-1, i);
+ }
+
+ return intervals[i];
+ }
+#endif
+
+const r_Minterval&
+r_Minterval::operator=(const r_Minterval& minterval)
+ {
+ if (this != &minterval)
+ {
+ if (intervals && dimensionality != minterval.dimension())
+ {
+ delete[] intervals;
+ intervals = NULL;
+ }
+
+ dimensionality = minterval.dimension();
+ streamInitCnt = minterval.streamInitCnt;
+
+ if(minterval.intervals)
+ {
+ if (!intervals)
+ intervals = new r_Sinterval[ dimensionality ];
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i] = minterval[i];
+ }
+ }
+
+ return *this;
+ }
+
+bool
+r_Minterval::operator==(const r_Minterval& mint) const
+ {
+ bool returnValue = false;
+
+ if (dimensionality == mint.dimensionality)
+ {
+ returnValue = true;
+
+ for (r_Dimension i=0; i<dimensionality && returnValue ; i++)
+ {
+ if (intervals[i] != mint[i])
+ {
+ returnValue = false;
+ break;
+ }
+ }
+ }
+
+ return returnValue;
+ }
+
+bool
+r_Minterval::operator!=(const r_Minterval& mint) const
+ {
+ return !operator==(mint);
+ }
+
+r_Point
+r_Minterval::get_origin() const throw(r_Error)
+ {
+ r_Point pt(dimensionality);
+
+ if(!is_origin_fixed())
+ {
+ RMInit::logOut << "r_Minterval::get_origin() " << *this << " is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ pt[i]=intervals[i].low();
+
+ return pt;
+ }
+
+r_Point
+r_Minterval::get_high() const throw(r_Error)
+ {
+ r_Point pt(dimensionality);
+
+ if(!is_high_fixed())
+ {
+ RMInit::logOut << "r_Minterval::get_high() " << *this << " is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ pt[i] = intervals[i].high();
+
+ return pt;
+ }
+
+r_Point
+r_Minterval::get_extent() const throw(r_Error)
+ {
+ r_Point pt(dimensionality);
+
+ if(!is_origin_fixed() || !is_high_fixed())
+ {
+ RMInit::logOut << "r_Minterval::get_high() " << *this << " is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ pt[i] = intervals[i].get_extent();
+
+ return pt;
+ }
+
+r_Minterval&
+r_Minterval::reverse_translate(const r_Point& t) throw(r_Error, r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != t.dimension())
+ {
+ RMInit::logOut << "r_Minterval::reverse_translate(" << t << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, t.dimension()));
+ }
+
+ if (!is_origin_fixed() || !is_high_fixed())
+ {
+ RMInit::logOut << "r_Minterval::reverse_translate(" << t << ") " << *this << " is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].set_interval(intervals[i].low() - t[i], intervals[i].high() - t[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::translate(const r_Point& t) throw(r_Error, r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != t.dimension())
+ {
+ RMInit::logOut << "r_Minterval::translate(" << t << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, t.dimension()));
+ }
+
+ if (!is_origin_fixed() || !is_high_fixed())
+ {
+ RMInit::logOut << "r_Minterval::translate(" << t << ") " << *this << " is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].set_interval(intervals[i].low() + t[i], intervals[i].high() + t[i]);
+
+ return *this;
+ }
+
+r_Minterval
+r_Minterval::create_reverse_translation(const r_Point& t) const throw(r_Error, r_Edim_mismatch, r_Eno_interval)
+ {
+ r_Minterval result(*this);
+
+ result.reverse_translate(t);
+
+ return result;
+ }
+
+r_Minterval
+r_Minterval::create_translation(const r_Point& t) const throw(r_Error, r_Edim_mismatch, r_Eno_interval)
+ {
+ r_Minterval result(*this);
+
+ result.translate(t);
+
+ return result;
+ }
+
+r_Minterval&
+r_Minterval::scale(const double& d) throw(r_Eno_interval)
+ {
+ vector<double> scaleVec;
+
+ //create scale vector
+ for (r_Dimension i = 0; i < dimensionality; i++){
+ scaleVec.push_back(d);
+ }
+
+ scale(scaleVec);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::scale(const vector<double>& scaleVec) throw(r_Eno_interval)
+ {
+ double high = 0., low = 0.;
+
+ RMDBGENTER(1, RMDebug::module_raslib, "r_Minterval", "scale(" << scaleVec << ") before " << *this );
+
+ // if the size of scale vector is different from dimensionality, undefined behaviour
+ if(scaleVec.size() != dimensionality) {
+ RMDBGEXIT(1, RMDebug::module_raslib, "r_Minterval", "scale(" << scaleVec << ") scaleVec has wrong size " << *this );
+ throw r_Edim_mismatch(scaleVec.size(), dimensionality);
+ }
+
+ for (r_Dimension i = 0; i < dimensionality; i++)
+ {
+ // do explicit rounding, because the cast down in set_interval doesn't do the good rounding for negative values -- PB 2005-jun-19
+ low = floor( scaleVec[i] * intervals[i].low() );
+
+ //correction by 1e-6 to avoid the strage bug when high was a
+ //integer value and floor return value-1(e.g. query 47.ql)
+ high = floor(scaleVec[i] * (intervals[i].high() +1) + 0.000001) - 1;
+
+// FIXME BUG it was not forseen to be able to scale [a:a] with a very low factor f
+// to [af, af]
+// if((r_Range)high != (r_Range)low)
+// high--; // substract 1 which was added to high()
+
+ intervals[i].set_interval((r_Range)low, (r_Range)high);
+ }
+
+ RMDBGEXIT(1, RMDebug::module_raslib, "r_Minterval", "scale(" << scaleVec << ") after " << *this );
+
+ return *this;
+ }
+
+r_Minterval
+r_Minterval::create_scale(const double& d) const throw(r_Eno_interval)
+ {
+ r_Minterval result(*this);
+
+ result.scale(d);
+
+ return result;
+ }
+
+
+r_Minterval
+r_Minterval::create_scale(const vector<double>& scaleVec) const throw(r_Eno_interval)
+ {
+ r_Minterval result(*this);
+
+ result.scale(scaleVec);
+
+ return result;
+ }
+
+
+
+r_Minterval&
+r_Minterval::union_of(const r_Minterval& mint1, const r_Minterval& mint2) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (mint1.dimension() != mint2.dimension())
+ {
+ RMInit::logOut << "r_Minterval::union_of(" << mint1 << ", " << mint2 << ") dimensions do not match" << endl;
+ throw(r_Edim_mismatch( mint1.dimension(), mint2.dimension()));
+ }
+
+ // cleanup + initializing of this
+ if (dimensionality != mint1.dimension())
+ {
+ if (intervals)
+ delete[] intervals;
+ dimensionality = mint1.dimension();
+ streamInitCnt = dimensionality;
+ intervals = new r_Sinterval[ dimensionality ];
+ }
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].union_of(mint1[i], mint2[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::union_with(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::union_with(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].union_with(mint[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::operator+=(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ return union_with(mint);
+ }
+
+r_Minterval
+r_Minterval::create_union(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::create_union(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ r_Minterval result(dimensionality);
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ result << intervals[i].create_union(mint[i]);
+
+ return result;
+ }
+
+r_Minterval
+r_Minterval::operator+(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ return create_union(mint);
+ }
+
+r_Minterval&
+r_Minterval::difference_of(const r_Minterval& mint1, const r_Minterval& mint2) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (mint1.dimension() != mint2.dimension())
+ {
+ RMInit::logOut << "r_Minterval::difference_of(" << mint1 << ", " << mint2 << ") dimensions do not match" << endl;
+ throw(r_Edim_mismatch( mint1.dimension(), mint2.dimension()));
+ }
+
+ if (dimensionality != mint1.dimension())
+ {
+ // cleanup + initializing of this
+ if (intervals)
+ delete[] intervals;
+
+ dimensionality = mint1.dimension();
+ streamInitCnt = dimensionality;
+ intervals = new r_Sinterval[ dimensionality ];
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].difference_of(mint1[i], mint2[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::difference_with(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::difference_with(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].difference_with(mint[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::operator-=(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ return difference_with(mint);
+ }
+
+r_Minterval
+r_Minterval::create_difference(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::create_difference(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ r_Minterval result(dimensionality);
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ result << intervals[i].create_difference(mint[i]);
+
+ return result;
+ }
+
+r_Minterval
+r_Minterval::operator-(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ return create_difference(mint);
+ }
+
+r_Minterval&
+r_Minterval::intersection_of(const r_Minterval& mint1, const r_Minterval& mint2) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (mint1.dimension() != mint2.dimension())
+ {
+ RMInit::logOut << "r_Minterval::intersection_of(" << mint1 << ", " << mint2 << ") dimensions do not match" << endl;
+ throw(r_Edim_mismatch( mint1.dimension(), mint2.dimension()));
+ }
+ if (dimensionality != mint1.dimension())
+ {
+ // cleanup + initializing of this
+ if (intervals)
+ delete[] intervals;
+
+ dimensionality = mint1.dimension();
+ streamInitCnt = dimensionality;
+ intervals = new r_Sinterval[ dimensionality ];
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].intersection_of(mint1[i], mint2[i]);
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::intersection_with(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::intersection_with(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].intersection_with(mint[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::operator*=(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ return intersection_with(mint);
+ }
+
+r_Minterval
+r_Minterval::create_intersection(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::create_intersection(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ r_Minterval result(dimensionality);
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ result << intervals[i].create_intersection(mint[i]);
+
+ return result;
+ }
+
+r_Minterval
+r_Minterval::operator*(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ return create_intersection(mint);
+ }
+
+r_Minterval&
+r_Minterval::closure_of(const r_Minterval& mint1, const r_Minterval& mint2) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (mint1.dimension() != mint2.dimension())
+ {
+ RMInit::logOut << "r_Minterval::closure_of(" << mint1 << ", " << mint2 << ") dimensions do not match" << endl;
+ throw(r_Edim_mismatch( mint1.dimension(), mint2.dimension()));
+ }
+ if (mint1.dimension() != dimensionality)
+ {
+ // cleanup + initializing of this
+ if (intervals)
+ delete[] intervals;
+
+ dimensionality = mint1.dimension();
+ streamInitCnt = dimensionality;
+ intervals = new r_Sinterval[ dimensionality ];
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].closure_of(mint1[i], mint2[i]);
+
+ return *this;
+ }
+
+r_Minterval&
+r_Minterval::closure_with(const r_Minterval& mint) throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::closure_with(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ intervals[i].closure_with(mint[i]);
+
+ return *this;
+ }
+
+r_Minterval
+r_Minterval::create_closure(const r_Minterval& mint) const throw(r_Edim_mismatch, r_Eno_interval)
+ {
+ if (dimensionality != mint.dimension())
+ {
+ RMInit::logOut << "r_Minterval::create_closure(" << mint << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw(r_Edim_mismatch( dimensionality, mint.dimension()));
+ }
+
+ r_Minterval result(dimensionality);
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ result << intervals[i].create_closure(mint[i]);
+
+ return result;
+ }
+
+void
+r_Minterval::print_status(std::ostream& s) const
+ {
+ s << "[";
+
+ if (dimensionality > 0)
+ {
+ for (r_Dimension i=0; i<dimensionality-1; i++)
+ s << intervals[i] << ",";
+
+ s << intervals[dimensionality-1];
+ }
+
+ s << "]";
+ }
+
+char*
+r_Minterval::get_string_representation() const
+ {
+ unsigned int bufferSize = dimensionality*25+3; // should be enough
+
+ // allocate buffer and initialize string stream
+ char* buffer = new char[bufferSize];
+ std::ostrstream domainStream(buffer, bufferSize);
+
+ // write into string stream
+ domainStream << (*this) << std::ends;
+
+ // allocate memory taking the final string
+ char* returnString = strdup(buffer);
+
+ // delete buffer
+ delete[] buffer;
+
+ return returnString;
+ }
+
+r_Area
+r_Minterval::cell_count() const throw(r_Error)
+ {
+ r_Area cellCount = 1;
+ r_Point ptExt=get_extent();
+
+ for (r_Dimension i=0; i<dimensionality; i++)
+ cellCount *= ptExt[i];
+
+ return cellCount;
+ }
+
+// offset in cells for linear access of the data element referred by point in the data memory area
+// Lower dimensions are higher valued which means that the highest dimension is stored in a sequence.
+r_Area
+r_Minterval::cell_offset(const r_Point& point) const throw(r_Eindex_violation, r_Error)
+ {
+ r_Dimension i = 0;
+ r_Area offset = 0;
+ r_Point ptExt;
+
+ if (dimensionality != point.dimension())
+ {
+ RMInit::logOut << "r_Minterval::cell_offset(" << point << ") dimension of domain (" << dimensionality << ") does not match dimension of argument (" << point.dimension() << ")" << endl;
+ throw r_Edim_mismatch(point.dimension(), dimensionality);
+ }
+
+ ptExt=get_extent();
+
+ // calculate offset
+ for (i = 0; i < dimensionality - 1; i++)
+ {
+ if (point[i] < intervals[i].low() || point[i] > intervals[i].high())
+ {
+ RMInit::logOut << "r_Minterval::cell_offset(" << point << ") point is out of range (" << *this << ")" << endl;
+ throw(r_Eindex_violation(point[i], intervals[i].low(), intervals[i].high()));
+ }
+
+ offset = (offset + point[i] - intervals[i].low()) * ptExt[i+1];
+ }
+
+ // now i = dimensionality - 1
+ if (point[i] < intervals[i].low() || point[i] > intervals[i].high())
+ {
+ RMInit::logOut << "r_Minterval::cell_offset(" << point << ") point is out of range (" << *this << ")" << endl;
+ throw(r_Eindex_violation(point[i], intervals[i].low(), intervals[i].high()));
+ }
+ offset += point[i] - intervals[i].low();
+
+ return offset;
+ }
+
+// Arguments.....: linear offset
+// Return value..: point object which corresponds to the linear offset of the argument
+// Description...: The method calucaltes the spatial domain coordinates as a point out of an offset specification. Lower dimensions are higher valued which means that the highest dimension is stored in a sequence.
+r_Point
+r_Minterval::cell_point(r_Area offset) const throw(r_Eno_cell, r_Error)
+ {
+ r_Dimension i;
+ unsigned int factor=1;
+ r_Point pt(dimensionality), ptExt;
+
+ if (offset >= cell_count())
+ {
+ RMInit::logOut << "r_Minterval::cell_point(" << offset << ") offset is out of range (" << cell_count() << ")" << endl;
+ throw r_Eno_cell();
+ }
+
+ ptExt=get_extent();
+
+ for (i=0; i<dimensionality; i++)
+ factor *= ptExt[i];
+
+ for (i=0; i<dimensionality; i++)
+ {
+ factor /= ptExt[i];
+ pt[i] = intervals[i].low() + (offset - (offset%factor))/factor;
+ offset %= factor;
+ }
+
+ return pt;
+ }
+
+void
+r_Minterval::delete_dimension(r_Dimension dim) throw(r_Eindex_violation)
+ {
+ if (dim < 0 || dim >= dimensionality)
+ {
+ RMInit::logOut << "r_Minterval::delete_dimension(" << dim << ") dimension is out of range (" << dimensionality << ")" << endl;
+ throw r_Eindex_violation(0, dimensionality-1, dim);
+ }
+
+ dimensionality -= 1;
+ streamInitCnt = dimensionality;
+ r_Sinterval* newIntervals = new r_Sinterval[ dimensionality ];
+
+ for (r_Dimension i=0, j=0; i<dimensionality; i++, j++)
+ {
+ if (i==dim) j++;
+ newIntervals[i] = intervals[j];
+ }
+
+ delete[] intervals;
+
+ intervals = newIntervals;
+ }
+
+r_Bytes
+r_Minterval::get_storage_size() const
+ {
+ r_Bytes sz = sizeof(r_Sinterval*) + 2 * sizeof(r_Dimension);
+
+ if (dimensionality > 0)
+ sz += dimensionality * intervals->get_storage_size();
+
+ return sz;
+ }
+
+bool
+r_Minterval::is_mergeable(const r_Minterval& b) const
+ {
+ bool is_merg = true;
+ // An alias to this object
+ const r_Minterval& a = *this;
+
+ // The blocks must have the same dimensionality to be mergeable
+ if (a.dimensionality != b.dimensionality)
+ {
+ is_merg = false;
+ }
+ else {
+
+ // Count the number of adjacent frontiers
+ int ones_differences = 0;
+
+ // For all dimensions
+ for (r_Dimension i=0; i<dimensionality; i++)
+ {
+ // Diferente origins
+ if (a[i].low() != b[i].low())
+ {
+ if ((a[i].low() == b[i].high()+1) || (b[i].low() == a[i].high()+1))
+ // If borders are adjacent
+ {
+ // Update counter
+ ++ones_differences;
+ }
+ else {
+ // Else non-mergeable blocks
+ is_merg = false;
+ break;
+ }
+ }
+ else {
+ // Check ending
+ if (a[i].high() != b[i].high())
+ {
+ is_merg = false;
+ // Not the same, can't be
+ break;
+ // mergeable
+ }
+ }
+ }
+
+ // Only one adjacent borded
+ if (is_merg && (ones_differences!=1))
+ is_merg = false;
+ // allowed
+ }
+ return is_merg;
+ }
+
+std::ostream& operator<<(std::ostream& s, const r_Minterval& d)
+ {
+ d.print_status(s);
+ return s;
+ }
+
+std::ostream& operator<<(std::ostream& s, const vector<double>& doubleVec)
+ {
+ vector<double>::const_iterator iter, iterEnd;
+
+ iter=doubleVec.begin();
+ iterEnd=doubleVec.end();
+ s << "{";
+ while(iter != iterEnd){
+ s << *iter;
+ ++iter;
+ if(iter != iterEnd)
+ s << ", ";
+ }
+ s << "}";
+
+ return s;
+ }
diff --git a/raslib/minterval.hh b/raslib/minterval.hh
new file mode 100644
index 0000000..a9b596d
--- /dev/null
+++ b/raslib/minterval.hh
@@ -0,0 +1,567 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: minterval.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Minterval
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_MINTERVAL_
+#define _D_MINTERVAL_
+
+#include <iostream>
+#include <vector>
+using std::endl;
+using std::vector;
+
+#ifdef __VISUALC__
+// Diable warning for exception specification.
+#pragma warning( disable : 4290 )
+#include <strstrea.h>
+#else
+#include <sstream> // for istrstream
+#endif
+
+class r_Edim_mismatch;
+class r_Error;
+class r_Einit_overflow;
+class r_Eno_interval;
+class r_Eno_cell;
+class r_Error;
+
+
+#include "raslib/sinterval.hh"
+#include "raslib/point.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ The spatial domain of an MDD is represented by an object
+ of class \Ref{r_Minterval}. It specifies lower and upper bound
+ of the point set for each dimension of an MDD. Internally,
+ the class is realized through an array of intervals of type
+ \Ref{r_Sinterval}.
+
+ For the operations union, difference, and intersection the
+ dimensionalties of the operands must be equal, otherwise an
+ exception is raised. The semantics of the operations are
+ defined as follows for each dimension:
+
+ | ... fixed bound \\
+ * ... open bound
+
+ \begin{verbatim}
+
+ class orientation union difference intersection
+ -----------------------------------------------------------
+ 1 |-a-| |-b-| error a error
+
+ 2 |-a-| [a1,b2] [a1,b1] [b1,a2]
+ |-b-|
+
+ 3 |--a--| a error b
+ |-b-|
+
+ 4 |-b-| [b1,a2] [b2,a2] [a1,b2]
+ |-a-|
+
+ 5 |--b--| b error a
+ |-a-|
+
+ 6 |-b-| |-a-| error a error
+
+ 7 |-a-|-b-| [a1,b2] a [a2,a2]
+
+ 8 |-b-|-a-| [b1,a2] a [b2,b2]
+
+ 9 |--a--| a [a1,b1] b
+ |-b-|
+
+ 10 |--a--| a [b2,a2] b
+ |-b-|
+
+ 11 |-a-| a error a
+ |-b-|
+
+ 12 |--b--| b error a
+ |-a-|
+
+ 13 |--b--| b error a
+ |-a-|
+
+ -----------------------------------------------------
+
+ 14 |--a--* a error b
+ |-b-|
+
+ 15 |--a--* a [b2,a2] b
+ |-b-|
+
+ 16 |-b-| |-a-* error a error
+
+ 17 |-b-|-a-* [b1,a2] a [b2,b2]
+
+ 18 |--a--* [b1,a2] [b2,a2] [a1,b2]
+ |-b-|
+
+ -----------------------------------------------------
+
+ 19 *--a--| a error b
+ |-b-|
+
+ 20 *--a--| a [a1,b1] b
+ |-b-|
+
+ 21 *-a-| |-b-| error a error
+
+ 22 *-a-|-b-| [a1,b2] a [a2,a2]
+
+ 23 *--a--| [a1,b2] [a1,b1] [b1,a2]
+ |-b-|
+
+ -----------------------------------------------------
+
+ 24 |--b--* b error a
+ |-a-|
+
+ 25 |--b--* b error a
+ |-a-|
+
+ 26 |-a-| |-b-* error a error
+
+ 27 |-a-|-b-* [a1,b2] a [a2,a2]
+
+ 28 |--b--* [a1,b2] [a1,b1] [b1,a2]
+ |-a-|
+
+ -----------------------------------------------------
+
+ 29 *--b--| b error a
+ |-a-|
+
+ 30 *--b--| b error a
+ |-a-|
+
+ 31 *-b-| |-a-| error a error
+
+ 32 *-b-|-a-| [b1,a2] a [b2,b2]
+
+ 33 *--b--| [b1,a2] [b2,a2] [a1,b2]
+ |-a-|
+
+ -----------------------------------------------------
+
+ 34 *-a-| |-b-* error a error
+
+ 35 *-a-|-b-* [a1,b2] a [a2,a2]
+
+ 36 *-a-| [a1,b2] [a1,b1] [b1,a2]
+ |-b-*
+
+ -----------------------------------------------------
+
+ 37 *-b-| |-a-* error a error
+
+ 38 *-b-|-a-* [b1,a2] a [b2,b2]
+
+ 39 *-b-| [b1,a2] [a1,b1] [a1,b2]
+ |-a-*
+
+ -----------------------------------------------------
+
+ 40 *-a-| b error a
+ *-b-|
+
+ 41 *-a-| a error a
+ *-b-|
+
+ 42 *-b-| a [b2,a2] b
+ *-a-|
+
+ -----------------------------------------------------
+
+ 43 |-a-* a [a1,b1] b
+ |-b-*
+
+ 44 |-a-* a error a
+ |-b-*
+
+ 45 |-b-* b error a
+ |-a-*
+
+ -----------------------------------------------------
+ 46 *-a-* |-b-| a error b
+
+ 47 *-b-* |-a-| b error b
+
+ 48 *-a-* a [b2,a2] b
+ *-b-|
+
+ 49 *-a-* a [a1,b1] b
+ |-b-*
+
+ 50 *-b-* b error a
+ *-a-|
+
+ 51 *-b-* b error a
+ |-a-*
+
+ 52 *-a-* a error a
+ *-b-*
+
+ \end{verbatim}
+
+ Attention: The difference operation has to be reconsidered in future
+ concerning a discrete interpretation of the intervals.
+
+ The closure operation defines an interval which is the smallest
+ interval containing the two operands.
+ The method {\tt intersects_with()} returns 0 in the error cases of the
+ intersection operation and 1 otherwise.
+
+*/
+
+class r_Minterval
+{
+ public:
+ /// constructor getting dimensionality for stream initializing
+ r_Minterval( r_Dimension );
+ /// constructor taking string representation (e.g. [ 1:255, *:200, *:* ])
+ r_Minterval( const char* ) throw(r_Eno_interval);
+ /// constructor taking string representation (e.g. [ 1:255, *:200, *:* ])
+ r_Minterval( char* ) throw(r_Eno_interval);
+ /// for stream initializing with intervals
+ r_Minterval& operator<<( const r_Sinterval& )
+ throw( r_Einit_overflow );
+ /// for stream initializing with point intervals
+ r_Minterval& operator<<( r_Range )
+ throw( r_Einit_overflow );
+
+ /// default constructor
+ r_Minterval();
+ /// copy constructor
+ r_Minterval( const r_Minterval& );
+ /// destructor: cleanup dynamic memory
+ ~r_Minterval();
+
+ /// it is called when an object leaves transient memory
+ void r_deactivate();
+
+ /// determines if the self minterval intersects with the delivered one
+ bool intersects_with( const r_Minterval& ) const;
+
+#ifdef OPT_INLINE
+ inline
+#endif
+ /// read access the i-th interval
+ r_Sinterval operator[]( r_Dimension ) const;
+#ifdef OPT_INLINE
+ inline
+#endif
+ /// write access the i-th interval
+ r_Sinterval& operator[]( r_Dimension );
+
+ /// assignment: cleanup + copy
+ const r_Minterval& operator= ( const r_Minterval& );
+
+ /// equal operator
+ bool operator==( const r_Minterval& ) const;
+
+ /**
+ Two domains are equal if they have the same number of dimensions and
+ each dimension has the same lower and upper bounds.
+ */
+
+ /// non equal operator - negation of equal operator
+ bool operator!=( const r_Minterval& ) const;
+
+ /// does this interval cover the given point
+ inline const bool covers( const r_Point& pnt ) const;
+ /**
+ throws r_Edim_mismatch when dimensions do not match
+ */
+
+ /// does this interval cover the given interval
+ inline const bool covers( const r_Minterval& inter ) const;
+ /**
+ throws r_Edim_mismatch when dimensions do not match
+ */
+
+ /// get dimensionality
+ inline r_Dimension dimension() const;
+
+ /// checks if all lower bounds are fixed
+ inline const bool is_origin_fixed() const;
+ /*@Doc:
+ Returns true if all lower bounds are fixed, otherwise false.
+ */
+
+ /// get lower left corner of minterval.
+ r_Point get_origin() const throw(r_Error);
+ /*@Doc:
+ Returns a point with the minimum coordinates in all dimensions.
+ This is operation is only legal if all lower bounds are fixed!
+ */
+
+ /// checks if all upper bounds are fixed
+ inline const bool is_high_fixed() const;
+ /*@Doc:
+ Returns true if all upper bounds are fixed, otherwise false.
+ */
+
+ /// get highest corner of tile.
+ r_Point get_high() const throw(r_Error);
+ /*@Doc:
+ Returns a point with the maximum coordinates in all dimensions.
+ This is operation is only legal if all upper bounds are fixed!
+ */
+
+ /// get size of minterval as point.
+ r_Point get_extent() const throw(r_Error);
+ /*@Doc:
+ Returns a point with high() - low() + 1 of this in each
+ dimension when all bounds are fixed
+ */
+
+ /// Checks if this block is mergeable with another block (interval)
+ bool is_mergeable(const r_Minterval& other) const;
+ /**
+ This method checks if two r_Mintervals are "mergeable" side by side.
+ For this to be possible, they have to have the same low() and high()
+ values in all dimensions except in one where they differ by one point,
+ this is, a.low()==b.high()+1 or b.low()==a.high()+1. For instance, the
+ following two blocks are mergeable:
+
+ +-------------+---------------------------------------+
+ | A | B |
+ +-------------|---------------------------------------|
+
+ and the following two are not:
+
+ +-------------+-------------------------+
+ | | B |
+ | A +-------------------------+
+ +-------------+
+ */
+
+ //@Man: Methods for translation:
+ //@{
+ /// translates this by a point.
+ r_Minterval& reverse_translate( const r_Point& )
+ throw( r_Error, r_Edim_mismatch, r_Eno_interval );
+ /*@Doc:
+ Subtracts respective coordinate of a point to the lower bounds of an
+ interval. This operation is only legal if all bounds are
+ fixed!
+ */
+ /// returns new interval as translation of this by a point.
+ r_Minterval create_reverse_translation( const r_Point& ) const
+ throw( r_Error, r_Edim_mismatch, r_Eno_interval );
+ /*@Doc:
+ Subtracts respective coordinate of a point to the lower bounds of an
+ interval. This operation is only legal if all bounds are
+ fixed!
+ */
+ /// translates this by a point.
+ r_Minterval& translate( const r_Point& )
+ throw( r_Error, r_Edim_mismatch, r_Eno_interval );
+ /*@Doc:
+ Adds respective coordinate of a point to the lower bounds of an
+ interval. This operation is only legal if all bounds are
+ fixed!
+ */
+ /// returns new interval as translation of this by a point.
+ r_Minterval create_translation( const r_Point& ) const
+ throw( r_Error, r_Edim_mismatch, r_Eno_interval );
+ /*@Doc:
+ Adds respective coordinate of a point to the lower bounds of an
+ interval. This operation is only legal if all lower bounds are
+ fixed!
+ */
+ ///
+ //@}
+
+ //*****************************************
+
+ //@Man: Methods for scaling:
+ //@{
+ /// scales this by a factor.
+ r_Minterval& scale( const double& ) throw ( r_Eno_interval );
+ /*@Doc:
+ Scales respective extents by factor.
+ */
+ /// scales this by a factor.
+ r_Minterval& scale( const vector<double>& ) throw ( r_Eno_interval );
+ /*@Doc:
+ Scales respective extents by vector of factors.
+ */
+ /// returns new interval as scaled from this by a point.
+ r_Minterval create_scale( const double& ) const throw ( r_Eno_interval );
+ /*@Doc:
+ Scales respective extents by factor.
+ */
+ /// returns new interval as scaled from this by a point.
+ r_Minterval create_scale( const vector<double>& ) const throw ( r_Eno_interval );
+ /*@Doc:
+ Scales respective extents by vector of factors.
+ */
+ //@}
+
+ //*****************************************
+
+
+
+
+
+ //@Man: Methods/Operators for the union operation:
+ //@{
+ ///
+ r_Minterval& union_of ( const r_Minterval&, const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& union_with ( const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& operator+= ( const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval create_union ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval operator+ ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ //@}
+
+ //@Man: Methods/Operators for the difference operation:
+ //@{
+ ///
+ r_Minterval& difference_of ( const r_Minterval&, const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& difference_with ( const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& operator-= ( const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval create_difference ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval operator- ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ //@}
+
+ //@Man: Methods/Operators for the intersection operation:
+ //@{
+ ///
+ r_Minterval& intersection_of ( const r_Minterval&, const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& intersection_with ( const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& operator*= ( const r_Minterval&)
+ throw( r_Edim_mismatch, r_Eno_interval);
+ ///
+ r_Minterval create_intersection ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval operator* ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ //@}
+
+ //@Man: Methods/Operators for the closure operation:
+ //@{
+ ///
+ r_Minterval& closure_of ( const r_Minterval&, const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval& closure_with ( const r_Minterval& )
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ r_Minterval create_closure ( const r_Minterval& ) const
+ throw( r_Edim_mismatch, r_Eno_interval );
+ ///
+ //@}
+
+ /// writes the state of the object to the specified stream
+ void print_status( std::ostream& s = std::cout ) const;
+
+ /// gives back the string representation
+ char* get_string_representation() const;
+ /**
+ The string representation delivered by this method is allocated using {\tt malloc()} and
+ has to be free unsing {\tt free()} in the end. It can be used to construct a {\tt r_Minterval}
+ again with a special constructor provided. The string representation is build using
+ {\tt print_status()}.
+ */
+
+ //@Man: Methods for internal use only:
+ //@{
+ /// calculate number of cells
+ r_Area cell_count() const throw(r_Error);
+ /// calculate offset in cells for one dimensional access (dimension ordering is high first)
+ r_Area cell_offset( const r_Point& ) const throw( r_Eindex_violation, r_Error );
+ /// calculate point index out of offset
+ r_Point cell_point( r_Area ) const throw( r_Eno_cell, r_Error );
+ /// delete the specified dimension
+ void delete_dimension( r_Dimension ) throw( r_Eindex_violation );
+ /// calculate the size of the storage space occupied
+ r_Bytes get_storage_size( ) const;
+ ///
+ //@}
+
+ protected:
+ /// array for storing the intervals
+ r_Sinterval* intervals;
+
+ /// dimensionality of the domain
+ r_Dimension dimensionality;
+
+ /// number of components initialized already
+ r_Dimension streamInitCnt;
+
+ /// initialization for constructors which take chars
+ void constructorinit(char* ) throw(r_Eno_interval);
+};
+
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Minterval}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Minterval& d );
+
+#include "raslib/minterval.icc"
+
+#endif
diff --git a/raslib/minterval.icc b/raslib/minterval.icc
new file mode 100644
index 0000000..aec847f
--- /dev/null
+++ b/raslib/minterval.icc
@@ -0,0 +1,138 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INLINE SOURCE: minterval.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_Minterval
+ *
+ * COMMENTS:
+ *
+*/
+
+// -*-C++-*- (for Emacs)
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+inline r_Dimension
+r_Minterval::dimension() const
+{
+ return dimensionality;
+}
+
+inline const bool
+r_Minterval::is_origin_fixed() const
+{
+ bool retval=true;
+
+ if(!dimensionality)
+ {
+ retval=false;
+ }
+ else
+ {
+ for(r_Dimension i=0; i < dimensionality; i++)
+ retval &= intervals[i].is_low_fixed();
+ }
+
+ return retval;
+}
+
+inline const bool
+r_Minterval::is_high_fixed() const
+{
+ bool retval=true;
+
+ if(!dimensionality)
+ {
+ //we have an uninitialized interval
+ retval=false;
+ }
+ else
+ {
+ for(r_Dimension i=0; i < dimensionality; i++)
+ retval &= intervals[i].is_high_fixed();
+ }
+
+ return retval;
+}
+
+
+
+inline const bool
+r_Minterval::covers( const r_Point& pnt ) const
+ {
+ bool retval = true;
+ if (dimensionality == pnt.dimension())
+ {
+ for (r_Dimension i = 0; i < pnt.dimension(); i++)
+ {
+ if ((intervals[i].is_low_fixed() && pnt[i] < intervals[i].low()) || (intervals[i].is_high_fixed() && pnt[i] > intervals[i].high()))
+ {
+ retval = false;
+ break;
+ }
+ }
+ }
+ else {
+ RMInit::logOut << "r_Minterval::covers(" << pnt << ") dimensions do not match" << endl;
+ retval=false;
+ }
+
+ return retval;
+ }
+
+
+inline const bool
+r_Minterval::covers( const r_Minterval& inter2 ) const
+ {
+ bool retval = true;
+ if (dimensionality == inter2.dimension())
+ {
+ for (r_Dimension i = 0; i < dimensionality ; i++)
+ {
+ // first check if i am low fixed and the other isn't: false
+ // both are low fixed
+ // check if i am smaller than the other: false
+ // second check if i am high fixed and the other isn't: false
+ // both are high fixed
+ // check if i am smaller than the other: false
+ if (
+ (intervals[i].is_low_fixed() && (!(inter2[i].is_low_fixed()) || intervals[i].low() > inter2[i].low()))
+ ||
+ (intervals[i].is_high_fixed() && (!(inter2[i].is_high_fixed()) || intervals[i].high() < inter2[i].high()))
+ )
+ {
+ retval = false;
+ break;
+ }
+ }
+ }
+ else {
+ RMInit::logOut << "r_Minterval::covers(" << inter2 << ") dimensions do not match" << endl;
+ retval=false;
+ }
+
+ return retval;
+ }
+
diff --git a/raslib/mintervaltype.cc b/raslib/mintervaltype.cc
new file mode 100644
index 0000000..beff527
--- /dev/null
+++ b/raslib/mintervaltype.cc
@@ -0,0 +1,80 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Minterval_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/mintervaltype.cc,v 1.6 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/mintervaltype.hh"
+
+r_Minterval_Type::r_Minterval_Type()
+ : r_Type()
+{
+}
+
+r_Minterval_Type::r_Minterval_Type( const r_Minterval_Type& oldObj )
+ : r_Type(oldObj)
+{
+}
+
+bool
+r_Minterval_Type::isMintervalType() const
+ {
+ return true;
+ }
+
+r_Type*
+r_Minterval_Type::clone() const
+{
+ return new r_Minterval_Type( *this );
+}
+
+r_Type::r_Type_Id
+r_Minterval_Type::type_id() const
+{
+ return MINTERVALTYPE;
+}
+
+void
+r_Minterval_Type::convertToLittleEndian(char* cells, r_Area noCells) const
+{
+}
+
+void
+r_Minterval_Type::convertToBigEndian(char* cells, r_Area noCells) const
+{
+}
+
+void
+r_Minterval_Type::print_status( std::ostream& s ) const
+{
+ s << "minterval";
+}
+
+r_Minterval_Type::~r_Minterval_Type()
+{
+}
+
+std::ostream &operator<<( std::ostream &str, const r_Minterval_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/mintervaltype.hh b/raslib/mintervaltype.hh
new file mode 100644
index 0000000..9f3f620
--- /dev/null
+++ b/raslib/mintervaltype.hh
@@ -0,0 +1,79 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: mintervaltype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Minterval_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_MINTERVAL_TYPE_
+#define _D_MINTERVAL_TYPE_
+
+#include "raslib/type.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents the multidimensional interval type in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+class r_Minterval_Type : public r_Type
+{
+public:
+ /// default constructor
+ r_Minterval_Type();
+
+ /// copy constructor
+ r_Minterval_Type( const r_Minterval_Type& oldObj );
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const;
+
+ virtual bool isMintervalType() const;
+
+ /// destructor
+ ~r_Minterval_Type();
+};
+
+//@Doc: write the status of a minterval type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Minterval_Type &type );
+
+#endif
+
diff --git a/raslib/miter.cc b/raslib/miter.cc
new file mode 100644
index 0000000..35acb54
--- /dev/null
+++ b/raslib/miter.cc
@@ -0,0 +1,33 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: miter.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Miter
+ *
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Miter: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/miter.cc,v 1.5 2003/12/27 23:01:21 rasdev Exp $";
+
+// moved everything to miter.icc
diff --git a/raslib/miter.hh b/raslib/miter.hh
new file mode 100644
index 0000000..98ee03c
--- /dev/null
+++ b/raslib/miter.hh
@@ -0,0 +1,99 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: miter.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Miter
+ *
+*/
+
+#ifndef _D_MITER_
+#define _D_MITER_
+
+class r_Minterval;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ r_Miter is used for iterating through parts of
+ multidimensional intervals. It is given the domain of
+ the object to be iterated through, the size of the base
+ base type, the address of the first cell in the Tile and
+ an Minterval specifying the area to be iterated through.
+
+ Going to the next cell is done with nextCell() which
+ returns the adress of the next cell. Test for the end
+ is done with isDone(). The iterator can be reset with
+ reset().
+*/
+
+class r_Miter
+{
+public:
+ /// constructor.
+ inline r_Miter( const r_Minterval* newAreaIter,
+ const r_Minterval* newAreaTile, r_Bytes newCellSize,
+ const char* newFirstCell );
+ /**
+ The pointers are stored, do not delete the objects as long
+ as the iterator is used!
+ */
+
+ /// destructor.
+ inline ~r_Miter();
+ /// resets iterator to first cell.
+ inline void reset();
+ /// returns current cell and sets iterator to next cell.
+ inline char* nextCell();
+ /// returns TRUE if iteration is finished.
+ inline bool isDone();
+protected:
+ // structure storing information on iteration for each dimension
+ // (perhaps add dimension for reordering later)
+ typedef struct {
+ int repeat; // total number of repeats
+ int inc; // increment per repeat
+ int curr; // current repeat
+ } incArrElem;
+ /// area to be iterated through
+ const r_Minterval* areaIter;
+ /// area of tile.
+ const r_Minterval* areaTile;
+ /// size of base type.
+ r_Bytes cellSize;
+ /// offset of first cell in tile.
+ const char* firstCell;
+ /// array with increments
+ incArrElem* incArrIter;
+ /// flag set if iteration is finished.
+ bool done;
+ /// current cell for iteration;
+ char* currCell;
+ /// counter for position in lowest dimension.
+ int lowCount;
+};
+
+#include "miter.icc"
+
+#endif
diff --git a/raslib/miter.icc b/raslib/miter.icc
new file mode 100644
index 0000000..f4578d2
--- /dev/null
+++ b/raslib/miter.icc
@@ -0,0 +1,144 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: miter.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Miter
+ *
+*/
+
+#include "raslib/miter.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rmdebug.hh"
+
+inline
+r_Miter::r_Miter( const r_Minterval* newAreaIter,
+ const r_Minterval* newAreaTile,
+ r_Bytes newCellSize, const char* newFirstCell )
+ : areaIter(newAreaIter), areaTile(newAreaTile), cellSize(newCellSize),
+ firstCell(newFirstCell), done(false)
+{
+ RMDBGENTER(1, RMDebug::module_raslib, "r_Miter", "r_Miter()");
+ // the following initializes incArrIter and calculates the first offset
+ int tIncIter = 1; // total increment for current dimension
+ int prevTIncIter = 1; // total increment for previous dimension
+ r_Bytes incIter = cellSize; // current increment
+ r_Dimension i;
+ int firstOff = 0;
+
+ RMDBGMIDDLE(2, RMDebug::module_raslib, "r_Miter", "area for iteration: " << *newAreaIter);
+ RMDBGMIDDLE(2, RMDebug::module_raslib, "r_Miter", "whole area: " << *newAreaTile);
+
+ // dimensionality of both areaIter and areaTile
+ r_Dimension dim = areaIter->dimension();
+ // stores the increments
+ incArrIter = new incArrElem[dim];
+
+ for( i=0; i<dim; i++ ) {
+ // in RasDaMan the order of dimensions is the other way round!
+ int r = dim - i - 1;
+ // used for counting in iteration, initialize with 0
+ incArrIter[i].curr = 0;
+ // how often is the increment added?
+ incArrIter[i].repeat = (*areaIter)[r].high() - (*areaIter)[r].low() + 1;
+ RMDBGMIDDLE(4, RMDebug::module_raslib, "r_Miter", "repeat dim " << i << ": " << incArrIter[i].repeat );
+ // the increment for the result tile (higher dimensions calculated
+ // further down)
+ incArrIter[i].inc = incIter;
+ RMDBGMIDDLE(4, RMDebug::module_raslib, "r_Miter", "incIter dim " << i << ": " << incIter );
+
+ // calculate starting offset and increments for higher dimensions
+ // firstOff is the offset in chars of the first cell
+ firstOff += ((*areaIter)[r].low()-(*areaTile)[r].low()) * prevTIncIter * cellSize;
+ // tInc is the increment if the dimension would be skipped
+ tIncIter = ((*areaTile)[r].high()-(*areaTile)[r].low()+1) * prevTIncIter;
+ // inc is the real increment, after some cells in the dimensions
+ // have been iterated through.
+ incIter = (tIncIter - incArrIter[i].repeat*prevTIncIter) * cellSize;
+ // remember total increment of last dimension
+ prevTIncIter = tIncIter;
+ }
+ firstCell += firstOff;
+ reset();
+ RMDBGEXIT(1, RMDebug::module_raslib, "r_Miter", "r_Miter()");
+}
+
+inline
+r_Miter::~r_Miter()
+{
+ delete [] incArrIter;
+}
+
+inline void
+r_Miter::reset()
+{
+ currCell = (char*)firstCell;
+ done = false;
+ lowCount = 0;
+ for( r_Dimension i=0; i<areaIter->dimension(); i++ ) {
+ incArrIter[i].curr = 0;
+ }
+}
+
+inline char*
+r_Miter::nextCell()
+{
+ // return the current cell
+ char* retVal = currCell;
+ r_Dimension i = 0;
+
+ if(done)
+ return retVal;
+
+ // increment adresses
+ currCell += incArrIter[0].inc;
+ lowCount++;
+ if(lowCount == incArrIter[0].repeat) {
+ lowCount = 0;
+ // increment other dimensions
+ for(i=1; i < areaIter->dimension(); i++) {
+ incArrIter[i].curr++;
+ currCell += incArrIter[i].inc;
+ if(incArrIter[i].curr < incArrIter[i].repeat) {
+ // no overflow in this dimension
+ break;
+ } else {
+ // overflow in this dimension
+ incArrIter[i].curr = 0;
+ }
+ }
+ if( i == areaIter->dimension() ) {
+ // overflow in last dimension
+ done = true;
+ currCell = retVal;
+ }
+ }
+ return retVal;
+}
+
+bool
+r_Miter::isDone()
+{
+ return done;
+}
diff --git a/raslib/mitera.cc b/raslib/mitera.cc
new file mode 100644
index 0000000..b92cb72
--- /dev/null
+++ b/raslib/mitera.cc
@@ -0,0 +1,141 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: mitera.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_MiterArea
+ *
+*/
+
+#include "raslib/mitera.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rmdebug.hh"
+
+r_MiterArea::r_MiterArea( const r_Minterval* newIterDom,
+ const r_Minterval* newImgDom ) throw(r_Error)
+ : iterDom(newIterDom), imgDom(newImgDom), done(false)
+{
+ RMDBGENTER( 1, RMDebug::module_raslib, "r_MiterArea", "r_MiterArea()");
+
+ if (imgDom->dimension() != iterDom->dimension())
+ {
+ //in this case we have an undefined situation
+ RMInit::logOut << "r_MiterArea::rMiterArea(" << iterDom << ", " << imgDom << ") dimension mismatch" << endl;
+ throw r_Error(INTERVALSWITHDIFFERENTDIMENSION);
+ }
+
+ if(!imgDom->is_origin_fixed() ||
+ !imgDom->is_high_fixed())
+ {
+ //in this case we have an undefined situation
+ RMInit::logOut << "r_MiterArea::rMiterArea(" << iterDom << ", " << imgDom << ") imgDom is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ if(!iterDom->is_origin_fixed() ||
+ !iterDom->is_high_fixed())
+ {
+ //in this case we have an undefined situation
+ RMInit::logOut << "r_MiterArea::rMiterArea(" << iterDom << ", " << imgDom << ") iterDom is opened" << endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+
+ // dimensionality of both iterDom and imgDom
+ r_Dimension dim = imgDom->dimension();
+ // stores the increments
+ incArrIter = new incArrElem[dim];
+
+ for(r_Dimension i=0; i<dim; i++ ) {
+ // used for counting in iteration, initialize with 0
+ incArrIter[i].curr = 0;
+ // how often is the iterDom moved inside the imgDom
+ incArrIter[i].repeat = (imgDom->get_extent()[i] / iterDom->get_extent()[i]) +
+ ( imgDom->get_extent()[i] % iterDom->get_extent()[i] != 0 );
+
+ RMDBGMIDDLE( 4, RMDebug::module_raslib, "r_MiterArea", "repeat dim " << i << ": " << incArrIter[i].repeat );
+ }
+ reset();
+ RMDBGEXIT( 1, RMDebug::module_raslib, "r_MiterArea", "r_MiterArea()" );
+}
+
+
+r_MiterArea::~r_MiterArea()
+{
+ delete [] incArrIter;
+}
+
+void
+r_MiterArea::reset()
+{
+ done = false;
+ for( int i=0; i<iterDom->dimension(); i++ ) {
+ incArrIter[i].curr = 0;
+ }
+}
+
+r_Minterval
+r_MiterArea::nextArea()
+{
+ r_Dimension i = 0;
+
+ if(done)
+ return retVal;
+
+ r_Minterval currDom(iterDom->dimension());
+
+ // calculate new result domain here
+ if(!done) {
+ for(i=0; i < iterDom->dimension(); i++) {
+ currDom << r_Sinterval( (*imgDom)[i].low() + incArrIter[i].curr*iterDom->get_extent()[i],
+ (*imgDom)[i].low() + (incArrIter[i].curr+1)*iterDom->get_extent()[i]
+ - 1 );
+ }
+ }
+ retVal = currDom.intersection_with((*imgDom));
+
+ // increment dimensions
+ for(i=0; i < iterDom->dimension(); i++) {
+ incArrIter[i].curr++;
+ if(incArrIter[i].curr < incArrIter[i].repeat) {
+ // no overflow in this dimension
+ break;
+ } else {
+ // overflow in this dimension
+ incArrIter[i].curr = 0;
+ }
+ }
+ if( i == iterDom->dimension() ) {
+ // overflow in last dimension
+ done = true;
+ }
+
+ return retVal;
+}
+
+bool
+r_MiterArea::isDone()
+{
+ return done;
+}
diff --git a/raslib/mitera.hh b/raslib/mitera.hh
new file mode 100644
index 0000000..3784e44
--- /dev/null
+++ b/raslib/mitera.hh
@@ -0,0 +1,92 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: mitera.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_MiterArea
+ *
+*/
+
+#ifndef _D_MITERA_
+#define _D_MITERA_
+
+#include "raslib/minterval.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ r_MiterArea is used for iterating r_Mintervals through larger
+ r_Mintervals. It is given the domain to be iterated through and
+ an Minterval specifying the shape of area to be iterated with.
+
+
+ Going to the next area is done with nextArea() which returns an
+ r_Minterval. Test for the end is done with isDone(). The
+ iterator can be reset with reset(). Iteration starts at the
+ lowest border in all dimensions. Note that if the shape of
+ r_Minterval iterated does not completely fit into the
+ r_Minterval iterated through the results at the border may have
+ a different (smaller) shape.
+*/
+
+class r_MiterArea
+{
+public:
+ /// constructor.
+ /// An exception is thrown if newIterDom and newImgDom have different dimension
+ r_MiterArea( const r_Minterval* newIterDom,
+ const r_Minterval* newImgDom ) throw(r_Error);
+ /**
+ The pointers are stored, do not delete the objects as long
+ as the iterator is used!
+ */
+
+ /// destructor.
+ ~r_MiterArea();
+ /// resets iterator to beginning.
+ void reset();
+ /// returns current cell and sets iterator to next cell.
+ r_Minterval nextArea();
+ /// returns TRUE if iteration is finished.
+ bool isDone();
+protected:
+ // structure storing information on iteration for each dimension
+ // (perhaps add dimension for reordering later)
+ typedef struct {
+ int repeat; // total number of repeats
+ int curr; // current repeat
+ } incArrElem;
+ /// area to be iterated through
+ const r_Minterval* iterDom;
+ /// area of tile.
+ const r_Minterval* imgDom;
+ /// array with increments
+ incArrElem* incArrIter;
+ /// flag set if iteration is finished.
+ bool done;
+ /// This is used for the return value in nextArea()
+ r_Minterval retVal;
+};
+
+#endif
diff --git a/raslib/miterd.cc b/raslib/miterd.cc
new file mode 100644
index 0000000..d50c50a
--- /dev/null
+++ b/raslib/miterd.cc
@@ -0,0 +1,117 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: miterd.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Miter
+ *
+*/
+
+#include <iostream>
+
+#include "raslib/miterd.hh"
+#include "raslib/minterval.hh"
+
+
+
+r_MiterDirect::r_MiterDirect(void *data, const r_Minterval &total, const r_Minterval &iter, unsigned int tlen, unsigned int step)
+ : done(false),
+ dim(total.dimension()),
+ length(step),
+ id(NULL),
+ baseAddress(data)
+{
+ int i = 0;
+ r_Range s = tlen;
+ r_Range offset = 0;
+
+ id=new r_miter_direct_data[dim];
+
+ for (i=(int)dim-1; i>=0; i--)
+ {
+ id[i].low = iter[i].low();
+ id[i].high = iter[i].high();
+ id[i].pos = id[i].low;
+ id[i].origin = total[i].low();
+ id[i].extent = (total[i].high() - total[i].low() + 1);
+ id[i].baseStep = s;
+ id[i].step = s * step;
+ offset += s * (id[i].pos - id[i].origin);
+ s *= id[i].extent;
+ }
+ for (i=0; i<(int)dim; i++)
+ {
+ id[i].data = (void*)(((r_Octet*)data) + offset);
+ }
+}
+
+r_MiterDirect::~r_MiterDirect(void)
+{
+ delete [] id;
+}
+
+
+void r_MiterDirect::reset(void)
+{
+ r_Dimension i = 0;
+ r_ULong offset = 0;
+
+ for (i=0; i<dim; i++)
+ {
+ id[i].pos = id[i].low;
+ offset += id[i].step * (id[i].low - id[i].origin);
+ }
+ for (i=0; i<dim; i++)
+ {
+ id[i].data = (void*)(((r_Octet*)baseAddress) + offset);
+ }
+ done = false;
+}
+
+
+void
+r_MiterDirect::print_pos(std::ostream &str) const
+{
+ str << '[' << id[0].pos;
+ for (r_Dimension i=1; i<dim; i++) str << ',' << id[i].pos;
+ str << ']';
+}
+
+
+
+std::ostream &operator<<(std::ostream &str, const r_MiterDirect &iter)
+{
+ iter.print_pos(str);
+ return str;
+}
+
+r_miter_direct_data::r_miter_direct_data()
+:data(NULL), pos(0), low(0), high(0),
+ step(0), baseStep(0), extent(0), origin(0)
+{
+}
+
+r_miter_direct_data::~r_miter_direct_data()
+{
+}
diff --git a/raslib/miterd.hh b/raslib/miterd.hh
new file mode 100644
index 0000000..a4c26d1
--- /dev/null
+++ b/raslib/miterd.hh
@@ -0,0 +1,165 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: miterd.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_MiterDirect
+ *
+*/
+
+#ifndef _R_MITERD_
+#define _R_MITERD_
+
+#include "raslib/mddtypes.hh"
+#include "raslib/odmgtypes.hh"
+
+#include <iosfwd>
+
+class r_Minterval;
+
+class r_miter_direct_data;
+
+//@ManMemo: Module {\bf raslib}
+
+/*@Doc:
+ r_MiterDirect is similar to r_Miter, but allows stepping by more
+ than one cell in each direction, arbitrary order of dimensions in
+ the iteration and has a lot of its internal state variables as public
+ members.
+ It should be used in low-level, very time-critical code like
+ folding operations which would otherwise require construction
+ of a new iterator for each cell when only position and base
+ address need to change.
+*/
+
+class r_MiterDirect
+{
+ public:
+ /// constructor
+ r_MiterDirect(void *data, const r_Minterval &total, const r_Minterval &iter,
+ r_Bytes tlen, unsigned int step=1);
+ /**
+ constructor getting the data, the total domain, the iteration
+ domain, the base type length and the number of steps per
+ iteration.
+ */
+
+ /// destructor
+ ~r_MiterDirect(void);
+
+ /// increment the iterator in the default order, i.e. last dimension first
+ inline r_MiterDirect &operator++(void);
+ /// increment in user-specified order
+ inline r_MiterDirect &iterateUserOrder(const r_Dimension *order, const unsigned int *step);
+ /**
+ increment the iterator in a user-specified order. order points to an array
+ defining the order of the dimensions during iteration, e.g. for a 3D
+ iteration 0,1,2 would iterate over the first dimension first and the
+ last dimension last wheres 2,1,0 is equivalent to operator++(). step
+ is the number of steps to do in each dimension.
+ */
+ /// increment or decrement in user-specified order
+ inline r_MiterDirect &iterateUserOrder(const unsigned int *order, const int *step);
+ /**
+ see the other incrementUserOrder method for more details
+ */
+
+ /// returns != 0 if iteration is finished.
+ inline bool isDone(void) const;
+ /// returns pointer to data during normal iteration.
+ inline void* getData(void);
+ /// return pointer to data for non-standard iteration order
+ inline void* getData(unsigned int *order);
+ /**
+ returns pointer to data during user-defined iteration; order is as
+ defined in iterateUserOrder().
+ */
+ /// returns number of bytes to step in dimension d in one iteration
+ inline r_Range getDimStep(r_Dimension d) const;
+ /// returns number of bytes to step in dimension d when pos changes by 1.
+ inline r_Bytes getDimBaseStep(r_Dimension d) const;
+ /// returns extent in dimension d
+ inline r_Range getExtent(r_Dimension d) const;
+ /// notify that the position was changed and internal variables need to be recalculated
+ inline void posChanged( void );
+ /// reset the iterator (pos to low and data to baseAddress + offset)
+ void reset(void);
+ /// print the position
+ void print_pos(std::ostream &str) const;
+
+ bool done;
+ r_miter_direct_data* id;
+ void* baseAddress;
+
+ private:
+
+ /// if this data should change you must construct a new iterator,
+ /// therefore no public access.
+ r_Dimension dim;
+ r_ULong length;
+};
+
+
+
+/*@Doc:
+ r_miter_direct_data encapsulates data for each dimension.
+ It's an auxiliary class for r_MiterDirect. The only reason
+ not to make it a simple struct was data protection.
+ */
+
+class r_miter_direct_data
+{
+ friend class r_MiterDirect;
+
+ public:
+
+ r_miter_direct_data();
+ ~r_miter_direct_data();
+
+ /// Data concerning the iteration position and domain. May
+ /// be changed by the user.
+ void *data;
+ r_Range pos;
+ r_Range low;
+ r_Range high;
+
+ private:
+
+ /// Data concerning the domain of the source object. Is fixed
+ /// in the constructor.
+ r_Range step;
+ r_Range baseStep;
+ r_Range extent;
+ r_Range origin;
+};
+
+
+/// overloaded stream operator
+extern std::ostream &operator<<(std::ostream &str, const r_MiterDirect &iter);
+
+
+
+#include "raslib/miterd.icc"
+
+#endif
diff --git a/raslib/miterd.icc b/raslib/miterd.icc
new file mode 100644
index 0000000..a30ec98
--- /dev/null
+++ b/raslib/miterd.icc
@@ -0,0 +1,166 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/* ------------------------------------------------------------------------ */
+// r_MiterDirect inline functions
+
+inline bool r_MiterDirect::isDone( void ) const
+{
+ return done;
+}
+
+inline void *r_MiterDirect::getData( void )
+{
+ return id[dim-1].data;
+}
+
+inline void *r_MiterDirect::getData( unsigned int *order )
+{
+ return id[order[0]].data;
+}
+
+inline r_Range r_MiterDirect::getDimStep( r_Dimension d ) const
+{
+ return id[d].step;
+}
+
+inline r_Bytes r_MiterDirect::getDimBaseStep( r_Dimension d ) const
+{
+ return id[d].baseStep;
+}
+
+inline r_Range r_MiterDirect::getExtent( r_Dimension d ) const
+{
+ return id[d].extent;
+}
+
+inline r_MiterDirect&
+r_MiterDirect::operator++(void)
+{
+ int d = (int)dim-1;
+
+ while (d >= 0)
+ {
+ id[d].pos += length;
+ id[d].data = (void*)(((char*)(id[d].data)) + id[d].step);
+ if (id[d].pos <= id[d].high) break;
+ id[d].pos = id[d].low;
+ d--;
+ }
+ if (d >= 0)
+ {
+ int i;
+
+ for (i=d+1; i < (int)dim; i++)
+ {
+ id[i].data = id[d].data;
+ }
+ }
+ else
+ done = true;
+
+ return *this;
+}
+
+inline r_MiterDirect&
+r_MiterDirect::iterateUserOrder(const unsigned int *order, const int *step)
+{
+ r_Dimension d = 0;
+
+ while (d < dim)
+ {
+ r_miter_direct_data *idp = id + order[d];
+
+ idp->pos += step[d];
+ idp->data = (void*)(((char*)(idp->data)) + step[d] * idp->baseStep);
+ if (idp->pos <= idp->high) break;
+ idp->pos = idp->low;
+ d++;
+ }
+ if (d < dim)
+ {
+ r_Dimension i;
+ void *newData = id[order[d]].data;
+
+ for (i=d; i > 0; i--)
+ {
+ id[order[i-1]].data = newData;
+ }
+ }
+ else
+ done = true;
+
+ return *this;
+}
+
+inline r_MiterDirect&
+r_MiterDirect::iterateUserOrder(const r_Dimension *order, const unsigned int *step)
+{
+ r_Dimension d = 0;
+
+ while (d < dim)
+ {
+ r_miter_direct_data *idp = id + order[d];
+
+ idp->pos += step[d];
+ idp->data = (void*)(((char*)(idp->data)) + step[d] * idp->baseStep);
+ if (step[d] > 0)
+ {
+ if (idp->pos <= idp->high) break;
+ idp->pos = idp->low;
+ }
+ else
+ {
+ if (idp->pos >= idp->low) break;
+ idp->pos = idp->high;
+ }
+ d++;
+ }
+ if (d < dim)
+ {
+ r_Dimension i;
+ void *newData = id[order[d]].data;
+
+ for (i=d; i>0; i--)
+ {
+ id[order[i-1]].data = newData;
+ }
+ }
+ else
+ done = true;
+
+ return *this;
+}
+
+
+inline void
+r_MiterDirect::posChanged( void )
+{
+ r_Range offset = 0;
+ r_Dimension i = 0;
+
+ for (i=0; i<dim; i++)
+ offset += id[i].step * (id[i].pos - id[i].origin);
+
+ for (i=0; i<dim; i++)
+ id[i].data = (void*)(((char*)baseAddress) + offset);
+}
diff --git a/raslib/miterf.hh b/raslib/miterf.hh
new file mode 100644
index 0000000..18f38b6
--- /dev/null
+++ b/raslib/miterf.hh
@@ -0,0 +1,128 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: miter.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_MiterFloat
+ *
+*/
+
+#ifndef _D_MITERF_
+#define _D_MITERF_
+
+class r_Minterval;
+
+
+#include "raslib/mddtypes.hh"
+
+class r_FixedPointNumber
+ {
+ public:
+ inline r_FixedPointNumber();
+ inline r_FixedPointNumber(const double&);
+
+ inline r_FixedPointNumber& operator=(const r_FixedPointNumber&);
+ inline r_FixedPointNumber& operator=(const double&);
+
+ // returns intPart_new - intPart_old -- used for tests
+ inline r_Range stepForward(const r_FixedPointNumber&);
+
+ // returns carry of fracPart
+ inline bool stepForwardFlag(const r_FixedPointNumber&);
+
+ inline r_Range getIntPart();
+
+ private:
+ inline void init(const double&);
+
+ r_Range intPart;
+ r_Range fracPart;
+
+ static const int FIXPREC;
+ static const r_Range carryPos;
+ static const r_Range fracMask;
+ static const double fixOne;
+
+ friend std::ostream& operator<<(std::ostream&,r_FixedPointNumber&);
+ };
+
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ r_MiterFloat is used for iterating through parts of
+ multidimensional intervals with arbitrary stepping size using
+ nearest neighbours. It is given the tile, the source domain
+ and the destination domain
+ Apart from that behaviour is exactly as in r_Miter.
+
+*/
+
+class r_MiterFloat
+ {
+ public:
+ /// Constructor getting the source tile, the source domain and the destination domain
+ inline r_MiterFloat(Tile *sourceTile, r_Minterval& sourceDomain, r_Minterval& destDomain);
+
+ /// destructor
+ inline ~r_MiterFloat();
+
+ /// iterator reset
+ inline void reset();
+
+ /// get the next cell
+ inline char* nextCell();
+
+ /// true if done
+ inline bool isDone();
+
+ protected:
+ struct iter_desc
+ {
+ r_FixedPointNumber min;
+ r_FixedPointNumber pos;
+ r_FixedPointNumber step;
+
+ r_Range countSteps;
+ r_Range maxSteps;
+
+ r_Range dimStep;
+ r_Range scaleStep;
+ char *cell;
+ };
+
+ r_Dimension dim;
+ char *currentCell;
+ const char *firstCell;
+
+ iter_desc *iterDesc;
+
+ bool done;
+ };
+
+
+#include "miterf.icc"
+
+#endif
diff --git a/raslib/miterf.icc b/raslib/miterf.icc
new file mode 100644
index 0000000..dad1b2e
--- /dev/null
+++ b/raslib/miterf.icc
@@ -0,0 +1,222 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: miterf.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_MiterFloat
+ *
+*/
+
+#include "raslib/miterf.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rmdebug.hh"
+
+#include <math.h>
+
+
+const int r_FixedPointNumber::FIXPREC = 30;
+const r_Range r_FixedPointNumber::carryPos = 1<<FIXPREC;
+const r_Range r_FixedPointNumber::fracMask = carryPos-1;
+const double r_FixedPointNumber::fixOne = pow(2,(double)FIXPREC);
+
+inline
+r_FixedPointNumber::r_FixedPointNumber()
+ {
+ intPart=0; fracPart=0;
+ }
+
+inline
+r_FixedPointNumber::r_FixedPointNumber(const double &d)
+ { init(d);
+ }
+
+inline
+r_FixedPointNumber& r_FixedPointNumber::operator=(const r_FixedPointNumber &f)
+ {
+ intPart = f.intPart;
+ fracPart = f.fracPart;
+ return *this;
+ }
+
+inline
+r_FixedPointNumber& r_FixedPointNumber::operator=(const double &d)
+ {
+ init(d);
+ return *this;
+ }
+
+inline
+void r_FixedPointNumber::init(const double &d)
+ {
+ intPart = (r_Range)d;
+
+ fracPart= (r_Range)fmod(fixOne*d,fixOne);
+
+ }
+
+inline
+r_Range r_FixedPointNumber::stepForward(const r_FixedPointNumber &f)
+ {
+ r_Range oldIntPart = intPart;
+
+ intPart+=f.intPart; fracPart+=f.fracPart;
+
+ if(fracPart & carryPos)
+ {
+ intPart++;
+ fracPart &= fracMask;
+
+ }
+ return intPart-oldIntPart;
+ }
+
+inline
+bool r_FixedPointNumber::stepForwardFlag(const r_FixedPointNumber &f)
+ {
+ intPart+=f.intPart; fracPart+=f.fracPart;
+
+ if(fracPart & carryPos)
+ {
+ intPart++;
+ fracPart &= fracMask;
+ return true;
+ }
+ return false;
+ }
+
+inline
+r_Range r_FixedPointNumber::getIntPart()
+ {
+ return intPart;
+ }
+
+inline
+std::ostream& operator<<(std::ostream &os,r_FixedPointNumber &f)
+ { os<<'('<<f.intPart<<':'<<f.fracPart<<')';
+ return os;
+ }
+
+//######################################
+
+inline
+r_MiterFloat::r_MiterFloat(Tile *sourceTile, r_Minterval& sourceDomain, r_Minterval& destDomain)
+ {
+ dim = sourceDomain.dimension();
+ iterDesc = new iter_desc[dim];
+
+ r_Bytes cellSize = sourceTile->getType()->getSize();
+ firstCell = sourceTile->getContents();
+
+ iter_desc *id = 0;
+ const r_Minterval& tileDomain = sourceTile->getDomain();
+
+ int i = 0;
+ r_Bytes step = cellSize;
+
+ id = iterDesc + dim-1;
+
+ for(i=dim-1; i>=0; i--, id-- )
+ {
+ id->min = (double)sourceDomain[i].low();
+ id->step = (double)(sourceDomain[i].high()-sourceDomain[i].low() +1) / ( destDomain[i].high() - destDomain[i].low()+1);
+ id->maxSteps = destDomain[i].high() - destDomain[i].low()+1;
+ id->dimStep = step;
+ id->scaleStep = step * id->step.getIntPart();
+ firstCell += step* (sourceDomain[i].low() - tileDomain[i].low());
+ step *= (tileDomain[i].high() - tileDomain[i].low() + 1);
+ }
+ reset();
+ }
+
+inline
+r_MiterFloat::~r_MiterFloat()
+ {
+ if(iterDesc) delete[] iterDesc;
+ }
+
+inline
+void r_MiterFloat::reset()
+ {
+ for(r_Dimension i=0;i<dim;i++)
+ {
+ iterDesc[i].pos = iterDesc[i].min;
+ iterDesc[i].cell = (char*)firstCell;
+ iterDesc[i].countSteps = iterDesc[i].maxSteps;
+ }
+
+ done=false;
+ }
+
+inline
+char* r_MiterFloat::nextCell()
+ {
+ if(done) return currentCell;
+
+ r_Dimension i = dim;
+ iter_desc *id = iterDesc + dim -1;
+ currentCell = iterDesc[dim-1].cell;
+
+ while( i>0 )
+ {
+ id->countSteps--;
+
+ if(id->countSteps)
+ {// one more step in this dimension
+ if(id->pos.stepForwardFlag(id->step))
+ id->cell += id->dimStep;
+
+ id->cell += id->scaleStep;
+ break;
+ }
+ else
+ { // we are finished with this dimension
+ id->pos = id->min;
+ id->countSteps = id-> maxSteps;
+ id--;
+ i--;
+ }
+ }
+
+ if(i<dim)
+ {
+ if(i == 0)
+ done = true;
+ else
+ {
+ r_Dimension j;
+ for( j=i; j<dim; j++)
+ iterDesc[j].cell = iterDesc[i-1].cell;
+ }
+ }
+ return currentCell;
+ }
+
+inline
+bool r_MiterFloat::isDone()
+ {
+ return done;
+ }
+
+
+
diff --git a/raslib/odmgtypes.hh b/raslib/odmgtypes.hh
new file mode 100644
index 0000000..21354e9
--- /dev/null
+++ b/raslib/odmgtypes.hh
@@ -0,0 +1,204 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: odmgtypes.hh
+ *
+ * MODULE: rasodmg
+ *
+ * PURPOSE:
+ * The file contains ODMG type definitions.
+ *
+ * COMMENTS:
+ * For further porting please adapt the typedef for r_Long and r_Ulong
+*/
+
+#ifndef _D_ODMGTYPES_
+#define _D_ODMGTYPES_
+
+// for type-limits
+#include <limits.h>
+#include <float.h>
+
+//@Man: r_Char
+//@Type: typedef
+//@Args: as unsigned char (1 byte)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef unsigned char r_Char;
+
+/**
+ {\tt typedef unsigned char r_Char;}
+*/
+
+
+
+//@Man: r_Octet
+//@Type: typedef
+//@Args: as signed char (1 byte)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef signed char r_Octet;
+
+/**
+ {\tt typedef signed char r_Octet;}
+ (Stroustroup: sign of plain char is implementation-defined)
+*/
+
+
+
+//@Man: r_Short
+//@Type: typedef
+//@Args: as short (2 bytes)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef short r_Short;
+
+/**
+ {\tt typedef short r_Short;}
+*/
+
+
+
+//@Man: r_UShort
+//@Type: typedef
+//@Args: as unsigned short (2 bytes)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef unsigned short r_UShort;
+
+/**
+ {\tt typedef short r_UShort;}
+*/
+
+
+
+//@Man: r_Long
+//@Type: typedef
+//@Args: as long (4 bytes)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef int r_Long;
+/**
+ {\tt typedef int r_Long;}
+*/
+
+
+
+
+
+//@Man: r_ULong
+//@Type: typedef
+//@Args: as unsigned long (4 bytes)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef unsigned int r_ULong;
+/**
+ {\tt typedef unsigned long r_ULong;}
+*/
+
+
+//@Man: r_Float
+//@Type: typedef
+//@Args: as float
+//@Memo: Module: {\bf rasodmg}.
+
+typedef float r_Float;
+
+/**
+ {\tt typedef float r_Float;}
+*/
+
+
+
+//@Man: r_Double
+//@Type: typedef
+//@Args: as double
+//@Memo: Module: {\bf rasodmg}.
+
+typedef double r_Double;
+
+/**
+ {\tt typedef double r_Double;}
+*/
+
+
+
+//@Man: r_Boolean
+//@Type: typedef
+//@Args: as unsigned char (1 byte)
+//@Memo: Module: {\bf rasodmg}.
+
+typedef unsigned char r_Boolean;
+
+/**
+ {\tt typedef unsigned char r_Boolean;}
+ Changed to unsigned char
+*/
+
+
+//@Man: get_limits()
+//@Type: function
+//@Args: as function
+//@Memo: Module: {\bf rasodmg}
+
+inline void get_limits( const r_Octet *tptr, double &min, double &max )
+{
+ min = (double)SCHAR_MIN; max = (double)SCHAR_MAX;
+}
+
+inline void get_limits( const r_Char *tptr, double &min, double &max )
+{
+ min = (double)0.0; max = (double)UCHAR_MAX;
+}
+
+inline void get_limits( const r_Short *tptr, double &min, double &max )
+{
+ min = (double)SHRT_MIN; max = (double)SHRT_MAX;
+}
+
+inline void get_limits( const r_UShort *tptr, double &min, double &max )
+{
+ min = (double)0.0; max = (double)USHRT_MAX;
+}
+
+inline void get_limits( const r_Long *tptr, double &min, double &max )
+{
+ min = (double)INT_MIN; max = (double)INT_MAX;
+}
+
+inline void get_limits( const r_ULong *tptr, double &min, double &max )
+{
+ min = (double)0.0; max = (double)UINT_MAX;
+}
+
+inline void get_limits( const r_Float *tptr, double &min, double &max )
+{
+ min = -((double)FLT_MAX); max = (double)FLT_MAX;
+}
+
+inline void get_limits( const r_Double *tptr, double &min, double &max )
+{
+ min = -((double)DBL_MAX); max = (double)DBL_MAX;
+}
+
+#endif
diff --git a/raslib/oid.cc b/raslib/oid.cc
new file mode 100644
index 0000000..402aeb3
--- /dev/null
+++ b/raslib/oid.cc
@@ -0,0 +1,352 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: oid.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_OId
+ *
+ * COMMENTS:
+ *
+*/
+
+#include "raslib/oid.hh"
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+#include <fstream>
+#include <iomanip>
+#include <string.h>
+#include <stdlib.h>
+
+
+r_OId::r_OId()
+ : oidString(NULL),
+ systemName(NULL),
+ baseName(NULL),
+ localOId(0)
+{
+}
+
+r_OId::r_OId( const char* initOIdString )
+ : oidString(NULL),
+ systemName(NULL),
+ baseName(NULL),
+ localOId(0)
+{
+ // set oidString
+ if( initOIdString )
+ {
+ oidString = new char[ strlen(initOIdString)+1 ];
+ strcpy( oidString, initOIdString );
+
+ //
+ // extract oid parts
+ //
+ char* startPtr = NULL;
+ char* endPtr = NULL;
+
+ // system name
+ startPtr = endPtr = oidString;
+ while( *endPtr != '|' && *endPtr != '\0' ) endPtr++;
+ if( endPtr - startPtr >= 1 )
+ {
+ systemName = new char[ endPtr - startPtr + 1 ];
+ strncpy( systemName, startPtr, endPtr - startPtr );
+ systemName[endPtr - startPtr] = '\0';
+ }
+
+ if( *endPtr != '\0' )
+ {
+ // base name
+ endPtr++;
+ startPtr = endPtr;
+ while( *endPtr != '|' && *endPtr != '\0' ) endPtr++;
+ if( endPtr - startPtr >= 1 )
+ {
+ baseName = new char[ endPtr - startPtr + 1 ];
+ strncpy( baseName, startPtr, endPtr - startPtr );
+ baseName[endPtr - startPtr] = '\0';
+ }
+
+ if( *endPtr != '\0' )
+ {
+ // local oid
+ endPtr++;
+ startPtr = endPtr;
+
+ localOId = atof( startPtr );
+ }
+
+ }
+
+ }
+}
+
+r_OId::r_OId( const char* initSystemName, const char* initBaseName, double initLocalOId )
+ : oidString(NULL),
+ systemName(NULL),
+ baseName(NULL),
+ localOId( initLocalOId )
+{
+ // set members
+ if( initSystemName )
+ {
+ systemName= new char[ strlen(initSystemName)+1 ];
+ strcpy( systemName, initSystemName );
+ }
+
+ if( initBaseName )
+ {
+ baseName= new char[ strlen(initBaseName)+1 ];
+ strcpy( baseName, initBaseName );
+ }
+
+ // allocate buffer which is big enough
+ int bufferSize = ( systemName ? strlen( systemName ) : 0 ) +
+ ( baseName ? strlen( baseName ) : 0 ) +
+ 1024;
+ char* buffer = new char[bufferSize];
+ std::ostrstream oidStream( buffer, bufferSize );
+
+ // write into the string stream
+ if( systemName )
+ oidStream << systemName << "|";
+ else
+ oidStream << "|";
+
+ if( baseName )
+ oidStream << baseName << "|";
+ else
+ oidStream << "|";
+
+ oidStream << std::setprecision(50) << localOId << std::ends;
+
+ // allocate memory taking the final string
+ oidString = new char[strlen(buffer)+1];
+
+ // copy string
+ strcpy( oidString, buffer );
+
+ // delete buffer
+ delete[] buffer;
+}
+
+r_OId::r_OId( const r_OId& obj )
+ : oidString(NULL),
+ systemName(NULL),
+ baseName(NULL),
+ localOId(0)
+{
+ if( obj.oidString )
+ {
+ oidString= new char[ strlen(obj.oidString)+1 ];
+ strcpy( oidString, obj.oidString );
+ }
+
+ if( obj.systemName )
+ {
+ systemName= new char[ strlen(obj.systemName)+1 ];
+ strcpy( systemName, obj.systemName );
+ }
+
+ if( obj.baseName )
+ {
+ baseName= new char[ strlen(obj.baseName)+1 ];
+ strcpy( baseName, obj.baseName );
+ }
+
+ localOId = obj.localOId;
+}
+
+r_OId::~r_OId()
+{
+ r_deactivate();
+}
+
+void
+r_OId::r_deactivate()
+{
+ if( oidString )
+ {
+ delete[] oidString;
+ oidString = NULL;
+ }
+
+ if( systemName )
+ {
+ delete[] systemName;
+ systemName = NULL;
+ }
+
+ if( baseName )
+ {
+ delete[] baseName;
+ baseName = NULL;
+ }
+}
+
+void
+r_OId::print_status( std::ostream& s ) const
+{
+ if( oidString )
+ s << oidString;
+}
+
+const r_OId&
+r_OId::operator=( const r_OId& obj )
+{
+ if( this != &obj )
+ {
+ if( oidString )
+ {
+ delete[] oidString;
+ oidString = NULL;
+ }
+
+ if( obj.oidString )
+ {
+ oidString = new char[ strlen(obj.oidString)+1 ];
+ strcpy( oidString, obj.oidString );
+ }
+
+ if( systemName )
+ {
+ delete[] systemName;
+ systemName = NULL;
+ }
+
+ if( obj.systemName )
+ {
+ systemName = new char[ strlen(obj.systemName)+1 ];
+ strcpy( systemName, obj.systemName );
+ }
+
+ if( baseName )
+ {
+ delete[] baseName;
+ baseName = NULL;
+ }
+
+ if( obj.baseName )
+ {
+ baseName = new char[ strlen(obj.baseName)+1 ];
+ strcpy( baseName, obj.baseName );
+ }
+
+ localOId = obj.localOId;
+ }
+
+ return *this;
+}
+
+bool
+r_OId::operator==( const r_OId& oid ) const
+{
+ bool equal = false;
+
+ if( oidString && oid.oidString )
+ equal = !strcmp( oidString, oid.oidString );
+
+ return equal;
+}
+
+bool
+r_OId::operator!=( const r_OId& oid ) const
+{
+ return !operator==( oid );
+}
+
+bool
+r_OId::operator> ( const r_OId& oid ) const
+{
+ int comparison;
+
+ if( systemName && oid.systemName )
+ {
+ comparison = strcmp( systemName, oid.systemName );
+
+ if( !comparison && baseName && oid.baseName )
+ {
+ comparison = strcmp( baseName, oid.baseName );
+
+ if( !comparison )
+ if( localOId < oid.localOId )
+ comparison = -1;
+ else if( localOId == oid.localOId )
+ comparison = 0;
+ else
+ comparison = 1;
+ }
+ }
+
+ return comparison > 0;
+}
+
+bool
+r_OId::operator< ( const r_OId& oid ) const
+{
+ int comparison;
+
+ if( systemName && oid.systemName )
+ {
+ comparison = strcmp( systemName, oid.systemName );
+
+ if( !comparison && baseName && oid.baseName )
+ {
+ comparison = strcmp( baseName, oid.baseName );
+
+ if( !comparison )
+ if( localOId < oid.localOId )
+ comparison = -1;
+ else if( localOId == oid.localOId )
+ comparison = 0;
+ else
+ comparison = 1;
+ }
+ }
+
+ return comparison < 0;
+}
+
+bool
+r_OId::operator>=( const r_OId& oid ) const
+{
+ return !operator< ( oid );
+}
+
+bool
+r_OId::operator<=( const r_OId& oid ) const
+{
+ return !operator> ( oid );
+}
+
+std::ostream& operator<<( std::ostream& s, const r_OId& oid )
+{
+ oid.print_status( s );
+ return s;
+}
+
diff --git a/raslib/oid.hh b/raslib/oid.hh
new file mode 100644
index 0000000..df2a824
--- /dev/null
+++ b/raslib/oid.hh
@@ -0,0 +1,137 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: oid.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_OId
+ *
+ * COMMENTS:
+ * The class represents an object identifier (OId).
+ *
+*/
+
+#ifndef _D_OID_
+#define _D_OID_
+
+#include <iosfwd>
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class \Ref{r_OId} represents an object identifier.
+
+*/
+
+class r_OId
+{
+ public:
+ /// default constructor
+ r_OId();
+
+ /// constructs an OId from the string representation
+ r_OId( const char* );
+
+ /// constructor getting oid parts
+ r_OId( const char* initSystemName, const char* initBaseName, double initLocalOId );
+
+ /// copy constructor
+ r_OId( const r_OId& );
+
+ /// destructor
+ virtual ~r_OId();
+
+ /// it is called when an object leaves transient memory
+ virtual void r_deactivate();
+
+ /// debug output
+ void print_status(std::ostream& s) const;
+
+ /// operator for assigning an oid
+ const r_OId& operator= ( const r_OId& );
+
+ //@Man: Comparison operators:
+ //@{
+ ///
+
+ /// operator for equality
+ bool operator==( const r_OId& ) const;
+
+ /// operator for not equal
+ bool operator!=( const r_OId& ) const;
+
+ /// operator for greater than
+ bool operator> ( const r_OId& ) const;
+
+ /// operator for less than
+ bool operator< ( const r_OId& ) const;
+
+ /// operator for greater or equal than
+ bool operator>=( const r_OId& ) const;
+
+ /// operator for less than or equal
+ bool operator<=( const r_OId& ) const;
+
+ ///
+ //@}
+
+ /// gets the oid's string representation
+ inline const char* get_string_representation() const;
+
+ /// get system name
+ inline const char* get_system_name() const;
+
+ /// get base name
+ inline const char* get_base_name() const;
+
+ /// get local oid
+ inline double get_local_oid() const;
+
+ /// determines if oid is valid
+ inline bool is_valid() const;
+
+ private:
+ /// string representation
+ char* oidString;
+
+ /// system name
+ char* systemName;
+
+ /// base name
+ char* baseName;
+
+ /// local oid
+ double localOId;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Oid}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_OId& oid );
+
+#include "raslib/oid.icc"
+#endif
diff --git a/raslib/oid.icc b/raslib/oid.icc
new file mode 100644
index 0000000..70b0ab1
--- /dev/null
+++ b/raslib/oid.icc
@@ -0,0 +1,62 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INLINE SOURCE: oid.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_OId
+ *
+ * COMMENTS:
+ *
+*/
+
+inline const char*
+r_OId::get_string_representation() const
+{
+ return oidString;
+}
+
+inline const char*
+r_OId::get_system_name() const
+{
+ return systemName;
+}
+
+inline const char*
+r_OId::get_base_name() const
+{
+ return baseName;
+}
+
+inline double
+r_OId::get_local_oid() const
+{
+ return localOId;
+}
+
+inline bool
+r_OId::is_valid() const
+{
+ return localOId != 0;
+}
+
diff --git a/raslib/oidtype.cc b/raslib/oidtype.cc
new file mode 100644
index 0000000..df751c9
--- /dev/null
+++ b/raslib/oidtype.cc
@@ -0,0 +1,80 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Oid_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/oidtype.cc,v 1.6 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/oidtype.hh"
+
+r_Oid_Type::r_Oid_Type()
+ : r_Type()
+{
+}
+
+bool
+r_Oid_Type::isOidType() const
+ {
+ return true;
+ }
+
+r_Oid_Type::r_Oid_Type( const r_Oid_Type& oldObj )
+ : r_Type(oldObj)
+{
+}
+
+r_Type*
+r_Oid_Type::clone() const
+{
+ return new r_Oid_Type( *this );
+}
+
+r_Type::r_Type_Id
+r_Oid_Type::type_id() const
+{
+ return OIDTYPE;
+}
+
+void
+r_Oid_Type::convertToLittleEndian(char* cells, r_Area noCells) const
+{
+}
+
+void
+r_Oid_Type::convertToBigEndian(char* cells, r_Area noCells) const
+{
+}
+
+void
+r_Oid_Type::print_status( std::ostream& s ) const
+{
+ s << "oid";
+}
+
+r_Oid_Type::~r_Oid_Type()
+{
+}
+
+std::ostream &operator<<( std::ostream &str, const r_Oid_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/oidtype.hh b/raslib/oidtype.hh
new file mode 100644
index 0000000..e3018de
--- /dev/null
+++ b/raslib/oidtype.hh
@@ -0,0 +1,79 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: oidtype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Oid_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_OID_TYPE_
+#define _D_OID_TYPE_
+
+#include "raslib/type.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents the oid type in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+class r_Oid_Type : public r_Type
+{
+public:
+ /// default constructor
+ r_Oid_Type();
+
+ /// copy constructor
+ r_Oid_Type( const r_Oid_Type& oldObj );
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const;
+
+ virtual bool isOidType() const;
+
+ /// destructor
+ ~r_Oid_Type();
+};
+
+//@Doc: write the status of a oid type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Oid_Type &type );
+
+#endif
+
diff --git a/raslib/parseparams.cc b/raslib/parseparams.cc
new file mode 100644
index 0000000..963d68f
--- /dev/null
+++ b/raslib/parseparams.cc
@@ -0,0 +1,283 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: parseparams.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Parse_Params
+ *
+ * COMMENTS:
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cctype>
+#include <cstring>
+#include <cerrno>
+
+extern int errno;
+
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+
+#include "raslib/parseparams.hh"
+
+
+
+const unsigned int r_Parse_Params::granularity = 4;
+
+r_Parse_Params::r_Parse_Params( void )
+{
+ params = NULL;
+ number = 0;
+ maxnum = 0;
+}
+
+
+r_Parse_Params::r_Parse_Params( unsigned int num )
+{
+ number = 0;
+ maxnum = num;
+ params = (parse_params_t*)mymalloc(maxnum * sizeof(parse_params_t));
+}
+
+
+r_Parse_Params::~r_Parse_Params( void )
+{
+ if (params != NULL)
+ free(params);
+}
+
+
+int r_Parse_Params::add( const char *key, void *store, parse_param_type type )
+{
+
+ RMDBGONCE(2, RMDebug::module_raslib, "r_Parse_Params", "add('"
+ << (key?key:"NULL") << "', "
+ << (store?store:"NULL") << ","
+ << type << ")");
+
+ if (number >= maxnum)
+ {
+ maxnum += granularity;
+ if (params == NULL)
+ params = (parse_params_t*)mymalloc(maxnum * sizeof(parse_params_t));
+ else
+ params = (parse_params_t*)realloc(params, maxnum * sizeof(parse_params_t));
+
+ if (params == NULL)
+ {
+ maxnum = 0; return -1;
+ }
+ }
+ params[number].key = key;
+ params[number].store = store;
+ params[number].type = type;
+ number++;
+
+ return 0;
+}
+
+
+int r_Parse_Params::process( const char *str ) const
+{
+ static const int lenBuff=256;
+ static char buff[lenBuff];
+ int numkeys = 0;
+ const char *b = str;
+
+ RMDBGONCE(2, RMDebug::module_raslib, "r_Parse_Params", "process('" << (str?str:"NULL") << ")");
+
+ if ( (number == 0) ||
+ (str == NULL) ||
+ (!strcmp(str,"")) ) {
+ return 0;
+ }
+
+ while (*b != '\0')
+ {
+ //cout << numkeys << '(' << b << ')' << std::endl;
+ while ((isspace((unsigned int)(*b))) || (*b == ',')) b++;
+ if (*b == '\0') break;
+ if (isalpha((unsigned int)(*b)))
+ {
+ const char *key = b;
+ unsigned int klen;
+ int knum;
+ int inquotes;
+
+ while (isalnum((unsigned int)(*b))) b++;
+
+ //store current item
+ klen = (b - key);
+ memset(buff,0, lenBuff);
+ memcpy(buff, key, klen);
+ for (knum=0; knum<number; knum++)
+ {
+ if (strcmp(buff, params[knum].key) == 0)
+ break;
+ }
+ // we actually understand this key
+ if (knum < number)
+ {
+ int statval = 0; // status: -1 error, 0 not found, 1 OK
+
+ while (isspace((unsigned int)(*b))) b++;
+ if (*b == '=')
+ {
+ b++;
+ while (isspace((unsigned int)(*b))) b++;
+ if ((*b != ',') && (*b != '\0'))
+ {
+ const char *aux=b;
+
+ switch (params[knum].type)
+ {
+ case param_type_int:
+ {
+ int val=0;
+
+ errno=0;
+ val = strtol(b, (char**)&aux, 10);
+ if ((b == aux) || errno)
+ statval = -1;
+ else
+ {
+ int *vptr = (int*)(params[knum].store);
+ *vptr = val;
+ b = aux; statval = 1;
+ }
+ }
+ break;
+ case param_type_double:
+ {
+ double val=0.;
+
+ errno=0;
+ val = strtod(b, (char**)&aux);
+ if ((b == aux) || errno)
+ statval = -1;
+ else
+ {
+ double *vptr = (double*)(params[knum].store);
+ *vptr = val;
+ b = aux; statval = 1;
+ }
+ }
+ break;
+ case param_type_string:
+ {
+ unsigned int vlen = 0;
+
+ if (*b == '\"')
+ {
+ aux = ++b;
+ while ((*b != '\"') && (*b != '\0')) b++;
+ if (*b == '\0')
+ statval = -1;
+ else
+ {
+ vlen = (b - aux);
+ b++; statval = 1;
+ }
+ }
+ else
+ {
+ aux = b;
+ while ((!isspace((unsigned int)(*b))) && (*b != '\0') && (*b != ',')) b++;
+ vlen = (b - aux); statval = 1;
+ }
+ if (vlen > 0)
+ {
+ char **vptr = (char**)(params[knum].store);
+ if (*vptr != NULL)
+ delete [] *vptr;
+ *vptr = new char[vlen+1];
+ strncpy(*vptr, aux, vlen);
+ (*vptr)[vlen] = '\0';
+ }
+ }
+ break;
+ }
+ }
+ }
+ switch (statval)
+ {
+ case -1:
+ RMInit::logOut << "r_Parse_Params::process('" << str << "'): error parsing value for keyword " << params[knum].key << std::endl;
+ return -1;
+ case 0:
+ RMInit::logOut << "r_Parse_Params::process('" << str << "'): keyword " << params[knum].key << " without value" << std::endl;
+ return -1;
+ case 1:
+ numkeys++;
+ break;
+ default:
+ break;
+ }
+ }
+ inquotes = 0;
+ while (((*b != ',') || (inquotes != 0)) && (*b != '\0'))
+ {
+ if (*b == '\"')
+ inquotes ^= 1;
+ b++;
+ }
+ if (inquotes != 0)
+ {
+ RMInit::logOut << "r_Parse_Params::process('" << str << "'): unterminated string" << std::endl;
+ return -1;
+ }
+ }
+ else
+ {
+ RMInit::logOut << "r_Parse_Params::process('" << str << "'): the string must start with alphabetic character" << std::endl;
+ return -1;
+ }
+ }
+
+ return numkeys;
+}
+
+std::ostream& operator<<( std::ostream& s, const r_Parse_Params::parse_param_type& d )
+{
+ switch( d )
+ {
+ case r_Parse_Params::param_type_int:
+ s << "param_type_int";
+ break;
+ case r_Parse_Params::param_type_double:
+ s << "param_type_double";
+ break;
+ case r_Parse_Params::param_type_string:
+ s << "param_type_string";
+ break;
+ default:
+ s << "UNKNOWN r_Parse_Params::parse_paramt_type" << d;
+ break;
+ }
+ return s;
+}
diff --git a/raslib/parseparams.hh b/raslib/parseparams.hh
new file mode 100644
index 0000000..b5ebed6
--- /dev/null
+++ b/raslib/parseparams.hh
@@ -0,0 +1,116 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: parseparams.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Parse_Params
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _PARSE_PARAMS_HH_
+#define _PARSE_PARAMS_HH_
+
+#include <iosfwd>
+
+//@ManMemo: Module {\bf raslib}
+
+/*@Doc:
+ Class for parsing a string consisting of key=value pairs separated by ",".
+*/
+
+class r_Parse_Params
+{
+public:
+
+ /// the possible parameter types used for add()
+ enum parse_param_type {
+ param_type_int,
+ param_type_double,
+ param_type_string
+ };
+ /**
+ Possible parameter types and their corresponding C types are
+
+ \begin{tabular}{ll}
+ param_type_int && int\\
+ param_type_double && double\\
+ param_type_string && char*\\
+ \end{tabular}
+ */
+
+ struct parse_params_s;
+
+ /// default constructor, should not be used
+ r_Parse_Params( void );
+ /// constructor, gets descriptor of the values to scan for
+ r_Parse_Params( unsigned int num );
+ /// destructor
+ ~r_Parse_Params( void );
+ /// add parameters to the list
+ int add( const char *key, void *store, parse_param_type type );
+ /**
+ Add a parameter to the list. key is the keyword, e.g. ``quality'', type
+ is one of the available types and describes the data type of the parameter
+ and store is a pointer to a variable of this type that will be updated
+ by process() if the parameter is encountered there. The variable pointed
+ to by store must not be initalized except for param_type_string where it
+ must be set to NULL before calling process() for the first time. The contents
+ of a string variable must be freed by the caller by first checking whether
+ the variable is NULL and if not doing a delete [] <var>.
+ */
+ /// process parameter string
+ int process( const char *str ) const;
+ /**
+ process the parameter string. Returns the number of keywords found
+ or -1 for error.
+ */
+
+
+protected:
+ //@Man: The parameter descriptor
+ //@{
+ typedef struct parse_params_s {
+ const char *key;
+ void *store;
+ parse_param_type type;
+ } parse_params_t;
+ //@}
+
+ parse_params_t *params;
+ unsigned int maxnum;
+ unsigned int number;
+
+ static const unsigned int granularity;
+};
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Parse_Params::parse_param_type}.
+ */
+extern std::ostream& operator<<( std::ostream& s, const r_Parse_Params::parse_param_type& d );
+
+
+#endif
diff --git a/raslib/point.cc b/raslib/point.cc
new file mode 100644
index 0000000..8679dc5
--- /dev/null
+++ b/raslib/point.cc
@@ -0,0 +1,372 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: point.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Point
+ *
+ * COMMENTS:
+ *
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Point: $Id: point.cc,v 1.22 2002/08/28 11:58:13 coman Exp $";
+
+#include "point.hh"
+
+#include <string.h>
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+r_Point::r_Point( char* stringRep ) throw (r_Error)
+ : dimensionality(1), streamInitCnt(0), points(NULL)
+{
+ char charToken = 0;
+ r_Range valueToken = 0;
+
+ // for parsing the string
+ std::istrstream str( stringRep, strlen(stringRep) + 1 );
+
+ // calculate dimensionality
+ char* p = stringRep;
+ while(p = strchr(++p, ','))
+ dimensionality++;
+
+ // allocate space for intervals
+ points = new r_Range[ dimensionality ];
+
+ str >> charToken;
+ if(charToken != '[')
+ {
+ // error
+ dimensionality = 0;
+ delete[] points;
+ points = NULL;
+ throw r_Error(NOPOINT);
+ }
+
+ for( r_Dimension i=0; i<dimensionality; i++ )
+ {
+ str >> valueToken;
+ points[i] = valueToken;
+
+ if( i < dimensionality-1 )
+ {
+ str >> charToken;
+ if(charToken != ',')
+ {
+ // error
+ dimensionality = 0;
+ delete[] points;
+ points = NULL;
+ throw r_Error(NOPOINT);
+ }
+ }
+ }
+}
+
+
+r_Point::r_Point( r_Dimension dim )
+ : dimensionality( dim ),
+ streamInitCnt(0)
+{
+ points = new r_Range[ dimensionality ];
+
+ for( r_Dimension i=0; i< dimensionality; i++ )
+ points[i] = 0;
+}
+
+
+r_Point& r_Point::operator<<( r_Range newElement ) throw( r_Einit_overflow )
+{
+ if( streamInitCnt >= dimensionality )
+ {
+ RMInit::logOut << "r_Point::operator<<(" << newElement << ") already fully initialised" << endl;
+ throw r_Einit_overflow();
+ }
+
+ points[streamInitCnt++] = newElement;
+ return *this;
+}
+
+
+r_Point::r_Point( r_Range p1, r_Range p2 )
+ : dimensionality(2),
+ streamInitCnt(2)
+{
+ points = new r_Range[dimensionality];
+ points[0] = p1;
+ points[1] = p2;
+}
+
+
+r_Point::r_Point( r_Range p1, r_Range p2, r_Range p3 )
+ : dimensionality(3),
+ streamInitCnt(3)
+{
+ points = new r_Range[dimensionality];
+ points[0] = p1;
+ points[1] = p2;
+ points[2] = p3;
+}
+
+
+r_Point::r_Point( r_Range p1, r_Range p2, r_Range p3, r_Range p4 )
+ : dimensionality(4),
+ streamInitCnt(4)
+{
+ points = new r_Range[dimensionality];
+ points[0] = p1;
+ points[1] = p2;
+ points[2] = p3;
+ points[3] = p4;
+}
+
+
+r_Point::r_Point( r_Range p1, r_Range p2, r_Range p3, r_Range p4, r_Range p5 )
+ : dimensionality(5),
+ streamInitCnt(5)
+{
+ points = new r_Range[dimensionality];
+ points[0] = p1;
+ points[1] = p2;
+ points[2] = p3;
+ points[3] = p4;
+ points[4] = p5;
+}
+
+
+r_Point::r_Point()
+ : dimensionality(0),
+ streamInitCnt(0),
+ points(NULL)
+{
+}
+
+
+r_Point::r_Point( const r_Point& pt )
+ : dimensionality(pt.dimensionality),
+ streamInitCnt(pt.streamInitCnt),
+ points(new r_Range[pt.dimensionality])
+{
+ for( r_Dimension i=0; i<dimensionality; i++ )
+ points[i] = pt[i];
+}
+
+
+r_Point::~r_Point()
+{
+ if( points )
+ {
+ delete[] points;
+ points = NULL;
+ }
+}
+
+
+r_Range
+r_Point::operator[]( r_Dimension i ) const throw( r_Eindex_violation )
+{
+ if( i < 0 || i >= dimensionality )
+ {
+ RMInit::logOut << "r_Point::operator[](" << i << ") const dimension out of bounds (" << dimensionality << ")" << endl;
+ throw r_Eindex_violation( 0, dimensionality-1, i );
+ }
+
+ return points[i];
+}
+
+
+r_Range&
+r_Point::operator[]( r_Dimension i ) throw( r_Eindex_violation )
+{
+ if( i < 0 || i >= dimensionality )
+ {
+ RMInit::logOut << "r_Point::operator[](" << i << ") dimension out of bounds (" << dimensionality << ")" << endl;
+ throw r_Eindex_violation( 0, dimensionality-1, i );
+ }
+
+ return points[i];
+}
+
+
+const r_Point&
+r_Point::operator=( const r_Point& pt )
+{
+ if( this != &pt )
+ {
+ if( points && dimensionality != pt.dimension() )
+ {
+ delete[] points;
+ points = NULL;
+ }
+
+ dimensionality = pt.dimension();
+ streamInitCnt = dimensionality;
+
+ if( !points )
+ points = new r_Range[ dimensionality ];
+
+ for( r_Dimension i=0; i<dimensionality; i++ )
+ points[i] = pt[i];
+
+ }
+
+ return *this;
+}
+
+
+
+bool
+r_Point::operator==( const r_Point& pt ) const
+{
+ bool returnValue = false;
+
+ if( dimensionality == pt.dimensionality )
+ {
+ returnValue = true;
+
+ for( r_Dimension i=0; i<dimensionality && returnValue ; i++ )
+ {
+ if (points[i] != pt[i])
+ {
+ returnValue = false;
+ break;
+ }
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+bool
+r_Point::operator!=( const r_Point& pt ) const
+{
+ return !operator==( pt );
+}
+
+
+
+r_Point
+r_Point::operator+( const r_Point& pt ) const throw( r_Edim_mismatch )
+{
+ if( dimensionality != pt.dimension() )
+ {
+ RMInit::logOut << "r_Point::operator+(" << pt << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw r_Edim_mismatch( dimensionality, pt.dimension() );
+ }
+
+ r_Point result( dimensionality );
+
+ for( r_Dimension i=0; i<dimensionality; i++ )
+ result[i] = points[i] + pt[i];
+
+ return result;
+}
+
+r_Point
+r_Point::operator-( const r_Point& pt ) const throw( r_Edim_mismatch )
+{
+ if( dimensionality != pt.dimension() )
+ {
+ RMInit::logOut << "r_Point::operator-(" << pt << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw r_Edim_mismatch( dimensionality, pt.dimension() );
+ }
+
+ r_Point result( dimensionality );
+
+ for( r_Dimension i=0; i<dimensionality; i++ )
+ result[i] = points[i] - pt[i];
+
+ return result;
+}
+
+r_Point
+r_Point::operator*( const r_Point& pt ) const throw( r_Edim_mismatch )
+{
+ if( dimensionality != pt.dimension() )
+ {
+ RMInit::logOut << "r_Point::operator*(" << pt << ") dimensions (" << dimensionality << ") do not match" << endl;
+ throw r_Edim_mismatch( dimensionality, pt.dimension() );
+ }
+
+ r_Point result( dimensionality );
+
+ for( r_Dimension i=0; i<dimensionality; i++ )
+ result[i] = points[i] * pt[i];
+
+ return result;
+}
+
+void
+r_Point::print_status( std::ostream& s ) const
+{
+ s << "[";
+
+ if( dimensionality > 0 )
+ {
+ for( r_Dimension i=0; i<dimensionality-1; i++ )
+ s << points[i] << ",";
+
+ s << points[dimensionality-1];
+ }
+
+ s << "]";
+}
+
+
+char*
+r_Point::get_string_representation() const
+{
+ r_Bytes bufferSize = dimensionality*25+3; // should be enough
+
+ // allocate buffer and initialize string stream
+ char* buffer = new char[bufferSize];
+ std::ostrstream domainStream( buffer, bufferSize );
+
+ // write into string stream
+ domainStream << (*this) << std::ends;
+
+ // allocate memory taking the final string
+ char* returnString = strdup(buffer);
+
+ // delete buffer
+ delete[] buffer;
+
+ return returnString;
+}
+
+std::ostream& operator<<( std::ostream& s, const r_Point& d )
+{
+ d.print_status( s );
+ return s;
+}
+
diff --git a/raslib/point.hh b/raslib/point.hh
new file mode 100644
index 0000000..6f6e634
--- /dev/null
+++ b/raslib/point.hh
@@ -0,0 +1,165 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: point.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Point
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_POINT_
+#define _D_POINT_
+
+#ifdef __VISUALC__
+// disable warning for exception specification
+#pragma warning( disable : 4290 )
+#endif
+
+class r_Error;
+class r_Einit_overflow;
+class r_Eindex_violation;
+class r_Edim_mismatch;
+
+#include "raslib/mddtypes.hh"
+#include "raslib/error.hh"
+
+#include <iostream>
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class \Ref{r_Point} represents an n-dimensional point vector.
+
+*/
+
+class r_Point
+{
+ public:
+ /// constructor getting dimensionality for stream initializing
+ r_Point( r_Dimension );
+
+ /// stream-input operator for stream initializing
+ r_Point& operator<<( r_Range ) throw( r_Einit_overflow );
+
+ /// constructor taking string representation (e.g. [ 1, 2, 3])
+ r_Point( char* ) throw( r_Error );
+
+ //@Man: 'easy-to-use' constructors
+ //@{
+ ///
+ r_Point( r_Range, r_Range );
+ ///
+ r_Point( r_Range, r_Range, r_Range );
+ ///
+ r_Point( r_Range, r_Range, r_Range, r_Range );
+ ///
+ r_Point( r_Range, r_Range, r_Range, r_Range, r_Range );
+ ///
+ //@}
+
+ /// default constructor
+ r_Point();
+
+ /// copy constructor
+ r_Point( const r_Point& );
+
+ /// destructor: cleanup dynamic memory
+ ~r_Point();
+
+ /// subscriptor for read access
+ r_Range operator[]( r_Dimension ) const throw( r_Eindex_violation );
+ /// subscriptor for write access
+ r_Range& operator[]( r_Dimension ) throw( r_Eindex_violation );
+
+ /// assignment: cleanup + copy
+ const r_Point& operator= ( const r_Point& );
+
+ /// compares this point with the given point.
+ inline const int compare_with( const r_Point& p ) const;
+ /**
+ Returns 0 if this == p, -1 if this < p, 1 if this > p (considering
+ the coordinates in decreasing order of magnitude).
+ */
+
+ /// equal operator
+ bool operator==( const r_Point& ) const;
+
+ /**
+ Two points are equal if they have the same number of dimensions and
+ the same values.
+ */
+
+ /// non equal operator - negation of equal operator
+ bool operator!=( const r_Point& ) const;
+
+ /// vector addition
+ r_Point operator+( const r_Point& ) const
+ throw( r_Edim_mismatch );
+
+ /// vector subtraction
+ r_Point operator-( const r_Point& ) const
+ throw( r_Edim_mismatch );
+
+ /// vector multiplication
+ r_Point operator*( const r_Point& ) const
+ throw( r_Edim_mismatch );
+
+ /// get dimensionality
+ inline r_Dimension dimension() const;
+
+ /// writes the state of the object to the specified stream
+ void print_status( std::ostream& s = std::cout ) const;
+
+ /// gives back the string representation
+ char* get_string_representation() const;
+ /**
+ The string representation delivered by this method is allocated using {\tt malloc()} and
+ has to be free unsing {\tt free()} in the end. It can be used to construct a {\tt r_Point}
+ again with a special constructor provided. The string representation is build using
+ {\tt print_status()}.
+ */
+
+ private:
+ /// array holding the point coordinates
+ r_Range* points;
+ /// dimensionality of the point
+ r_Dimension dimensionality;
+ /// number of components initialized already
+ r_Dimension streamInitCnt;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Point}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Point& d );
+
+#include "raslib/point.icc"
+
+#endif
diff --git a/raslib/point.icc b/raslib/point.icc
new file mode 100644
index 0000000..5bbbd27
--- /dev/null
+++ b/raslib/point.icc
@@ -0,0 +1,54 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INLINE SOURCE: point.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_Point
+ *
+ * COMMENTS:
+ *
+*/
+
+inline r_Dimension
+r_Point::dimension() const
+{
+ return dimensionality;
+};
+
+const int
+r_Point::compare_with( const r_Point& p ) const
+{
+ if( dimensionality != p.dimensionality )
+ return -2;
+
+ for ( r_Dimension i = 0; i < dimensionality; i++ )
+ {
+ if ( points[i] > p[i] )
+ return 1;
+ if ( points[i] < p[i] )
+ return -1 ;
+ }
+ return 0;
+}
+
diff --git a/raslib/pointtype.cc b/raslib/pointtype.cc
new file mode 100644
index 0000000..0a4f1a0
--- /dev/null
+++ b/raslib/pointtype.cc
@@ -0,0 +1,81 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Point_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/pointtype.cc,v 1.6 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/pointtype.hh"
+
+r_Point_Type::r_Point_Type()
+ : r_Type()
+{
+}
+
+r_Point_Type::r_Point_Type( const r_Point_Type& oldObj )
+ : r_Type(oldObj)
+{
+}
+
+r_Type*
+r_Point_Type::clone() const
+{
+ return new r_Point_Type( *this );
+}
+
+r_Type::r_Type_Id
+r_Point_Type::type_id() const
+{
+ return POINTTYPE;
+}
+
+void
+r_Point_Type::convertToLittleEndian(char* cells, unsigned int noCells)
+ const
+{
+}
+
+void
+r_Point_Type::convertToBigEndian(char* cells, unsigned int noCells) const
+{
+}
+
+void
+r_Point_Type::print_status( std::ostream& s ) const
+{
+ s << "point";
+}
+
+r_Point_Type::~r_Point_Type()
+{
+}
+
+bool
+r_Point_Type::isPointType() const
+ {
+ return true;
+ }
+
+std::ostream &operator<<( std::ostream &str, const r_Point_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/pointtype.hh b/raslib/pointtype.hh
new file mode 100644
index 0000000..53a1d26
--- /dev/null
+++ b/raslib/pointtype.hh
@@ -0,0 +1,81 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: pointtype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Point_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_POINT_TYPE_
+#define _D_POINT_TYPE_
+
+#include "raslib/type.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents the point type in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+class r_Point_Type : public r_Type
+{
+public:
+ /// default constructor
+ r_Point_Type();
+
+ /// copy constructor
+ r_Point_Type( const r_Point_Type& oldObj );
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, unsigned int noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, unsigned int noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const;
+
+ virtual bool isPointType() const;
+
+ /// destructor
+ ~r_Point_Type();
+};
+
+//@Doc: write the status of point type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Point_Type &type );
+
+#endif
+
+
+
diff --git a/raslib/primitive.cc b/raslib/primitive.cc
new file mode 100644
index 0000000..a9ffc1e
--- /dev/null
+++ b/raslib/primitive.cc
@@ -0,0 +1,439 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: primitive.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Primitive
+ *
+ * COMMENTS:
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+#include "raslib/primitive.hh"
+#include "raslib/primitivetype.hh"
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+#include <string.h>
+#include <fstream>
+#include <stdlib.h>
+
+r_Primitive::r_Primitive( const char* newBuffer, const r_Primitive_Type* newType )
+ : r_Scalar( newType )
+{
+ if( valueType )
+ {
+ valueBuffer = (char*)mymalloc( valueType->size() );
+ if( newBuffer)
+ memcpy( (void*)valueBuffer, (void*)newBuffer, valueType->size() );
+ else
+ memset( (void*)valueBuffer, 0, valueType->size() );
+ }
+}
+
+r_Primitive::r_Primitive( const r_Primitive& obj )
+ : r_Scalar( obj ),
+ valueBuffer(NULL)
+{
+ valueBuffer = (char*)mymalloc( valueType->size() );
+ if( obj.valueBuffer )
+ memcpy( (void*)valueBuffer, (void*)obj.valueBuffer, valueType->size() );
+ else
+ memset( (void*)valueBuffer, 0, valueType->size());
+}
+
+r_Primitive::~r_Primitive()
+{
+ if( valueBuffer ) free( valueBuffer );
+}
+
+bool
+r_Primitive::isPrimitive() const
+ {
+ return true;
+ }
+
+r_Scalar*
+r_Primitive::clone() const
+{
+ return new r_Primitive( *this );
+}
+
+
+
+const r_Primitive&
+r_Primitive::operator=( const r_Primitive& obj )
+{
+ if( this != &obj )
+ {
+ // assign scalar
+ r_Scalar::operator=( obj );
+
+ if( valueBuffer )
+ {
+ free( valueBuffer );
+ valueBuffer = NULL;
+ }
+
+ if( valueType )
+ {
+ valueBuffer = (char*)mymalloc( valueType->size() );
+ if( obj.valueBuffer )
+ memcpy( (void*)valueBuffer, (void*)obj.valueBuffer, valueType->size() );
+ else
+ memset((void*)valueBuffer, 0, valueType->size());
+ }
+ }
+
+ return *this;
+}
+
+
+
+const char*
+r_Primitive::get_buffer() const
+{
+ return valueBuffer;
+}
+
+
+
+void
+r_Primitive::print_status( std::ostream& s ) const
+{
+ if( valueType && valueBuffer )
+ valueType->print_value( valueBuffer, s );
+ else
+ s << "<nn>" << std::flush;
+}
+
+
+
+r_Boolean
+r_Primitive::get_boolean() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_boolean() buffer null or type null " << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_boolean(valueBuffer);
+}
+
+
+
+r_Char
+r_Primitive::get_char() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType)
+ {
+ RMInit::logOut << "r_Primitive::get_char() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_char(valueBuffer);
+}
+
+
+
+r_Octet
+r_Primitive::get_octet() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_octet() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_octet(valueBuffer);
+}
+
+
+
+r_Short
+r_Primitive::get_short() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_short() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_short(valueBuffer);
+}
+
+
+
+r_UShort
+r_Primitive::get_ushort() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_ushort() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_ushort(valueBuffer);
+}
+
+
+
+r_Long
+r_Primitive::get_long() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_long() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_long(valueBuffer);
+}
+
+
+
+r_ULong
+r_Primitive::get_ulong() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_ulong() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_ulong(valueBuffer);
+}
+
+
+
+r_Float
+r_Primitive::get_float() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_float() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_float(valueBuffer);
+}
+
+
+
+r_Double
+r_Primitive::get_double() const throw( r_Error )
+{
+ if( !valueBuffer || !valueType )
+ {
+ RMInit::logOut << "r_Primitive::get_double() buffer null or type null" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ return ((r_Primitive_Type*)valueType)->get_double(valueBuffer);
+}
+
+
+void
+r_Primitive::set_boolean(r_Boolean val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::BOOL )
+ {
+ RMInit::logOut << "r_Primitive::set_boolean(" << val << ") not a boolean" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_char(r_Char val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::CHAR )
+ {
+ RMInit::logOut << "r_Primitive::set_char(" << val << ") not a char" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_octet(r_Octet val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::OCTET )
+ {
+ RMInit::logOut << "r_Primitive::set_octet(" << val << ") not a octet" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_short(r_Short val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::SHORT )
+ {
+ RMInit::logOut << "r_Primitive::set_short(" << val << ") not a short" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_ushort(r_UShort val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::USHORT )
+ {
+ RMInit::logOut << "r_Primitive::set_ushort(" << val << ") not a ushort" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_long(r_Long val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::LONG )
+ {
+ RMInit::logOut << "r_Primitive::set_long(" << val << ") not a long" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_ulong(r_ULong val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::ULONG )
+ {
+ RMInit::logOut << "r_Primitive::set_ulong(" << val << ") not a ulong" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_float(r_Float val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::FLOAT )
+ {
+ RMInit::logOut << "r_Primitive::set_float(" << val << ") not a float" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+
+void
+r_Primitive::set_double(r_Double val) throw( r_Error )
+{
+ if( !valueType || valueType->type_id() != r_Type::DOUBLE )
+ {
+ RMInit::logOut << "r_Primitive::set_double(" << val << ") not a double" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ if( !valueBuffer )
+ valueBuffer = (char*)mymalloc( valueType->size());
+ memmove(valueBuffer, &val, valueType->size());
+}
+
+
+std::ostream& operator<<( std::ostream& s, const r_Primitive& obj )
+{
+ obj.print_status( s );
+ return s;
+}
+
diff --git a/raslib/primitive.hh b/raslib/primitive.hh
new file mode 100644
index 0000000..a4d1dc6
--- /dev/null
+++ b/raslib/primitive.hh
@@ -0,0 +1,143 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: primitive.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Primitive
+ *
+ * COMMENTS:
+ * The class represents a primitive type value.
+ *
+*/
+
+#ifndef _D_PRIMITIVE_
+#define _D_PRIMITIVE_
+
+#include <iostream>
+
+class r_Error;
+
+#include "raslib/scalar.hh"
+#include "raslib/odmgtypes.hh"
+
+class r_Primitive_Type;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class \Ref{r_Primitive} represents a primitive type value.
+
+*/
+
+class r_Primitive : public r_Scalar
+{
+ public:
+
+ explicit
+
+ /// constructs a scalar type value
+ r_Primitive( const char* newBuffer, const r_Primitive_Type* newType );
+
+ /// copy constructor
+ r_Primitive( const r_Primitive& obj );
+
+ /// destructor
+ ~r_Primitive();
+
+ /// clone operator
+ virtual r_Scalar* clone() const;
+
+ /// operator for assigning a primitive
+ virtual const r_Primitive& operator= ( const r_Primitive& );
+
+ /// gets the pointer to the buffer
+ const char* get_buffer() const;
+
+ /// debug output
+ virtual void print_status(std::ostream& s) const;
+
+ virtual bool isPrimitive() const;
+
+ //@Man: Type-safe value access methods. In case of type mismatch, an exception is raised.
+ //@{
+ ///
+
+ ///
+ r_Boolean get_boolean() const throw( r_Error );
+ ///
+ r_Char get_char() const throw( r_Error );
+ ///
+ r_Octet get_octet() const throw( r_Error );
+ ///
+ r_Short get_short() const throw( r_Error );
+ ///
+ r_UShort get_ushort() const throw( r_Error );
+ ///
+ r_Long get_long() const throw( r_Error );
+ ///
+ r_ULong get_ulong() const throw( r_Error );
+ ///
+ r_Float get_float() const throw( r_Error );
+ ///
+ r_Double get_double() const throw( r_Error );
+
+ ///
+ void set_boolean(r_Boolean) throw( r_Error );
+ ///
+ void set_char(r_Char) throw( r_Error );
+ ///
+ void set_octet(r_Octet) throw( r_Error );
+ ///
+ void set_short(r_Short) throw( r_Error );
+ ///
+ void set_ushort(r_UShort) throw( r_Error );
+ ///
+ void set_long(r_Long) throw( r_Error );
+ ///
+ void set_ulong(r_ULong) throw( r_Error );
+ ///
+ void set_float(r_Float) throw( r_Error );
+ ///
+ void set_double(r_Double) throw( r_Error );
+
+
+ ///
+ //@}
+
+ private:
+ /// buffer
+ char* valueBuffer;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Primitive}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Primitive& obj );
+
+#endif
+
diff --git a/raslib/primitivetype.cc b/raslib/primitivetype.cc
new file mode 100644
index 0000000..a0dbb37
--- /dev/null
+++ b/raslib/primitivetype.cc
@@ -0,0 +1,601 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Primitive_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/primitivetype.cc,v 1.26 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/primitivetype.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+#include "raslib/odmgtypes.hh"
+#include "raslib/endian.hh"
+#include "raslib/error.hh"
+
+#include <iomanip>
+#include <string>
+#include <cstring>
+
+r_Primitive_Type::r_Primitive_Type()
+ : r_Base_Type(),
+ typeId(UNKNOWNTYPE)
+{
+}
+
+r_Primitive_Type::r_Primitive_Type( const char* newTypeName,
+ const r_Type::r_Type_Id newTypeId )
+ : r_Base_Type(newTypeName, 0),
+ typeId(newTypeId)
+{
+
+ switch( typeId )
+ {
+ case ULONG: typeSize = 4; break;
+ case USHORT: typeSize = 2; break;
+ case BOOL: typeSize = 1; break;
+ case LONG: typeSize = 4; break;
+ case SHORT: typeSize = 2; break;
+ case OCTET: typeSize = 1; break;
+ case DOUBLE: typeSize = 8; break;
+ case FLOAT: typeSize = 4; break;
+ case CHAR: typeSize = 1; break;
+ case COMPLEXTYPE1:
+ typeSize = 2 * sizeof(float);
+ break;
+ case COMPLEXTYPE2:
+ typeSize = 2 * sizeof(double);
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Primitive_Type", "r_Primitive_Type(....) bad typeId " << typeId);
+ break;
+ }
+}
+
+r_Primitive_Type::r_Primitive_Type( const r_Primitive_Type& oldObj )
+ : r_Base_Type(oldObj),
+ typeId(oldObj.typeId)
+{
+}
+
+const r_Primitive_Type&
+r_Primitive_Type::operator=( const r_Primitive_Type& oldObj )
+{
+ // Gracefully handle self assignment
+ if (this == &oldObj) return *this;
+
+ r_Base_Type::operator=( oldObj );
+ typeId = oldObj.typeId;
+
+ return *this;
+}
+
+r_Primitive_Type::~r_Primitive_Type()
+{
+}
+
+r_Type*
+r_Primitive_Type::clone() const
+{
+ return new r_Primitive_Type( *this );
+}
+
+
+r_Type::r_Type_Id
+r_Primitive_Type::type_id() const
+{
+ return typeId;
+}
+
+bool
+r_Primitive_Type::isPrimitiveType() const
+{
+ return true;
+}
+
+void
+r_Primitive_Type::convertToLittleEndian(char* cells, r_Bytes noCells) const
+ {
+ char c0 = 0;
+ char c1 = 0;
+ char c2 = 0;
+ char c3 = 0;
+ r_Bytes i = 0;
+
+ switch( typeId )
+ {
+ case USHORT:
+ case SHORT:
+ for(i=0; i<noCells; i++ )
+ {
+ c1 = cells[i*typeSize];
+ c0 = cells[i*typeSize + 1];
+ cells[i*typeSize] = c0;
+ cells[i*typeSize + 1] = c1;
+ }
+ break;
+
+ case ULONG:
+ case LONG:
+ for(i=0; i<noCells; i++ )
+ {
+ c3 = cells[i*typeSize];
+ c2 = cells[i*typeSize + 1];
+ c1 = cells[i*typeSize + 2];
+ c0 = cells[i*typeSize + 3];
+ cells[i*typeSize] = c0;
+ cells[i*typeSize + 1] = c1;
+ cells[i*typeSize + 2] = c2;
+ cells[i*typeSize + 3] = c3;
+ }
+ break;
+
+ case FLOAT:
+ for(i = 0; i < noCells; ++i)
+ ((r_Float *)cells)[i] = r_Endian::swap( ((r_Float *)cells)[i] );
+ break;
+
+ case DOUBLE:
+ for(i = 0; i < noCells; ++i)
+ ((r_Double *)cells)[i] = r_Endian::swap( ((r_Double *)cells)[i] );
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Primitive_Type", "convertToLittleEndian(....) bad typeId " << typeId);
+ break;
+ }
+ }
+
+void
+r_Primitive_Type::convertToBigEndian(char* cells, r_Bytes noCells) const
+ {
+ char c0 = 0;
+ char c1 = 0;
+ char c2 = 0;
+ char c3 = 0;
+ r_Bytes i = 0;
+
+ switch( typeId )
+ {
+ case USHORT:
+ case SHORT:
+ for(i=0; i<noCells; i++)
+ {
+ c1 = cells[i*typeSize];
+ c0 = cells[i*typeSize + 1];
+ cells[i*typeSize] = c0;
+ cells[i*typeSize + 1] = c1;
+ }
+ break;
+
+ case ULONG:
+ case LONG:
+ for(i=0; i<noCells; i++)
+ {
+ c3 = cells[i*typeSize];
+ c2 = cells[i*typeSize + 1];
+ c1 = cells[i*typeSize + 2];
+ c0 = cells[i*typeSize + 3];
+ cells[i*typeSize] = c0;
+ cells[i*typeSize + 1] = c1;
+ cells[i*typeSize + 2] = c2;
+ cells[i*typeSize + 3] = c3;
+ }
+ break;
+
+ case FLOAT:
+ for(i = 0; i < noCells; ++i)
+ ((r_Float *)cells)[i] = r_Endian::swap( ((r_Float *)cells)[i] );
+ break;
+
+ case DOUBLE:
+ for(i = 0; i < noCells; ++i)
+ ((r_Double *)cells)[i] = r_Endian::swap( ((r_Double *)cells)[i] );
+ break;
+ default:
+ RMDBGONCE(3, RMDebug::module_raslib, "r_Primitive_Type", "convertToBigEndian(....) bad typeId " << typeId);
+ break;
+ }
+ }
+
+void
+r_Primitive_Type::print_status( std::ostream& s ) const
+{
+ s << typeId;
+}
+
+void
+r_Primitive_Type::print_value( const char* storage, std::ostream& s ) const
+{
+ switch( typeId )
+ {
+ case r_Type::ULONG: s << std::setw(5) << get_ulong( storage ); break;
+ case r_Type::USHORT: s << std::setw(5) << get_ushort( storage ); break;
+ case r_Type::BOOL: s << std::setw(5) << ( get_boolean( storage ) ? "T" : "F" ); break;
+ case r_Type::LONG: s << std::setw(5) << get_long( storage ); break;
+ case r_Type::SHORT: s << std::setw(5) << get_short( storage ); break;
+ case r_Type::OCTET: s << std::setw(5) << (int)( get_octet( storage ) ); break;
+ case r_Type::DOUBLE: s << std::setw(5) << get_double( storage ) ; break;
+ case r_Type::FLOAT: s << std::setw(5) << get_float( storage ); break;
+ case r_Type::CHAR: s << std::setw(5) << (int)( get_char( storage ) ); break;
+ default:
+ RMInit::logOut << "r_Primitive_Type::print_value(...) type unknown" << endl;
+ break;
+ }
+}
+
+//FIXME
+// We have to return the value in the most powerfull type(e.g. now r_Double) without loss
+// This may change in future
+
+r_Double
+r_Primitive_Type::get_value( const char* storage ) const throw(r_Error)
+{
+ r_Double retVal=0.;
+
+ switch( typeId )
+ {
+ case r_Type::ULONG: retVal=get_ulong( storage ); break;
+ case r_Type::USHORT: retVal=get_ushort( storage ); break;
+ case r_Type::BOOL: retVal=get_boolean( storage ); break;
+ case r_Type::LONG: retVal=get_long( storage ); break;
+ case r_Type::SHORT: retVal=get_short( storage ); break;
+ case r_Type::OCTET: retVal=get_octet( storage ); break;
+ case r_Type::DOUBLE: retVal=get_double( storage ); break;
+ case r_Type::FLOAT: retVal=get_float( storage ); break;
+ case r_Type::CHAR: retVal=get_char( storage ); break;
+ default:
+ {
+ RMInit::logOut << "r_Primitive_Type::get_value(...) type unknown" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ };
+ break;
+ }
+ return retVal;
+}
+
+//FIXME
+// We have to set the value from the most powerfull type(e.g. now r_Double) without loss
+// This may change in future
+
+void
+r_Primitive_Type::set_value( char* storage, r_Double val ) throw(r_Error)
+{
+ switch( typeId )
+ {
+ case r_Type::ULONG: set_ulong( storage, (r_ULong)val ); break;
+ case r_Type::USHORT: set_ushort( storage, (r_UShort)val ); break;
+ case r_Type::BOOL: set_boolean( storage, (r_Boolean)val ); break;
+ case r_Type::LONG: set_long( storage, (r_Long)val ); break;
+ case r_Type::SHORT: set_short( storage, (r_Short)val ); break;
+ case r_Type::OCTET: set_octet( storage, (r_Octet)val ); break;
+ case r_Type::DOUBLE: set_double( storage, (r_Double)val); break;
+ case r_Type::FLOAT: set_float( storage, (r_Float)val ); break;
+ case r_Type::CHAR: set_char( storage, (r_Char)val ); break;
+ default:
+ {
+ RMInit::logOut << "r_Primitive_Type::set_value(...) type unknown" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ };
+ break;
+ }
+}
+
+//FIXME
+// We have to set the value from the most powerfull type(e.g. now r_Double) without loss
+// This may change in future
+
+void
+r_Primitive_Type::get_limits( r_Double& min, r_Double& max ) throw(r_Error)
+{
+ r_Double *type=NULL;
+ switch( typeId )
+ {
+ case r_Type::ULONG: ::get_limits( (r_ULong*)type, min, max ); break;
+ case r_Type::USHORT: ::get_limits( (r_UShort*)type, min, max ); break;
+ case r_Type::BOOL: ::get_limits( (r_Boolean*)type, min, max ); break;
+ case r_Type::LONG: ::get_limits( (r_Long*)type, min, max ); break;
+ case r_Type::SHORT: ::get_limits( (r_Short*)type, min, max ); break;
+ case r_Type::OCTET: ::get_limits( (r_Octet*)type, min, max ); break;
+ case r_Type::DOUBLE: ::get_limits( (r_Double*)type, min, max); break;
+ case r_Type::FLOAT: ::get_limits( (r_Float*)type, min, max ); break;
+ case r_Type::CHAR: ::get_limits( (r_Char*)type, min, max ); break;
+ default:
+ {
+ RMInit::logOut << "r_Primitive_Type::get_limits(...) type unknown" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ };
+ break;
+ }
+}
+
+r_Boolean
+r_Primitive_Type::get_boolean( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::BOOL )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_boolean(cell) type not a boolean" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Boolean*)cell);
+}
+
+
+
+r_Char
+r_Primitive_Type::get_char( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::CHAR )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_char(cell) type not a char" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Char*)cell);
+}
+
+
+
+r_Octet
+r_Primitive_Type::get_octet( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::OCTET )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_octet(cell) type not a octet" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Octet*)cell);
+}
+
+
+
+r_Short
+r_Primitive_Type::get_short( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::SHORT )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_short(cell) type not a short" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Short*)cell);
+}
+
+
+
+r_UShort
+r_Primitive_Type::get_ushort( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::USHORT )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_ushort(cell) type not a ushort" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_UShort*)cell);
+}
+
+
+
+r_Long
+r_Primitive_Type::get_long( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::LONG )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_long(cell) type not a long" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Long*)cell);
+}
+
+
+
+r_ULong
+r_Primitive_Type::get_ulong( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::ULONG )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_ulong(cell) type not a ulong" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_ULong*)cell);
+}
+
+
+
+r_Float
+r_Primitive_Type::get_float( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::FLOAT )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_float(cell) type not a float" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Float*)cell);
+}
+
+
+
+r_Double
+r_Primitive_Type::get_double( const char* cell ) const throw( r_Error )
+{
+ if( typeId != r_Type::DOUBLE )
+ {
+ RMInit::logOut << "r_Primitive_Type::get_double(cell) type not a double" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ return *((r_Double*)cell);
+}
+
+void
+r_Primitive_Type::set_boolean( char* cell, r_Boolean val ) throw( r_Error )
+{
+ if( typeId != r_Type::BOOL )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_boolean(cell, val) type not a boolean" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_char( char* cell, r_Char val ) throw( r_Error )
+{
+ if( typeId != r_Type::CHAR )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_char(cell, val) type not a char" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_octet( char* cell, r_Octet val ) throw( r_Error )
+{
+ if( typeId != r_Type::OCTET )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_octet(cell, val) type not a octet" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_short( char* cell, r_Short val ) throw( r_Error )
+{
+ if( typeId != r_Type::SHORT )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_short(cell, val) type not a short" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_ushort( char* cell, r_UShort val ) throw( r_Error )
+{
+ if( typeId != r_Type::USHORT )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_ushort(cell, val) type not a ushort" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_long( char* cell, r_Long val ) throw( r_Error )
+{
+ if( typeId != r_Type::LONG )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_long(cell, val) type not a long" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_ulong( char* cell, r_ULong val ) throw( r_Error )
+{
+ if( typeId != r_Type::ULONG )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_ulong(cell, val) type not a ulong" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_float( char* cell, r_Float val ) throw( r_Error )
+{
+ if( typeId != r_Type::FLOAT )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_float(cell, val) type not a float" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+
+
+void
+r_Primitive_Type::set_double( char* cell, r_Double val ) throw( r_Error )
+{
+ if( typeId != r_Type::DOUBLE )
+ {
+ RMInit::logOut << "r_Primitive_Type::set_double(cell, val) type not a double" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ memmove(cell, &val, typeSize);
+}
+
+std::ostream &operator<<( std::ostream &str, const r_Primitive_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/primitivetype.hh b/raslib/primitivetype.hh
new file mode 100644
index 0000000..9dac808
--- /dev/null
+++ b/raslib/primitivetype.hh
@@ -0,0 +1,147 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: primitivetype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Primitive_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_PRIMITIVE_TYPE_
+#define _D_PRIMITIVE_TYPE_
+
+class r_Error;
+
+#include "raslib/basetype.hh"
+#include "raslib/odmgtypes.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents all primitive types in the ODMG conformant
+ representation of the RasDaMan type system. Examples are ULONG or
+ BOOL.
+*/
+
+class r_Primitive_Type : public r_Base_Type
+{
+public:
+ /// constructor getting name of type, size of type and type id.
+ r_Primitive_Type( const char* newTypeName, const r_Type::r_Type_Id newTypeId );
+ /// copy constructor
+ r_Primitive_Type( const r_Primitive_Type& oldObj );
+ /// assignment operator.
+ const r_Primitive_Type& operator=( const r_Primitive_Type& oldObj );
+ /// destructor.
+ virtual ~r_Primitive_Type();
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const;
+
+ /// check, if type is primitive.
+ virtual bool isPrimitiveType() const;
+
+ /// prints value of a primitive type
+ virtual void print_value( const char* storage, std::ostream& s = std::cout ) const;
+
+ //@Man: Type-safe value access methods. In case of type mismatch, an exception is raised.
+ //@{
+ ///
+
+ ///
+ r_Double get_value( const char* cell ) const throw( r_Error );
+ ///
+ void set_value( char* cell, r_Double ) throw( r_Error );
+ ///
+ void get_limits( r_Double&, r_Double& ) throw( r_Error );
+
+
+ ///
+ r_Boolean get_boolean( const char* cell ) const throw( r_Error );
+ ///
+ r_Char get_char( const char* cell ) const throw( r_Error );
+ ///
+ r_Octet get_octet( const char* cell ) const throw( r_Error );
+ ///
+ r_Short get_short( const char* cell ) const throw( r_Error );
+ ///
+ r_UShort get_ushort( const char* cell ) const throw( r_Error );
+ ///
+ r_Long get_long( const char* cell ) const throw( r_Error );
+ ///
+ r_ULong get_ulong( const char* cell ) const throw( r_Error );
+ ///
+ r_Float get_float( const char* cell ) const throw( r_Error );
+ ///
+ r_Double get_double( const char* cell ) const throw( r_Error );
+
+ ///
+ void set_boolean( char* cell, r_Boolean ) throw( r_Error );
+ ///
+ void set_char( char* cell, r_Char ) throw( r_Error );
+ ///
+ void set_octet( char* cell, r_Octet ) throw( r_Error );
+ ///
+ void set_short( char* cell, r_Short ) throw( r_Error );
+ ///
+ void set_ushort( char* cell, r_UShort ) throw( r_Error );
+ ///
+ void set_long( char* cell, r_Long ) throw( r_Error );
+ ///
+ void set_ulong( char* cell, r_ULong ) throw( r_Error );
+ ///
+ void set_float( char* cell, r_Float ) throw( r_Error );
+ ///
+ void set_double( char* cell, r_Double ) throw( r_Error );
+
+
+ ///
+ //@}
+
+ protected:
+ /// default constructor.
+ r_Primitive_Type();
+
+ r_Type::r_Type_Id typeId;
+};
+
+//@Doc: write the status of a primitive type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Primitive_Type &type );
+
+#endif
+
diff --git a/raslib/property.cc b/raslib/property.cc
new file mode 100644
index 0000000..ddd75c2
--- /dev/null
+++ b/raslib/property.cc
@@ -0,0 +1,99 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Meta_Object: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/property.cc,v 1.7 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/property.hh"
+#include "raslib/basetype.hh"
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+
+#include <malloc.h>
+#include <string.h>
+
+r_Property::r_Property()
+ : r_Meta_Object(),
+ myType(NULL)
+ {
+ }
+
+r_Property::r_Property(const char* newTypeName, const r_Base_Type& newType)
+ : r_Meta_Object(newTypeName),
+ myType((r_Base_Type*)newType.clone())
+ {
+ }
+
+r_Property::r_Property(const r_Property& oldObj)
+ : r_Meta_Object(oldObj)
+ {
+ if (oldObj.myType)
+ myType = (r_Base_Type*)oldObj.myType->clone();
+ else {
+ RMInit::logOut << "r_Property::r_Property(oldObj) property does not have a base type" << endl;
+ throw r_Error(PROPERTYTYPEHASNOELEMENTTYPE);
+ }
+ }
+
+const r_Property&
+r_Property::operator=(const r_Property& oldObj)
+ {
+ // Gracefully handle self assignment
+ if (this != &oldObj)
+ {
+ r_Meta_Object::operator=(oldObj);
+ if (myType)
+ {
+ delete myType;
+ myType = 0;
+ }
+
+ if (oldObj.myType)
+ myType = (r_Base_Type*)oldObj.myType->clone();
+ else {
+ RMInit::logOut << "r_Property::operator=(oldObj) property does not have a base type" << endl;
+ throw r_Error(PROPERTYTYPEHASNOELEMENTTYPE);
+ }
+ }
+
+ return *this;
+ }
+
+r_Property::~r_Property()
+ {
+ if (myType)
+ delete myType;
+ }
+
+const r_Base_Type&
+r_Property::type_of() const
+ {
+ if (!myType)
+ {
+ RMInit::logOut << "r_Property::type_of() property does not have a base type" << endl;
+ throw r_Error(PROPERTYTYPEHASNOELEMENTTYPE);
+ }
+
+ return *myType;
+ }
+
diff --git a/raslib/property.hh b/raslib/property.hh
new file mode 100644
index 0000000..1985993
--- /dev/null
+++ b/raslib/property.hh
@@ -0,0 +1,77 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: property.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Property
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_PROPERTY_
+#define _D_PROPERTY_
+
+#include "metaobject.hh"
+
+
+class r_Base_Type;
+class r_Type_Id;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class the superclass for properties of classes in the ODMG
+ conformant representation of the RasDaMan type system.
+*/
+
+class r_Property : public r_Meta_Object
+ {
+ public:
+
+ /// constructor getting name and type of property.
+ r_Property( const char* newTypeName, const r_Base_Type& newType );
+
+ /// copy constructor.
+ r_Property( const r_Property& oldObj );
+
+ /// assignment operator.
+ const r_Property& operator=( const r_Property& oldObj );
+
+ /// destructor.
+ virtual ~r_Property();
+
+ /// retrieve type of property.
+ const r_Base_Type& type_of() const;
+
+ protected:
+
+ r_Base_Type* myType;
+
+ /// default constructor.
+ r_Property();
+
+ };
+
+#endif
diff --git a/raslib/rm.cc b/raslib/rm.cc
new file mode 100644
index 0000000..4698f5b
--- /dev/null
+++ b/raslib/rm.cc
@@ -0,0 +1,31 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: rm.hh
+ *
+ * PURPOSE:
+ * Artificially created to manipulate hierarchy tree.
+ *
+ * COMMENTS:
+ *
+*/
diff --git a/raslib/rm.hh b/raslib/rm.hh
new file mode 100644
index 0000000..39643b9
--- /dev/null
+++ b/raslib/rm.hh
@@ -0,0 +1,38 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: rm.hh
+ *
+ * PURPOSE:
+ * Artificial class to manipulate hierarchy tree.
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _RM_CLASS_
+#define _RM_CLASS_
+
+class RM_Class {};
+
+#endif
diff --git a/raslib/rmdebug.cc b/raslib/rmdebug.cc
new file mode 100644
index 0000000..d047812
--- /dev/null
+++ b/raslib/rmdebug.cc
@@ -0,0 +1,430 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: rmdebug.cc
+ *
+ * MODULE: raslib
+ * CLASS:
+ *
+ * COMMENTS:
+ *
+*/
+
+static const char rcsid[] = "@(#)raslib, RMDebug: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/rmdebug.cc,v 1.33 2005/12/02 14:51:55 rasdev Exp $";
+
+#include <iostream>
+using namespace std;
+
+#include <stdio.h> // fopen, getc
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <fstream>
+
+
+#include "raslib/rmdebug.hh"
+#include "raslib/odmgtypes.hh"
+
+int RManDebug = 0; // debug level (0-4), 0 means no debug info at all
+int RManBenchmark = 0; // benchmark level (0-4)
+
+// initialization of static variables for RMDebug
+int RMDebug::level = 0;
+int RMDebug::numDebugModules = 0;
+char** RMDebug::debugModules = 0;
+char* RMDebug::debugModulesText = 0;
+int* RMDebug::transDebugModules = 0;
+int RMDebug::numDebugClasses = 0;
+char** RMDebug::debugClasses = 0;
+char* RMDebug::debugClassesText = 0;
+
+// all module names
+const char* RMDebug::allModuleNames[] = {
+ "adminif",
+ "applications",
+ "blobif",
+ "cachetamgr",
+ "catalogif",
+ "catalogmgr",
+ "clientcomm",
+ "conversion",
+ "compression",
+ "httpserver",
+ "indexif",
+ "indexmgr",
+ "insertutils",
+ "mddif",
+ "mddmgr",
+ "qlparser",
+ "rasdl",
+ "raslib",
+ "rasodmg",
+ "rasql",
+ "server",
+ "servercomm",
+ "storageif",
+ "storagemgr",
+ "tools",
+ "tilemgr",
+ "utilities"
+};
+
+int RMDebug::allModuleLevels[RMDebug::module_number];
+
+
+// initialization of static variable for RMTimer
+#ifndef __VISUALC__
+struct timezone RMTimer::dummy;
+#endif
+
+RMDebug::RMDebug(const char* newClass, const char* newFunc, const char* newModule,
+ const char* newFile, int newLine)
+ : myClass(newClass), myFunc(newFunc), myModule(newModule),
+ myFile(newFile), myLine(newLine), myModuleNum(-1), myDebugLevel(2)
+{
+ myDebugOn = checkDebug();
+
+ int useLevel = -1;
+ if (myModuleNum >= 0)
+ useLevel = allModuleLevels[myModuleNum];
+
+ if (useLevel < 0)
+ useLevel = RManDebug;
+
+ myDebugOn = myDebugOn && (useLevel >= myDebugLevel);
+
+ if( myDebugOn )
+ {
+ indentLine();
+ // output, when entering function
+ RMInit::dbgOut << "D: " << myClass << "::" << myFunc << " entered "
+ << "(" << myModule << ", " << myFile << ": " << myLine
+ << ")." << endl;
+ // indentation
+ level++;
+ }
+}
+
+RMDebug::RMDebug(int newLevel, const char* newClass, const char* newFunc, int newModuleNum,
+ const char* newFile, int newLine)
+ : myClass(newClass), myFunc(newFunc), myModule(NULL), myFile(newFile),
+ myLine(newLine), myModuleNum(newModuleNum), myDebugLevel(newLevel)
+{
+ myDebugOn = checkDebug() && (allModuleLevels[newModuleNum] >= myDebugLevel);
+
+ if ( myDebugOn )
+ {
+ indentLine();
+ // output when entering function
+ RMInit::dbgOut << "D: " << myClass << "::" << myFunc << " entered "
+ << "(" << allModuleNames[myModuleNum] << ", " << myFile << ": "
+ << myLine << ")." << endl;
+ // indentation
+ level++;
+ }
+}
+
+RMDebug::~RMDebug(void)
+{
+ if( myDebugOn )
+ {
+ // indentation
+ level--;
+ indentLine();
+ // output, when exiting function
+ RMInit::dbgOut << "D: " << myClass << "::" << myFunc
+ << " exited." << endl;
+ }
+}
+
+char*
+RMDebug::loadTextFile(const char* name)
+{
+
+ std::ifstream f;
+ f.open(name);
+ if (f.is_open())
+ {
+ char* result;
+ f.seekg(0, std::ios::end);
+ std::streampos end = f.tellg();
+ r_Long resLen=(r_Long)end + 1;
+ result = new char[resLen];
+ memset(result, 0, resLen);
+ f.seekg(0, std::ios::beg);
+ f.read(result, end);
+ f.close();
+ result[resLen] = '\0';
+ return result;
+ }
+ return NULL;
+}
+
+int
+RMDebug::initRMDebug(void)
+{
+ int errmod=0;
+ int errclass=0;
+ int j;
+ const char* enVar;
+ char* myPtr;
+
+ // init all debug levels to global debug level
+ for (j=0; j<module_number; j++)
+ allModuleLevels[j] = RManDebug;
+
+ // -------------------
+ // reading rmdbmodules
+ // -------------------
+
+ // environment variable overrides text file
+ if ((enVar = getenv("RMDBGMODULES")) != NULL)
+ {
+ debugModulesText = new char[strlen(enVar)+1];
+ strcpy(debugModulesText, enVar);
+ }
+ else
+ {
+ if ((debugModulesText = loadTextFile("rmdbmodules")) == NULL)
+ errmod = -1;
+ }
+
+ if (debugModulesText != NULL)
+ {
+ // first switch off debugging info for all modules
+ for (j=0; j<module_number; j++)
+ allModuleLevels[j] = 0;
+
+ // count number of lines (whitespace separates)
+ myPtr = debugModulesText;
+ while (*myPtr != '\0')
+ {
+ while (isspace((unsigned int)(*myPtr))) myPtr++;
+ if (*myPtr != '\0')
+ {
+ numDebugModules++;
+ while ((*myPtr != '\0') && !isspace((unsigned int)(*myPtr))) myPtr++;
+ }
+ }
+ debugModules = new char*[numDebugModules];
+ transDebugModules = new int[numDebugModules];
+ // read text
+ j = 0;
+ myPtr = debugModulesText;
+ while (*myPtr != '\0')
+ {
+ int modLevel = RManDebug; // default debug level
+ transDebugModules[j] = -1;
+ while (isspace((unsigned int)(*myPtr))) myPtr++;
+ if (*myPtr != '\0')
+ {
+ debugModules[j] = myPtr;
+ while ((*myPtr != '\0') && !isspace((unsigned int)(*myPtr)))
+ {
+ if (*myPtr == ',')
+ {
+ char* rest;
+ *myPtr++ = '\0';
+ modLevel = strtol(myPtr, &rest, 10);
+ if (rest == myPtr)
+ {
+ cerr << "RMDebug::initRMDebug: Parse error in item " << j << endl;
+ }
+ myPtr = rest;
+ }
+ else myPtr++;
+ }
+ }
+ if (*myPtr != '\0') *myPtr++ = '\0';
+ for (int i=0; i<module_number; i++)
+ {
+ if (debugModules[j] == NULL)
+ RMInit::logOut << "RMDebug::initRMDebug: debugModules[" << j << "] is NULL, skipping this." << std::endl;
+ else if (allModuleNames[i] == NULL)
+ RMInit::logOut << "RMDebug::initRMDebug: allModuleNames[" << i << "] is NULL, skipping this." << std::endl;
+ else if (strcmp(debugModules[j], allModuleNames[i]) == 0)
+ {
+ transDebugModules[j] = i; break;
+ }
+ }
+ if (transDebugModules[j] >= 0)
+ allModuleLevels[transDebugModules[j]] = modLevel;
+ j++;
+ }
+ for (j=0; j<module_number; j++)
+ RMInit::dbgOut << allModuleNames[j] << " : " << allModuleLevels[j] << endl;
+ }
+
+ // -------------------
+ // reading rmdbclasses
+ // -------------------
+
+ if ((enVar = getenv("RMDBGCLASSES")) != NULL)
+ {
+ debugClassesText = new char[strlen(enVar)+1];
+ strcpy(debugClassesText, enVar);
+ }
+ else
+ {
+ if ((debugClassesText = loadTextFile("rmdbclasses")) == NULL)
+ errclass = -1;
+ }
+
+ if (debugClassesText != NULL)
+ {
+ myPtr = debugClassesText;
+ while (*myPtr != '\0')
+ {
+ while (isspace((unsigned int)(*myPtr))) myPtr++;
+ if (*myPtr != '\0')
+ {
+ numDebugClasses++;
+ while ((*myPtr != '\0') && !isspace((unsigned int)(*myPtr))) myPtr++;
+ }
+ }
+ debugClasses = new char*[numDebugClasses];
+ // read text
+ j = 0;
+ myPtr = debugClassesText;
+ while (*myPtr != '\0')
+ {
+ while (isspace((unsigned int)(*myPtr))) myPtr++;
+ if (*myPtr != '\0')
+ {
+ debugClasses[j++] = myPtr;
+ while ((*myPtr != '\0') && !isspace((unsigned int)(*myPtr))) myPtr++;
+ if (*myPtr != '\0') *myPtr++ = '\0';
+ }
+ }
+ }
+RMInit::dbgOut << endl;
+ for (j=0; j<numDebugClasses; j++)
+ RMInit::dbgOut << debugClasses[j] << endl;
+
+ if(errmod == -1 && errclass == -1)
+ return -1;
+ else
+ return 0;
+}
+
+int
+RMDebug::checkDebug(void)
+{
+ int i;
+
+ if(numDebugModules == 0 && numDebugClasses == 0)
+ // all classes should be debugged
+ return 1;
+ else
+ {
+ if (numDebugModules > 0)
+ {
+ if(myModuleNum >= 0)
+ {
+ if (allModuleLevels[myModuleNum] == 0)
+ return 0;
+ }
+ else
+ {
+ // check if module is mentioned
+ for(i = 0; i < numDebugModules; i++)
+ {
+ if(strcmp(debugModules[i], myModule) == 0)
+ {
+ myModuleNum = transDebugModules[i];
+ break;
+ }
+ }
+ if (i >= numDebugModules) return 0;
+ }
+ }
+ if((numDebugClasses > 0) && (myClass != NULL))
+ {
+ // check if class is mentioned
+ for(i = 0; i < numDebugClasses; i++)
+ if(strcmp(debugClasses[i], myClass) == 0)
+ break;
+ if (i >= numDebugClasses) return 0;
+ }
+ }
+ return 1;
+}
+
+int
+RMDebug::debugOutput(int dbgLevel, int modNum, const char* className)
+{
+ int retval = 0;
+ if ((numDebugModules == 0) && (numDebugClasses == 0))
+ {
+ retval = (RManDebug >= dbgLevel);
+ }
+ else {
+ if (numDebugModules > 0) {
+ retval = (allModuleLevels[modNum] >= dbgLevel);
+ }
+ else {
+ if ((numDebugClasses > 0) && (className != NULL))
+ {
+ int i;
+ for (i=0; i<numDebugClasses; i++)
+ {
+ if (strcmp(debugClasses[i], className) == 0)
+ {
+ break;
+ }
+ }
+ if (i >= numDebugClasses)
+ retval = 0;
+ else
+ retval = 1;
+ }
+ else {
+ //nothing to do
+ }
+ }
+ }
+ return retval;
+}
+
+RMCounter::RMCounter(int levell, int module, const char* cls)
+ : doStuff(false)
+ {
+ if (RMDebug::debugOutput( levell, module, cls ))
+ {
+ //RMInit::dbgOut << "RMCounter() " << RMDebug::level << " ";
+ doStuff = true;
+ RMDebug::level++;
+ //RMInit::dbgOut << RMDebug::level << endl;
+ }
+ }
+
+RMCounter::~RMCounter()
+ {
+ if (doStuff == true)
+ {
+ //RMInit::dbgOut << "~RMCounter() " << RMDebug::level << " ";
+ RMDebug::level--;
+ //RMInit::dbgOut << RMDebug::level << endl;
+ }
+ }
+
diff --git a/raslib/rmdebug.hh b/raslib/rmdebug.hh
new file mode 100644
index 0000000..08e38cc
--- /dev/null
+++ b/raslib/rmdebug.hh
@@ -0,0 +1,382 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: rmdebug.hh
+ *
+ * PURPOSE:
+ * Contains debug stuff.
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _RMDEBUG_
+#define _RMDEBUG_
+
+#ifdef __VISUALC__
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include "raslib/rminit.hh"
+#include "raslib/rm.hh"
+
+extern int RManDebug;
+extern int RManBenchmark;
+
+#ifdef RMANDEBUG
+
+#define RMDBGIF( levell, module, cls, text ) \
+ if (RMDebug::debugOutput( levell, module, cls )) { text }
+
+#define RMDBGENTER( levell, module, cls, text ) \
+ RMCounter rmCounter(levell, module, cls); \
+ if (RMDebug::debugOutput( levell, module, cls )) { \
+ RMInit::dbgOut << "ENTER "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; RMDebug::indentLine(); RMInit::dbgOut << text << endl << std::flush; \
+ }
+
+#define RMDBGMIDDLE( levell, module, cls, text ) \
+ if (RMDebug::debugOutput( levell, module, cls )) { \
+ RMInit::dbgOut << "MIDDLE "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; RMDebug::indentLine(); RMInit::dbgOut << text << endl << std::flush; \
+ }
+
+#define RMDBGONCE( levell, module, cls, text ) \
+ RMCounter rmCounter(levell, module, cls); \
+ if (RMDebug::debugOutput(levell, module, cls)) \
+ { \
+ RMInit::dbgOut << "ONCE "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; \
+ RMDebug::indentLine(); \
+ RMInit::dbgOut << text << endl << std::flush; \
+ }
+
+#define RMDBGEXIT( levell, module, cls, text ) \
+ if (RMDebug::debugOutput( levell, module, cls )) { \
+ RMInit::dbgOut << "EXIT "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; RMDebug::indentLine(); RMInit::dbgOut << text << endl << std::flush; \
+ }
+
+#define RMDBCLASS( t1, t2, t3, t4, t5 ) RMDebug localRMDebug = RMDebug( t1, t2, t3, t4, t5 );
+
+#else
+
+// Note: some parts of the code rely on these to be terminated by a ';'!
+#define RMDBGENTER( level, module, cls, text ) ;
+#define RMDBGMIDDLE( level, module, cls, text ) ;
+#define RMDBGONCE( level, module, cls, text ) ;
+#define RMDBGEXIT( level, module, cls, text ) ;
+#define RMDBGIF( level, module, cls, text) ;
+
+#define RMDBCLASS( t1, t2, t3, t4, t5 ) ;
+#endif
+
+#ifdef RMANBENCHMARK
+
+#define RMTIMER(class, func) RMTimer localRMTimer = RMTimer(class, func);
+
+#else
+
+#define RMTIMER(class, func)
+
+#endif
+
+//@ManMemo: Module: {\bf raslib}.
+
+/*@Doc:
+RMDebug is not strictly part of RasLib. It is a class used for
+generating debug output if compiling with RMANDEBUG defined. One way
+of using it is to put the following at the beginning of a function:
+
+{\tt RMDebug localRMDebug = RMDebug("className", "functionName",
+"moduleName", __FILE__, __LINE__");}
+
+This can be patched in automatically by a modified funchead.pl script.
+
+{\bf Functionality}
+
+Debug output printing class name, function name, module name, file
+name and line number given as parameters to the constructor is
+created, whenever the constructor is called. The destructor
+outputs class name and function name. If the static members {\tt
+debugModules} or {\tt debugClasses} are set, then only modules
+which are mentioned in the array of strings {\tt debugModules} or
+classes which are mentioned {\tt debugClasses} give debug output.
+{\tt debugModules} and {\tt debugClasses} can either be read from
+files named "rmdbmodules" and "rmdbclasses" or from the environment
+variables RMDBGMODULES and RMDBGCLASSES. The environment variables
+override the files. The contents of the files / variables are the
+names of the modules / classes separated by whitespace (space,
+newlines, ...). In the case of the modules each modulename may
+be followed by ",<dbgLevel>" to set the debug level for that
+module explizitly, otherwise the default is used.
+
+{\bf Interdependencies}
+
+If only certain modules or classes are to be debugged, RMDebug
+has to be initialized in {\Ref RMInit}. This is done by reading
+the files {\tt rmdbmodules} and {\tt rmdbclasses}. The files
+should contain names of modules resp. classes to be debugged, each
+(including the last one!) followed by end of line. */
+
+/**
+ * \defgroup RMs RM Classes
+ */
+
+/**
+ * \ingroup RMs
+ */
+
+class RMDebug : public RM_Class
+{
+public:
+ /// constructor, initializes members and prints message.
+ RMDebug(const char* newClass, const char* newFunc, const char* newModule,
+ const char* newFile, int newLine);
+ /// constructor taking an identifier to the module for more efficiency
+ RMDebug(int newLevel, const char* newClass, const char* newFun, int newModuleNum,
+ const char* newFile, int newLine);
+ /// destructor, prints message.
+ ~RMDebug(void);
+
+ /// for initializing modules and classes to debug.
+ static int initRMDebug(void);
+
+ /// get the debug level of a module by its number
+ static inline int getModuleDebugLevel(int modNum) {
+ return allModuleLevels[modNum];
+ }
+ /// get the name of a module by its number
+ static inline const char* getModuleName(int modNum) {
+ return allModuleNames[modNum];
+ }
+ /// indent by the amount specified by level
+ static inline void indentLine(void) {
+ for (int i=0; i<level; i++) RMInit::dbgOut << " ";
+ }
+
+ /// return whether debug output should happen for the given module, class
+ /// and debugging level
+ static int debugOutput(int dbgLevel, int modNum, const char* className);
+
+ /// all modules for debugging
+ enum {
+ module_adminif = 0,
+ module_applications,
+ module_blobif,
+ module_cachetamgr,
+ module_catalogif,
+ module_catalogmgr,
+ module_clientcomm,
+ module_conversion,
+ module_compression,
+ module_httpserver,
+ module_indexif,
+ module_indexmgr,
+ module_insertutils,
+ module_mddif,
+ module_mddmgr,
+ module_qlparser,
+ module_rasdl,
+ module_raslib,
+ module_rasodmg,
+ module_rasql,
+ module_server,
+ module_servercomm,
+ module_storageif,
+ module_storagemgr,
+ module_tilemgr,
+ module_tools,
+ module_utilities,
+ module_number
+ } RMDebugModules;
+ /*@ManMemo level of function calls (incremented by constructor,
+ decremented by destrctor. */
+ static int level;
+
+private:
+ /// checks, if messages should be printed.
+ int checkDebug(void);
+ /// loads a file containing text and returns a 0-terminated string
+ static char* loadTextFile(const char* name);
+ /*@Doc:
+ If {\tt debugModules} or {\tt debugClasses} is set, checks
+ if myModule or myClass is in the corresponding array.
+ */
+
+ /// name of class.
+ const char* myClass;
+ /// name of function (no parameters).
+ const char* myFunc;
+ /// name of module.
+ const char* myModule;
+ /// name of source file.
+ const char* myFile;
+ /// line of code where destructor call is.
+ int myLine;
+ /// number of module
+ int myModuleNum;
+ /// debugging level for this instance
+ int myDebugLevel;
+ /// debugging on for this class?
+ int myDebugOn;
+ /// number of strings in {\tt debugModules}.
+ static int numDebugModules;
+ /// array with pointers into names of modules to be debugged.
+ static char** debugModules;
+ /// names of modules to be debugged.
+ static char* debugModulesText;
+ /// number of strings in {\tt debugClasses}.
+ static int numDebugClasses;
+ /// array with pointers into names of classes to be debugged.
+ static char** debugClasses;
+ /// names of class es to be debugged.
+ static char* debugClassesText;
+ /// translate index of debug module into index of all modules
+ static int* transDebugModules;
+ /// names of all modules
+ static const char* allModuleNames[];
+ /// the debug levels for all modules
+ static int allModuleLevels[];
+};
+
+///Module: {\bf raslib}.
+
+/**
+RMTimer is not strictly part of RasLib. It is a class used for taking
+timing measurements if compiling with RMANBENCHMARK defined. One way
+of using it is to put the following at the beginning of a function:
+
+{\tt RMTIMER("className", "functionName");}
+
+If RMANBENCHMARK is defined this is expanded to:
+
+{\tt RMTimer localRMTimer = RMTimer("className", "functionName");}
+
+Time is taken between this line and exiting the block where this line
+was. For more elaborate timing measurements an RMTimer object can be
+used directly. All timing information is stored in the object, so
+multiple RMTimer objects can be used at the same time.
+
+If output is generated on RMInit::bmOut depends on the flag {\tt
+output} and the benchmark level. Output is generated if {\tt output}
+is TRUE and {\tt bmLevel} is lower than the global benchmark level
+stored in RManBenchmark. The flag {\tt output} can be changed with
+setOutput(). The function start() sets {\tt output} to TRUE, stop()
+sets {\tt output} to FALSE.
+
+{\bf Important}: If a RMTimer is used as a static variable, it must be
+ensured that no output is generated in the destructor either by
+calling stop() or by manually setting {\tt output} to FALSE using
+setOutput() before termination of the program. The reason is that
+potentially RMInit::bmOut may be destructed before the RMTimer
+destructor is called possibly causing a crash.
+*/
+
+/**
+ * \ingroup RMs
+ */
+
+class RMTimer : public RM_Class
+{
+public:
+ /// constructor, initializes members and starts timer.
+ inline RMTimer(const char* newClass, const char* newFunc,
+ int newBmLevel = 0);
+ /**
+ The parameters newClass and newFunc have to be string literals. Just
+ a pointer to them is stored. No output is generated if RManBenchmark
+ < newBmLevel.
+ */
+ /// destructor, calls stop().
+ inline ~RMTimer();
+ /// switch output on RMInit::bmOut on and off.
+ inline void setOutput(int newOutput);
+ /**
+ If newOutoutput is FALSE no output is created on RMInit::bmOut on
+ the following calls to stop() and ~RMTimer() until the next start().
+ */
+ /// pauses timer.
+ inline void pause();
+ /// resumes timer.
+ inline void resume();
+ /// resets timer.
+ inline void start();
+ /**
+ Also switches output to RMInit::bmOut on again.
+ */
+ /// prints time spent if output is TRUE.
+ inline void stop();
+ /**
+ Time spent is the time since construction or last start() excluding
+ the times between pause() and resume().
+ */
+private:
+ /// name of class.
+ const char* myClass;
+ /// name of function (no parameters).
+ const char* myFunc;
+ /// flag, if stop() should print timing information
+ int output;
+ /// stores benchmark level, checked before output.
+ int bmLevel;
+ // reference parameter for gettimeofday().
+#ifdef __VISUALC__
+ time_t acttime;
+#else
+ timeval acttime;
+#endif
+ /// accu for saving time in us
+ long accuTime;
+ /// flag indicating if the timer is currently running.
+ unsigned short running;
+ // reference parameter for gettimeofday, not used.
+ static struct timezone dummy;
+ /// used to calculate time spent in function.
+ long oldsec;
+ /// used to calculate time spent in function.
+ long oldusec;
+};
+///Module: {\bf raslib}.
+
+/**
+Objects of this class increment the indent level of RMDebug at construction time and decrease this level at destruction time.
+*/
+
+/**
+ * \ingroup RMs
+ */
+
+class RMCounter : public RM_Class
+{
+public:
+ /// constructor, increments indent level if the class should be debugged.
+ RMCounter(int levell, int module, const char* cls);
+ /// destructor, decrements indent level.
+ ~RMCounter();
+private:
+ bool doStuff;
+};
+
+
+#include "raslib/rmdebug.icc"
+
+#endif
diff --git a/raslib/rmdebug.icc b/raslib/rmdebug.icc
new file mode 100644
index 0000000..5c7a292
--- /dev/null
+++ b/raslib/rmdebug.icc
@@ -0,0 +1,120 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+// -*-C++-*- (for Emacs)
+
+inline
+RMTimer::RMTimer(const char* newClass, const char* newFunc, int newBmLevel)
+ : myClass(newClass), myFunc(newFunc), bmLevel(newBmLevel), running(0)
+{
+#ifdef __VISUALC__
+ /* Set time zone from TZ environment variable.If TZ is not set,
+ * the operating system is queried to obtain the default value
+ * for the variable
+ */
+ _tzset();
+#endif
+ start();
+}
+
+inline
+RMTimer::~RMTimer()
+{
+ stop();
+}
+
+inline void
+RMTimer::setOutput(int newOutput)
+{
+ output = newOutput;
+}
+
+inline void
+RMTimer::start()
+{
+ // reset accu
+ accuTime = 0;
+ // set output to TRUE
+ output = 1;
+ resume();
+}
+
+inline void
+RMTimer::pause()
+{
+ if( running )
+ {
+#ifdef __VISUALC__
+ // save start time
+ oldsec = acttime;
+ oldusec = 0; // Windows only counts the seconds (too slow??!!)
+
+ // get stop time
+ time(&acttime);
+
+ // add new time to accu
+ accuTime += (acttime-oldsec)*1000000;
+#else
+ // save start time
+ oldsec = acttime.tv_sec;
+ oldusec = acttime.tv_usec;
+
+ // get stop time
+ gettimeofday(&acttime, &dummy);
+
+ // add new time to accu
+ accuTime += (acttime.tv_sec-oldsec)*1000000 + acttime.tv_usec - oldusec;
+
+ // reset acttime.tv_usec which means that no timer is running
+ acttime.tv_usec = 0;
+#endif
+ // timer is not running
+ running = 0;
+ }
+}
+
+inline void
+RMTimer::resume()
+{
+#ifdef __VISUALC__
+ time(&acttime);
+#else
+ gettimeofday(&acttime, &dummy);
+#endif
+
+ // timer is running
+ running = 1;
+}
+
+inline void
+RMTimer::stop()
+{
+ pause();
+
+ if(output && RManBenchmark >= bmLevel ) {
+ RMInit::bmOut << "T: " << myClass << "::" << myFunc << ": "
+ << accuTime << "us" << std::endl;
+ // set output to FALSE
+ output = 0;
+ }
+}
diff --git a/raslib/rminit.cc b/raslib/rminit.cc
new file mode 100644
index 0000000..78c68cf
--- /dev/null
+++ b/raslib/rminit.cc
@@ -0,0 +1,321 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: rminit.cc
+ *
+ * MODULE: raslib
+ * CLASS: RMInit
+ *
+ * COMMENTS:
+ *
+*/
+
+static const char rcsid[] = "@(#)raslib, RMInit: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/rminit.cc,v 1.36 2005/09/09 16:14:24 rasdev Exp $";
+
+#include "raslib/rminit.hh"
+
+#include "raslib/error.hh"
+#include "raslib/rmdebug.hh"
+
+#include <string.h>
+#include <stdlib.h>
+
+using std::cout;
+using std::ios;
+
+char* RMInit::userName = 0;
+bool RMInit::useTileContainer = false;
+bool RMInit::tiling;
+unsigned long RMInit::timeOut;
+bool RMInit::noTimeOut = 0;
+unsigned int RMInit::clientcommMaxRetry = 6; // changed from 100, with new wait algorithm in rnprotocol/rnpclientcomm.cc this is ~6sec -- PB 2005-sep-09
+unsigned int RMInit::clientcommSleep = 0;
+unsigned int RMInit::rpcMaxRetry = 5;
+
+r_Bytes RMInit::clientTileSize = 786432;
+
+RMInit::RMInit( char initApplicationType )
+ : applicationType( initApplicationType )
+{
+ char* optString;
+
+ if( applicationType == 'C' )
+ {
+ char* value;
+
+ // read environment options
+ optString = getenv("RMANCLIENTOPT");
+
+ //
+ // set log stream
+ //
+ if( optString && checkOptionString( optString, "-l", value ) )
+ if( value )
+ {
+ logFileOut.open( value );
+ logOut.rdbuf(logFileOut.rdbuf());
+ delete[] value;
+ }
+ else {
+ logOut.rdbuf(cout.rdbuf());
+ }
+ else
+ {
+ // default
+ logFileOut.open("/dev/null",ios::app); //"client.log");
+ logOut.rdbuf(logFileOut.rdbuf());
+ }
+
+
+
+ //
+ // set dbg stream
+ //
+ if( optString && checkOptionString( optString, "-d", value ) )
+ if( value )
+ {
+ dbgFileOut.open( value );
+ dbgOut.rdbuf(dbgFileOut.rdbuf());
+ delete[] value;
+ }
+ else
+ dbgOut.rdbuf(cout.rdbuf());
+ else
+ {
+ // default
+ dbgFileOut.open("/dev/null",ios::app); //"client.dbg");
+ dbgOut.rdbuf(dbgFileOut.rdbuf());
+ }
+
+
+ //
+ // set debug level
+ //
+ if( optString && checkOptionString( optString, "-dl", value ) )
+ if( value )
+ {
+ RManDebug = (int)strtoul( value, (char **)NULL, 10 );
+// It is not clarrified why the delete statement crashes with VISUALC.
+#ifndef __VISUALC__
+ delete[] value;
+#endif
+ }
+
+
+ //
+ // set bm stream
+ //
+ if( optString && checkOptionString( optString, "-b", value ) )
+ if( value )
+ {
+ bmFileOut.open( value );
+ bmOut.rdbuf(bmFileOut.rdbuf());
+ delete[] value;
+ }
+ else
+ bmOut.rdbuf(cout.rdbuf());
+ else
+ {
+ // default
+ bmFileOut.open("/dev/null",ios::app); //"client.bm");
+ bmOut.rdbuf(bmFileOut.rdbuf());
+ }
+
+
+ //
+ // set benchmark level
+ //
+ if( optString && checkOptionString( optString, "-bl", value ) )
+ if( value )
+ {
+ RManBenchmark = (int)strtoul( value, (char **)NULL, 10 );
+// It is not clarrified why the delete statement crashes with VISUALC.
+#ifndef __VISUALC__
+ delete[] value;
+#endif
+ }
+
+
+ //
+ // set tiling parameters
+ //
+ if(optString)
+ tiling = !checkOptionString( optString, "-notiling", value );
+ else
+ tiling = 1;
+
+ if( optString && checkOptionString( optString, "-tilesize", value ) )
+ if( value )
+ {
+ RMInit::clientTileSize = strtoul( value, (char **)NULL, 10 );
+ delete[] value;
+ }
+
+ if(optString && checkOptionString( optString, "-useTC", value ))
+ useTileContainer = true;
+ else
+ useTileContainer = false;
+
+ timeOut = 3600; // default
+ if( optString && checkOptionString( optString, "-timeout", value ) )
+ if( value )
+ {
+ timeOut = strtoul( value, (char **)NULL, 10 );
+ delete[] value;
+ }
+
+ if( optString && checkOptionString( optString, "-notimeout", value ) )
+ noTimeOut = 1;
+ else
+ noTimeOut = 0;
+ }
+ else
+ {
+ // default
+ logOut.rdbuf(cout.rdbuf());
+ dbgOut.rdbuf(cout.rdbuf());
+ bmOut.rdbuf(cout.rdbuf());
+ }
+
+ // initialize error text table
+ initTextTable();
+
+ // initialize user name
+ if( userName )
+ {
+ delete [] userName;
+ userName = 0;
+ }
+
+ optString = getenv("USER");
+ if( optString )
+ {
+ userName = new char[strlen(optString)+1];
+ strcpy( userName, optString );
+ }
+ else
+ {
+ userName = new char[8];
+ strcpy( userName, "unknown" );
+ }
+
+#ifdef RMANDEBUG
+ RMDebug::initRMDebug();
+#endif
+}
+
+
+
+RMInit::~RMInit()
+{
+ // reset output streams
+ logOut.rdbuf(NULL);
+ dbgOut.rdbuf(NULL);
+ bmOut.rdbuf(NULL);
+
+ // free error text table
+ freeTextTable();
+
+ if( userName )
+ {
+ delete [] userName;
+ userName = 0;
+ }
+}
+
+
+
+int
+RMInit::checkOptionString( const char* optString, const char* option, char* &value )
+{
+ char* optPos=0;
+ char* optValueStart;
+ char* optValueEnd;
+ int valueLength;
+
+ using namespace std;
+
+ value = 0;
+
+ if( (optString != NULL) && (option != NULL) )
+ {
+ unsigned short found = 0;
+
+ optPos = (char*)optString;
+
+ do{
+ optPos = strstr( optPos, option );
+
+ if( optPos )
+ {
+ // Check if character after option is either a space or end of string.
+ // If not, continue with search.
+
+ char* continuePos = optPos + strlen(option);
+
+ found = (*continuePos == ' ') || (*continuePos == '\0');
+
+ if( !found ) optPos = continuePos;
+ }
+
+ }while( !found && optPos != 0 );
+
+ }
+
+ if( optPos )
+ {
+
+ optValueStart = optPos + strlen(option); // move over option
+ while( *optValueStart == ' ' ) optValueStart++; // move over spaces
+
+ if( *optValueStart != '-' && *optValueStart != '\0' )
+ {
+ optValueEnd = optValueStart;
+ while( *optValueEnd != ' ' && *optValueEnd != '\0' ) optValueEnd++; // move over option value
+
+ valueLength = optValueEnd - optValueStart;
+ if( valueLength )
+ {
+ value = new char[valueLength+1];
+ strncpy( value, optValueStart, valueLength );
+ value[valueLength] = '\0';
+ }
+ }
+ }
+
+ /*
+ if( optPos )
+ {
+ cout << "Option " << option << " specified;" << flush;
+
+ if( value )
+ cout << " value: " << value << " length: " << strlen(value) << endl;
+ else
+ cout << endl;
+ }
+ else
+ cout << "Option " << option << " not specified." << endl;
+ */
+
+ return optPos != 0;
+}
diff --git a/raslib/rminit.hh b/raslib/rminit.hh
new file mode 100644
index 0000000..fc1ef9e
--- /dev/null
+++ b/raslib/rminit.hh
@@ -0,0 +1,181 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: rminit.hh
+ *
+ * PURPOSE:
+ * Contains the RMInit class.
+ *
+ * COMMENTS:
+ * - RASMGRPORT should be centrally defined
+*/
+
+#ifndef _RMINIT_
+#define _RMINIT_
+
+#include <iostream>
+using std::ios;
+using std::endl;
+
+#include <fstream>
+#include <raslib/mddtypes.hh>
+#include <raslib/rm.hh>
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ RMANVERSION is the version of the RasDaMan server times 1000 (int).
+ RPCVERSION is the version of the RPC interface times 1000 (int);
+
+*/
+
+//@Man: Version numbers
+// RMANVERSION now comes in via -DRMANVERSION -- PB 2003-sep-03
+// const int RMANVERSION = 5100;
+const int RPCVERSION = 1003;
+
+// default rasmgr port
+const int RASMGRPORT = 7001;
+
+// RPC timeout [secs]; used in clientcomm/rpcclientcomm.cc -- PB 2005-sep-09
+const unsigned int RPC_TIMEOUT = 3;
+
+// timeout in RNP communication
+const unsigned int RNP_COMM_TIMEOUT = 60;
+
+// timeout in nerver.cc
+const unsigned int RNP_TIMEOUT_LISTEN = 30;
+
+// maximum number of retries in rnprotocol/rnpclientcomm2.cc
+const unsigned int RNP_MAX_RETRY = 10;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class {\tt RMInit} is supposed to be instantiated just once. The scope
+ of this instance is equal to the program scope (global variable)
+ and therefore lifetime of the {\tt RMInit} instance and the application
+ are the same. The constructor is used to allocate ressources needed
+ during the whole application and the destructor cleans up memory at
+ the end of the application.
+
+*/
+
+/**
+ * \ingroup RMs
+ */
+
+class RMInit : public RM_Class
+{
+ public:
+ /// constructor
+ RMInit( char applicationType );
+
+ /// destructor
+ ~RMInit();
+
+ /// output stream for log information
+ static std::ostream logOut;
+
+ /// output stream for debug information
+ static std::ostream dbgOut;
+
+ /// output stream for benchmark information
+ static std::ostream bmOut;
+
+ /// file output for log information
+ static std::ofstream logFileOut;
+
+ /// file output for debug information
+ static std::ofstream dbgFileOut;
+
+ /// file output for benchmark information
+ static std::ofstream bmFileOut;
+
+ /// name of the user
+ static char* userName;
+
+ /// use inlinetiles and inlinetile container index
+ static bool useTileContainer;
+
+ /// switch for turning on/off tiling
+ static bool tiling;
+
+ /// specifies time out in seconds
+ static unsigned long timeOut;
+
+ /// flag, if time out checking is enabled (causes sometimes problems because of signal handler)
+ static bool noTimeOut;
+
+ static r_Bytes clientTileSize;
+
+ static unsigned int clientcommMaxRetry;
+
+ static unsigned int clientcommSleep;
+
+ static unsigned int rpcMaxRetry;
+
+ private:
+ /// check the option string for the occurance of an option and return its value if available
+ int checkOptionString( const char* optString, const char* option, char* &value );
+ /**
+ The method searches for an option of type {\tt -option value } in the option string specified.
+ It returns 1 if the option is in the string, otherwise 0. If a value is given for the option
+ to check, it is returned by the reference pointer {\tt value}. The value has to freed using
+ {\tt delete[] value} after it is not needed anymore.
+ */
+
+ /// type of application can either be 'S' for server or 'C' for client
+ char applicationType;
+};
+
+// Macro for initialization of static members and creation of global RMInit instance
+// ---------------------------------------------------------------------------------
+// The macro has to be invoked exactly once in each executable using raslib.
+//
+// rasserver -> in servercomm.o
+// rasdaman clients -> in clientcomm.o
+// test programms without clientcomm.o and servercomm.o -> in main.o
+//
+// The reason is that initialisation of globals can be initialized in any
+// order if they are in different files. Only in one file the order is defined.
+// As it is implemented now, the streams have to be defined somewhere. This
+// could easily be done in rminit.cc. But the call to the constructor of RMInit
+// has to get a flag for client ('C') or server ('S') as a parameter. This has
+// be done somewhere else. In that case the constructor may be called before
+// initialization of the streams, the pogram crashes! If all initialisations
+// are in the same file, the order is defined. That is what this macro is for.
+//
+// Note: At some point it may be useful to reimplement this mess.
+
+#define RMINITGLOBALS( appMode ) std::ostream RMInit::logOut(std::cout.rdbuf()); \
+ std::ostream RMInit::dbgOut(std::cout.rdbuf()); \
+ std::ostream RMInit::bmOut(std::cout.rdbuf()); \
+ std::ofstream RMInit::logFileOut; \
+ std::ofstream RMInit::dbgFileOut; \
+ std::ofstream RMInit::bmFileOut; \
+ RMInit rmInit( appMode );
+
+#endif
diff --git a/raslib/scalar.cc b/raslib/scalar.cc
new file mode 100644
index 0000000..23603e4
--- /dev/null
+++ b/raslib/scalar.cc
@@ -0,0 +1,120 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: scalar.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Scalar
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+#include <string.h>
+#include <fstream>
+#include <stdlib.h>
+
+#include "raslib/rminit.hh"
+#include "raslib/scalar.hh"
+#include "raslib/basetype.hh"
+#include "raslib/error.hh"
+
+
+
+
+r_Scalar::r_Scalar( const r_Base_Type* newType )
+ : valueType(NULL)
+{
+ if( newType )
+ valueType = (r_Base_Type*)newType->clone();
+ else {
+ RMInit::logOut << "r_Scalar::r_Scalar(NULL) base type must be not NULL" << endl;
+ throw r_Error(SCALARWASPASSEDNULLTYPE);
+ }
+}
+
+
+
+r_Scalar::r_Scalar( const r_Scalar& obj )
+ : valueType(obj.valueType)
+{
+}
+
+
+
+r_Scalar::~r_Scalar()
+{
+ delete valueType;
+}
+
+
+
+const r_Scalar&
+r_Scalar::operator=( const r_Scalar& obj )
+{
+ if( this != &obj )
+ {
+ delete valueType;
+ valueType = (r_Base_Type*)obj.valueType->clone();
+ }
+
+ return *this;
+}
+
+bool
+r_Scalar::isStructure() const
+ {
+ return false;
+ }
+
+bool
+r_Scalar::isComplex() const
+ {
+ return false;
+ }
+
+bool
+r_Scalar::isPrimitive() const
+ {
+ return false;
+ }
+
+const r_Base_Type*
+r_Scalar::get_type() const
+{
+ return valueType;
+}
+
+
+std::ostream& operator<<( std::ostream& s, const r_Scalar& obj )
+{
+ obj.print_status( s );
+ return s;
+}
+
+
diff --git a/raslib/scalar.hh b/raslib/scalar.hh
new file mode 100644
index 0000000..84132b4
--- /dev/null
+++ b/raslib/scalar.hh
@@ -0,0 +1,100 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: scalar.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Scalar
+ *
+ * COMMENTS:
+ *
+ * The class represents a scalar type value.
+ *
+*/
+
+#ifndef _D_SCALAR_
+#define _D_SCALAR_
+
+#include <iosfwd>
+
+#include "raslib/error.hh"
+
+class r_Base_Type;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class \Ref{r_Scalar} represents a scalar type value which
+ is either \Ref{r_Primitive} or \Ref{r_Structure}.
+
+*/
+
+class r_Scalar
+{
+ public:
+ /// constructs a scalar value
+ r_Scalar( const r_Base_Type* newType );
+
+ /// copy constructor
+ r_Scalar( const r_Scalar& obj );
+
+ /// destructor
+ virtual ~r_Scalar();
+
+ /// clone operator
+ virtual r_Scalar* clone() const=0;
+
+ /// operator for assigning a scalar
+ virtual const r_Scalar& operator= ( const r_Scalar& );
+
+ /// debug output
+ virtual void print_status(std::ostream& s) const = 0;
+
+ /// get type
+ virtual const r_Base_Type* get_type() const;
+
+ ///
+ virtual bool isStructure() const;
+
+ ///
+ virtual bool isComplex() const;
+
+ ///
+ virtual bool isPrimitive() const;
+
+ protected:
+ /// type
+ r_Base_Type* valueType;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Scalar}.
+*/
+extern std::ostream& operator<<(std::ostream& s, const r_Scalar& obj );
+
+#endif
+
diff --git a/raslib/shhopt.c b/raslib/shhopt.c
new file mode 100644
index 0000000..217c096
--- /dev/null
+++ b/raslib/shhopt.c
@@ -0,0 +1,485 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/* $Id: shhopt.c,v 1.4 2000/09/20 14:41:56 widmann Exp $ */
+/* *
+ * FILE shhopt.c
+ *
+ * DESCRIPTION Functions for parsing command line arguments. Values
+ * of miscellaneous types may be stored in variables,
+ * or passed to functions as specified.
+ *
+ * REQUIREMENTS Some systems lack the ANSI C -function strtoul. If your
+ * system is one of those, you'll ned to write one yourself,
+ * or get the GNU liberty-library (from prep.ai.mit.edu).
+ *
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "shhopt.h"
+
+/**************************************************************************
+ * *
+ * P R I V A T E D A T A *
+ * *
+ **************************************************************************/
+
+static void optFatalFunc(const char *, ...);
+static void (*optFatal)(const char *format, ...) = optFatalFunc;
+
+
+
+/**************************************************************************
+ * *
+ * P R I V A T E F U N C T I O N S *
+ * *
+ **************************************************************************/
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optFatalFunc
+ *
+ * FUNCTION Show given message and abort the program.
+ *
+ * INPUT format, ...
+ * Arguments used as with printf().
+ *
+ * RETURNS Never returns. The program is aborted.
+ *
+ */
+void optFatalFunc(const char *format, ...)
+{
+ va_list ap;
+
+ fflush(stdout);
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ exit(99);
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optStructCount
+ *
+ * FUNCTION Get number of options in a optStruct.
+ *
+ * INPUT opt array of possible options.
+ *
+ * RETURNS Number of options in the given array.
+ *
+ * DESCRIPTION Count elements in an optStruct-array. The strcture must
+ * be ended using an element of type OPT_END.
+ *
+ */
+static int optStructCount(optStruct opt[])
+{
+ int ret = 0;
+
+ while (opt[ret].type != OPT_END)
+ ++ret;
+ return ret;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optMatch
+ *
+ * FUNCTION Find a matching option.
+ *
+ * INPUT opt array of possible options.
+ * s string to match, without `-' or `--'.
+ * lng match long option, otherwise short.
+ *
+ * RETURNS Index to the option if found, -1 if not found.
+ *
+ * DESCRIPTION Short options are matched from the first character in
+ * the given string.
+ *
+ */
+static int optMatch(optStruct opt[], const char *s, int lng)
+{
+ int nopt, q, matchlen = 0;
+ char *p;
+
+ nopt = optStructCount(opt);
+ if (lng) {
+ if ((p = (char*)strchr(s, '=')) != NULL)
+ matchlen = p - s;
+ else
+ matchlen = strlen(s);
+ }
+ for (q = 0; q < nopt; q++) {
+ if (lng) {
+ if (!opt[q].longName)
+ continue;
+ if (strncmp(s, opt[q].longName, matchlen) == 0)
+ return q;
+ } else {
+ if (!opt[q].shortName)
+ continue;
+ if (*s == opt[q].shortName)
+ return q;
+ }
+ }
+ return -1;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optString
+ *
+ * FUNCTION Return a (static) string with the option name.
+ *
+ * INPUT opt the option to stringify.
+ * lng is it a long option?
+ *
+ * RETURNS Pointer to static string.
+ *
+ */
+static char *optString(optStruct *opt, int lng)
+{
+ static char ret[31];
+
+ if (lng) {
+ strcpy(ret, "--");
+ strncpy(ret + 2, opt->longName, 28);
+ } else {
+ ret[0] = '-';
+ ret[1] = opt->shortName;
+ ret[2] = '\0';
+ }
+ return ret;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optNeedsArgument
+ *
+ * FUNCTION Check if an option requires an argument.
+ *
+ * INPUT opt the option to check.
+ *
+ * RETURNS Boolean value.
+ *
+ */
+static int optNeedsArgument(optStruct *opt)
+{
+ return opt->type == OPT_STRING
+ || opt->type == OPT_INT
+ || opt->type == OPT_UINT
+ || opt->type == OPT_LONG
+ || opt->type == OPT_ULONG;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME argvRemove
+ *
+ * FUNCTION Remove an entry from an argv-array.
+ *
+ * INPUT argc pointer to number of options.
+ * argv array of option-/argument-strings.
+ * i index of option to remove.
+ *
+ * OUTPUT argc new argument count.
+ * argv array with given argument removed.
+ *
+ */
+static void argvRemove(int *argc, char *argv[], int i)
+{
+ if (i >= *argc)
+ return;
+ while (i++ < *argc)
+ argv[i - 1] = argv[i];
+ --*argc;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optExecute
+ *
+ * FUNCTION Perform the action of an option.
+ *
+ * INPUT opt array of possible options.
+ * arg argument to option, if it applies.
+ * lng was the option given as a long option?
+ *
+ * RETURNS Nothing. Aborts in case of error.
+ *
+ */
+void optExecute(optStruct *opt, char *arg, int lng)
+{
+ switch (opt->type) {
+ case OPT_FLAG:
+ if (opt->flags & OPT_CALLFUNC)
+ ((void (*)(void)) opt->arg)();
+ else
+ *((int *) opt->arg) = 1;
+ break;
+
+ case OPT_STRING:
+ if (opt->flags & OPT_CALLFUNC)
+ ((void (*)(char *)) opt->arg)(arg);
+ else
+ *((char **) opt->arg) = arg;
+ break;
+
+ case OPT_INT:
+ case OPT_LONG: {
+ long tmp;
+ char *e;
+
+ tmp = strtol(arg, &e, 10);
+ if (*e)
+ optFatal("invalid number `%s'\n", arg);
+ if (errno == ERANGE
+ || (opt->type == OPT_INT && (tmp > INT_MAX || tmp < INT_MIN)))
+ optFatal("number `%s' to `%s' out of range\n",
+ arg, optString(opt, lng));
+ if (opt->type == OPT_INT) {
+ if (opt->flags & OPT_CALLFUNC)
+ ((void (*)(int)) opt->arg)((int) tmp);
+ else
+ *((int *) opt->arg) = (int) tmp;
+ } else /* OPT_LONG */ {
+ if (opt->flags & OPT_CALLFUNC)
+ ((void (*)(long)) opt->arg)(tmp);
+ else
+ *((long *) opt->arg) = tmp;
+ }
+ break;
+ }
+
+ case OPT_UINT:
+ case OPT_ULONG: {
+ unsigned long tmp;
+ char *e;
+
+ tmp = strtoul(arg, &e, 10);
+ if (*e)
+ optFatal("invalid number `%s'\n", arg);
+ if (errno == ERANGE
+ || (opt->type == OPT_UINT && tmp > UINT_MAX))
+ optFatal("number `%s' to `%s' out of range\n",
+ arg, optString(opt, lng));
+ if (opt->type == OPT_UINT) {
+ if (opt->flags & OPT_CALLFUNC)
+ ((void (*)(unsigned)) opt->arg)((unsigned) tmp);
+ else
+ *((unsigned *) opt->arg) = (unsigned) tmp;
+ } else /* OPT_ULONG */ {
+ if (opt->flags & OPT_CALLFUNC)
+ ((void (*)(unsigned long)) opt->arg)(tmp);
+ else
+ *((unsigned long *) opt->arg) = tmp;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+
+/**************************************************************************
+ * *
+ * P U B L I C F U N C T I O N S *
+ * *
+ **************************************************************************/
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optSetFatalFunc
+ *
+ * FUNCTION Set function used to display error message and exit.
+ *
+ * SYNOPSIS #include "shhmsg.h"
+ * void optSetFatalFunc(void (*f)(const char *, ...));
+ *
+ * INPUT f function accepting printf()'like parameters,
+ * that _must_ abort the program.
+ *
+ */
+void optSetFatalFunc(void (*f)(const char *, ...))
+{
+ optFatal = f;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NAME optParseOptions
+ *
+ * FUNCTION Parse commandline options.
+ *
+ * SYNOPSIS #include "shhopt.h"
+ * void optParseOptions(int *argc, char *argv[],
+ * optStruct opt[], int allowNegNum);
+ *
+ * INPUT argc Pointer to number of options.
+ * argv Array of option-/argument-strings.
+ * opt Array of possible options.
+ * allowNegNum
+ * a negative number is not to be taken as
+ * an option.
+ *
+ * OUTPUT argc new argument count.
+ * argv array with arguments removed.
+ *
+ * RETURNS Nothing. Aborts in case of error.
+ *
+ * DESCRIPTION This function checks each option in the argv-array
+ * against strings in the opt-array, and `executes' any
+ * matching action. Any arguments to the options are
+ * extracted and stored in the variables or passed to
+ * functions pointed to by entries in opt.
+ *
+ * Options and arguments used are removed from the argv-
+ * array, and argc is decreased accordingly.
+ *
+ * Any error leads to program abortion.
+ *
+ */
+void optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
+{
+ int ai, /* argv index. */
+ optarg, /* argv index of option argument, or -1 if none. */
+ mi, /* Match index in opt. */
+ done;
+ char *arg, /* Pointer to argument to an option. */
+ *o, /* pointer to an option character */
+ *p;
+
+ /*
+ * Loop through all arguments.
+ */
+ for (ai = 0; ai < *argc; ) {
+ /*
+ * "--" indicates that the rest of the argv-array does not
+ * contain options.
+ */
+ if (strcmp(argv[ai], "--") == 0) {
+ argvRemove(argc, argv, ai);
+ break;
+ }
+
+ if (allowNegNum && argv[ai][0] == '-' && isdigit(argv[ai][1])) {
+ ++ai;
+ continue;
+ } else if (strncmp(argv[ai], "--", 2) == 0) {
+ /* long option */
+ /* find matching option */
+ if ((mi = optMatch(opt, argv[ai] + 2, 1)) < 0)
+ optFatal("unrecognized option `%s'\n", argv[ai]);
+
+ /* possibly locate the argument to this option. */
+ arg = NULL;
+ if ((p = strchr(argv[ai], '=')) != NULL)
+ arg = p + 1;
+
+ /* does this option take an argument? */
+ optarg = -1;
+ if (optNeedsArgument(&opt[mi])) {
+ /* option needs an argument. find it. */
+ if (!arg) {
+ if ((optarg = ai + 1) == *argc)
+ optFatal("option `%s' requires an argument\n",
+ optString(&opt[mi], 1));
+ arg = argv[optarg];
+ }
+ } else {
+ if (arg)
+ optFatal("option `%s' doesn't allow an argument\n",
+ optString(&opt[mi], 1));
+ }
+ /* perform the action of this option. */
+ optExecute(&opt[mi], arg, 1);
+ /* remove option and any argument from the argv-array. */
+ if (optarg >= 0)
+ argvRemove(argc, argv, ai);
+ argvRemove(argc, argv, ai);
+ } else if (*argv[ai] == '-') {
+ /* A dash by itself is not considered an option. */
+ if (argv[ai][1] == '\0') {
+ ++ai;
+ continue;
+ }
+ /* Short option(s) following */
+ o = argv[ai] + 1;
+ done = 0;
+ optarg = -1;
+ while (*o && !done) {
+ /* find matching option */
+ if ((mi = optMatch(opt, o, 0)) < 0)
+ optFatal("unrecognized option `-%c'\n", *o);
+
+ /* does this option take an argument? */
+ optarg = -1;
+ arg = NULL;
+ if (optNeedsArgument(&opt[mi])) {
+ /* option needs an argument. find it. */
+ arg = o + 1;
+ if (!*arg) {
+ if ((optarg = ai + 1) == *argc)
+ optFatal("option `%s' requires an argument\n",
+ optString(&opt[mi], 0));
+ arg = argv[optarg];
+ }
+ done = 1;
+ }
+ /* perform the action of this option. */
+ optExecute(&opt[mi], arg, 0);
+ ++o;
+ }
+ /* remove option and any argument from the argv-array. */
+ if (optarg >= 0)
+ argvRemove(argc, argv, ai);
+ argvRemove(argc, argv, ai);
+ } else {
+ /* a non-option argument */
+ ++ai;
+ }
+ }
+}
diff --git a/raslib/shhopt.h b/raslib/shhopt.h
new file mode 100644
index 0000000..2fca504
--- /dev/null
+++ b/raslib/shhopt.h
@@ -0,0 +1,56 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+/* $Id: shhopt.h,v 1.4 2000/09/20 14:41:56 widmann Exp $ */
+#ifndef SHHOPT_H
+#define SHHOPT_H
+
+/* constants for recognized option types. */
+typedef enum {
+ OPT_END, /* nothing. used as ending element. */
+ OPT_FLAG, /* no argument following. sets variable to 1. */
+ OPT_STRING, /* string argument. */
+ OPT_INT, /* signed integer argument. */
+ OPT_UINT, /* unsigned integer argument. */
+ OPT_LONG, /* signed long integer argument. */
+ OPT_ULONG /* unsigned long integer argument. */
+} optArgType;
+
+/* flags modifying the default way options are handeled. */
+#define OPT_CALLFUNC 1 /* pass argument to a function. */
+
+typedef struct {
+ char shortName; /* Short option name. */
+ char *longName; /* Long option name, no including '--'. */
+ optArgType type; /* Option type. */
+ void *arg; /* Pointer to variable to fill with argument,
+ * or pointer to function if Type == OPT_FUNC. */
+ int flags; /* Modifier flags. */
+} optStruct;
+
+
+void optSetFatalFunc(void (*f)(const char *, ...));
+void optParseOptions(int *argc, char *argv[],
+ optStruct opt[], int allowNegNum);
+
+#endif
diff --git a/raslib/sinterval.cc b/raslib/sinterval.cc
new file mode 100644
index 0000000..e05857f
--- /dev/null
+++ b/raslib/sinterval.cc
@@ -0,0 +1,1018 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: sinterval.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Sinterval
+ *
+ * COMMENTS:
+ *
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Sinterval: $Id: sinterval.cc,v 1.29 2002/08/19 11:11:25 coman Exp $";
+
+#include "sinterval.hh"
+
+#include <string>
+#include <cstring>
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+
+// for min and max
+#include <algorithm>
+
+using namespace std;
+
+
+#include "raslib/error.hh"
+#include "raslib/rminit.hh"
+
+r_Sinterval::r_Sinterval()
+ : lower_bound(0),
+ upper_bound(0),
+ low_fixed(false),
+ high_fixed(false)
+{
+}
+
+
+r_Sinterval::r_Sinterval( char* stringRep ) throw(r_Eno_interval)
+ : lower_bound(0),
+ upper_bound(0),
+ low_fixed(false),
+ high_fixed(false)
+{
+ if(!stringRep) {
+ RMInit::dbgOut << "r_Sinterval::r_Sinterval(" << (stringRep?stringRep: "NULL") << ")" << std::endl;
+ throw r_Eno_interval();
+ }
+
+ char charToken = 0;
+ r_Range valueToken = 0;
+
+ // for parsing the string
+ std::istrstream str(stringRep, strlen(stringRep) + 1);
+
+ str >> charToken;
+ if(charToken == '*')
+ set_low('*');
+ else
+ {
+ str.putback(charToken);
+ str >> valueToken;
+ set_low(valueToken);
+ }
+
+ str >> charToken;
+ if(charToken != ':')
+ {
+ // error
+ lower_bound=0;
+ upper_bound=0;
+ low_fixed=false;
+ high_fixed=false;
+
+ RMInit::dbgOut << "r_Sinterval::r_Sinterval(" << stringRep << ") string doesn't have the pattern a:b" << endl;
+ throw r_Eno_interval();
+ }
+
+ str >> charToken;
+ if(charToken == '*')
+ set_high('*');
+ else
+ {
+ str.putback(charToken);
+ str >> valueToken;
+ set_high(valueToken);
+ }
+}
+
+
+r_Sinterval::r_Sinterval( r_Range low, r_Range high ) throw( r_Eno_interval )
+ : lower_bound(low),
+ upper_bound(high),
+ low_fixed(true),
+ high_fixed(true)
+{
+ if( low > high )
+ {
+ RMInit::dbgOut << "r_Sinterval::r_Sinterval(" << low << ", " << high << ") not a interval" << endl;
+ throw r_Eno_interval();
+ }
+}
+
+
+r_Sinterval::r_Sinterval( char, r_Range high )
+ : lower_bound(0),
+ upper_bound(high),
+ low_fixed(false),
+ high_fixed(true)
+{
+}
+
+
+r_Sinterval::r_Sinterval( r_Range low, char )
+ : lower_bound(low),
+ upper_bound(0),
+ low_fixed(true),
+ high_fixed(false)
+{
+}
+
+
+r_Sinterval::r_Sinterval( char, char)
+ : lower_bound(0),
+ upper_bound(0),
+ low_fixed(false),
+ high_fixed(false)
+{
+}
+
+
+bool
+r_Sinterval::operator==( const r_Sinterval& interval ) const
+{
+ bool returnValue=true;
+
+ if (low_fixed)
+ returnValue = interval.low_fixed && lower_bound == interval.lower_bound;
+ else
+ returnValue = !interval.low_fixed;//other is fixed -> false
+ if (returnValue)
+ {
+ if( high_fixed )
+ returnValue = interval.high_fixed && upper_bound == interval.upper_bound;
+ else
+ returnValue = !interval.high_fixed;
+ }
+
+ return returnValue;
+}
+
+
+
+bool
+r_Sinterval::operator!=( const r_Sinterval& interval ) const
+{
+ return !operator==( interval );
+}
+
+r_Range
+r_Sinterval::get_extent() const throw(r_Error)
+ {
+ r_Range ext;
+
+ if(!low_fixed || !high_fixed) {
+ RMInit::dbgOut << "r_Sinterval::get_extent() low or high are not fixed (" << *this << ")" << std::endl;
+ throw r_Error(INTERVALOPEN);
+ }
+
+ ext = upper_bound - lower_bound + 1;
+
+ return ext;
+ }
+
+void
+r_Sinterval::set_low ( r_Range low ) throw( r_Eno_interval ) {
+ if( high_fixed && low > upper_bound ) {
+ RMInit::dbgOut << "r_Sinterval::set_low(" << low << ") not an interval (" << *this << ")" << endl;
+ throw r_Eno_interval();
+ }
+
+ lower_bound = low;
+ low_fixed = true;
+}
+
+
+void
+r_Sinterval::set_high( r_Range high ) throw( r_Eno_interval )
+{
+ if( low_fixed && high < lower_bound ) {
+ RMInit::dbgOut << "r_Sinterval::set_high(" << high << ") not an interval (" << *this << ")" << endl;
+ throw r_Eno_interval();
+ }
+
+ upper_bound = high;
+ high_fixed = true;
+}
+
+
+void
+r_Sinterval::set_interval( r_Range low, r_Range high ) throw( r_Eno_interval )
+{
+ if( low > high ) {
+ RMInit::dbgOut << "r_Sinterval::set_interval(" << low << ", " << high << ") not an interval (" << *this << ")" << endl;
+ throw r_Eno_interval();
+ }
+
+ lower_bound = low;
+ upper_bound = high;
+ low_fixed = true;
+ high_fixed = true;
+}
+
+
+void
+r_Sinterval::set_interval( char, r_Range high )
+{
+ lower_bound = 0;
+ upper_bound = high;
+ low_fixed = false;
+ high_fixed = true;
+}
+
+
+void
+r_Sinterval::set_interval( r_Range low, char )
+{
+ lower_bound = low;
+ upper_bound = 0;
+ low_fixed = true;
+ high_fixed = false;
+}
+
+
+void
+r_Sinterval::set_interval( char, char )
+{
+ lower_bound = 0;
+ upper_bound = 0;
+ low_fixed = false;
+ high_fixed = false;
+}
+
+
+bool
+r_Sinterval::intersects_with( const r_Sinterval& interval ) const
+{
+ int classnr = classify( *this, interval );
+
+ return classnr != 1 && classnr != 6 && classnr != 16 && classnr != 21 &&
+ classnr != 26 && classnr != 31 && classnr != 34 && classnr != 37;
+}
+
+
+r_Sinterval&
+r_Sinterval::union_of( const r_Sinterval& interval1, const r_Sinterval& interval2 ) throw( r_Eno_interval )
+{
+ *this = calc_union( interval1, interval2 );
+
+ return *this;
+}
+
+
+r_Sinterval&
+r_Sinterval::union_with( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_union( interval, *this );
+
+ return *this;
+}
+
+
+r_Sinterval&
+r_Sinterval::operator+=( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_union( interval, *this );
+
+ return *this;
+}
+
+
+r_Sinterval
+r_Sinterval::create_union( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_union( interval, *this );
+
+ return result;
+}
+
+
+r_Sinterval
+r_Sinterval::operator+( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_union( interval, *this );
+
+ return result;
+}
+
+
+r_Sinterval&
+r_Sinterval::difference_of( const r_Sinterval& interval1, const r_Sinterval& interval2 ) throw( r_Eno_interval )
+{
+ *this = calc_difference( interval1, interval2 );
+
+ return *this;
+}
+
+
+r_Sinterval&
+r_Sinterval::difference_with( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_difference( interval, *this );
+
+ return *this;
+}
+
+
+
+r_Sinterval&
+r_Sinterval::operator-=( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_difference( interval, *this );
+
+ return *this;
+}
+
+
+r_Sinterval
+r_Sinterval::create_difference( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_difference( interval, *this );
+
+ return result;
+}
+
+
+r_Sinterval
+r_Sinterval::operator-( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_difference( interval, *this );
+
+ return result;
+}
+
+
+r_Sinterval&
+r_Sinterval::intersection_of( const r_Sinterval& interval1, const r_Sinterval& interval2 ) throw( r_Eno_interval )
+{
+ *this = calc_intersection( interval1, interval2 );
+
+ return *this;
+}
+
+
+r_Sinterval&
+r_Sinterval::intersection_with( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_intersection( interval, *this );
+
+ return *this;
+}
+
+
+r_Sinterval&
+r_Sinterval::operator*=( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_intersection( interval, *this );
+
+ return *this;
+}
+
+
+r_Sinterval
+r_Sinterval::create_intersection( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_intersection( interval, *this );
+
+ return result;
+}
+
+
+r_Sinterval
+r_Sinterval::operator*( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_intersection( interval, *this );
+
+ return result;
+}
+
+
+r_Sinterval&
+r_Sinterval::closure_of( const r_Sinterval& interval1, const r_Sinterval& interval2 ) throw( r_Eno_interval )
+{
+ *this = calc_closure( interval1, interval2 );
+
+ return *this;
+}
+
+
+r_Sinterval&
+r_Sinterval::closure_with( const r_Sinterval& interval ) throw( r_Eno_interval )
+{
+ *this = calc_closure( interval, *this );
+
+ return *this;
+}
+
+
+r_Sinterval
+r_Sinterval::create_closure( const r_Sinterval& interval ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ result = calc_closure( interval, *this );
+
+ return result;
+}
+
+
+void
+r_Sinterval::print_status( std::ostream& s ) const
+{
+ if( low_fixed )
+ s << lower_bound;
+ else
+ s << "*";
+
+ s << ":";
+
+ if( high_fixed )
+ s << upper_bound;
+ else
+ s << "*";
+}
+
+
+r_Bytes
+r_Sinterval::get_storage_size( ) const
+{
+ return ( 2 * ( sizeof( r_Range ) + sizeof(bool) ) );
+}
+
+r_Sinterval
+r_Sinterval::calc_union( const r_Sinterval& a, const r_Sinterval& b ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ switch( classify( a, b ) )
+ {
+ case 2:
+ case 7:
+ case 9:
+ case 12:
+ case 22:
+ case 23:
+ case 27:
+ case 28:
+ case 35:
+ case 36:
+ // result = [a1:b2]
+
+ if( a.is_low_fixed() )
+ result.set_low( a.low() );
+ else
+ result.set_low('*');
+
+ if( b.is_high_fixed() )
+ result.set_high( b.high() );
+ else
+ result.set_high('*');
+
+ break;
+
+ case 4:
+ case 8:
+ case 10:
+ case 13:
+ case 17:
+ case 18:
+ case 32:
+ case 33:
+ case 38:
+ case 39:
+ // result = [b1:a2]
+
+ if( b.is_low_fixed() )
+ result.set_low( b.low() );
+ else
+ result.set_low('*');
+
+ if( a.is_high_fixed() )
+ result.set_high( a.high() );
+ else
+ result.set_high('*');
+
+ break;
+
+ case 3:
+ case 11:
+ case 14:
+ case 15:
+ case 19:
+ case 20:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 46:
+ case 48:
+ case 49:
+ case 52:
+ result = a;
+ break;
+
+ case 5:
+ case 24:
+ case 25:
+ case 29:
+ case 30:
+ case 40:
+ case 45:
+ case 47:
+ case 50:
+ case 51:
+ result = b;
+ break;
+
+ default: // case in { 1, 6, 16, 21, 26, 31, 34, 37 }
+ {
+ RMInit::dbgOut << "r_Sinterval::calc_union(" << a << ", " << b << ") not an interval" << endl;
+ throw r_Eno_interval();
+ }
+ }
+
+ return result;
+}
+
+
+r_Sinterval
+r_Sinterval::calc_difference( const r_Sinterval& a, const r_Sinterval& b ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ switch( classify( a, b ) )
+ {
+ case 2:
+ case 9:
+ case 20:
+ case 23:
+ case 28:
+ case 36:
+ case 39:
+ case 43:
+ case 49:
+ // result = [a1:b1]
+
+ if( a.is_low_fixed() )
+ result.set_low( a.low() );
+ else
+ result.set_low('*');
+
+ if( b.is_low_fixed() )
+ result.set_high( b.low() );
+ else
+ result.set_high('*');
+
+ break;
+
+ case 1:
+ case 6:
+ case 7:
+ case 8:
+ case 16:
+ case 17:
+ case 21:
+ case 22:
+ case 26:
+ case 27:
+ case 31:
+ case 32:
+ case 34:
+ case 35:
+ case 37:
+ case 38:
+ result = a;
+ break;
+
+ case 4:
+ case 10:
+ case 15:
+ case 18:
+ case 33:
+ case 42:
+ case 48:
+ // result = [b2:a2]
+
+ if( b.is_high_fixed() )
+ result.set_low( b.high() );
+ else
+ result.set_low('*');
+
+ if( a.is_high_fixed() )
+ result.set_high( a.high() );
+ else
+ result.set_high('*');
+
+ break;
+
+ default: // case in { 3, 5, 11, 12, 13, 14, 19, 24, 25, 29, 30, 40, 41, 44, 45, 46, 47, 50, 51, 52 }
+ {
+ RMInit::dbgOut << "r_Sinterval::calc_difference(" << a << ", " << b << ") not an interval" << endl;
+ throw r_Eno_interval();
+ }
+ }
+
+ return result;
+}
+
+
+r_Sinterval
+r_Sinterval::calc_intersection( const r_Sinterval& a, const r_Sinterval& b ) const throw( r_Eno_interval )
+{
+ r_Sinterval result;
+
+ switch( classify( a, b ) )
+ {
+ case 4:
+ case 18:
+ case 33:
+ case 39:
+ // result = [a1:b2]
+
+ if( a.is_low_fixed() )
+ result.set_low( a.low() );
+ else
+ result.set_low('*');
+
+ if( b.is_high_fixed() )
+ result.set_high( b.high() );
+ else
+ result.set_high('*');
+
+ break;
+
+ case 2:
+ case 23:
+ case 28:
+ case 36:
+ // result = [b1:a2]
+
+ if( b.is_low_fixed() )
+ result.set_low( b.low() );
+ else
+ result.set_low('*');
+
+ if( a.is_high_fixed() )
+ result.set_high( a.high() );
+ else
+ result.set_high('*');
+
+ break;
+
+ case 5:
+ case 11:
+ case 12:
+ case 13:
+ case 24:
+ case 25:
+ case 29:
+ case 30:
+ case 40:
+ case 41:
+ case 44:
+ case 45:
+ case 47:
+ case 50:
+ case 51:
+ case 52:
+ result = a;
+ break;
+
+ case 3:
+ case 9:
+ case 10:
+ case 14:
+ case 15:
+ case 19:
+ case 20:
+ case 42:
+ case 43:
+ case 46:
+ case 48:
+ case 49:
+ result = b;
+ break;
+
+ case 7:
+ case 22:
+ case 27:
+ case 35:
+ // result = [a2:a2]
+
+ if( a.is_high_fixed() )
+ result.set_interval( a.high(), a.high() );
+ else
+ result.set_interval( '*', '*' );
+
+ break;
+
+ case 8:
+ case 17:
+ case 32:
+ case 38:
+ // result = [b2:b2]
+
+ if( b.is_high_fixed() )
+ result.set_interval( b.high(), b.high() );
+ else
+ result.set_interval( '*', '*' );
+
+ break;
+
+ default: // case in { 1, 6, 16, 21, 26, 31, 34, 37 }
+ RMInit::dbgOut << "r_Sinterval::calc_intersection(" << a << ", " << b << ") not an interval" << endl;
+ throw r_Eno_interval();
+ }
+
+ return result;
+}
+
+
+r_Sinterval
+r_Sinterval::calc_closure( const r_Sinterval& a, const r_Sinterval& b ) const throw( r_Eno_interval )
+{
+ r_Sinterval closure;
+
+ if( !a.is_low_fixed() || !b.is_low_fixed() )
+ closure.set_low('*');
+ else
+ closure.set_low( std::min( a.low(), b.low() ) );
+
+ if( !a.is_high_fixed() || !b.is_high_fixed() )
+ closure.set_high('*');
+ else
+ closure.set_high( std::max( a.high(), b.high() ) );
+
+ return closure;
+}
+
+
+/*************************************************************
+ * Method name...: classify
+ *
+ * Arguments.....: Two intervals for the classification.
+ * Return value..: The classification class number (1..52).
+ * Description...: The method classifies the two intervals into
+ * one of 13 classes according to their spatial
+ * relationship. Based on the classification, the
+ * result of the operations union, difference,
+ * and intersection can be calculated as shown
+ * in the table in file sinterval.hh:
+ ************************************************************/
+
+int
+r_Sinterval::classify( const r_Sinterval& a, const r_Sinterval& b ) const
+{
+ int classification = 0;
+
+ if( a.is_low_fixed() && a.is_high_fixed() && b.is_low_fixed() && b.is_high_fixed() )
+ {
+ // classification 1..13
+
+ if( a.low() < b.low() )
+ {
+ if( a.high() < b.high() )
+ {
+ if( a.high() < b.low() )
+ classification = 1;
+ else
+ if( a.high() == b.low() )
+ classification = 7;
+ else
+ classification = 2;
+ }
+ else if( a.high() == b.high() )
+ classification = 9;
+ else
+ classification = 3;
+ }
+ else if( a.low() == b.low() )
+ {
+ if( a.high() < b.high() )
+ classification = 12;
+ else if( a.high() == b.high() )
+ classification = 11;
+ else
+ classification = 10;
+ }
+ else
+ if( a.high() < b.high() )
+ classification = 5;
+ else if( a.high() == b.high() )
+ classification = 13;
+ else
+ {
+ if( a.low() < b.high() )
+ classification = 4;
+ else if( a.low() == b.high() )
+ classification = 8;
+ else
+ classification = 6;
+ }
+ }
+ else if( a.is_low_fixed() && !a.is_high_fixed() && b.is_low_fixed() && b.is_high_fixed() )
+ {
+ // classification 14..18
+
+ if( a.low() < b.low() )
+ classification = 14;
+ else if( a.low() == b.low() )
+ classification = 15;
+ else
+ {
+ if( b.high() < a.low() )
+ classification = 16;
+ else if( b.high() == a.low() )
+ classification = 17;
+ else
+ classification = 18;
+ }
+ }
+ else if( !a.is_low_fixed() && a.is_high_fixed() && b.is_low_fixed() && b.is_high_fixed() )
+ {
+ // classification 19..23
+
+ if( a.high() > b.high() )
+ classification = 19;
+ else if( a.high() == b.high() )
+ classification = 20;
+ else
+ {
+ if( a.high() < b.low() )
+ classification = 21;
+ else if( a.high() == b.low() )
+ classification = 22;
+ else
+ classification = 23;
+ }
+ }
+ else if( a.is_low_fixed() && a.is_high_fixed() && b.is_low_fixed() && !b.is_high_fixed() )
+ {
+ // classification 24..28
+
+ if( b.low() < a.low() )
+ classification = 24;
+ else if( b.low() == a.low() )
+ classification = 25;
+ else
+ {
+ if( a.high() < b.low() )
+ classification = 26;
+ else if( a.high() == b.low() )
+ classification = 27;
+ else
+ classification = 28;
+ }
+ }
+ else if( a.is_low_fixed() && a.is_high_fixed() && !b.is_low_fixed() && b.is_high_fixed() )
+ {
+ // classification 29..33
+
+ if( b.high() > a.high() )
+ classification = 29;
+ else if( b.high() == a.high() )
+ classification = 30;
+ else
+ {
+ if( b.high() < a.low() )
+ classification = 31;
+ else if( b.high() == a.low() )
+ classification = 32;
+ else
+ classification = 33;
+ }
+ }
+ else if( !a.is_low_fixed() && a.is_high_fixed() && b.is_low_fixed() && !b.is_high_fixed() )
+ {
+ // classification 34..36
+
+ if( a.high() < b.low() )
+ classification = 34;
+ else if( a.high() == b.low() )
+ classification = 35;
+ else
+ classification = 36;
+ }
+ else if( a.is_low_fixed() && !a.is_high_fixed() && !b.is_low_fixed() && b.is_high_fixed() )
+ {
+ // classification 37..39
+
+ if( b.high() < a.low() )
+ classification = 37;
+ else if( b.high() == a.low() )
+ classification = 38;
+ else
+ classification = 39;
+ }
+ else if( !a.is_low_fixed() && a.is_high_fixed() && !b.is_low_fixed() && b.is_high_fixed() )
+ {
+ // classification 40..42
+
+ if( a.high() < b.high() )
+ classification = 40;
+ else if( a.high() == b.high() )
+ classification = 41;
+ else
+ classification = 42;
+ }
+ else if( a.is_low_fixed() && !a.is_high_fixed() && b.is_low_fixed() && !b.is_high_fixed() )
+ {
+ // classification 43..45
+
+ if( a.low() < b.low() )
+ classification = 43;
+ else if( a.low() == b.low() )
+ classification = 44;
+ else
+ classification = 45;
+ }
+ else if( !a.is_low_fixed() && !a.is_high_fixed() && b.is_low_fixed() && b.is_high_fixed() )
+ classification = 46;
+ else if( a.is_low_fixed() && a.is_high_fixed() && !b.is_low_fixed() && !b.is_high_fixed() )
+ classification = 47;
+ else if( !a.is_low_fixed() && !a.is_high_fixed() && !b.is_low_fixed() && b.is_high_fixed() )
+ classification = 48;
+ else if( !a.is_low_fixed() && !a.is_high_fixed() && b.is_low_fixed() && !b.is_high_fixed() )
+ classification = 49;
+ else if( !a.is_low_fixed() && a.is_high_fixed() && !b.is_low_fixed() && !b.is_high_fixed() )
+ classification = 50;
+ else if( a.is_low_fixed() && !a.is_high_fixed() && !b.is_low_fixed() && !b.is_high_fixed() )
+ classification = 51;
+ else // !a.is_low_fixed() && !a.is_high_fixed() && !b.is_low_fixed() && !b.is_high_fixed()
+ classification = 52;
+
+ return classification;
+}
+
+
+
+char*
+r_Sinterval::get_string_representation() const
+{
+ unsigned int bufferSize = 128; // should be enough
+
+ // allocate buffer and initialize string stream
+ char* buffer = new char[bufferSize];
+ std::ostrstream domainStream( buffer, bufferSize );
+
+ // write into string stream
+ domainStream << (*this) << ends;
+
+ // allocate memory taking the final string
+ char* returnString = strdup(buffer);
+
+ // delete buffer
+ delete[] buffer;
+
+ return returnString;
+}
+
+
+
+/*************************************************************
+ * Method name...: operator<<( std::ostream& s, r_Sinterval& d )
+ ************************************************************/
+std::ostream& operator<<( std::ostream& s, const r_Sinterval& d )
+{
+ d.print_status( s );
+ return s;
+}
+
diff --git a/raslib/sinterval.hh b/raslib/sinterval.hh
new file mode 100644
index 0000000..f3edfab
--- /dev/null
+++ b/raslib/sinterval.hh
@@ -0,0 +1,451 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: sinterval.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Sinterval
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_SINTERVAL_
+#define _D_SINTERVAL_
+
+#ifdef __VISUALC__
+// Disable warning about exception specification.
+#pragma warning( disable : 4290 )
+#endif
+
+class r_Error;
+class r_Eno_interval;
+
+#include <iostream>
+
+#include "raslib/point.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ The class represents an interval with lower and upper bound.
+ Operations on the interval are defined according to the
+ ODMG-93 standard.
+ The operations union, difference, and intersection are
+ defined according to the following table:
+
+ | ... fixed bound \\
+ * ... open bound
+
+
+ \begin{verbatim}
+
+ class orientation union difference intersection
+ -----------------------------------------------------------
+ 1 |-a-| |-b-| error a error
+
+ 2 |-a-| [a1,b2] [a1,b1] [b1,a2]
+ |-b-|
+
+ 3 |--a--| a error b
+ |-b-|
+
+ 4 |-b-| [b1,a2] [b2,a2] [a1,b2]
+ |-a-|
+
+ 5 |--b--| b error a
+ |-a-|
+
+ 6 |-b-| |-a-| error a error
+
+ 7 |-a-|-b-| [a1,b2] a [a2,a2]
+
+ 8 |-b-|-a-| [b1,a2] a [b2,b2]
+
+ 9 |--a--| a [a1,b1] b
+ |-b-|
+
+ 10 |--a--| a [b2,a2] b
+ |-b-|
+
+ 11 |-a-| a error a
+ |-b-|
+
+ 12 |--b--| b error a
+ |-a-|
+
+ 13 |--b--| b error a
+ |-a-|
+
+ -----------------------------------------------------
+
+ 14 |--a--* a error b
+ |-b-|
+
+ 15 |--a--* a [b2,a2] b
+ |-b-|
+
+ 16 |-b-| |-a-* error a error
+
+ 17 |-b-|-a-* [b1,a2] a [b2,b2]
+
+ 18 |--a--* [b1,a2] [b2,a2] [a1,b2]
+ |-b-|
+
+ -----------------------------------------------------
+
+ 19 *--a--| a error b
+ |-b-|
+
+ 20 *--a--| a [a1,b1] b
+ |-b-|
+
+ 21 *-a-| |-b-| error a error
+
+ 22 *-a-|-b-| [a1,b2] a [a2,a2]
+
+ 23 *--a--| [a1,b2] [a1,b1] [b1,a2]
+ |-b-|
+
+ -----------------------------------------------------
+
+ 24 |--b--* b error a
+ |-a-|
+
+ 25 |--b--* b error a
+ |-a-|
+
+ 26 |-a-| |-b-* error a error
+
+ 27 |-a-|-b-* [a1,b2] a [a2,a2]
+
+ 28 |--b--* [a1,b2] [a1,b1] [b1,a2]
+ |-a-|
+
+ -----------------------------------------------------
+
+ 29 *--b--| b error a
+ |-a-|
+
+ 30 *--b--| b error a
+ |-a-|
+
+ 31 *-b-| |-a-| error a error
+
+ 32 *-b-|-a-| [b1,a2] a [b2,b2]
+
+ 33 *--b--| [b1,a2] [b2,a2] [a1,b2]
+ |-a-|
+
+ -----------------------------------------------------
+
+ 34 *-a-| |-b-* error a error
+
+ 35 *-a-|-b-* [a1,b2] a [a2,a2]
+
+ 36 *-a-| [a1,b2] [a1,b1] [b1,a2]
+ |-b-*
+
+ -----------------------------------------------------
+
+ 37 *-b-| |-a-* error a error
+
+ 38 *-b-|-a-* [b1,a2] a [b2,b2]
+
+ 39 *-b-| [b1,a2] [a1,b1] [a1,b2]
+ |-a-*
+
+ -----------------------------------------------------
+
+ 40 *-a-| b error a
+ *-b-|
+
+ 41 *-a-| a error a
+ *-b-|
+
+ 42 *-b-| a [b2,a2] b
+ *-a-|
+
+ -----------------------------------------------------
+
+ 43 |-a-* a [a1,b1] b
+ |-b-*
+
+ 44 |-a-* a error a
+ |-b-*
+
+ 45 |-b-* b error a
+ |-a-*
+
+ -----------------------------------------------------
+ 46 *-a-* |-b-| a error b
+
+ 47 *-b-* |-a-| b error a
+
+ 48 *-a-* a [b2,a2] b
+ *-b-|
+
+ 49 *-a-* a [a1,b1] b
+ |-b-*
+
+ 50 *-b-* b error a
+ *-a-|
+
+ 51 *-b-* b error a
+ |-a-*
+
+ 52 *-a-* a error a
+ *-b-*
+
+ \end{verbatim}
+
+ Attention: The difference operation has to be reconsidered in future
+ concerning a discrete interpretation of the intervals.
+
+ The closure operation defines an interval which is the smallest
+ interval containing the two operands.
+ The method {\tt intersects_with()} returns 0 in the error cases of the
+ intersection operation and 1 otherwise.
+
+*/
+
+class r_Sinterval
+{
+ public:
+ /// default constructor creates an interval with open bounds
+ r_Sinterval();
+
+ /// constructor taking string representation (e.g. *:200 )
+ r_Sinterval( char* ) throw(r_Eno_interval);
+
+ /// constructor for an interval with fixed bounds
+ r_Sinterval( r_Range low, r_Range high ) throw( r_Eno_interval );
+
+ //@Man: Constructors for intervals with at least one open bound.
+ //@{
+ ///
+ r_Sinterval( char, r_Range high );
+ ///
+ r_Sinterval( r_Range low, char );
+ ///
+ r_Sinterval( char, char );
+ ///
+ //@}
+
+ /// equal operator
+ bool operator==( const r_Sinterval& ) const;
+
+ /**
+ Two intervals are equal if they have the same lower and upper bound.
+ */
+
+ /// non equal operator - negation of equal operator
+ bool operator!=( const r_Sinterval& ) const;
+
+ //@Man: Read/Write methods:
+ //@{
+ ///
+ inline r_Range low () const;
+ ///
+ inline r_Range high() const;
+ ///
+ inline bool is_low_fixed() const;
+ ///
+ inline bool is_high_fixed() const;
+
+ ///
+ void set_low ( r_Range low ) throw( r_Eno_interval );
+ ///
+ void set_high ( r_Range high ) throw( r_Eno_interval );
+ ///
+ inline void set_low ( char );
+ ///
+ inline void set_high( char );
+
+ /// get the size of one dimensional interval as range.
+ r_Range get_extent() const throw(r_Error);
+ /*@Doc:
+ Returns a range with high() - low() + 1 of this interval.
+ */
+
+ ///
+ void set_interval( r_Range low, r_Range high ) throw( r_Eno_interval );
+ ///
+ void set_interval( char, r_Range high );
+ ///
+ void set_interval( r_Range low, char );
+ ///
+ void set_interval( char, char );
+ ///
+ //@}
+
+ /// determines if the self interval intersects with the delivered one
+ bool intersects_with( const r_Sinterval& ) const;
+
+ //@Man: Methods/Operators for the union operation:
+ //@{
+ ///
+ r_Sinterval& union_of ( const r_Sinterval&, const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& union_with ( const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& operator+= ( const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval create_union ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval operator+ ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ //@}
+
+ //@Man: Methods/Operators for the difference operation:
+ //@{
+ ///
+ r_Sinterval& difference_of ( const r_Sinterval&, const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& difference_with ( const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& operator-= ( const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval create_difference ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval operator- ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ //@}
+
+ //@Man: Methods/Operators for the intersection operation:
+ //@{
+ ///
+ r_Sinterval& intersection_of ( const r_Sinterval&, const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& intersection_with ( const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& operator*= ( const r_Sinterval&)
+ throw( r_Eno_interval);
+ ///
+ r_Sinterval create_intersection ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval operator* ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ //@}
+
+ //@Man: Methods/Operators for the closure operation:
+ //@{
+ ///
+ r_Sinterval& closure_of ( const r_Sinterval&, const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval& closure_with ( const r_Sinterval& )
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval create_closure ( const r_Sinterval& ) const
+ throw( r_Eno_interval );
+ ///
+ //@}
+
+ /// writes the state of the object to the specified stream
+ void print_status( std::ostream& s = std::cout ) const;
+
+ /// gives back the string representation
+ char* get_string_representation() const;
+ /**
+ The string representation delivered by this method is allocated using {\tt malloc()} and
+ has to be free unsing {\tt free()} in the end. It can be used to construct a {\tt r_Sinterval}
+ again with a special constructor provided. The string representation is build using
+ {\tt print_status()}.
+ */
+
+ //@Man: Methods for internal use only:
+ //@{
+ /// calculate the size of the storage space occupied
+ r_Bytes get_storage_size( ) const;
+ ///
+ //@}
+
+private:
+
+ //@Man: Calculation methods for the operations:
+ //@{
+ ///
+ r_Sinterval calc_union ( const r_Sinterval& a, const r_Sinterval& b ) const
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval calc_difference ( const r_Sinterval& a, const r_Sinterval& b ) const
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval calc_intersection( const r_Sinterval& a, const r_Sinterval& b ) const
+ throw( r_Eno_interval );
+ ///
+ r_Sinterval calc_closure ( const r_Sinterval& a, const r_Sinterval& b ) const
+ throw( r_Eno_interval );
+ ///
+ //@}
+
+ /// compute the class of the two operands
+ int classify( const r_Sinterval& a, const r_Sinterval& b ) const;
+
+ //@Man: Attributes storing the bounds:
+ //@{
+ ///
+ r_Range lower_bound;
+ ///
+ r_Range upper_bound;
+ ///
+ //@}
+
+ //@Man: Attributes specifying wheter the lower/upper bound is fixed or not:
+ //@{
+ ///
+ bool low_fixed;
+ ///
+ bool high_fixed;
+ ///
+ //@}
+};
+
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const r_Sinterval}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Sinterval& d );
+
+#include "raslib/sinterval.icc"
+
+#endif
diff --git a/raslib/sinterval.icc b/raslib/sinterval.icc
new file mode 100644
index 0000000..5d3311e
--- /dev/null
+++ b/raslib/sinterval.icc
@@ -0,0 +1,76 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INLINE SOURCE: sinterval.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_Sinterval
+ *
+ * COMMENTS:
+ *
+*/
+
+inline r_Range
+r_Sinterval::low() const
+{
+ return lower_bound;
+};
+
+
+inline r_Range
+r_Sinterval::high() const
+{
+ return upper_bound;
+};
+
+
+inline bool
+r_Sinterval::is_low_fixed() const
+{
+ return low_fixed;
+};
+
+
+inline bool
+r_Sinterval::is_high_fixed() const
+{
+ return high_fixed;
+};
+
+
+inline void
+r_Sinterval::set_low( char )
+{
+ lower_bound = 0;
+ low_fixed = false;
+};
+
+
+inline void
+r_Sinterval::set_high( char )
+{
+ upper_bound = 0;
+ high_fixed = false;
+};
+
+
diff --git a/raslib/sintervaltype.cc b/raslib/sintervaltype.cc
new file mode 100644
index 0000000..241d606
--- /dev/null
+++ b/raslib/sintervaltype.cc
@@ -0,0 +1,80 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Sinterval_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/sintervaltype.cc,v 1.6 2003/12/27 23:01:21 rasdev Exp $";
+
+#include "raslib/sintervaltype.hh"
+
+r_Sinterval_Type::r_Sinterval_Type()
+ : r_Type()
+{
+}
+
+r_Sinterval_Type::r_Sinterval_Type( const r_Sinterval_Type& oldObj )
+ : r_Type(oldObj)
+{
+}
+
+r_Type*
+r_Sinterval_Type::clone() const
+{
+ return new r_Sinterval_Type( *this );
+}
+
+r_Type::r_Type_Id
+r_Sinterval_Type::type_id() const
+{
+ return SINTERVALTYPE;
+}
+
+bool
+r_Sinterval_Type::isSintervalType() const
+ {
+ return true;
+ }
+
+void
+r_Sinterval_Type::convertToLittleEndian(char* cells, r_Bytes noCells) const
+{
+}
+
+void
+r_Sinterval_Type::convertToBigEndian(char* cells, r_Bytes noCells) const
+{
+}
+
+void
+r_Sinterval_Type::print_status( std::ostream& s ) const
+{
+ s << "interval";
+}
+
+r_Sinterval_Type::~r_Sinterval_Type()
+{
+}
+
+std::ostream &operator<<( std::ostream &str, const r_Sinterval_Type &type )
+{
+ type.print_status(str);
+ return str;
+}
diff --git a/raslib/sintervaltype.hh b/raslib/sintervaltype.hh
new file mode 100644
index 0000000..1a102cd
--- /dev/null
+++ b/raslib/sintervaltype.hh
@@ -0,0 +1,81 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: sintervaltype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Sinterval_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_SINTERVAL_TYPE_
+#define _D_SINTERVAL_TYPE_
+
+#include "raslib/type.hh"
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents the sinterval type in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+class r_Sinterval_Type : public r_Type
+{
+public:
+ /// default constructor
+ r_Sinterval_Type();
+
+ /// copy constructor
+ r_Sinterval_Type( const r_Sinterval_Type& oldObj );
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const;
+
+ virtual bool isSintervalType() const;
+
+ /// destructor
+ ~r_Sinterval_Type();
+};
+
+//@Doc: write the status of a sinterval type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Sinterval_Type &type );
+
+#endif
+
+
+
diff --git a/raslib/storageman.cc b/raslib/storageman.cc
new file mode 100644
index 0000000..8527bde
--- /dev/null
+++ b/raslib/storageman.cc
@@ -0,0 +1,133 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: storageman.cc
+ *
+ * MODULE: raslib
+ *
+ * CLASSES: r_Storage_Man, r_Storage_Man_C, r_Storage_Man_CPP
+ *
+ * COMMENTS:
+ *
+ * Transparent handling of malloc/free vs. new/delete
+ *
+*/
+
+#include "mymalloc/mymalloc.h"
+
+#include "raslib/storageman.hh"
+
+
+// auxiliary static functions
+static void *alloc_c_style( size_t size )
+{
+ return mymalloc( size );
+}
+
+static void free_c_style( void *data )
+{
+ free(data);
+}
+
+static void *alloc_cpp_style( size_t size )
+{
+ return new char[size];
+}
+
+static void free_cpp_style( void *data )
+{
+ delete [] data;
+}
+
+
+
+r_Storage_Man::r_Storage_Man( void )
+{
+ myalloc = alloc_c_style;
+ myfree = free_c_style;
+}
+
+r_Storage_Man::r_Storage_Man( storage_man_alloc a, storage_man_free f )
+{
+ myalloc = a;
+ myfree = f;
+}
+
+r_Storage_Man::r_Storage_Man( const r_Storage_Man &src )
+{
+ myalloc = src.myalloc;
+ myfree = src.myfree;
+}
+
+r_Storage_Man::~r_Storage_Man( void )
+{
+}
+
+void r_Storage_Man::set_storage_functions( storage_man_alloc a, storage_man_free f )
+{
+ myalloc = a;
+ myfree = f;
+}
+
+r_Storage_Man &r_Storage_Man::operator=( const r_Storage_Man &src )
+{
+ myalloc = src.myalloc;
+ myfree = src.myfree;
+ return *this;
+}
+
+void *r_Storage_Man::storage_alloc( size_t size ) const throw(r_Error)
+{
+ void *result;
+
+ if ((result = myalloc(size)) == NULL)
+ {
+ r_Error err(r_Error::r_Error_General);
+ throw(err);
+ }
+ return result;
+}
+
+void r_Storage_Man::storage_free( void *data ) const
+{
+ myfree(data);
+}
+
+
+
+r_Storage_Man_C::r_Storage_Man_C( void ) : r_Storage_Man( alloc_c_style, free_c_style )
+{
+}
+
+r_Storage_Man_C::~r_Storage_Man_C( void )
+{
+}
+
+
+r_Storage_Man_CPP::r_Storage_Man_CPP( void ) : r_Storage_Man( alloc_cpp_style, free_cpp_style )
+{
+}
+
+r_Storage_Man_CPP::~r_Storage_Man_CPP( void )
+{
+}
diff --git a/raslib/storageman.hh b/raslib/storageman.hh
new file mode 100644
index 0000000..a985f8c
--- /dev/null
+++ b/raslib/storageman.hh
@@ -0,0 +1,116 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: storageman.hh
+ *
+ * MODULE: raslib
+ *
+ * CLASSES: r_Storage_Man, r_Storage_Man_C, r_Storage_Man_CPP
+ *
+ * COMMENTS:
+ *
+ * Transparent handling of malloc/free vs. new/delete
+ *
+*/
+
+#ifndef _R_STORAGE_MAN_
+#define _R_STORAGE_MAN_
+
+
+// for size_t
+#include <stdlib.h>
+
+#include "raslib/error.hh"
+
+
+
+//@ManMemo: Module {\bf raslib}
+
+/*@Doc:
+ r_Storage_Man provides an interface to a pair of heap management
+ functions for allocating and freeing blocks. I want to be able
+ to use constructs like sman1 = sman2, therefore I can't use
+ virtual functions to implement this.
+*/
+
+class r_Storage_Man
+{
+ public:
+
+ /// types of storage management functions
+ typedef void *(*storage_man_alloc)( size_t );
+ typedef void (*storage_man_free)( void *data );
+
+ /// default constructor, switches to c-style allocation
+ r_Storage_Man( void );
+ /// constructor setting the storage functions
+ r_Storage_Man( storage_man_alloc a, storage_man_free f );
+ /// copy constructor
+ r_Storage_Man( const r_Storage_Man &src );
+ /// destructor
+ ~r_Storage_Man( void );
+ /// setting the storage functions
+ void set_storage_functions( storage_man_alloc a, storage_man_free f );
+ /// assignment
+ r_Storage_Man &operator=( const r_Storage_Man &src );
+ /// allocation
+ void *storage_alloc( size_t size ) const throw(r_Error);
+ /// deallocation
+ void storage_free( void *data ) const;
+
+
+ protected:
+ /// the storage functions
+ storage_man_alloc myalloc;
+ storage_man_free myfree;
+};
+
+
+/*@Doc:
+ r_Storage_Man_C implements C-style allocation using malloc/free
+*/
+
+class r_Storage_Man_C : public r_Storage_Man
+{
+ public:
+ /// default constructor
+ r_Storage_Man_C( void );
+ /// default destructor
+ ~r_Storage_Man_C( void );
+};
+
+
+/*@Doc:
+ r_Storage_Man_CPP implements C++-style allocation using new/delete
+*/
+
+class r_Storage_Man_CPP : public r_Storage_Man
+{
+ public:
+ /// default constructor
+ r_Storage_Man_CPP( void );
+ /// destructor
+ ~r_Storage_Man_CPP( void );
+};
+
+#endif
diff --git a/raslib/structure.cc b/raslib/structure.cc
new file mode 100644
index 0000000..4c81015
--- /dev/null
+++ b/raslib/structure.cc
@@ -0,0 +1,282 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: structure.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Structure
+ *
+ * COMMENTS:
+ *
+*/
+
+#include "raslib/structure.hh"
+#include "raslib/primitive.hh"
+#include "raslib/structuretype.hh"
+#include "raslib/error.hh"
+#include "raslib/rminit.hh"
+#include "mymalloc/mymalloc.h"
+
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+#include <string.h>
+#include <fstream>
+#include <stdlib.h>
+
+
+
+
+r_Structure::r_Structure( const char* newBuffer, const r_Structure_Type* newType )
+ : r_Scalar( newType ),
+ numElements(0),
+ elements(NULL),
+ valueBuffer(NULL)
+{
+ if( newType )
+ {
+
+ numElements = newType->count_elements();
+ elements = new r_Scalar*[numElements];
+
+ valueBuffer = (char*)mymalloc(newType->size());
+
+ if(newBuffer)
+ memcpy(valueBuffer, newBuffer, newType->size());
+ else
+ memset(valueBuffer, 0, newType->size());
+
+ r_Structure_Type::attribute_iterator iter( newType->defines_attribute_begin() );
+
+ for( int i=0; iter != newType->defines_attribute_end(); iter++, i++ )
+ {
+ if( (*iter).type_of().type_id() == r_Type::STRUCTURETYPE )
+ elements[i] = new r_Structure( valueBuffer + (*iter).offset(), (r_Structure_Type*)&((*iter).type_of()) );
+ else
+ elements[i] = new r_Primitive( valueBuffer + (*iter).offset(), (r_Primitive_Type*)&((*iter).type_of()) );
+ }
+ }
+}
+
+
+
+r_Structure::r_Structure( const r_Structure& obj )
+ : r_Scalar( obj ),
+ numElements(obj.numElements),
+ elements(NULL),
+ valueBuffer(NULL)
+{
+ if( numElements )
+ {
+ elements = new r_Scalar*[numElements];
+
+ for( unsigned int i=0; i < numElements; i++ )
+ elements[i] = obj.elements[i]->clone();
+ }
+
+ valueBuffer = (char*) mymalloc(valueType->size());
+
+ if(obj.valueBuffer)
+ memcpy(valueBuffer, obj.valueBuffer, valueType->size());
+ else
+ memset(valueBuffer, 0, valueType->size());
+}
+
+
+
+r_Structure::~r_Structure()
+{
+ if( numElements )
+ {
+ for( unsigned int i =0; i < numElements; i++ )
+ delete elements[i];
+
+ delete[] elements;
+ }
+
+ if(valueBuffer)
+ free(valueBuffer);
+}
+
+
+
+r_Scalar*
+r_Structure::clone() const
+{
+ return new r_Structure( *this );
+}
+
+
+
+const r_Structure&
+r_Structure::operator=( const r_Structure& obj )
+{
+ if( this != &obj )
+ {
+ // assign scalar
+ r_Scalar::operator=( obj );
+
+ if( numElements )
+ {
+ for( unsigned int i =0; i < numElements; i++ )
+ delete elements[i];
+
+ delete[] elements;
+ }
+
+ if( obj.numElements )
+ {
+ numElements = obj.numElements;
+ elements = new r_Scalar*[numElements];
+
+ for( unsigned int i =0; i < numElements; i++ )
+ elements[i] = obj.elements[i]->clone();
+ }
+
+ if(valueBuffer)
+ free(valueBuffer);
+
+ valueBuffer = (char*) mymalloc(valueType->size());
+
+ if(obj.valueBuffer)
+ memcpy(valueBuffer, obj.valueBuffer, valueType->size());
+ else
+ memset(valueBuffer, 0, valueType->size());
+
+ }
+
+ return *this;
+}
+
+
+
+unsigned int
+r_Structure::count_elements() const
+{
+ return numElements;
+}
+
+const char*
+r_Structure::get_buffer() const
+{
+ memset(valueBuffer, 0, valueType->size());
+
+ r_Structure_Type::attribute_iterator iter( ((r_Structure_Type*)valueType)->defines_attribute_begin() );
+
+ for( int i=0; iter != ((r_Structure_Type*)valueType)->defines_attribute_end(); iter++, i++ )
+ if( (*iter).type_of().type_id() == r_Type::STRUCTURETYPE )
+ memcpy( valueBuffer + (*iter).offset(), ((r_Structure*)elements[i])->get_buffer(), elements[i]->get_type()->size());
+ else
+ memcpy( valueBuffer + (*iter).offset(), ((r_Primitive*)elements[i])->get_buffer(), elements[i]->get_type()->size());
+
+ return valueBuffer;
+}
+
+
+bool
+r_Structure::isStructure() const
+{
+ return true;
+}
+
+
+
+const r_Scalar&
+r_Structure::operator[]( unsigned int index ) const throw( r_Error )
+{
+ if( !valueType )
+ {
+ RMInit::logOut << "r_Structure::operator[](" << index << ") const value type is NULL" << endl;
+ throw r_Error( r_Error::r_Error_TypeInvalid );
+ }
+
+ if( index > numElements )
+ {
+ RMInit::logOut << "r_Structure::operator[](" << index << ") const index is out of bounds (" << numElements - 1 << ")" << endl;
+ throw r_Eindex_violation( 0, numElements, index );
+ }
+
+ return *(elements[index]);
+}
+
+
+
+const r_Scalar&
+r_Structure::operator[]( const char* name ) const throw( r_Error )
+{
+ if( !valueType )
+ {
+ RMInit::logOut << "r_Structure::operator[](" << name << ") value type is NULL" << endl;
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw( err );
+ }
+
+ r_Structure_Type* structType = (r_Structure_Type*)valueType;
+
+ r_Structure_Type::attribute_iterator iter( structType->defines_attribute_begin() );
+
+ int index = 0;
+ for( ; iter != structType->defines_attribute_end() && strcmp((*iter).name(), name); iter++, index++ );
+
+ if( iter == structType->defines_attribute_end() )
+ {
+ RMInit::logOut << "r_Structure::operator[](" << name << ") name is not valid" << endl;
+ r_Error err( r_Error::r_Error_NameInvalid );
+ throw( err );
+ }
+
+ return *(elements[index]);
+}
+
+
+void
+r_Structure::print_status( std::ostream& s ) const
+{
+ if( valueType )
+ {
+ s << "{ " << std::flush;
+
+ for( unsigned int i =0; i < numElements; i++ )
+ {
+ s << *(elements[i]) << std::flush;
+
+ if( i < numElements-1 )
+ s << ", " << std::flush;
+ }
+
+ s << " }" << std::flush;
+ }
+ else
+ s << "<nn>" << std::flush;
+}
+
+
+
+std::ostream& operator<<( std::ostream& s, const r_Structure& obj )
+{
+ obj.print_status( s );
+ return s;
+}
+
diff --git a/raslib/structure.hh b/raslib/structure.hh
new file mode 100644
index 0000000..a41cdbf
--- /dev/null
+++ b/raslib/structure.hh
@@ -0,0 +1,111 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: structure.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Structure
+ *
+ * COMMENTS:
+ *
+ * The class represents a structured value.
+ *
+*/
+
+#ifndef _D_STRUCTURE_
+#define _D_STRUCTURE_
+
+#include <iostream>
+
+class r_Error;
+
+#include "raslib/scalar.hh"
+
+class r_Structure_Type;
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+
+ Class \Ref{r_Structure} represents a structured value.
+
+*/
+
+class r_Structure : public r_Scalar
+{
+ public:
+ /// constructs a structured type value
+ r_Structure( const char* newBuffer, const r_Structure_Type* newType );
+
+ /// copy constructor
+ r_Structure( const r_Structure& obj );
+
+ /// destructor
+ virtual ~r_Structure();
+
+ /// clone operator
+ virtual r_Scalar* clone() const;
+
+ /// operator for assigning a structure
+ virtual const r_Structure& operator= ( const r_Structure& );
+
+ /// debug output
+ virtual void print_status(std::ostream& s) const;
+
+ /// returns true to indicate that this is a structured value
+ virtual bool isStructure() const;
+
+ /// get number of elements
+ unsigned int count_elements() const;
+
+ /// get buffer
+ const char* get_buffer() const;
+
+ /// access an element by name
+ /// throws TypeInvalid and r_Eindex_violation
+ const r_Scalar& operator[]( const char* name ) const throw( r_Error );
+
+ /// access an element by number
+ /// throws TypeInvalid and NameInvalid
+ const r_Scalar& operator[]( unsigned int ) const throw( r_Error );
+
+ private:
+ /// number of elements
+ unsigned int numElements;
+
+ /// array of pointers to elements
+ r_Scalar** elements;
+
+ /// char representation
+ char* valueBuffer;
+};
+
+
+
+//@ManMemo: Module: {\bf raslib}
+/**
+ Output stream operator for objects of type {\tt const} \Ref{r_Structure}.
+*/
+extern std::ostream& operator<<( std::ostream& s, const r_Structure& oid );
+#endif
+
diff --git a/raslib/structuretype.cc b/raslib/structuretype.cc
new file mode 100644
index 0000000..ddfd9fb
--- /dev/null
+++ b/raslib/structuretype.cc
@@ -0,0 +1,276 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Structure_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/structuretype.cc,v 1.23 2003/12/27 23:01:21 rasdev Exp $";
+
+#include <malloc.h>
+#include <string.h>
+
+#include "raslib/structuretype.hh"
+#include "raslib/attribute.hh"
+#include "raslib/rminit.hh"
+#include "raslib/error.hh"
+
+r_Structure_Type::r_Structure_Type()
+ : r_Base_Type(),
+ myAttributes(NULL),
+ numAttrs(0)
+{
+}
+
+r_Structure_Type::r_Structure_Type( char* newTypeName,
+ unsigned int newNumAttrs,
+ r_Attribute* newAttrs, int offset )
+ : r_Base_Type(newTypeName, 0),
+ numAttrs(newNumAttrs),
+ myAttributes(new r_Attribute[newNumAttrs])
+{
+ for(unsigned int i = 0; i < numAttrs; i++)
+ {
+ myAttributes[i] = newAttrs[i];
+ myAttributes[i].set_offset( typeSize );
+ myAttributes[i].set_global_offset( typeSize + offset );
+ typeSize += myAttributes[i].type_of().size();
+ }
+}
+
+r_Structure_Type::r_Structure_Type( const r_Structure_Type& oldObj )
+ : r_Base_Type(oldObj), myAttributes(NULL), numAttrs(oldObj.numAttrs)
+{
+
+ if( oldObj.myAttributes )
+ {
+ myAttributes = new r_Attribute[numAttrs];
+ for( unsigned int i = 0; i < numAttrs; i++)
+ myAttributes[i] = oldObj.myAttributes[i];
+ }
+}
+
+const r_Structure_Type&
+r_Structure_Type::operator=( const r_Structure_Type& oldObj )
+{
+ // Gracefully handle self assignment
+ if (this == &oldObj) return *this;
+
+ r_Base_Type::operator=( oldObj );
+ numAttrs = oldObj.numAttrs;
+ if( myAttributes )
+ {
+ delete[] myAttributes;
+ myAttributes=NULL;
+ }
+
+ if( oldObj.myAttributes )
+ {
+ myAttributes = new r_Attribute[numAttrs];
+ for(unsigned int i = 0; i < numAttrs; i++)
+ myAttributes[i] = oldObj.myAttributes[i];
+ }
+
+ return *this;
+}
+
+r_Structure_Type::~r_Structure_Type()
+{
+ if( myAttributes )
+ delete[] myAttributes;
+}
+
+r_Type*
+r_Structure_Type::clone() const
+{
+ return new r_Structure_Type( *this );
+}
+
+
+r_Type::r_Type_Id
+r_Structure_Type::type_id() const
+{
+ return STRUCTURETYPE;
+}
+
+bool
+r_Structure_Type::isStructType() const
+{
+ return true;
+}
+
+bool
+r_Structure_Type::compatibleWith(const r_Structure_Type* myType) const
+{
+ if(myType == NULL)
+ return false;
+ if( count_elements() != myType->count_elements())
+ return false;
+
+ r_Structure_Type::attribute_iterator myIter(defines_attribute_begin());
+ r_Structure_Type::attribute_iterator myTypeIter(myType->defines_attribute_begin());
+ r_Structure_Type::attribute_iterator myIterEnd(defines_attribute_end());
+ // FIXME not used in curr implementation
+ // r_Structure_Type::attribute_iterator myTypeIterEnd(myType->defines_attribute_end());
+ while(myIter != myIterEnd) {
+ if((*myIter).type_of().type_id() != (*myTypeIter).type_of().type_id())
+ return false;
+ myIter++;
+ myTypeIter++;
+ }
+
+ return true;
+}
+
+r_Structure_Type::attribute_iterator
+r_Structure_Type::defines_attribute_begin() const
+{
+ return attribute_iterator(myAttributes + numAttrs, myAttributes);
+}
+
+r_Structure_Type::attribute_iterator
+r_Structure_Type::defines_attribute_end() const
+{
+ return attribute_iterator(myAttributes + numAttrs - 1, myAttributes,
+ myAttributes + numAttrs);
+}
+
+r_Attribute
+r_Structure_Type::resolve_attribute(const char* name) const throw( r_Error )
+{
+ r_Structure_Type::attribute_iterator iter(defines_attribute_begin());
+
+ while( iter != defines_attribute_end() && strcmp((*iter).name(), name) != 0 )
+ iter++;
+
+ if( iter == defines_attribute_end() )
+ {
+ RMInit::logOut << "r_Structure_Type::resolve_attribute(" << name << ") not a valid atribute name" << endl;
+ r_Error err(r_Error::r_Error_NameInvalid);
+ throw err;
+ }
+
+ return (*iter);
+}
+
+r_Attribute
+r_Structure_Type::resolve_attribute(unsigned int number) const throw( r_Error )
+{
+ r_Structure_Type::attribute_iterator iter(defines_attribute_begin());
+ unsigned int i = 0;
+ while( iter != defines_attribute_end() && i < number )
+ {
+ i++;
+ iter++;
+ }
+
+ if( iter == defines_attribute_end() || i < number )
+ {
+ RMInit::logOut << "r_Structure_Type::resolve_attribute(" << number << ") index out of bounds (" << i << ")" << endl;
+ throw r_Eindex_violation( 0, numAttrs-1, number );
+ }
+
+ return (*iter);
+}
+
+r_Attribute
+r_Structure_Type::operator[]( unsigned int number ) const throw( r_Error )
+{
+ return resolve_attribute( number );
+}
+
+unsigned int
+r_Structure_Type::count_elements() const
+{
+ return numAttrs;
+}
+
+void
+r_Structure_Type::convertToLittleEndian(char* cells, r_Area noCells) const
+{
+ r_Area i = 0;
+ unsigned int j = 0;
+
+ for(i=0; i<noCells; i++) {
+ for(j=0; j<numAttrs; j++) {
+ myAttributes[j].type_of().convertToLittleEndian(
+ &cells[i*typeSize + myAttributes[j].offset()], 1);
+ }
+ }
+}
+
+void
+r_Structure_Type::convertToBigEndian(char* cells, r_Area noCells) const
+{
+ r_Area i = 0;
+ unsigned int j = 0;
+
+ for(i=0; i<noCells; i++) {
+ for(j=0; j<numAttrs; j++) {
+ myAttributes[j].type_of().convertToBigEndian(
+ &cells[i*typeSize + myAttributes[j].offset()], 1);
+ }
+ }
+}
+
+void
+r_Structure_Type::print_status( std::ostream& s ) const
+{
+ r_Structure_Type::attribute_iterator iter(defines_attribute_begin());
+
+ s << "struct{ ";
+
+ while(iter != defines_attribute_end())
+ {
+ (*iter).print_status( s );
+
+ iter++;
+
+ if( iter != defines_attribute_end() )
+ s << ", ";
+ }
+
+ s << " }";
+}
+
+void
+r_Structure_Type::print_value( const char* storage, std::ostream& s ) const
+{
+ s << "{ ";
+
+ r_Structure_Type::attribute_iterator iter( defines_attribute_begin() );
+
+ while( iter != defines_attribute_end() )
+ {
+ (*iter).type_of().print_value( storage + (*iter).offset(), s );
+
+ iter++;
+
+ if( iter != defines_attribute_end() )
+ s << ", ";
+ }
+ s << "} ";
+}
+
+
+std::ostream &operator<<( std::ostream &str, const r_Structure_Type &type )
+{
+ type.print_status(str);
+ return str;
+} \ No newline at end of file
diff --git a/raslib/structuretype.hh b/raslib/structuretype.hh
new file mode 100644
index 0000000..fae53b4
--- /dev/null
+++ b/raslib/structuretype.hh
@@ -0,0 +1,118 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: structuretype.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Structure_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_STRUCTURE_TYPE_
+#define _D_STRUCTURE_TYPE_
+
+#if (defined(__VISUALC__) && !defined(__EXECUTABLE__))
+ #define __EXECUTABLE__
+ #include "raslib/itertype.hh"
+ #undef __EXECUTABLE__
+#else
+ #include "raslib/itertype.hh"
+#endif
+
+class r_Error;
+#include "raslib/basetype.hh"
+#include "raslib/attribute.hh"
+
+
+//@ManMemo: Module: {\bf raslib}
+
+/*@Doc:
+ This class represents all user defined structured types in the
+ ODMG conformant representation of the RasDaMan type system.
+*/
+
+class r_Structure_Type : public r_Base_Type
+{
+public:
+ /// typedef for iterator iterating through all attributes;
+ typedef r_IterType<r_Attribute> attribute_iterator;
+ /// default constructor.
+ r_Structure_Type();
+ /// constructor getting name of type and type id.
+ r_Structure_Type( char* newTypeName, unsigned int newNumAttrs, r_Attribute* newAttrs, int offset = 0 );
+ /// copy constructor
+ r_Structure_Type( const r_Structure_Type& oldObj );
+ /// assignment operator.
+ const r_Structure_Type& operator=( const r_Structure_Type& oldObj );
+ /// destructor.
+ virtual ~r_Structure_Type();
+
+ /// clone operation
+ virtual r_Type* clone() const;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const;
+
+ /// check, if type is primitive or structured.
+ virtual bool isStructType() const;
+
+ /// check, if this type is compatible with myType (e.g. check the structure ignoring then names of atributtes)
+ virtual bool compatibleWith(const r_Structure_Type* myType) const;
+
+ /// returns attribute iterator at begin position.
+ attribute_iterator defines_attribute_begin() const;
+ /// returns attribute iterator at end position (behind last attribute).
+ attribute_iterator defines_attribute_end() const;
+ /// return attribute specified by name.
+ r_Attribute resolve_attribute(const char* name) const throw( r_Error );
+ /// return attribute specified by number starting with zero.
+ r_Attribute resolve_attribute(unsigned int number) const throw( r_Error );
+ /// subscript operator to access attributes by index
+ r_Attribute operator[]( unsigned int number ) const throw( r_Error );
+
+ /// get number of attributes
+ unsigned int count_elements() const;
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const;
+
+ /// writes state of object to specified stream
+ virtual void print_status( std::ostream& s = std::cout ) const;
+
+ /// prints values of a structured type
+ virtual void print_value( const char* storage, std::ostream& s = std::cout ) const;
+
+protected:
+ unsigned int numAttrs;
+ r_Attribute* myAttributes;
+};
+
+//@Doc: write the status of a structure type to a stream
+extern std::ostream &operator<<( std::ostream &str, const r_Structure_Type &type );
+
+#endif
diff --git a/raslib/template_inst.hh b/raslib/template_inst.hh
new file mode 100644
index 0000000..63874c6
--- /dev/null
+++ b/raslib/template_inst.hh
@@ -0,0 +1,78 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+// This version was created based on rview. Let's see if the other programs compile
+// also.
+
+#ifndef _TEMPLATE_INST_RASLIB_
+#define _TEMPLATE_INST_RASLIB_
+
+#include <vector>
+
+#include <raslib/attribute.hh>
+#include <raslib/itertype.hh>
+#include <raslib/dlist.hh>
+#include <raslib/minterval.hh>
+
+#include <rasodmg/tiling.hh>
+#include <rasodmg/stattiling.hh>
+#include <rasodmg/iterator.hh>
+#include <rasodmg/ref.hh>
+#include <rasodmg/object.hh>
+#include <rasodmg/set.hh>
+#include <rasodmg/collection.hh>
+#include <rasodmg/gmarray.hh>
+#include <rasodmg/transaction.hh>
+#include <rasodmg/marray.hh>
+#include <rasodmg/dirdecompose.hh>
+
+template class r_Ref<r_Object>;
+template class r_Ref<r_Minterval>;
+template class r_Collection<r_Transaction::GenRefElement *>;
+template class r_Set<r_Transaction::GenRefElement *>;
+template class r_Iterator<r_GMarray *>;
+template class r_Iterator<r_Ref<r_GMarray > >;
+template class r_Collection<r_Ref<r_GMarray> >;
+template class r_Collection<r_GMarray *>;
+template class r_Set<r_GMarray *>;
+template class r_Iterator<r_Ref<r_Object> >;
+template class r_IterType<r_Attribute>;
+template class r_Collection<r_Ref<r_Object> >;
+template class r_Set<r_Ref<r_Object> >;
+template class r_Iterator<r_Ref_Any>;
+template class r_Ref<r_GMarray>;
+template class r_Collection<r_Ref_Any>;
+template class std::vector<r_Minterval>;
+template class r_Iterator<r_Transaction::GenRefElement *>;
+template class r_Set<r_Ref<r_GMarray> >;
+template class r_Ref<r_Set<r_Ref<r_GMarray> > >;
+template class r_Set<r_Ref_Any>;
+template class r_Marray<r_ULong>;
+template class r_Marray<r_Char>;
+
+template std::ostream& operator << (std::ostream& os, const std::vector<r_Minterval>& list);
+template std::ostream& operator << (std::ostream& os, const std::vector<r_Dir_Decompose>& list);
+template std::ostream& operator << (std::ostream& os, const std::vector<r_Access>& list);
+template std::ostream& operator << (std::ostream& os, const std::vector<double>& list);
+
+#endif
diff --git a/raslib/test/Makefile b/raslib/test/Makefile
new file mode 100644
index 0000000..379b344
--- /dev/null
+++ b/raslib/test/Makefile
@@ -0,0 +1,192 @@
+# -*-Makefile-*-
+#
+# This file is part of rasdaman community.
+#
+# Rasdaman community is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rasdaman community is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>. # Top Level makefile. This points to the various modules that have to be build
+# and/or deployed
+#
+# MAKEFILE FOR:
+# test programs of module raslib
+#
+#
+# COMMENTS:
+#
+##################################################################
+#
+# This is just an example Makefile for a test program.
+# The dependency of the test program on the lib of the
+# corresponding module is in the Makefile of the module.
+#
+
+######################### Definitions ############################
+
+# standard include with general options
+include $(RMANBASE)/Makefile.inc
+
+# uses our own mem management routine:
+MYMALLOC_H := ../../mymalloc/mymalloc.hh
+MYMALLOC_O := ../../mymalloc/mymalloc_cln.o
+
+# use client specific flags
+CXXFLAGS := $(CLIENTCXXFLAGS) $(I_SYM)$(MYMALLOC_H)
+LDFLAGS := $(CLIENTLDFLAGS) $(L_SYM)$(MYMALLOC_O)
+
+# raslib has its own template directory because of the name clashes with O2
+
+ifneq ($(OSTYPE),linux-gnu)
+ CXXFLAGS := -ptr$(RMANBASE)/rasodmg/ptrepository $(CXXFLAGS)
+ LDFLAGS := -ptr$(RMANBASE)/rasodmg/ptrepository $(LDFLAGS)
+endif
+
+# all test programs
+ALLTESTS = test_error
+
+# test_sinterval test_point test_minterval test_rmdebug \
+# test_metaobject test_oid test_timer test_miter test_miterf \
+# test_params
+
+########################### Targets ##############################
+
+# test target for class r_Minterval
+.PHONY : minterval
+minterval: test_module test_minterval
+
+# test target for class r_Miter
+.PHONY : miterd
+miterd: test_module test_miterd
+
+# test target for class r_Miter
+.PHONY : miter
+miter: test_module test_miter
+
+# test target for class r_MiterFloat
+.PHONY : miterf
+miterf: test_module test_miterf
+
+# test target for class r_Sinterval
+.PHONY : sinterval
+sinterval: test_module test_sinterval
+
+# test target for class r_Point
+.PHONY : point
+point: test_module test_point
+
+# test target for class r_Error and its subclasses
+.PHONY : error
+error: test_module test_error
+
+# test target for class RMDebug
+.PHONY : rmdebug
+rmdebug: test_module test_rmdebug
+
+# test target for class r_Meta_Object and its subclasses
+.PHONY : metaobject
+metaobject: test_module test_metaobject
+
+# test target for class r_OId
+.PHONY : oid
+oid: test_module test_oid
+
+# test target for RMTimer
+.PHONY : timer
+timer: test_module test_timer
+
+# test target for lincomstreams
+.PHONY : params
+params: test_module test_params
+
+.PHONY : test_module
+test_module:
+ cd $(RMANBASE)/raslib; $(MAKE)
+
+test_minterval: test_minterval.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_miterd: test_miterd.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -lm -o $@ $^
+
+test_miter: test_miter.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -lm -o $@ $^
+
+test_miterf: test_miterf.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -lm -o $@ $^
+
+test_sinterval: test_sinterval.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_point: test_point.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_error: test_error.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_rmdebug: test_rmdebug.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_metaobject: test_metaobject.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_oid: test_oid.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_timer: test_timer.o $(RASLIB)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+test_params: test_params.o $(RASLIB) $(CLIENTCOMM)
+ $(PURIFY) $(CXX) $(LDFLAGS) -o $@ $^
+
+.PHONY : clean
+clean:
+ -rm $(ALLTESTS)
+ -rm *.o
+
+# deletes all non modified, but checked out files
+.PHONY : rcsclean
+rcsclean:
+ -rcsclean
+
+# perform all tests as part of general systemtest
+.PHONY: systemtest
+systemtest: $(ALLTESTS)
+ cp $(RMANBASE)/bin/errtxts . # needed by test_error
+ for PROG in $^; \
+ do \
+ $$PROG; \
+ done
+
+######################## Dependencies ############################
+
+test_minterval.o: test_minterval.cc $(RMANBASE)/raslib/minterval.hh
+
+test_miter.o: test_miter.cc $(RMANBASE)/raslib/miter.hh
+
+test_miterf.o: test_miterf.cc $(RMANBASE)/raslib/miterf.hh
+
+test_sinterval.o: test_sinterval.cc $(RMANBASE)/raslib/sinterval.hh
+
+test_point.o: test_point.cc $(RMANBASE)/raslib/point.hh
+
+test_error.o: test_error.cc $(RMANBASE)/raslib/error.hh
+
+test_oid.o: test_oid.cc $(RMANBASE)/raslib/oid.hh
+
+test_timer.o: test_timer.cc $(RMANBASE)/raslib/
+
+test_params.o: test_params.cc $(RMANBASE)/raslib/parseparams.hh
diff --git a/raslib/test/errtxts b/raslib/test/errtxts
new file mode 100644
index 0000000..0004f30
--- /dev/null
+++ b/raslib/test/errtxts
@@ -0,0 +1,244 @@
+190
+# Increment the number above every time you add a new exception
+#
+#
+# This file contains types and textual descriptions of RasDaMan errors.
+# The ascending error numbers are used as index to the descriptions. Each
+# line follows the following syntax:
+#
+# number^type^description.
+#
+# The character '^' is used as delimiter and with '#' a comment line is
+# started. Empty lines are not allowed.
+#
+#
+#
+#
+66^E^Exception: Memory allocation failed.
+100^E^Exception: Internal error: DL parse error.
+200^E^Exception: The result is no point.
+201^E^Exception: The result is no interval.
+202^E^Exception: Index violation ( index range [$low,$high], index $index ).
+203^E^Exception: Dimension mismatch between $dim1 and $dim2.
+204^E^Exception: Stream initialization overflow.
+205^E^Exception: Result is no cell.
+206^E^Serialisable exception r_Ebase_dbms: error in base DBMS.
+207^E^Internal client exception in class $class, method $method: $code.
+208^E^Exception: Access type $aType does not fit base type $bType.
+209^E^Exception: RasType $type is unknown.
+210^E^Exception: Base type $type is not supported yet.
+211^E^Exception: Database is not open.
+212^E^Exception: RPC layer connection to RasDaMan failed.
+213^E^Exception: Wrong URL format (should be http://address:port)
+214^E^Exception: Illegal java long value $val for server base type ULong.
+215^E^Exception: Illegal java integer value $val for server base type UShort.
+216^E^Exception: System collection is not writable.
+217^E^Exception: System collection has no OID.
+218^E^Exception: Conversion format is not supported.
+219^E^Exception: The specified tile size is smaller than the length of the base type of the mdd object.
+220^E^Exception: The tiling strategy in the storage layout is not compatible with the marray.
+221^E^Exception: The domain passed as an argument was not initialised correctly (dimension is 0).
+222^E^Exception: The type name or type structure does not represent a marray type.
+223^E^Exception: The rc index requires a marray type that has a specified domain (with fixed borders in all dimensions).
+224^E^Exception: The tile configuration is incompatible to the marray domain.
+229^E^Exception: The parameterized query has invalid parameter format.
+230^E^Exception: The r_Object was already assigned a type.
+231^E^Exception: The Marray has no base type.
+232^E^Exception: The interval has at least one open bound.
+233^E^Exception: The intervals don't have the same dimension.
+234^E^Exception: The string passed to the tiling object was not correct.
+235^E^Exception: Connection to server already closed.
+236^E^Exception: Error in compression engine
+237^E^Exception: Client communication failure
+#
+300^E^Parsing error $errorNo in line $lineNo, column $columnNo: Unexpected name $token.
+301^E^Parsing error $errorNo in line $lineNo, column $columnNo, token $token: All cell values of an MDD must be of the same type.
+302^E^Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Number of cells specified does not match the number of cells of the given spatial domain.
+303^E^Parsing error $errorNo in line $lineNo, column $columnNo, token $token: OId is not valid.
+308^E^Parsing error: Unexpected end of query.
+309^E^Parsing error: Unknown error.
+310^E^Lexical analysing error $errorNo in line $lineNo, column $columnNo: Unexpected characters $token.
+311^E^Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Complex constructor must have both arguments of the same type (i.e. float or double).
+312^E^Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Variable already defined.
+313^E^Parsing error $errorNo in line $lineNo, column $columnNo, token $token: Only constant interval bounds allowed.
+#
+330^E^Preprocessing error $errorNo in line $lineNo, column $columnNo: Unexpected name $token:
+331^E^Preprocessing error $errorNo in line $lineNo, column $columnNo, token $token: attempt to redefine function.
+332^E^Preprocessing error $errorNo in line $lineNo, column $columnNo, token $token: number of actual arguments for the called function differs from the number of formal arguments.
+333^E^Preprocessing error $errorNo in line $lineNo, column $columnNo, token $token: the called function name is ambiguous, try the full qualified name.
+#
+349^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand out of range.
+350^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: General.
+351^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Spatial domains of the binary induce operands are incompatible.
+352^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand types are incompatible.
+353^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of quantifier must be multidimensional.
+354^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of quantifier must be of type r_Marray<d_Boolean>.
+355^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Collection name is unknown.
+356^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Specified domain does not intersect with spatial domain of MDD.
+357^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Variable is unknown.
+358^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Projection operand is not of type r_Marray<T>.
+359^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Result of the where clause must be of type boolean.
+360^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Type of operand is not supported.
+361^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Multiple query targets are not supported.
+362^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Specified domain dimensionality does not equal defined dimensionality of MDD.
+#
+363^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base types of binary induce operation are incompatible.
+364^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base type and scalar type of binary induce operation are incompatible.
+365^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Scalar types of binary operation are incompatible.
+366^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base type of unary induce operation is not supported.
+367^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Scalar type of unary operation is not supported.
+368^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Cell base type for induced dot operation must be complex.
+369^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Scalar type for dot operation must be complex.
+370^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Struct selector is not valid.
+371^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Retrieval query must start with a SELECT statement.
+372^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Update query must start with an INSERT, UPDATE, DELETE, DROP or CREATE statement.
+373^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Unsatisfied MDD constant parameter.
+380^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Data type can not be converted to selected data exchange format.
+381^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Error in convertor of the selected data exchange format.
+382^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Unknown conversion format.
+383^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Parameter of oid function must be a persistent object of type MDD.
+384^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: OId is not valid.
+385^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operation is not supported on strings.
+386^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Base name of oid is not matching the currently opened one.
+387^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: System name of oid is not matching the currently used one.
+388^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Interval bound must be either an integer expression or an asterisk.
+389^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: No interval (in case of fixed bounds, the upper one can not be smaller than the lower one).
+390^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Minterval dimension specifications must be either of type interval or integer.
+391^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Spatial operation must be either of type minterval, point, or integer.
+393^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of operation lo/hi must be of type interval.
+394^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operation lo/hi can not be used for an open bound.
+395^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of function sdom() must be of type MDD.
+396^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Selection operation is not supported on this data type.
+397^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of minterval selection must be of type integer.
+398^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Index for minterval selection is out of range.
+399^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of point selection must be of type integer.
+#
+#
+#
+400^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Domain of MDD constructor has to be defined.
+401^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Can not evaluate domain expression to an minterval.
+402^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Projected cell is not defined.
+403^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Binary operation is not supported on these data types.
+404^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Type of cell expression is not supported.
+405^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: First operand of shift function must be of type MDD.
+406^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of shift function must be of type Point.
+407^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Dimensionality of MDD and point expression are not matching.
+408^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of shift function must be a constant expression.
+409^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Spatial domain shift of open bounds is not supported.
+#
+#
+#
+410^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of point expression must be of type integer.
+411^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Index for point selection is out of range.
+412^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Value expression must be either of type atomic or complex.
+413^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Condition expression must be of type boolean.
+415^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Operand of count_cells must be of type r_Marray<d_Boolean>.
+#
+416^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: First operand of scale function must be of type MDD.
+417^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of scale function must be either of type Point, Integer or Float.
+#
+418^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Second operand of bit function must be of integral type.
+419^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Could not scale the domain.
+#
+499^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: Language feature is not supported.
+#
+510^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: The argument is outside the function domain.
+511^E^Execution error $errorNo in line $lineNo, column $columnNo, near token $token: The function result exceeds the allowed range.
+#
+# 7XX errors for problems with Administration (some Oracle specific)
+#
+700^E^Admin error: General error creating RasDaMan database.
+701^E^Admin error: Error creating table in tablespace RAS_DB_SCHEMA.
+702^E^Admin error: Error inserting into table RAS_COUNTERS.
+703^E^Admin error: Error creating table in tablespace RAS_DB_BLOB.
+704^E^Admin error: Error creating index in tablespace RAS_DB_INDEX.
+705^E^Admin error: Error inserting into table RAS_BASETYPENAMES.
+706^E^Admin error: Error creating table in default tablespace.
+707^E^Admin error: Error on COMMIT creating RasDaMan database.
+708^E^Admin error: Database to be created already exists.
+#
+# 8xx errors for RasManager problems
+#
+800^E^RasManager Error: Could not connect to RasServer $url.
+801^E^RasManager Error: System overloaded, please try again later.
+802^E^RasManager Error: Acces denied, incorect user/password.
+803^E^RasManager Error: Acces denied, no permission for operation.
+804^E^RasManager Error: Acces denied, capability refused.
+805^E^RasManager Error: No suitable servers started, call rasadmin.
+806^E^RasManager Error: Write transaction in progress, please retry again later.
+807^E^RasManager Error: Requested database unknown.
+808^E^RasManager Error: Request format error.
+#
+# 9xx errors: Evaluation errors
+#
+900^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Type in typedef definition not supported.
+901^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Set template type has to be a type reference.
+902^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Type reference not found.
+903^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: MDD base type has to be a type reference or an atomic type.
+904^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: MDD type must have a domain specification.
+905^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Struct type name exists already.
+906^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: MDD type name exists already.
+907^E^Evaluation error $errorNo in line $lineNo, column $columnNo, near token $token: Set type name exists already.
+#
+950^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update target must be an iterator variable.
+951^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update source must be an expression resulting in an r_Marray<>.
+952^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update base type does not match MDD base type.
+953^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update domain is not within MDD definition domain.
+954^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update target expression must be an assignable value (l-value).
+955^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Collection name exists already.
+956^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Unknown collection type.
+957^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Unknown collection name.
+958^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Allocation of new oid failed.
+959^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: MDD and collection types are incompatible.
+960^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Insert expression must be of type MDD.
+961^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update domain must be of type Minterval.
+962^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Number of update intervals must match source dimensionaltiy.
+963^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Update domain dimensionality must match target MDD dimensionaltiy.
+964^E^Update error $errorNo in line $lineNo, column $columnNo, near token $token: Type is not persistent.
+965^E^Update error $errorNo: MDD type $token unknown.
+966^E^Update error $errorNo: MDD type is missing.
+#
+# 1xxx errors: General errors
+#
+1000^E^General error: RasDaMan tables inconsistent.
+1001^E^General error: RasDaMan server incompatible with database.
+1002^E^General error: Blob with zero length encountered.
+1003^E^General error: Tile container for TC index not found.
+1004^E^General error: Index of MDD Object is not defined.
+1005^E^General error: Storage structure of MDD Object is not defined.
+1006^E^General error: Unknown index type requested.
+1007^E^General error: Illegal index type choosen.
+1008^E^General error: No valid collection type passed to MDD collection.
+1009^E^General error: MDD object not valid or not persistent.
+1010^E^General error: No valid MDD type passed to MDD object.
+1011^E^General error: An illegal state has been reached. This is caused by a compiler bug or a library bug.
+1012^E^General error: Invalid collection type passed to MDD collection.
+1013^E^General error: The name of the type is too long.
+1014^E^General error: Invalid name of the object, should contain only [a-zA-Z0-9_]
+#
+# 2xxx errors: Internal errors
+#
+2000^E^Internal error: There seems to be another database open.
+2001^E^Internal error: Invalid OId type encountered.
+2002^E^Internal error: Entry in user defined type not found.
+2003^E^Internal error: Entry in user defined type out of bounds.
+2004^E^Internal error: Transient index used instead of persistent index.
+2005^E^Internal error: Index returned tiles multiple times.
+2006^E^Internal error: Tile was not inserted into index.
+2007^E^Internal error: Transient index access out of bounds.
+2008^E^Internal error: MDD object exists multiple times in cache.
+2009^E^Internal error: Some tile(s) were not inserted into the MDD object.
+2010^E^Internal error: A conversion module returned an incorrect base type.
+2011^E^Internal error: The collection type has no element type.
+2012^E^Internal error: The marray type has no base type.
+2013^E^Internal error: The property has no base type.
+2014^E^Internal error: The scalar was passed a NULL value.
+2015^E^Internal error: The index node that had to be split was not found in its parent.
+2016^E^Internal error: The index found more cells than allowed.
+2017^E^Internal error: The storage layout is incompatible with the index entries.
+2018^E^Internal error: Object does not support swaping.
+2019^E^Internal error: Error encountered during swaping.
+#
+# The last, the unexpected error in server
+#
+10000^E^Unexpected internal server error.
diff --git a/raslib/test/test_endian.cc b/raslib/test/test_endian.cc
new file mode 100644
index 0000000..250892a
--- /dev/null
+++ b/raslib/test/test_endian.cc
@@ -0,0 +1,156 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * INCLUDE: test_endian.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iostream>
+
+
+#ifdef EARLY_TEMPLATE
+#define __EXECUTABLE__
+#endif
+
+#include "raslib/basetype.hh"
+#include "raslib/primitivetype.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rminit.hh"
+#include "raslib/endian.hh"
+
+
+RMINITGLOBALS('C')
+
+
+static void print_numbers(const unsigned char *data, int size)
+{
+ int i;
+
+ for (i=0; i<size; i++)
+ {
+ if ((i & 15) == 0)
+ {
+ if (i != 0)
+ printf("\n");
+
+ printf("%04x: ", i);
+ }
+ printf("%02x ", data[i]);
+ }
+ printf("\n"); fflush(stdout);
+}
+
+static void test_endian(const char *schema, const r_Minterval &dom)
+{
+ r_Base_Type *type;
+ r_Primitive_Type *primType;
+ unsigned char *srcArray;
+ unsigned char *testArray;
+ unsigned char *smallArray;
+ unsigned long size;
+ unsigned long smallSize;
+ unsigned long i;
+
+ cout << "test type <" << schema << ">" << endl;
+
+ type = (r_Base_Type*)r_Type::get_any_type(schema);
+ primType = (r_Primitive_Type*)r_Type::get_any_type("long");
+
+ size = type->size() * dom.cell_count();
+
+ srcArray = new unsigned char[size];
+
+ for (i=0; i<size; i++)
+ srcArray[i] = (unsigned char)(i & 0xff);
+
+ r_Minterval iterDom(dom.dimension());
+ for (i=0; i<dom.dimension(); i++)
+ iterDom << r_Sinterval(dom[i].low(), (r_Range)(dom[i].low() + (dom[i].high() - dom[i].low() + 1) / 2));
+
+ cout << "dom = " << dom << ", iterDom = " << iterDom << endl;
+
+ print_numbers(srcArray, 64);
+
+ smallSize = type->size() * iterDom.cell_count();
+
+ testArray = new unsigned char[size];
+ memset(testArray, 0, size);
+ smallArray = new unsigned char[smallSize];
+ memset(smallArray, 0, smallSize);
+
+ cout << "Linear change..." << endl;
+ r_Endian::swap_array(primType, size, srcArray, testArray);
+ print_numbers(testArray, 64);
+
+ cout << "Semi-generic change, full..." << endl;
+ r_Endian::swap_array(type, dom, dom, srcArray, testArray);
+ print_numbers(testArray, 64);
+
+ cout << "Semi-generic change, half..." << endl;
+ r_Endian::swap_array(type, dom, iterDom, srcArray, testArray);
+ print_numbers(testArray, 64);
+
+ cout << "Fully generic change, full..." << endl;
+ r_Endian::swap_array(type, dom, dom, dom, dom, srcArray, testArray);
+ print_numbers(testArray, 64);
+
+ cout << "Fully generic change, half..." << endl;
+ r_Endian::swap_array(type, dom, iterDom, iterDom, iterDom, srcArray, smallArray);
+ print_numbers(smallArray, 64);
+
+ delete type;
+ delete primType;
+
+ delete [] smallArray;
+ delete [] testArray;
+ delete [] srcArray;
+}
+
+
+int main(int argc, char *argv[])
+{
+ r_Minterval dom(2);
+
+ dom << r_Sinterval((r_Range)0, (r_Range)123)
+ << r_Sinterval((r_Range)10, (r_Range)456);
+
+ test_endian("char", dom);
+ test_endian("short", dom);
+ test_endian("long", dom);
+ test_endian("float", dom);
+ test_endian("double", dom);
+ test_endian("struct {short, short, long}", dom);
+
+ return 0;
+}
diff --git a/raslib/test/test_error.cc b/raslib/test/test_error.cc
new file mode 100644
index 0000000..1f5fdb9
--- /dev/null
+++ b/raslib/test/test_error.cc
@@ -0,0 +1,223 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_error.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * Test program to test class r_Error and its subclasses.
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <malloc.h>
+#include "raslib/error.hh"
+
+#include "raslib/rminit.hh"
+
+RMINITGLOBALS('C')
+
+int main()
+{
+ cout << endl << "0. reading from errortxts table ----------------------------------" << endl;
+ try
+ {
+ throw r_Error( 10000 );
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "1. Throwing r_Error() -------------------------------------------" << endl;
+ try
+ {
+ throw r_Error();
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "2. Throwing r_Error( r_Error::r_Error_DatabaseUnknown ) ---------" << endl;
+ try
+ {
+ throw r_Error( r_Error::r_Error_DatabaseUnknown );
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "3. Throwing r_Eno_interval() ------------------------------------" << endl;
+ try
+ {
+ throw r_Eno_interval();
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "4. Throwing r_Eindex_violation( 10, 20, 25 ) --------------------" << endl;
+ try
+ {
+ throw r_Eindex_violation( 10, 20, 25 );
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+
+ cout << endl << "5. Throwing r_Edim_mismatch( 2, 3 ) -----------------------------" << endl;
+ try
+ {
+ throw r_Edim_mismatch( 2, 3 );
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+
+ cout << endl << "6. Throwing r_Einit_overflow() ----------------------------------" << endl;
+ try
+ {
+ throw r_Einit_overflow();
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+
+ cout << endl << "7. Throwing r_Eno_cell() ----------------------------------------" << endl;
+ try
+ {
+ throw r_Eno_cell();
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "8. Throwing r_Equery_execution_failed( 99, 5, 7, 'SELECT' ) -----" << endl;
+ try
+ {
+ throw r_Equery_execution_failed( 99, 5, 7, "SELECT" );
+ }
+ catch( r_Error &err )
+ {
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "8. Testing r_Ebase_dbms ------------------------------------------" << endl;
+ cout << endl << "8.1 Throwing (4711, 'This is a test') ----------------------------" << endl;
+ try
+ {
+ throw r_Ebase_dbms( 4711, "This is a test" );
+ }
+ catch( r_Error &err )
+ {
+ cout << "Output of what() catching an r_Error &err" << endl;
+ cout << err.what() << endl;
+ }
+ try
+ {
+ throw r_Ebase_dbms( 4711, "This is a test" );
+ }
+ catch( r_Ebase_dbms &err )
+ {
+ cout << "Output of what() catching an r_Ebase_dbms &err" << endl;
+ cout << err.what() << endl;
+ }
+
+ cout << endl << "8.2 Testing serialisation of r_Ebase_dbms ------------------------" << endl;
+ char* serialErr;
+ try
+ {
+ throw r_Ebase_dbms( 4711, "This is a test" );
+ }
+ catch( r_Error &err )
+ {
+ serialErr = err.serialiseError();
+ cout << "serialised form: " << serialErr << endl;
+ }
+ try
+ {
+ cout << "Throwing error constructed from serialised form." << endl;
+ r_Error* testErr = r_Error::getAnyError(serialErr);
+ // for some strange reason a simple throw(*testErr) does not work here. It does not work
+ // if an r_Ebase_dbms is caught (core dump), it works if an r_Error is caught. Hmm, makes
+ // some sense since *r_Error is not polymorphic anymore. But it should not core dump.
+ // Well strange, but like this it works and this will be done only once in clientcomm.cc.
+ if(testErr->get_errorno () == 206) {
+ r_Ebase_dbms correctErr(*(r_Ebase_dbms*)testErr);
+ delete testErr;
+ throw correctErr;
+ }
+ else
+ cout << "Unexpected error read from serialised representation." << endl;
+ }
+ catch( r_Ebase_dbms &err )
+ {
+ cout << "Output of what() catching an r_Ebase_dbms &err" << endl;
+ cout << err.what() << endl;
+ }
+ try
+ {
+ cout << "Throwing error constructed from serialised form." << endl;
+ r_Error* testErr = r_Error::getAnyError(serialErr);
+ if(testErr->get_errorno () == 206) {
+ r_Ebase_dbms correctErr(*(r_Ebase_dbms*)testErr);
+ delete testErr;
+ throw correctErr;
+ }
+ else
+ cout << "Unexpected error read from serialised representation." << endl;
+ }
+ catch( r_Error &err )
+ {
+ cout << "Output of what() catching an r_Error &err" << endl;
+ cout << err.what() << endl;
+ }
+ cout << "Done" << endl;
+ free(serialErr);
+
+ cout << endl;
+
+ cout << "freeing error text table...";
+ freeTextTable();
+ cout << "ok." << endl;
+
+ cout << endl << "------------------------------------------------------------------" << endl;
+
+ return 0;
+}
diff --git a/raslib/test/test_metaobject.cc b/raslib/test/test_metaobject.cc
new file mode 100644
index 0000000..4f93882
--- /dev/null
+++ b/raslib/test/test_metaobject.cc
@@ -0,0 +1,332 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_metaobject.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+
+#ifdef __VISUALC__
+ #define __EXECUTABLE__
+ #include "raslib/itertype.hh"
+ #include "raslib/structuretype.hh"
+ #include "raslib/attribute.hh"
+ #include "raslib/primitivetype.hh"
+ #include "raslib/rminit.hh"
+ #include "raslib/basetype.hh"
+ #include "raslib/marraytype.hh"
+ #undef __EXECUTABLE__
+#else
+ #include "raslib/itertype.hh"
+ #include "raslib/structuretype.hh"
+ #include "raslib/attribute.hh"
+ #include "raslib/primitivetype.hh"
+ #include "raslib/rminit.hh"
+ #include "raslib/basetype.hh"
+ #include "raslib/marraytype.hh"
+#endif
+
+#include "raslib/error.hh"
+#include "raslib/type.hh"
+#include "raslib/structure.hh"
+#include "raslib/primitive.hh"
+
+RMINITGLOBALS('C')
+
+
+void testType( const char* stringType )
+{
+ r_Type* type = NULL;
+
+ cout << "Create " << stringType << endl;
+
+ try
+ {
+ type = r_Type::get_any_type( stringType );
+ }
+ catch( r_Error& errorObj )
+ {
+ cout << errorObj.what() << endl << endl;
+ }
+
+ cout << " Type: ";
+
+ if( type )
+ {
+ type->print_status( cout );
+ cout << endl;
+ cout << type->type_id() << endl;
+ }
+ else
+ {
+ cout << "<not available>" << endl;
+ }
+ cout << endl;
+ delete type;
+
+}
+
+/*
+void testEndian()
+{
+ r_Primitive_Type boolType("Bool", r_Primitive_Type::BOOL);
+ r_Primitive_Type shortType("Short", r_Primitive_Type::SHORT);
+ r_Primitive_Type uLongType("ULong", r_Primitive_Type::ULONG);
+ r_Type* structType;
+ structType = r_Type::get_any_type( "struct{bool e1, short e2, ulong e3}" );
+
+ char cChar = 47;
+ short cShort = 1065;
+ unsigned long cULong = 92753;
+
+ char *boolCell = (char*)&cChar;
+ char *shortCell = (char*)&cShort;
+ char *uLongCell = (char*)&cULong;
+ char structCell[7] = { 1, 2, 3, 4, 5, 6, 7 };
+
+ cout << "Before convertToLittleEndian:" << endl;
+ cout << "Char: " << (long)*boolCell << endl
+ << "Short: " << (long)*shortCell << " " << (long)*(shortCell+1) << endl
+ << "ULong: " << (long)*uLongCell << " " << (long)*(uLongCell+1) << " "
+ << (long)*(uLongCell+2) << " " << (long)*(uLongCell+3)
+ << endl
+ << "Struct: " << (long)*structCell << " " << (long)*(structCell+1)
+ << " " << (long)*(structCell+2) << " "
+ << (long)*(structCell+3) << " "
+ << (long)*(structCell+4) << " "
+ << (long)*(structCell+5) << " "
+ << (long)*(structCell+6) << " "
+ << endl;
+
+ boolType.convertToLittleEndian(boolCell, 1);
+ shortType.convertToLittleEndian(shortCell, 1);
+ uLongType.convertToLittleEndian(uLongCell, 1);
+ structType->convertToLittleEndian(structCell, 1);
+
+ cout << "After convertToLittleEndian:" << endl;
+ cout << "Char: " << (long)*boolCell << endl
+ << "Short: " << (long)*shortCell << " " << (long)*(shortCell+1) << endl
+ << "ULong: " << (long)*uLongCell << " " << (long)*(uLongCell+1) << " "
+ << (long)*(uLongCell+2) << " " << (long)*(uLongCell+3)
+ << endl
+ << "Struct: " << (long)*structCell << " " << (long)*(structCell+1)
+ << " " << (long)*(structCell+2) << " "
+ << (long)*(structCell+3) << " "
+ << (long)*(structCell+4) << " "
+ << (long)*(structCell+5) << " "
+ << (long)*(structCell+6) << " "
+ << endl;
+
+ boolType.convertToBigEndian(boolCell, 1);
+ shortType.convertToBigEndian(shortCell, 1);
+ uLongType.convertToBigEndian(uLongCell, 1);
+ structType->convertToLittleEndian(structCell, 1);
+
+ cout << "After convertToBigEndian:" << endl;
+ cout << "Char: " << (long)*boolCell << endl
+ << "Short: " << (long)*shortCell << " " << (long)*(shortCell+1) << endl
+ << "ULong: " << (long)*uLongCell << " " << (long)*(uLongCell+1) << " "
+ << (long)*(uLongCell+2) << " " << (long)*(uLongCell+3)
+ << endl
+ << "Struct: " << (long)*structCell << " " << (long)*(structCell+1)
+ << " " << (long)*(structCell+2) << " "
+ << (long)*(structCell+3) << " "
+ << (long)*(structCell+4) << " "
+ << (long)*(structCell+5) << " "
+ << (long)*(structCell+6) << " "
+ << endl;
+
+ delete structType;
+}
+*/
+
+int main()
+{
+ cout << "Creating definining primitive types ..." << endl;
+ r_Primitive_Type myBool("Bool", r_Primitive_Type::BOOL);
+ myBool.print_status( cout ); cout << endl;
+ r_Primitive_Type myULong("ULong", r_Primitive_Type::ULONG);
+ myULong.print_status( cout ); cout << endl;
+
+ r_Primitive_Type tmp = myBool;
+ tmp.print_status( cout ); cout << endl;
+
+ r_Attribute tmpAtt("tmpAtt",tmp );
+ tmpAtt.print_status( cout ); cout << endl;
+
+ cout << "Creating a struct out of them ..." << endl;
+ r_Attribute myAttrs[2];
+ myAttrs[0] = r_Attribute("Attr1", myBool );
+ myAttrs[1] = r_Attribute("Attr2", myULong );
+
+ r_Structure_Type myStruct("aStruct", 2, myAttrs);
+ myStruct.print_status( cout ); cout << endl;
+
+ cout << "Iterating attributes of struct:" << endl;
+ r_Structure_Type::attribute_iterator
+ iter(myStruct.defines_attribute_begin());
+ while(iter != myStruct.defines_attribute_end())
+ {
+ cout << " Name of Attribute: " << (*iter).name() << endl;
+ cout << " Offset of Attribute: " << (*iter).offset() << endl;
+ cout << " Size of type of Attribute: "
+ << (*iter).type_of().size() << endl;
+ cout << " Name of type of Attribute: "
+ << (*iter).type_of().name() << endl;
+ ++iter;
+ }
+
+ testType("char");
+
+ testType("octet");
+ testType("short");
+ testType("ushort");
+ testType("long");
+ testType("ulong");
+ testType("bool");
+ testType("float");
+ testType("double");
+
+ testType("struct{ char }");
+ testType("struct{ char band1 }");
+
+ testType("struct{ char, octet, ulong, short }");
+
+ testType("struct{ char elem1, octet elem2, ulong elem3, short elem4 }");
+ testType("struct{ char red, char green, char blue }" );
+ testType("struct{char red, char green, char blue}" );
+
+ testType("struct{ struct{ char, char, char }, ulong }");
+ testType("struct{ struct{ char elem1, char elem2, char elem3 } record, ulong value }");
+
+
+ testType("marray< char >");
+ testType("marray< char green>");
+ testType("marray< struct{ char red} >");
+
+ testType("marray< struct{char red, char green, char blue} >" );
+
+ testType("set< marray< char > >");
+ testType("set< marray< struct{ char red, char green, char blue } > >" );
+
+ testType("interval");
+ testType("minterval");
+ testType("point");
+ testType("oid");
+
+ testType("set< interval >");
+ testType("set< minterval >");
+ testType("set< point >");
+ testType("set< oid >");
+
+ /* shouldn't work */
+ cout << endl << "Testing combinations which are not allowed..." << endl;
+ testType("set< marray< interval > >");
+ testType("set< marray< minterval > >");
+ testType("set< marray< point > >");
+ testType("set< marray< oid > >");
+
+ testType("interval<set< marray< char > > >");
+ testType("interval<struct{ point blue, interval green}>");
+ testType("set< marray{ char > >");
+ testType("struct<char>");
+
+
+
+ r_Type* type = NULL;
+ char* stringType = "marray< char blue>";
+
+ cout << "Create " << stringType << endl;
+
+ try
+ {
+ type = r_Type::get_any_type( stringType );
+ }
+ catch( r_Error& errorObj )
+ {
+ cout << errorObj.what() << endl << endl;
+ }
+
+ cout << " Type: ";
+
+ if( type )
+ {
+ type->print_status( cout );
+ }
+ else
+ {
+ cout << "<not available>" << endl;
+ }
+ cout << endl;
+
+ // cout << ((r_Marray_Type*)type)->getBaseType() << endl;
+
+ cout << "Erzeugen einer Kopie und Ausgabe..." << endl;
+ r_Marray_Type my_marray;
+
+ my_marray = *((r_Marray_Type*)(type));
+ my_marray.print_status( cout );
+
+ cout << endl;
+ // cout << my_marray.getBaseType() << endl;
+
+ delete type;
+
+ r_Type* type2 = r_Type::get_any_type("struct{ short band1, char band2 }");
+
+ if( type2->isBaseType() )
+ {
+ r_Base_Type* baseType2 = (r_Base_Type*)type2;
+
+ cout << "Type: " << flush;
+ baseType2->print_status();
+ cout << endl;
+ cout << "Size: " << baseType2->size() << endl;
+ }
+
+ struct structType{ short band1r; char band2i; };
+
+ structType structValue = { 1, 2 };
+
+ r_Structure structObject( (const char*)&structValue, (const r_Structure_Type*)type2 );
+
+ structObject.print_status( cout );
+
+ cout << endl;
+
+ delete type2;
+
+ /* testEndian(); */
+ return 0;
+}
+
+
diff --git a/raslib/test/test_minterval.cc b/raslib/test/test_minterval.cc
new file mode 100644
index 0000000..f8f388f
--- /dev/null
+++ b/raslib/test/test_minterval.cc
@@ -0,0 +1,118 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_sinterval.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <malloc.h>
+
+#include "raslib/minterval.hh"
+#include "raslib/sinterval.hh"
+
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+int main()
+{
+ cout << endl << endl;
+ cout << "Minterval Examples" << endl;
+ cout << "===================" << endl << endl;
+
+ cout << "initializing interval [1:2,3:3] : " << endl;
+ r_Minterval m1 = r_Minterval(2);
+ m1 << r_Sinterval(1l,2l) << 3;
+ cout << m1 << endl << endl;
+
+ cout << "copy the interval with copy constructor" << endl;
+ r_Minterval copy( m1 );
+ cout << copy << endl << endl;
+
+ cout << "test for equality: ";
+ if( copy == m1 )
+ cout << "OK" << endl << endl;
+ else
+ cout << "FAILED" << endl << endl;
+
+ cout << "union of [1:4,3:6] and [3:6,1:4] :" << endl;
+ r_Minterval m2 = r_Minterval(2) << r_Sinterval(1l,4l) << r_Sinterval(3l,6l);
+ r_Minterval m3 = r_Minterval(2) << r_Sinterval(3l,6l) << r_Sinterval(1l,4l);
+ try
+ {
+ m2 += m3;
+ }
+ catch( r_Error& ex1 )
+ {
+ cerr << ex1.what() << endl;
+ }
+ cout << m2 << endl << endl;
+
+ cout << "union of [1:4,3:6] and [3:6,8:9] : " << endl;
+ r_Minterval m4 = r_Minterval(2) << r_Sinterval(1l,4l) << r_Sinterval(3l,6l);
+ r_Minterval m5 = r_Minterval(2) << r_Sinterval(3l,6l) << r_Sinterval(8l,9l);
+ try
+ {
+ m4 += m5;
+ }
+ catch( r_Error& ex2 )
+ {
+ cerr << ex2.what() << endl;
+ }
+ cout << m4 << endl << endl;
+
+ cout << "closure of [1:4,3:6] and [7:9,1:2] : " << endl;
+ r_Minterval m6 = r_Minterval(2) << r_Sinterval(1l,4l) << r_Sinterval(3l,6l);
+ r_Minterval m7 = r_Minterval(2) << r_Sinterval(7l,9l) << r_Sinterval(1l,2l);
+ try
+ {
+ m6.closure_with( m7 );
+ }
+ catch( r_Error& ex2 )
+ {
+ cerr << ex2.what() << endl;
+ }
+ cout << m6 << endl << endl;
+
+ cout << "intersection of [7:9,1:2] and [ " << m6[0].low() << ":" << m6[0].high() << "," << m6[1].low() << ":" << m6[1].high() << "]" << endl;
+ cout << m7.intersects_with( m6 );
+ cout << endl;
+
+ cout << "initializing domain [1:4,*:6,7:*]" << endl;
+ r_Minterval m8 = r_Minterval(3) << r_Sinterval(1l,4l) << r_Sinterval('*',6l) << r_Sinterval(7l,'*');
+ char* stringRepresentation = m8.get_string_representation();
+ cout << "string representation " << stringRepresentation << " should be " << m8 << endl;
+
+ r_Minterval m9 = r_Minterval( stringRepresentation );
+ cout << "recreation of the string delivers " << m9 << endl;
+ free( stringRepresentation );
+
+ return 0;
+}
diff --git a/raslib/test/test_miter.cc b/raslib/test/test_miter.cc
new file mode 100644
index 0000000..55b2930
--- /dev/null
+++ b/raslib/test/test_miter.cc
@@ -0,0 +1,334 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_miter.cc
+ *
+ * MODULE: raslib
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <math.h>
+#include <stdlib.h>
+
+#include "raslib/miter.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+RMINITGLOBALS('C')
+
+// structure storing information on iteration for each dimension
+// (perhaps add dimension for reordering later)
+typedef struct {
+ int repeat; // total number of repeats
+ int inc; // increment per repeat
+ int curr; // current repeat
+} incArrElem;
+
+// for repeating inside the test functions
+const int numRepeat = 100;
+
+r_Minterval
+createCube(int size, int dim)
+{
+ int i;
+ long c = pow((double)size, 1.0/(double)dim);
+
+ r_Minterval res(dim);
+
+ for(i=0; i<dim; i++)
+ res << r_Sinterval(0l, c-1);
+
+ i = 0;
+ while(res.cell_count() < size) {
+ res[i].set_high(res[i].high() + 1);
+ i++;
+ }
+ if(res.cell_count() > size)
+ res[i-1].set_high(res[i-1].high() - 1);
+
+ return res;
+}
+
+void
+test_Miter( r_Minterval& m1, r_Minterval& m2, char* data )
+{
+ char* currCell;
+
+ // just to do something inside the loop
+ unsigned long sum = 0;
+
+ cout <<"Iteration r_Miter: ";
+
+ // for performance measurement
+ RMTimer mIterTimer("Iterator","r_Miter" );
+ mIterTimer.start( );
+
+ r_Miter iter(&m2, &m1, 4, (char*)data);
+ for(int i=0; i<numRepeat; i++) {
+ iter.reset();
+ while(!iter.isDone()) {
+ currCell = iter.nextCell();
+ sum += *(long*)currCell;
+ }
+ }
+
+ mIterTimer.stop( );
+ cout << sum << endl;
+}
+
+void
+test_DirectIter( r_Minterval& m1, r_Minterval& m2, char* data )
+{
+ int opSize = 4;
+ int dim = m1.dimension();
+ int i;
+ char* currCell;
+
+ // just to do something inside the loop
+ unsigned long sum = 0;
+
+ incArrElem* incArrIter;
+
+ cout <<"Iteration direct: ";
+
+ // for performance measurement
+ RMTimer iterTimer("Iterator","directIter" );
+ iterTimer.start( );
+
+ for(int r=0; r<numRepeat; r++) {
+
+ // stores the increments
+ incArrIter = new incArrElem[dim];
+
+ currCell = (char*)data;
+
+ // the following initializes incArrIter and calculates the first offset
+ int tIncIter = 1; // total increment for current dimension
+ int prevTIncIter = 1; // total increment for previous dimension
+ int incIter = 4; // current increment, corresponds to cell size
+ int firstOff = 0;
+
+ for( i=0; i<dim; i++ ) {
+ // in RasDaMan the order of dimensions is the other way round!
+ int r = dim - i - 1;
+ // used for counting in iteration, initialize with 0
+ incArrIter[i].curr = 0;
+ // how often is the increment added?
+ incArrIter[i].repeat = m2[r].high() - m2[r].low() + 1;
+ // the increment for the result tile (higher dimensions calculated
+ // further down)
+ incArrIter[i].inc = incIter;
+
+ // calculate starting offset and increments for higher dimensions
+ // firstOff is the offset in chars of the first cell
+ firstOff += (m2[r].low()-m1[r].low()) * prevTIncIter * 4;
+ // tInc is the increment if the dimension would be skipped
+ tIncIter = (m1[r].high() - m1[r].low()+1) * prevTIncIter;
+ // inc is the real increment, after some cells in the dimensions
+ // have been iterated through.
+ incIter = (tIncIter - incArrIter[i].repeat*prevTIncIter) * 4;
+ // remember total increment of last dimension
+ prevTIncIter = tIncIter;
+ }
+
+ currCell += firstOff;
+
+ int done = 0;
+ // get first adresses
+
+ while(!done) {
+ // iterate through lowest dimension
+ for(i=0; i<incArrIter[0].repeat; i++) {
+ // execute operation
+ sum += *(long*)currCell;
+ // increment adresses
+ currCell += incArrIter[0].inc;
+ }
+ // increment other dimensions
+ for(i=1; i<dim; i++) {
+ incArrIter[i].curr++;
+ currCell += incArrIter[i].inc;
+ if(incArrIter[i].curr < incArrIter[i].repeat) {
+ // no overflow in this dimension
+ break;
+ } else {
+ // overflow in this dimension
+ incArrIter[i].curr = 0;
+ }
+ }
+ if( i == dim ) {
+ // overflow in last dimension
+ done = 1;
+ }
+ }
+ delete [] incArrIter;
+ }
+ iterTimer.stop();
+ cout << sum << endl;
+}
+
+void
+test_OldIter( r_Minterval& m1, r_Minterval& m2, char* data )
+{
+ // just to do something inside the loop
+ unsigned long sum = 0;
+
+ cout <<"Iteration oldIter: ";
+ // for performance measurement
+ RMTimer oldIterTimer("Iterator","oldIter" );
+ oldIterTimer.start( );
+
+ r_Point pOp(m2.dimension());
+ int done;
+ int recalc;
+ int i, j;
+ const int opSize = 4;
+ int dim = m2.dimension();
+ int innerExtent = (m2.get_extent())[dim-1];
+ char* cellOp;
+
+ // initialize points
+ for(i = 0; i < dim; i++)
+ {
+ pOp << 0;
+ }
+
+ for(int r=0; r<numRepeat; r++) {
+ done = 0;
+ recalc = 0;
+
+ // initialize points
+ for(i = 0; i < dim; i++)
+ {
+ pOp[i] = m2[i].low();
+ }
+
+ cellOp = (char*)data + m1.cell_offset(pOp)*4;
+
+ // iterate over all cells
+ while(!done)
+ {
+ if( recalc )
+ {
+ cellOp = (char*)data + m1.cell_offset(pOp)*4;
+ recalc = 0;
+ }
+
+ // iterate through innermost dimension
+ for(j = 0; j < innerExtent; j++ ) {
+ // execute operation on cell
+ sum += *(long*)cellOp;
+ cellOp += opSize;
+ }
+
+ // increment coordinates
+ i = dim - 2;
+ // special case! 1-D operands!
+ if( i < 0 )
+ break;
+ ++pOp[i];
+ recalc = 1;
+ while( pOp[i] > m2[i].high() )
+ {
+ pOp[i] = m2[i].low();
+ i--;
+ if(i < 0)
+ {
+ done = 1;
+ break;
+ }
+ ++pOp[i];
+ }
+ }
+ }
+
+ oldIterTimer.stop();
+ cout << sum << endl;
+}
+
+void
+test_CppIter( unsigned long cells, char* data )
+{
+ unsigned long sum = 0;
+ RMTimer cppIterTimer("Iterator", "cppIter");
+ cppIterTimer.start();
+
+ for(int r=0; r<numRepeat; r++) {
+ for(int i = 0; i<1048576; i++) {
+ sum += data[i];
+ }
+ }
+
+ cppIterTimer.stop();
+ cout <<"Iteration C++: " << sum << endl;
+}
+
+int main()
+{
+ const unsigned long noCells = 1048576;
+ unsigned long* data;
+
+ for(int dim=1; dim<=7; dim++) {
+ r_Minterval m2;
+ r_Minterval m1(dim);
+
+ m2 = createCube(noCells, dim);
+
+ for(int i=0; i<dim; i++) {
+ m1 << r_Sinterval(m2[i].low()-1, m2[i].high()+1);
+ }
+
+ // as basis for the operations
+ data = new unsigned long[m1.cell_count()];
+ for(int i=0; i < m1.cell_count(); i++) {
+ data[i] = i;
+ }
+
+ cout <<"Iterate through " << m2 << " in "<< m1 << endl;
+
+ RMInit::bmOut << "Dimensionality: " << dim << ", cells: "
+ << m2.cell_count() << endl;
+
+ for(int i=0; i<5; i++) {
+ test_Miter( m1, m2, (char*)data );
+ test_OldIter( m1, m2, (char*)data );
+ test_DirectIter( m1, m2, (char*)data );
+ }
+ delete [] data;
+ }
+
+ RMInit::bmOut << "1-D Iteration in C++:" << endl;
+
+ data = new unsigned long[noCells];
+
+ for(int i=0; i < noCells; i++) {
+ data[i] = i;
+ }
+
+ for(int i=0; i<5; i++) {
+ test_CppIter( noCells, (char*)data );
+ }
+ delete [] data;
+}
diff --git a/raslib/test/test_miterd b/raslib/test/test_miterd
new file mode 100644
index 0000000..7ee9a45
--- /dev/null
+++ b/raslib/test/test_miterd
Binary files differ
diff --git a/raslib/test/test_miterd.cc b/raslib/test/test_miterd.cc
new file mode 100644
index 0000000..e664aec
--- /dev/null
+++ b/raslib/test/test_miterd.cc
@@ -0,0 +1,75 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_miter.cc
+ *
+ * MODULE: raslib
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <math.h>
+#include <stdlib.h>
+
+#include "raslib/miterd.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+RMINITGLOBALS('C')
+
+int
+main(int i, char** argv)
+ {
+ unsigned short src[][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
+ for (r_Dimension i = 0; i < 4; i++)
+ {
+ for (r_Dimension c = 0; c < 4; c++)
+ {
+ cout << src[i][c] << " ";
+ }
+ cout << endl;
+ }
+ for (r_Dimension i = 0; i < 4; i++)
+ {
+ for (r_Dimension c = 0; c < 4; c++)
+ {
+ cout << src[c][i] << " ";
+ }
+ cout << endl;
+ }
+ /*
+ r_MiterDirect iter(src, r_Minterval("[0:3,0:3]"), r_Minterval("[0:3,0:3]"), 2, 0);
+ r_Dimension order[] = {1,1};
+ unsigned int step[] = {1,0};
+ r_Dimension order2[] = {0};
+ while (!iter.isDone())
+ {
+ iter.iterateUserOrder(order, step);
+ cout << *(unsigned short*)(iter.getData()) << " " << endl;;
+ cout << "pos " << iter << endl;
+ // cout << *(unsigned short*)(iter.getData()) << " ";
+ iter.operator++();
+ }
+ */
+ }
diff --git a/raslib/test/test_miterf.cc b/raslib/test/test_miterf.cc
new file mode 100644
index 0000000..43660f9
--- /dev/null
+++ b/raslib/test/test_miterf.cc
@@ -0,0 +1,118 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_miterf.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+
+#include <iostream>
+#include <math.h>
+#include <stdlib.h>
+
+#include "raslib/mddtypes.hh"
+#include "raslib/miterf.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+
+
+
+RMINITGLOBALS('C')
+
+
+int main(int argc, char *argv[])
+{
+ r_Dimension dim = 3;
+ r_Minterval iv(dim);
+ r_Dimension i;
+ double *iterMin, *iterMax, *iterStep;
+ int typeLength = 1;
+ long totalSize = typeLength;
+ long totalSteps = 1;
+ double stepBy = 1.5;
+
+ i = 1;
+ while (i < argc)
+ {
+ if (strcmp(argv[i], "-s") == 0)
+ {
+ stepBy = atof(argv[++i]);
+ }
+ i++;
+ }
+
+ cout << "Step by " << stepBy << endl;
+
+ iterMin = new double[dim]; iterMax = new double[dim];
+ iterStep = new double[dim];
+ for (i=0; i<dim; i++)
+ {
+ int steps;
+
+ iterStep[i] = stepBy;
+ iterMin[i] = 0;
+ iterMax[i] = (1<<(4+i)) - 1;
+ iv << r_Sinterval((r_Range)(iterMin[i]), (r_Range)(iterMax[i]));
+ totalSize *= (r_Range)(iterMax[i]) - (r_Range)(iterMin[i]) + 1;
+ steps = (int)((iterMax[i] - iterMin[i]) / iterStep[i]);
+ totalSteps *= (steps + 1);
+ iterMax[i] = iterMin[i] + (steps + 0.5)*iterStep[i]; // rounding effects
+ }
+
+ char *srcData = new char[totalSize];
+
+ cout << "Total size: 0x" << hex << totalSize
+ << ", base address " << (void*)srcData << endl;
+
+ r_MiterFloat iter(&iv, iterMin, iterMax, iterStep, typeLength, srcData);
+
+ long steps = 0;
+ while (!iter.isDone())
+ {
+ char *cell = iter.nextCell();
+
+ if (cell + typeLength > srcData + totalSize)
+ {
+ cout << dec << "Overflow by " << (cell - srcData) - totalSize << endl;
+ }
+ steps++;
+ }
+
+ cout << dec << "Did " << steps << " steps out of " << totalSteps << endl;
+ if (steps != totalSteps)
+ cout << "!!! WRONG NUMBER OF STEPS !!!" << endl;
+
+ delete [] srcData;
+
+ delete [] iterMin; delete [] iterMax; delete [] iterStep;
+
+ return 0;
+}
diff --git a/raslib/test/test_oid.cc b/raslib/test/test_oid.cc
new file mode 100644
index 0000000..d7c3170
--- /dev/null
+++ b/raslib/test/test_oid.cc
@@ -0,0 +1,181 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_oid.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <iomanip.h>
+// #include <limits.h>
+#include "raslib/oid.hh"
+
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+int main()
+{
+ cout << endl << endl;
+ cout << "OId Examples" << endl;
+ cout << "============" << endl << endl;
+
+ cout << "Create oid1" << endl;
+ r_OId oid1( "testSystem", "testBase", 99 );
+ cout << " oid1........: " << oid1 << endl;
+ cout << " system name: " << oid1.get_system_name() << endl;
+ cout << " base name: " << oid1.get_base_name() << endl;
+ cout << " local oid..: " << oid1.get_local_oid() << endl << endl;
+
+ cout << "Create oid2 with string representation of oid1" << endl;
+ r_OId oid2( oid1.get_string_representation() );
+ cout << " oid2........: " << oid2 << endl;
+ cout << " system name: " << oid2.get_system_name() << endl;
+ cout << " base name: " << oid2.get_base_name() << endl;
+ cout << " local oid..: " << oid2.get_local_oid() << endl << endl;
+
+ cout << "Assign oid1 to oid2" << endl;
+ oid2 = oid1;
+ cout << " oid2........: " << oid2 << endl;
+ cout << " system name: " << oid2.get_system_name() << endl;
+ cout << " base name: " << oid2.get_base_name() << endl;
+ cout << " local oid..: " << oid2.get_local_oid() << endl << endl;
+
+ cout << "Assign temporary oid to oid2" << endl;
+ oid2 = r_OId( "testSystem|testBase|100" );
+ cout << " oid2........: " << oid2 << endl;
+ cout << " system name: " << oid2.get_system_name() << endl;
+ cout << " base name: " << oid2.get_base_name() << endl;
+ cout << " local oid..: " << oid2.get_local_oid() << endl << endl;
+
+ cout << "Assign oid1 to oid1" << endl;
+ oid1 = oid1;
+ cout << " oid1........: " << oid1 << endl;
+ cout << " system name: " << oid1.get_system_name() << endl;
+ cout << " base name: " << oid1.get_base_name() << endl;
+ cout << " local oid..: " << oid1.get_local_oid() << endl << endl;
+
+ cout << "Create oid3 as a copy of oid1 with the copy constructor" << endl;
+ r_OId oid3( oid1 );
+ cout << " oid3........: " << oid3 << endl;
+ cout << " system name: " << oid3.get_system_name() << endl;
+ cout << " base name: " << oid3.get_base_name() << endl;
+ cout << " local oid..: " << oid3.get_local_oid() << endl << endl;
+
+ cout << "Create oid4 with string testSystem|testBase|100" << endl;
+ r_OId oid4( "testSystem|testBase|100" );
+ cout << " oid4........: " << oid4 << endl;
+ cout << " system name: " << oid4.get_system_name() << endl;
+ cout << " base name: " << oid4.get_base_name() << endl;
+ cout << " local oid..: " << oid4.get_local_oid() << endl << endl;
+
+ cout << "Create oid5 with string |testBase|100" << endl;
+ r_OId oid5( "|testBase|100" );
+ cout << " oid5........: " << oid5 << endl;
+ cout << " system name: " << oid5.get_system_name() << endl;
+ cout << " base name: " << oid5.get_base_name() << endl;
+ cout << " local oid..: " << oid5.get_local_oid() << endl << endl;
+
+ cout << "Create oid6 with string ||100" << endl;
+ r_OId oid6( "||100" );
+ cout << " oid6........: " << oid6 << endl;
+ cout << " system name: " << oid6.get_system_name() << endl;
+ cout << " base name: " << oid6.get_base_name() << endl;
+ cout << " local oid..: " << oid6.get_local_oid() << endl << endl;
+
+ cout << "Create oid7 with string |||" << endl;
+ r_OId oid7( "|||" );
+ cout << " oid7........: " << oid7 << endl;
+ cout << " system name: " << oid7.get_system_name() << endl;
+ cout << " base name: " << oid7.get_base_name() << endl;
+ cout << " local oid..: " << oid7.get_local_oid() << endl << endl;
+
+ cout << "Create oid8 with an empty string" << endl;
+ r_OId oid8( "" );
+ cout << " oid8........: " << oid8 << endl;
+ cout << " system name: " << oid8.get_system_name() << endl;
+ cout << " base name: " << oid8.get_base_name() << endl;
+ cout << " local oid..: " << oid8.get_local_oid() << endl << endl;
+
+ cout << "Create oid9 with just a local oid" << endl;
+ r_OId oid9( 0, 0, 100 );
+ cout << " oid8........: " << oid9 << endl;
+ cout << " system name: " << oid9.get_system_name() << endl;
+ cout << " base name: " << oid9.get_base_name() << endl;
+ cout << " local oid..: " << oid9.get_local_oid() << endl << endl;
+
+ cout << "Create oid10 with copy constructor from oid1" << endl;
+ r_OId oid10( oid1 );
+ cout << " oid10.......: " << oid10 << endl;
+ cout << " system name: " << oid10.get_system_name() << endl;
+ cout << " base name: " << oid10.get_base_name() << endl;
+ cout << " local oid..: " << oid10.get_local_oid() << endl << endl;
+
+ cout << "Compare r_OId( \"testSystem1|testBase|99\") < r_OId( \"testSystem2|testBase|99\")" << endl;
+ cout << (r_OId( "testSystem1|testBase|99") < r_OId( "testSystem2|testBase|99")) << endl << endl;
+
+ cout << "Compare r_OId( \"testSystem|testBase1|99\") < r_OId( \"testSystem|testBase2|99\")" << endl;
+ cout << (r_OId( "testSystem|testBase1|99") < r_OId( "testSystem|testBase2|99")) << endl << endl;
+
+ cout << "Compare r_OId( \"testSystem|testBase|99\") < r_OId( \"testSystem|testBase|100\")" << endl;
+ cout << (r_OId( "testSystem1|testBase|99") < r_OId( "testSystem2|testBase|100")) << endl << endl;
+
+ cout << "Compare r_OId( \"testSystem1|testBase|99\") > r_OId( \"testSystem2|testBase|99\")" << endl;
+ cout << (r_OId( "testSystem1|testBase|99") > r_OId( "testSystem2|testBase|99")) << endl << endl;
+
+ cout << "Compare r_OId( \"testSystem|testBase1|99\") > r_OId( \"testSystem|testBase2|99\")" << endl;
+ cout << (r_OId( "testSystem|testBase1|99") > r_OId( "testSystem|testBase2|99")) << endl << endl;
+
+ cout << "Compare r_OId( \"testSystem|testBase|99\") > r_OId( \"testSystem|testBase|100\")" << endl;
+ cout << (r_OId( "testSystem1|testBase|99") > r_OId( "testSystem2|testBase|100")) << endl << endl;
+
+ cout << "Create oid11" << endl;
+ // cout << "Double limit: " << DBL_MAX << "= 0x" << hex << DBL_MAX << dec << endl;
+ double maxDouble = 0xffffffffffff;
+ cout << "48bit : " << setprecision(30) << maxDouble << endl;
+ cout << "48bit - 1 : " << setprecision(30) << maxDouble-1 << endl;
+ cout << "48bit + 1 : " << setprecision(30) << maxDouble+1 << endl;
+ r_OId oid11( "testSystem", "testBase", maxDouble );
+ cout << " oid11.......: " << oid11 << endl;
+ cout << " system name: " << oid11.get_system_name() << endl;
+ cout << " base name: " << oid11.get_base_name() << endl;
+ cout << " local oid..: " << oid11.get_local_oid() << endl << endl;
+
+ cout << endl;
+
+ cout << "Create oid12 with string ''" << endl;
+ r_OId oid12( "" );
+ cout << " oid12.......: " << oid12 << endl;
+ cout << " system name: " << oid12.get_system_name() << endl;
+ cout << " base name: " << oid12.get_base_name() << endl;
+ cout << " local oid..: " << oid12.get_local_oid() << endl << endl;
+
+ return 0;
+}
+
diff --git a/raslib/test/test_params.cc b/raslib/test/test_params.cc
new file mode 100644
index 0000000..4be15df
--- /dev/null
+++ b/raslib/test/test_params.cc
@@ -0,0 +1,101 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * INCLUDE: test_params.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <stdio.h>
+#include <iostream>
+#include <string.h>
+#include <stdlib.h>
+
+#include "raslib/rminit.hh"
+#include "raslib/parseparams.hh"
+
+
+RMINITGLOBALS('C')
+
+
+typedef struct test_params_s {
+ r_Parse_Params *pp;
+ int zlevel;
+ double fidelity;
+ char *lstream;
+} test_params_t;
+
+
+static void test_params(test_params_t &params, char *str)
+{
+ cout << "Processing (" << str << ") ..." << endl;
+
+ params.pp->process(str);
+
+ cout << "zlevel = " << params.zlevel
+ << ", fidelity = " << params.fidelity
+ << ", stream = <" << params.lstream << ">" << endl;
+
+ // string was allocated with strdup, free now
+ free(str);
+}
+
+
+int main(int argc, char *argv[])
+{
+ r_Parse_Params pp;
+ test_params_t params = {&pp, -1, -1.0, NULL};
+
+ pp.add("zlevel", &params.zlevel, r_Parse_Params::param_type_int);
+ pp.add("fidelity", &params.fidelity, r_Parse_Params::param_type_double);
+ pp.add("stream", &params.lstream, r_Parse_Params::param_type_string);
+
+ // Note: must use strdup() because Purify doesn't find reads over the end of
+ // static strings!
+ test_params(params, strdup("0123"));
+ test_params(params, strdup("zlevel, fidelity=0.1"));
+ test_params(params, strdup("zlevel=a"));
+ test_params(params, strdup("zlevel=6"));
+ test_params(params, strdup("\"zlevel=6\""));
+ test_params(params, strdup("fidelity=0.90"));
+ test_params(params, strdup("stream=rle"));
+ test_params(params, strdup("stream=eee "));
+ test_params(params, strdup("stream=\"rle\""));
+ test_params(params, strdup("zlevel=9, fidelity=0.75, stream=zlib"));
+ test_params(params, strdup("stream=rle, zlevel=5"));
+ test_params(params, strdup("zlevel=1, foobar=hello"));
+ test_params(params, strdup("foobar=hello, zlevel=2"));
+ test_params(params, strdup(" stream=\"zlib\" "));
+ test_params(params, strdup(" foobar=\"hello, you there\", stream=\"rle\""));
+
+ if (params.lstream != NULL)
+ delete [] params.lstream;
+
+ return 0;
+}
diff --git a/raslib/test/test_point.cc b/raslib/test/test_point.cc
new file mode 100644
index 0000000..63b2f05
--- /dev/null
+++ b/raslib/test/test_point.cc
@@ -0,0 +1,90 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_point.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <stdlib.h>
+
+#include "raslib/point.hh"
+
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+int main()
+{
+ cout << endl << endl;
+ cout << "Point Examples" << endl;
+ cout << "===============" << endl << endl;
+
+ cout << "initialize 1D-point: " << flush;
+ r_Point d1(1);
+ cout << d1 << endl;
+
+ cout << "set value to 9 : " << flush;
+ d1[0] = 9;
+ cout << d1 << endl;
+
+ r_Point a(3);
+ a << 1 << 2 << 3;
+ cout << "stream initializing point (1,2,3) : " << a << endl << endl;
+
+ try{
+ cout << "read out of range : " << a[3] << endl;
+ }
+ catch( r_Eindex_violation& ex ){
+ cout << ex.what();
+ }
+ cout << endl << endl;
+
+ r_Point b = r_Point(3) << 1 << 2 << 3;
+ cout << "assignment point (1,2,3) : " << b << endl << endl;
+
+ cout << "temp. obj. (1,2,3), access second coord. : " << ( r_Point(3) << 1 << 2 << 3 )[1] << endl << endl;
+
+ a[1] = 4;
+ cout << "assignment a[1]=4 to a(1,2,3) : " << a << endl << endl;
+
+ r_Point c = b;
+ cout << "equal operator test: " << flush;
+ if( c == b )
+ cout << "OK" << endl;
+ else
+ cout << "FALSE" << endl;
+
+ char* stringRep = b.get_string_representation();
+ cout << endl << "String representation of point " << b << ": " << stringRep << endl;
+ cout << "Result of string constructor: " << r_Point( stringRep ) << endl;
+ free( stringRep );
+
+ cout << "Result of r_Point(\"[ 0, 5, 3]\"): " << r_Point("[ 0, 5, 3]") << endl;
+}
diff --git a/raslib/test/test_rmdebug.cc b/raslib/test/test_rmdebug.cc
new file mode 100644
index 0000000..c6f29ca
--- /dev/null
+++ b/raslib/test/test_rmdebug.cc
@@ -0,0 +1,179 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_rmdebug.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include "raslib/rmdebug.hh"
+
+#include "raslib/rminit.hh"
+
+// number of repetitions for performance tests
+static const int repeat = 100000;
+
+RMINITGLOBALS('C')
+
+void testFunc1()
+{
+ RMDebug localRMDebug = RMDebug("Class1", "testFunc1", "Module1",
+ __FILE__, __LINE__);
+}
+
+void testFunc2(int reclevel)
+{
+ RMDebug localRMDebug = RMDebug("Class1", "testFunc2", "Module1",
+ __FILE__, __LINE__);
+
+ if(reclevel > 1)
+ testFunc2(reclevel - 1);
+}
+
+void testFunc3(void)
+{
+ RMDebug localRMDebug("Class1", "testFunc3", "server",
+ __FILE__, __LINE__);
+
+ RMDBGMOUT( 2, RMDebug::module_server, NULL, "D: testing 1" );
+ RMDBGMOUT( 3, RMDebug::module_server, "Class1", "D: testing 2" );
+ RMDBGMINOUT( 4, RMDebug::module_server, "Class1", "D: testing 3" );
+}
+
+void testFunc4(int reclevel)
+{
+ RMDebug localRMDebug(1, "Class2", "testFunc4", RMDebug::module_raslib,
+ __FILE__, __LINE__);
+
+ if (reclevel > 1)
+ testFunc4(reclevel - 1);
+}
+
+// this was used to test correctness
+
+void oldMain()
+{
+ int i;
+
+ for(i = 1; i<=5; i++)
+ testFunc1();
+
+ testFunc2(5);
+
+ testFunc3();
+
+ testFunc4(4);
+
+ cout << "Test of RMTimer" << endl;
+
+ cout << "The following should hold approximately: timer2 + timer3 = timer1" << endl << endl;
+
+ RMTimer* timer1 = new RMTimer("main","timer1");
+ RMTimer* timer2 = new RMTimer("main","timer2");
+
+ timer2->pause();
+
+ RMTimer* timer3 = new RMTimer("main","timer3");
+ for( long busy=0; busy <= 50000000; busy++ );
+ delete timer3;
+
+ timer2->resume();
+
+ for( busy=0; busy <= 30000000; busy++ );
+
+ delete timer2;
+ delete timer1;
+
+ cout << "Benchmark level set to " << RManBenchmark << endl;
+
+ RMInit::bmOut << "test output in benchmark stream" << endl;
+}
+
+double testStatic(double dummy)
+{
+ RMTIMER("test_rmdebug", "testStatic");
+
+ for(int i=0; i<repeat; i++)
+ dummy = dummy*4711.4712;
+ return dummy;
+}
+
+double testDynamic(double dummy)
+{
+#ifdef RMANBENCHMARK
+ RMTimer* localRMTimer = 0;
+
+ if( RManBenchmark >= 3 )
+ localRMTimer = new RMTimer("test_rmdebug", "testDynamic");
+#endif
+
+ for(int i=0; i<repeat; i++)
+ dummy = dummy*4711.4712;
+
+#ifdef RMANBENCHMARK
+ if( localRMTimer ) delete localRMTimer;
+#endif
+
+ return dummy;
+}
+
+// Evaluating time needed for measurement with different uses
+// of RMTimer.
+
+void testPerf()
+{
+ double dummy = 3.14;
+
+ cout << "Testing dynamic RMTimer vs. static RMTimer." << endl;
+
+ // to put in cache
+ dummy = testStatic(dummy);
+ cout << "Static:" << endl;
+ dummy = testStatic(dummy);
+
+ // to put in cache
+ dummy = testDynamic(dummy);
+ cout << "Dynamic:" << endl;
+ dummy = testDynamic(dummy);
+}
+
+int main()
+{
+ RMDebug::initRMDebug();
+ RManBenchmark = 4;
+ RMInit::bmOut = cout.rdbuf();
+
+ oldMain();
+ // testPerf();
+
+ return 0;
+}
+
+
diff --git a/raslib/test/test_sinterval.cc b/raslib/test/test_sinterval.cc
new file mode 100644
index 0000000..fa2fbc5
--- /dev/null
+++ b/raslib/test/test_sinterval.cc
@@ -0,0 +1,164 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_sinterval.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include <stdlib.h>
+
+#include "raslib/sinterval.hh"
+
+#include "raslib/rminit.hh"
+RMINITGLOBALS('C')
+
+int main()
+{
+ r_Sinterval interval1, interval2;
+
+ char Buffer[256];
+
+ cout << "lower bound ? ";
+ cin >> Buffer;
+ cout << endl;
+
+ if( Buffer[0] == '*' )
+ interval1.set_low('*');
+ else
+ interval1.set_low( atol( Buffer ) );
+
+ cout << "upper bound ? ";
+ cin >> Buffer;
+ cout << endl;
+
+ if( Buffer[0] == '*' )
+ interval1.set_high('*');
+ else
+ interval1.set_high( atol( Buffer ) );
+
+ cout << "interval1 = [";
+ interval1.print_status( cout );
+ cout << "]" << endl << endl;
+
+ cout << "lower bound ? ";
+ cin >> Buffer;
+ cout << endl;
+
+ if( Buffer[0] == '*' )
+ interval2.set_low('*');
+ else
+ interval2.set_low( atol( Buffer ) );
+
+ cout << "upper bound ? ";
+ cin >> Buffer;
+ cout << endl;
+
+ if( Buffer[0] == '*' )
+ interval2.set_high('*');
+ else
+ interval2.set_high( atol( Buffer ) );
+
+ cout << "interval1 = [";
+ interval2.print_status( cout );
+ cout << "]" << endl << endl;
+
+ r_Sinterval result;
+
+ try{
+ result.union_of( interval1, interval2 );
+
+ cout << "union = [";
+ result.print_status( cout );
+ cout << "]" << endl;
+ }
+ catch( r_Eno_interval error )
+ {
+ cerr << "union " << error.what() << endl;
+ }
+
+ try{
+ result.difference_of( interval1, interval2 );
+
+ cout << "difference = [";
+ result.print_status( cout );
+ cout << "]" << endl;
+ }
+ catch( r_Eno_interval error )
+ {
+ cerr << "difference " << error.what() << endl;
+ }
+
+ try{
+ result.intersection_of( interval1, interval2 );
+
+ cout << "intersection = [";
+ result.print_status( cout );
+ cout << "]" << endl;
+ }
+ catch( r_Eno_interval error )
+ {
+ cerr << "intersection " << error.what() << endl;
+ }
+
+ try{
+ result.closure_of( interval1, interval2 );
+
+ cout << "closure = [";
+ result.print_status( cout );
+ cout << "]" << endl;
+ }
+ catch( r_Eno_interval error )
+ {
+ cerr << "closure " << error.what() << endl;
+ }
+
+ if( interval1.intersects_with( interval2 ) )
+ cerr << "The intervals intersect." << endl;
+ else
+ cerr << "The intervals do not intersect." << endl;
+
+ cerr << endl;
+
+ r_Sinterval b( 4l, 10l );
+ char* stringRep = b.get_string_representation();
+ cout << endl << "String representation of interval " << b << ": " << stringRep << endl;
+ cout << "Result of string constructor: " << r_Sinterval( stringRep ) << endl;
+ free( stringRep );
+
+ cout << "Result of r_Sinterval(\" 10 : 100\"): " << r_Sinterval(" 10 : 100") << endl;
+ cout << "Result of r_Sinterval(\" * : 100\"): " << r_Sinterval(" * : 100") << endl;
+ cout << "Result of r_Sinterval(\" 10 : * \"): " << r_Sinterval(" 10 : * ") << endl;
+ cout << "Result of r_Sinterval(\" * : * \"): " << r_Sinterval(" * : * ") << endl;
+
+ return 0;
+}
+
+
diff --git a/raslib/test/test_timer.cc b/raslib/test/test_timer.cc
new file mode 100644
index 0000000..797c0fa
--- /dev/null
+++ b/raslib/test/test_timer.cc
@@ -0,0 +1,101 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ * SOURCE: test_timer.cc
+ *
+ * MODULE: raslib
+ *
+ * PURPOSE:
+ *
+ * Test program to test class RMTimer.
+ *
+ *
+ * COMMENTS:
+ *
+ ************************************************************/
+
+#include <iostream>
+#include "raslib/rmdebug.hh"
+
+
+RMINITGLOBALS('C')
+
+class Exp {
+
+public:
+ Exp( char* name );
+
+ void useTimer( );
+
+ ~Exp( );
+
+ RMTimer* t1;
+ RMTimer t2;
+ char* name;
+};
+
+Exp::Exp( char* n)
+ :t2("Test Timer ", "t2" ), name( n )
+{
+ t1 = new RMTimer( "Test Timer ", "t1" );
+}
+
+void Exp::useTimer( )
+{
+ cout << "useTimer "<< name << " t1 ... "<<endl;
+ t1->start( );
+ t1->stop( );
+ cout << "and t2"<<endl;
+ t2.start( );
+ t2.stop( );
+}
+
+Exp::~Exp( )
+{
+ cout << "Exp::~Exp( " << name << " ) "<< endl;
+ delete t1;
+}
+
+static const Exp exp1("Static Exp Object");
+
+int main()
+{
+
+ /*
+ RMTimer tt( "Test Timer ", "tt" );
+
+ cout << "RMTimer start( )" <<endl;
+ tt.start( );
+ tt.stop( );
+ */
+
+ Exp e( "Exp Object" );
+ e.useTimer( );
+
+ Exp* ep = new Exp("Pointer to Exp Object");
+ ep->useTimer( );
+ delete ep;
+
+ return 0;
+}
diff --git a/raslib/type.cc b/raslib/type.cc
new file mode 100644
index 0000000..690160c
--- /dev/null
+++ b/raslib/type.cc
@@ -0,0 +1,671 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+
+static const char rcsid[] = "@(#)raslib, r_Type: $Header: /home/rasdev/CVS-repository/rasdaman/raslib/type.cc,v 1.17 2003/12/27 23:01:21 rasdev Exp $";
+
+#include <ctype.h> // for isalpha()
+#include <string.h> // for strncmp()
+
+#include "raslib/type.hh"
+#include "raslib/collectiontype.hh"
+#include "raslib/primitivetype.hh"
+#include "raslib/complextype.hh"
+#include "raslib/structuretype.hh"
+#include "raslib/marraytype.hh"
+#include "raslib/sintervaltype.hh"
+#include "raslib/mintervaltype.hh"
+#include "raslib/pointtype.hh"
+#include "raslib/oidtype.hh"
+#include "raslib/attribute.hh"
+#include "raslib/error.hh"
+#include "raslib/rminit.hh"
+
+r_Type::r_Type()
+ : r_Meta_Object()
+{
+}
+
+r_Type::r_Type(const char* newTypeName)
+ : r_Meta_Object(newTypeName)
+{
+}
+
+r_Type::r_Type(const r_Type& oldObj)
+ : r_Meta_Object(oldObj)
+{
+}
+
+const r_Type&
+r_Type::operator=(const r_Type& oldObj)
+{
+ // Gracefully handle self assignment
+ if (this == &oldObj) return *this;
+
+ r_Meta_Object::operator=(oldObj);
+
+ return *this;
+}
+
+r_Type::~r_Type()
+{
+}
+
+bool
+r_Type::isStructType() const
+{
+ return false;
+}
+
+bool
+r_Type::isComplexType() const
+{
+ return false;
+}
+
+bool
+r_Type::isBaseType() const
+{
+ return false;
+}
+
+bool
+r_Type::isCollectionType() const
+{
+ return false;
+}
+
+bool
+r_Type::isMarrayType() const
+{
+ return false;
+}
+
+bool
+r_Type::isPrimitiveType() const
+{
+ return false;
+}
+
+bool
+r_Type::isSintervalType() const
+{
+ return false;
+}
+
+bool
+r_Type::isMintervalType() const
+{
+ return false;
+}
+
+bool
+r_Type::isPointType() const
+{
+ return false;
+}
+
+bool
+r_Type::isOidType() const
+{
+ return false;
+}
+
+r_Type*
+r_Type::get_any_type(const char* type_string)
+{
+ char* pos = (char*)type_string;
+ char* identifier = NULL;
+ r_Type* returnValue = NULL;
+ DLTOKEN token = DLUNKNOWN;
+
+ // one token look ahead
+ char* oldPos = pos;
+ token = getNextToken(pos, identifier);
+ pos = oldPos;
+
+ switch(token)
+ {
+ case DLMARRAY:
+ returnValue = getMarrayType(pos);
+ break;
+ case DLSET:
+ returnValue = getCollectionType(pos);
+ break;
+ default:
+ returnValue = getType(pos);
+ }
+
+ return returnValue;
+}
+
+r_Type::DLTOKEN
+r_Type::getNextToken(char* &pos, char* &identifier)
+{
+ DLTOKEN token = DLUNKNOWN;
+
+ while(*pos == ' ') pos ++;
+
+ if(!strncmp(pos, "marray", 6))
+ {
+ token = DLMARRAY;
+ pos += 6;
+ }
+ else if(!strncmp(pos, "set", 3))
+ {
+ token = DLSET;
+ pos += 3;
+ }
+ else if(!strncmp(pos, "struct", 6))
+ {
+ token = DLSTRUCT;
+ pos += 6;
+ }
+ else if(*pos == '[')
+ {
+ token = DLLEP;
+ pos += 1;
+ }
+ else if(*pos == ']')
+ {
+ token = DLREP;
+ pos += 1;
+ }
+ else if(*pos == '<')
+ {
+ token = DLLAP;
+ pos += 1;
+ }
+ else if(*pos == '>')
+ {
+ token = DLRAP;
+ pos += 1;
+ }
+ else if(*pos == '{')
+ {
+ token = DLLCP;
+ pos += 1;
+ }
+ else if(*pos == '}')
+ {
+ token = DLRCP;
+ pos += 1;
+ }
+ else if(*pos == ',')
+ {
+ token = DLCOMMA;
+ pos += 1;
+ }
+ else if(!strncmp(pos, "octet", 5))
+ {
+ token = DLOCTET;
+ pos += 5;
+ }
+ else if(!strncmp(pos, "char", 4))
+ {
+ token = DLCHAR;
+ pos += 4;
+ }
+ else if(!strncmp(pos, "ulong", 5))
+ {
+ token = DLULONG;
+ pos += 5;
+ }
+ else if(!strncmp(pos, "long", 4))
+ {
+ token = DLLONG;
+ pos += 4;
+ }
+ else if(!strncmp(pos, "short", 5))
+ {
+ token = DLSHORT;
+ pos += 5;
+ }
+ else if(!strncmp(pos, "ushort", 6))
+ {
+ token = DLUSHORT;
+ pos += 6;
+ }
+ else if(!strncmp(pos, "float", 5))
+ {
+ token = DLFLOAT;
+ pos += 5;
+ }
+ else if(!strncmp(pos, "double", 6))
+ {
+ token = DLDOUBLE;
+ pos += 6;
+ }
+ else if(!strncmp(pos, "bool", 4))
+ {
+ token = DLBOOL;
+ pos += 4;
+ }
+ else if(!strncmp(pos, "complexd", 8))
+ {
+ token = DLCOMPLEXTYPE2;
+ pos += 8;
+ }
+ // the order of testing it's important here
+ // (complex is a proper prefix of complexd!)
+ else if(!strncmp(pos, "complex", 7))
+ {
+ token = DLCOMPLEXTYPE1;
+ pos += 7;
+ }
+ else if(!strncmp(pos, "interval", 8))
+ {
+ token = DLINTERVAL;
+ pos += 8;
+ }
+ else if(!strncmp(pos, "minterval", 9))
+ {
+ token = DLMINTERVAL;
+ pos += 9;
+ }
+ else if(!strncmp(pos, "point", 5))
+ {
+ token = DLPOINT;
+ pos += 5;
+ }
+ else if(!strncmp(pos, "oid", 3))
+ {
+ token = DLOID;
+ pos += 3;
+ }
+ else
+ {
+ token = DLIDENTIFIER; // identifier
+
+ char* beginPos = pos;
+
+ // read identifier
+ while(isalnum(*pos) || *pos == '-' || *pos == '_') pos++;
+
+ identifier = new char[pos-beginPos+1];
+ strncpy(identifier, beginPos, pos-beginPos);
+ identifier[pos-beginPos] = '\0';
+ }
+
+ while(*pos == ' ') pos ++;
+
+ return token;
+}
+
+r_Collection_Type*
+r_Type::getCollectionType(char* &pos)
+{
+ char* identifier = NULL;
+ r_Collection_Type* returnValue = NULL;
+ r_Type* elementType = NULL;
+ DLTOKEN token = DLUNKNOWN;
+
+ // get 'set'
+ getNextToken(pos, identifier);
+
+ // get '<'
+ if(getNextToken(pos, identifier) != DLLAP)
+ {
+ RMInit::logOut << "r_Type::getCollectionType(" << pos << ") expected DLLAP" << endl;
+ throw r_Error(INTERNALDLPARSEERROR);
+ }
+
+ // one token look ahead
+ char* oldPos = pos;
+ token = getNextToken(pos, identifier);
+ pos = oldPos;
+
+ switch(token)
+ {
+ case DLMARRAY:
+ elementType = getMarrayType(pos);
+ break;
+ default:
+ elementType = getType(pos);
+ }
+
+ returnValue = new r_Collection_Type(*elementType);
+ delete elementType;
+
+ return returnValue;
+}
+
+r_Type*
+r_Type::getType(char* &pos)
+{
+ DLTOKEN token = DLUNKNOWN;
+ char* identifier = 0;
+ r_Type* returnValue = 0;
+
+ // one token look ahead
+ char* oldPos = pos;
+ token = getNextToken(pos, identifier);
+ pos = oldPos;
+
+ if(token == DLSTRUCT)
+ returnValue = getStructureType(pos);
+ else if(token == DLINTERVAL)
+ returnValue = getSintervalType(pos);
+ else if(token == DLMINTERVAL)
+ returnValue = getMintervalType(pos);
+ else if(token == DLPOINT)
+ returnValue = getPointType(pos);
+ else if(token == DLOID)
+ returnValue = getOidType(pos);
+ else
+ returnValue = getPrimitiveType(pos);
+
+ return returnValue;
+}
+
+r_Marray_Type*
+r_Type::getMarrayType(char* &pos)
+{
+ char* identifier = NULL;
+ r_Marray_Type* returnValue = NULL;
+ r_Base_Type* basetype = NULL;
+
+ // get 'marray'
+ getNextToken(pos, identifier);
+ // get '<'
+ if(getNextToken(pos, identifier) != DLLAP)
+ {
+ RMInit::logOut << "r_Type::getMarrayType(" << pos << ") expected DLLAP" << endl;
+ throw r_Error(INTERNALDLPARSEERROR);
+ }
+
+ // get base type (structure or primitive type)
+ basetype = getBaseType(pos);
+
+ returnValue = new r_Marray_Type(*basetype);
+
+ delete basetype;
+
+ return returnValue;
+}
+
+r_Base_Type*
+r_Type::getBaseType(char* &pos, int offset)
+{
+ DLTOKEN token = DLUNKNOWN;
+ char* identifier = NULL;
+ r_Base_Type* returnValue = NULL;
+
+ // one token look ahead
+ char* oldPos = pos;
+ token = getNextToken(pos, identifier);
+ pos = oldPos;
+
+ if(token == DLSTRUCT)
+ returnValue = getStructureType(pos, offset);
+ else
+ returnValue = getPrimitiveType(pos);
+
+ return returnValue;
+}
+
+r_Primitive_Type*
+r_Type::getPrimitiveType(char* &pos)
+{
+ char* dummy = NULL;
+ r_Primitive_Type* returnValue = NULL;
+
+ switch(getNextToken(pos, dummy))
+ {
+ case DLCHAR:
+ returnValue = new r_Primitive_Type("Char", r_Type::CHAR);
+ break;
+ case DLOCTET:
+ returnValue = new r_Primitive_Type("Octet", r_Type::OCTET);
+ break;
+ case DLSHORT:
+ returnValue = new r_Primitive_Type("Short", r_Type::SHORT);
+ break;
+ case DLUSHORT:
+ returnValue = new r_Primitive_Type("UShort", r_Type::USHORT);
+ break;
+ case DLLONG:
+ returnValue = new r_Primitive_Type("Long", r_Type::LONG);
+ break;
+ case DLULONG:
+ returnValue = new r_Primitive_Type("ULong", r_Type::ULONG);
+ break;
+ case DLBOOL:
+ returnValue = new r_Primitive_Type("Bool", r_Type::BOOL);
+ break;
+ case DLFLOAT:
+ returnValue = new r_Primitive_Type("Float", r_Type::FLOAT);
+ break;
+ case DLDOUBLE:
+ returnValue = new r_Primitive_Type("Double", r_Type::DOUBLE);
+ break;
+ case DLCOMPLEXTYPE1:
+ returnValue = new r_Complex_Type("Complex1", r_Type::COMPLEXTYPE1);
+ break;
+ case DLCOMPLEXTYPE2:
+ returnValue = new r_Complex_Type("Complex2", r_Type::COMPLEXTYPE2);
+ break;
+ default:
+ {
+ RMInit::logOut << "r_Type::getPrimitiveType(" << pos << ") unknown token" << endl;
+ throw r_Error(INTERNALDLPARSEERROR);
+ }
+ }
+
+ return returnValue;
+}
+
+r_Structure_Type*
+r_Type::getStructureType(char* &pos, int offset)
+{
+ r_Structure_Type* returnValue = NULL;
+ char* identifier = NULL;
+ DLTOKEN token = DLUNKNOWN;
+ r_Attribute* attributes = NULL;
+ int noAttributes=0;
+
+ // get 'struct'
+ getNextToken(pos, identifier);
+
+ // get '{'
+ if(getNextToken(pos, identifier) != DLLCP)
+ {
+ RMInit::logOut << "r_Type::getStructureType(" << pos << ", " << offset << ") expected DLLCP" << endl;
+ throw r_Error(INTERNALDLPARSEERROR);
+ }
+
+ int localOffset = offset;
+
+ while(token != DLRCP)
+ {
+ // get type
+ r_Base_Type* type = getBaseType(pos, localOffset);
+
+ // adjust local offset
+ localOffset += type->size();
+
+ // get optional name
+ token = getNextToken(pos, identifier);
+
+ // allocate another attribute (very inefficient)
+ noAttributes++;
+ r_Attribute* oldAttributes = attributes;
+ attributes = new r_Attribute[noAttributes];
+ for(int i=0; i < noAttributes-1; i++)
+ attributes[i] = oldAttributes[i];
+ if(oldAttributes)
+ delete[] oldAttributes;
+ oldAttributes = NULL;
+
+ if(token == DLIDENTIFIER)
+ {
+ // with identifier
+ attributes[noAttributes-1] = r_Attribute(identifier, *type);
+ delete[] identifier;
+ identifier = NULL;
+ // read next token
+ token = getNextToken(pos, identifier);
+ }
+ else
+ {
+ // without identifier
+ attributes[noAttributes-1] = r_Attribute("", *type);
+ }
+
+ delete type;
+ type = NULL;
+
+ if(token != DLCOMMA && token != DLRCP)
+ {
+ RMInit::logOut << "r_Type::getStructureType(" << pos << ", " << offset << ") expected DLRCP or DLCOMMA" << endl;
+ throw r_Error(INTERNALDLPARSEERROR);
+ }
+ }
+
+ returnValue = new r_Structure_Type("Structure", noAttributes, attributes, offset);
+
+ if(attributes)
+ delete[] attributes;
+ attributes = NULL;
+ return returnValue;
+}
+
+r_Sinterval_Type*
+r_Type::getSintervalType(char* &pos)
+{
+ char* dummy = NULL;
+ r_Sinterval_Type* returnValue = NULL;
+
+ getNextToken(pos, dummy);
+
+ returnValue = new r_Sinterval_Type();
+
+ return returnValue;
+}
+
+r_Minterval_Type*
+r_Type::getMintervalType(char* &pos)
+{
+ char* dummy = NULL;
+ r_Minterval_Type* returnValue = NULL;
+
+ getNextToken(pos, dummy);
+
+ returnValue = new r_Minterval_Type();
+
+ return returnValue;
+}
+
+r_Point_Type*
+r_Type::getPointType(char* &pos)
+{
+ char* dummy = NULL;
+ r_Point_Type* returnValue = NULL;
+
+ getNextToken(pos, dummy);
+
+ returnValue = new r_Point_Type();
+
+ return returnValue;
+}
+
+r_Oid_Type*
+r_Type::getOidType(char* &pos)
+{
+ char* dummy = NULL;
+ r_Oid_Type* returnValue = NULL;
+
+ getNextToken(pos, dummy);
+
+ returnValue = new r_Oid_Type();
+
+ return returnValue;
+}
+
+std::ostream& operator<<( std::ostream& s, r_Type::r_Type_Id t )
+{
+ switch( t )
+ {
+ case r_Type::ULONG:
+ s << "ulong";
+ break;
+ case r_Type::USHORT:
+ s << "ushort";
+ break;
+ case r_Type::BOOL:
+ s << "bool";
+ break;
+ case r_Type::LONG:
+ s << "long";
+ break;
+ case r_Type::SHORT:
+ s << "short";
+ break;
+ case r_Type::OCTET:
+ s << "octet";
+ break;
+ case r_Type::DOUBLE:
+ s << "double";
+ break;
+ case r_Type::FLOAT:
+ s << "float";
+ break;
+ case r_Type::CHAR:
+ s << "char";
+ break;
+ case r_Type::COMPLEXTYPE1:
+ s << "complextype1";
+ break;
+ case r_Type::COMPLEXTYPE2:
+ s << "complextype2";
+ break;
+ case r_Type::STRUCTURETYPE:
+ s << "structuretype";
+ break;
+ case r_Type::MARRAYTYPE:
+ s << "marraytype";
+ break;
+ case r_Type::COLLECTIONTYPE:
+ s << "collectiontype";
+ break;
+ case r_Type::SINTERVALTYPE:
+ s << "sintervaltype";
+ break;
+ case r_Type::MINTERVALTYPE:
+ s << "mintervaltype";
+ break;
+ case r_Type::POINTTYPE:
+ s << "pointtype";
+ break;
+ case r_Type::OIDTYPE:
+ s << "oidtype";
+ break;
+ case r_Type::UNKNOWNTYPE:
+ s << "unknowntype";
+ break;
+ default:
+ s << "UNKNOWN r_Type_Id" << t;
+ break;
+ }
+
+ return s;
+}
diff --git a/raslib/type.hh b/raslib/type.hh
new file mode 100644
index 0000000..da2272c
--- /dev/null
+++ b/raslib/type.hh
@@ -0,0 +1,167 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: type.hh
+ *
+ * MODULE: raslib
+ * CLASS: r_Type
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _D_TYPE_
+#define _D_TYPE_
+
+#include "raslib/metaobject.hh"
+#include "raslib/mddtypes.hh"
+
+class r_Primitive_Type;
+class r_Structure_Type;
+class r_Marray_Type;
+class r_Sinterval_Type;
+class r_Minterval_Type;
+class r_Point_Type;
+class r_Oid_Type;
+class r_Base_Type;
+class r_Collection_Type;
+
+//@ManMemo: Module: {\bf raslib}
+
+/**
+ This class the superclass for all types in the ODMG conformant
+ representation of the RasDaMan type system.
+*/
+
+class r_Type : public r_Meta_Object
+{
+public:
+ /// typedef for the enum specifying a primitive type, structure type, marray type,
+ /// interval type, minterval type, point type or oid type
+ enum r_Type_Id { ULONG, USHORT, BOOL, LONG, SHORT, OCTET,
+ DOUBLE, FLOAT, CHAR, COMPLEXTYPE1, COMPLEXTYPE2,
+ STRUCTURETYPE, MARRAYTYPE, COLLECTIONTYPE,
+ SINTERVALTYPE, MINTERVALTYPE, POINTTYPE, OIDTYPE,
+ UNKNOWNTYPE };
+ /// default constructor.
+ r_Type();
+ /// constructor getting name of type.
+ r_Type( const char* newTypeName);
+ /// copy constructor
+ r_Type( const r_Type& oldObj );
+ /// assignment operator.
+ const r_Type& operator=( const r_Type& oldObj );
+ /// destructor.
+ virtual ~r_Type();
+
+ /// clone operation
+ virtual r_Type* clone() const = 0;
+
+ /// retrieve id of the type.
+ virtual r_Type::r_Type_Id type_id() const = 0;
+
+ /// check, if type is primitive or structured.
+ virtual bool isStructType() const;
+
+ /// check, if type is a base type ( primitive type or structure type).
+ virtual bool isBaseType() const;
+
+ /// check, if type is a base type ( primitive type or structure type).
+ virtual bool isComplexType() const;
+
+ /// check, if type is a marray type.
+ virtual bool isMarrayType() const;
+
+ /// check, if type is a primitive type.
+ virtual bool isPrimitiveType() const;
+
+ /// check, if type is a Sinterval
+ virtual bool isSintervalType() const;
+
+ /// check, if type is a Minterval
+ virtual bool isMintervalType() const;
+
+ /// check, if type is a Colelction type
+ virtual bool isCollectionType() const;
+
+ /// check, if type is a Point
+ virtual bool isPointType() const;
+
+ /// check, if type is a oid
+ virtual bool isOidType() const;
+
+ /// build type schema from string representation
+ static r_Type* get_any_type( const char* type_string );
+
+ /// converts array of cells from NT byte order to Unix byte order.
+ virtual void convertToLittleEndian(char* cells, r_Area noCells) const = 0;
+
+ /// converts array of cells from Unix byte order to NT byte order.
+ virtual void convertToBigEndian(char* cells, r_Area noCells) const = 0;
+
+ /// token enumeration for parser
+ enum DLTOKEN { DLMARRAY, DLSET, DLSTRUCT, DLCOMMA,
+ DLLEP, DLREP, DLLAP, DLRAP, DLLCP, DLRCP,
+ DLIDENTIFIER, DLCHAR, DLOCTET, DLSHORT, DLUSHORT,
+ DLLONG, DLULONG, DLFLOAT, DLDOUBLE, DLBOOL, DLCOMPLEXTYPE1, DLCOMPLEXTYPE2,
+ DLINTERVAL, DLMINTERVAL, DLPOINT, DLOID, DLUNKNOWN };
+
+
+private:
+
+ //@Man: Methodes and structures for dl parser:
+ //@{
+ ///
+
+ ///
+ static DLTOKEN getNextToken( char* &pos, char* &identifier );
+ ///
+ static r_Collection_Type* getCollectionType( char* &pos );
+ ///
+ static r_Type* getType( char* &pos );
+ ///
+ static r_Marray_Type* getMarrayType( char* &pos );
+ ///
+ static r_Base_Type* getBaseType( char* &pos, int offset=0 );
+ ///
+ static r_Primitive_Type* getPrimitiveType( char* &pos );
+ ///
+ static r_Structure_Type* getStructureType( char* &pos, int offset=0 );
+ ///
+ static r_Sinterval_Type* getSintervalType( char* &pos );
+ ///
+ static r_Minterval_Type* getMintervalType( char* &pos );
+ ///
+ static r_Point_Type* getPointType( char* &pos );
+ ///
+ static r_Oid_Type* getOidType( char* &pos );
+
+ ///
+ //@}
+
+
+};
+
+extern std::ostream& operator<<( std::ostream& s, r_Type::r_Type_Id t );
+
+#endif