summaryrefslogtreecommitdiffstats
path: root/raslib/type.cc
diff options
context:
space:
mode:
Diffstat (limited to 'raslib/type.cc')
-rw-r--r--raslib/type.cc671
1 files changed, 671 insertions, 0 deletions
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;
+}