/* * 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 . / /** * 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 #else #include #endif #include #include #include 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 << "" << std::flush; } std::ostream& operator<<( std::ostream& s, const r_Structure& obj ) { obj.print_status( s ); return s; }