/* * 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 . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . / /** * INCLUDE: flatbasetype.cc * * MODULE: raslib * CLASS: r_Flat_Base_Type * * COMMENTS: * */ #include #include #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; itype_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; isize(); 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; iclone()); 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 << ""; } 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; iprint_status(str); str << '(' << offsets[i] << ')'; } str << '}'; } } } std::ostream &operator<<( std::ostream &str, const r_Flat_Base_Type &type ) { type.print_status(str); return str; }