diff options
Diffstat (limited to 'qlparser/qtconversion.cc')
-rw-r--r-- | qlparser/qtconversion.cc | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/qlparser/qtconversion.cc b/qlparser/qtconversion.cc new file mode 100644 index 0000000..72d751f --- /dev/null +++ b/qlparser/qtconversion.cc @@ -0,0 +1,590 @@ +/* +* 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>. +*/ +/************************************************************* + * + * + * PURPOSE: + * + * + * COMMENTS: + * + ************************************************************/ + +static const char rcsid[] = "@(#)qlparser, QtConversion: $Header: /home/rasdev/CVS-repository/rasdaman/qlparser/qtconversion.cc,v 1.36 2003/12/27 20:51:28 rasdev Exp $"; + +#include "raslib/rmdebug.hh" +#include "raslib/basetype.hh" +#include "raslib/structuretype.hh" +#include "conversion/convertor.hh" +#include "conversion/convfactory.hh" + +#include "qlparser/qtconversion.hh" +#include "qlparser/qtmdd.hh" + +#include "mddmgr/mddobj.hh" +#include "tilemgr/tile.hh" + +#include "catalogmgr/typefactory.hh" +#include "relcatalogif/typeiterator.hh" +#include "relcatalogif/structtype.hh" +#include "relcatalogif/chartype.hh" + +#include <iostream> +#ifndef CPPSTDLIB +#include <ospace/string.h> // STL<ToolKit> +#else +#include <string> +using namespace std; +#endif + +const QtNode::QtNodeType QtConversion::nodeType = QtNode::QT_CONVERSION; + + +QtConversion::QtConversion( QtOperation* newInput, QtConversionType +newConversionType, const char* s ) + : conversionType( newConversionType ), QtUnaryOperation( newInput ), paramStr(s) +{ + RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "QtConversion()" ) +} + +void +QtConversion::setConversionTypeByName( string formatName ) +{ + if(string("bmp") == formatName) + conversionType = QtConversion::QT_TOBMP; + else if(string("hdf") == formatName ) + conversionType = QtConversion::QT_TOHDF; + else if(string("png") == formatName) + conversionType = QtConversion::QT_TOPNG; + else if (string("jpeg") == formatName) + conversionType = QtConversion::QT_TOJPEG; + else if (string("tiff") == formatName) + conversionType = QtConversion::QT_TOTIFF; + else if (string("vff") == formatName) + conversionType = QtConversion::QT_TOVFF; + else if (string("csv") == formatName) + conversionType = QtConversion::QT_TOCSV; + else if (string("tor") == formatName) + conversionType = QtConversion::QT_TOTOR; + else if (string("dem") == formatName) + conversionType = QtConversion::QT_TODEM; + else if(string("inv_bmp") == formatName ) + conversionType = QtConversion::QT_FROMBMP; + else if(string("inv_hdf") == formatName ) + conversionType = QtConversion::QT_FROMHDF; + else if(string("inv_csv") == formatName ) + conversionType = QtConversion::QT_FROMCSV; + else if(string("inv_png") == formatName) + conversionType = QtConversion::QT_FROMPNG; + else if (string("inv_jpeg") == formatName) + conversionType = QtConversion::QT_FROMJPEG; + else if (string("inv_tiff") == formatName) + conversionType = QtConversion::QT_FROMTIFF; + else if (string("inv_vff") == formatName) + conversionType = QtConversion::QT_FROMVFF; + else if (string("inv_tor") == formatName) + conversionType = QtConversion::QT_FROMTOR; + else if (string("inv_dem") == formatName) + conversionType = QtConversion::QT_FROMDEM; + else + conversionType = QtConversion::QT_UNKNOWN; +} + +bool +QtConversion::lookupConversionTypeByName( string formatName ) +{ + return (( string("bmp") == formatName ) || ( string("hdf") == formatName ) || + ( string("png") == formatName ) || ( string("jpeg") == formatName ) || + ( string("dem") == formatName ) || ( string("tor") == formatName ) || + ( string("csv") == formatName ) || ( string("inv_csv") == formatName ) || + ( string("tiff") == formatName ) || ( string("vff") == formatName ) || + ( string("inv_bmp") == formatName ) || ( string("inv_hdf") == formatName ) || + ( string("inv_png") == formatName ) || ( string("inv_jpeg") == formatName ) || + ( string("inv_dem") == formatName ) || ( string("inv_tor") == formatName ) || + ( string("inv_tiff") == formatName ) || ( string("inv_vff") == formatName )); + +} + +bool +QtConversion::equalMeaning( QtNode* node ) +{ + + bool result = false; + + if( nodeType == node->getNodeType() ) + { + QtConversion* convNode; + convNode = (QtConversion*) node; // by force + + result = input->equalMeaning( convNode->getInput() ); + + result &= conversionType == convNode->conversionType; + }; + + return ( result ); +} + + +QtData* +QtConversion::evaluate( QtDataList* inputList ) +{ + RMDBCLASS( "QtConversion", "evaluate( QtDataList* )", "qlparser", __FILE__, __LINE__ ) + + QtData* returnValue = NULL; + QtData* operand = NULL; + + if( conversionType == QT_UNKNOWN ) + { + RMInit::logOut << "Error: QtConversion::evaluate() - unknown conversion format." << std::endl; + parseInfo.setErrorNo(382); + throw parseInfo; + } + + operand = input->evaluate( inputList ); + + if( operand ) + { +#ifdef QT_RUNTIME_TYPE_CHECK + if( operand->getDataType() != QT_MDD ) + { + RMInit::logOut << "Internal error in QtConversion::evaluate() - " + << "runtime type checking failed (MDD)." << std::endl; + + // delete old operand + if( operand ) operand->deleteRef(); + return 0; + } +#endif + + QtMDD* qtMDD = (QtMDD*) operand; + MDDObj* currentMDDObj = qtMDD->getMDDObject(); + Tile* sourceTile = NULL; + vector< Tile* >* tiles = NULL; + if (qtMDD->getLoadDomain().is_origin_fixed() && qtMDD->getLoadDomain().is_high_fixed()) + { + // get relevant tiles + tiles = currentMDDObj->intersect( qtMDD->getLoadDomain() ); + } + else { + RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - no tile available to convert." ) + return operand; + } + + // check the number of tiles + if( !tiles->size() ) + { + RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - no tile available to convert." ) + return operand; + } + + // create one single tile with the load domain + sourceTile = new Tile( tiles, qtMDD->getLoadDomain() ); + + // delete the tile vector + delete tiles; + tiles = NULL; + + // get type structure of the operand base type + char* typeStructure = qtMDD->getCellType()->getTypeStructure(); + + // convert structure to r_Type + r_Type* baseSchema = r_Type::get_any_type( typeStructure ); + + free( typeStructure ); + typeStructure = NULL; + RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - no tile available to convert." ) + RMDBGIF(2, RMDebug::module_qlparser, "QtConversion", \ + RMInit::dbgOut << "Cell base type for conversion: " << std::flush; \ + baseSchema->print_status( RMInit::dbgOut ); \ + RMInit::dbgOut << std::endl; ) + + // + // real conversion + // + + r_convDesc convResult; + r_Minterval tileDomain = sourceTile->getDomain(); + + //convertor type + r_Data_Format convType = r_Array; + //result type from convertor + r_Data_Format convFormat = r_Array; + + switch (conversionType) + { + case QT_TOTIFF: + convType = r_TIFF; + convFormat = r_TIFF; + break; + case QT_FROMTIFF: + convType = r_TIFF; + convFormat = r_Array; + break; + case QT_TOBMP: + convType = r_BMP; + convFormat = r_BMP; + break; + case QT_FROMBMP: + convType = r_BMP; + convFormat = r_Array; + break; + case QT_TOHDF: + convType = r_HDF; + convFormat = r_HDF; + break; + case QT_TOCSV: + convType = r_CSV; + convFormat = r_CSV; + break; + case QT_FROMHDF: + convType = r_HDF; + convFormat = r_Array; + break; + case QT_FROMCSV: + convType = r_CSV; + convFormat = r_Array; + break; + case QT_TOJPEG: + convType = r_JPEG; + convFormat = r_JPEG; + break; + case QT_FROMJPEG: + convType = r_JPEG; + convFormat = r_Array; + break; + case QT_TOPNG: + convType = r_PNG; + convFormat = r_PNG; + break; + case QT_FROMPNG: + convType = r_PNG; + convFormat = r_Array; + break; + case QT_TOVFF: + convType = r_VFF; + convFormat = r_VFF; + break; + case QT_FROMVFF: + convType = r_VFF; + convFormat = r_Array; + break; + case QT_TOTOR: + convType = r_TOR; + convFormat = r_TOR; + break; + case QT_FROMTOR: + convType = r_TOR; + convFormat = r_Array; + break; + case QT_TODEM: + convType = r_DEM; + convFormat = r_DEM; + break; + case QT_FROMDEM: + convType = r_DEM; + convFormat = r_Array; + break; + default: + RMInit::logOut << "Error: QtConversion::evaluate(): unsupported format " << conversionType << std::endl; + throw r_Error(CONVERSIONFORMATNOTSUPPORTED); + break; + } + convFormat = r_Array; + + r_Convertor *convertor = NULL; + + try { + convertor = r_Convertor_Factory::create(convType, sourceTile->getContents(), tileDomain, baseSchema); + if(conversionType < QT_FROMTIFF) { + RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - convertor " << convType << " converting to " << convFormat << "..."); + convResult = convertor->convertTo(paramStr); + } + else { + RMDBGONCE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - convertor " << convType << " converting from " << convFormat << "..."); + convResult = convertor->convertFrom(paramStr); + } + } + catch (r_Error &err) { + RMInit::logOut << "Error: QtConversion::evaluate(): conversion failed" << std::endl; + delete sourceTile; + sourceTile = NULL; + delete baseSchema; + baseSchema = NULL; + // delete old operand + if( operand ) operand->deleteRef(); + if (convertor != NULL) { + delete convertor; + convertor=NULL; + } + + parseInfo.setErrorNo(381); + throw parseInfo; + } + if (convertor != NULL) { + delete convertor; + convertor=NULL; + } + + RMDBGMIDDLE(2, RMDebug::module_qlparser, "QtConversion", "evalutate() - ok") + + + // + // done + // + + // delete sourceTile + delete sourceTile; + sourceTile = NULL; + + // create a transient tile for the compressed data + const BaseType* myType = NULL; + const r_Type* currStruct = NULL; + if(convResult.destType->isPrimitiveType()) { + myType=TypeFactory::mapType(convResult.destType->name()); + if(myType == NULL) { + RMInit::logOut << "Error: QtConversion::evaluate() no primitive type compatible found" << std::endl; + delete convResult.destType; + convResult.destType=NULL; + delete convResult.dest; + convResult.dest=NULL; + throw r_Error(BASETYPENOTSUPPORTED); + } + + if(strcasecmp( dataStreamType.getType()->getTypeName(), myType->getTypeName())) { + //FIXME here we have to change the dataStreamType.getType(), is not char for + //conversion from_DEF all the time, we don't know the result type until we parse the data + MDDBaseType* mddBaseType = new MDDBaseType( "tmp", TypeFactory::mapType(myType->getTypeName()) ); + TypeFactory::addTempType( mddBaseType ); + + dataStreamType.setType( mddBaseType ); + RMInit::logOut << " QtConversion::evaluate() for conversion " << conversionType << " real result is " << std::flush; + dataStreamType.printStatus(RMInit::logOut); + RMInit::logOut << std::endl; + } + } + else { //we assume that we deal with structure types + TypeIterator<StructType> structIter = TypeFactory::createStructIter(); + while(structIter.not_done()) { + // get type structure of current structtype + typeStructure = structIter.get_element()->getTypeStructure(); + // convert structure to r_Type + currStruct = r_Type::get_any_type( typeStructure ); + + if(currStruct == NULL) { + RMInit::logOut << "Error: QtConversion::evaluate() no structure type compatible found" << std::endl; + delete convResult.destType; + convResult.destType=NULL; + delete convResult.dest; + convResult.dest=NULL; + throw r_Error(STRUCTTYPE_ELEMENT_UNKNOWN); + } + + free(typeStructure); + typeStructure = NULL; + + if(((r_Structure_Type*)currStruct)->compatibleWith((r_Structure_Type*)convResult.destType)) { + //we found a type + delete currStruct; + currStruct = NULL; + myType=structIter.get_element().ptr(); + break; + } + + delete currStruct; + currStruct = NULL; + structIter.advance(); + } + if(myType == NULL) { + RMInit::logOut << "Error: QtConversion::evaluate() no structure type compatible found" << std::endl; + delete convResult.destType; + convResult.destType=NULL; + delete convResult.dest; + convResult.dest=NULL; + throw r_Error(STRUCTTYPE_ELEMENT_UNKNOWN); + } + + if(strcasecmp(dataStreamType.getType()->getTypeName(), myType->getTypeName())) { + //FIXME here we have to change the dataStreamType.getType(), is not char for + //conversion from_DEF all the time, we don't know the result type until we parse the data + MDDBaseType* mddBaseType = new MDDBaseType( "tmp", TypeFactory::mapType(myType->getTypeName()) ); + TypeFactory::addTempType( mddBaseType ); + + dataStreamType.setType( mddBaseType ); + RMInit::logOut << " QtConversion::evaluate() for conversion " << conversionType << " real result is " << std::flush; + dataStreamType.printStatus(RMInit::logOut); + RMInit::logOut << std::endl; + } + } + + Tile* resultTile = new Tile( convResult.destInterv, + myType, + convResult.dest, + 0, + convFormat ); + + // delete destination type + if( convResult.destType ) { + delete convResult.destType; + convResult.destType=NULL; + } + + // create a transient MDD object for the query result + MDDBaseType* mddBaseType = (MDDBaseType*)dataStreamType.getType(); + MDDObj* resultMDD = new MDDObj( mddBaseType, convResult.destInterv ); + resultMDD->insertTile( resultTile ); + + // create a new QtMDD object as carrier object for the transient MDD object + returnValue = new QtMDD( (MDDObj*)resultMDD ); + + // delete base type schema + delete baseSchema; + baseSchema = NULL; + + // delete old operand + if( operand ) operand->deleteRef(); + } + else + RMInit::logOut << "Error: QtConversion::evaluate() - operand is not provided." << std::endl; + + return returnValue; +} + + +void +QtConversion::printTree( int tab, ostream& s, QtChildType mode ) +{ + s << SPACE_STR(tab).c_str() << "QtConversion Object: "; + + switch( conversionType ) + { + case QT_TOTIFF: s << "to TIFF"; break; + case QT_TOBMP: s << "to BMP"; break; + case QT_TOHDF: s << "to HDF"; break; + case QT_TOCSV: s << "to CSV"; break; + case QT_TOJPEG: s << "to JPEG"; break; + case QT_TOPNG: s << "to PNG"; break; + case QT_TOVFF: s << "to VFF"; break; + case QT_TOTOR: s << "to TOR"; break; + case QT_TODEM: s << "to DEM"; break; + case QT_FROMTIFF: s << "from TIFF"; break; + case QT_FROMBMP: s << "from BMP"; break; + case QT_FROMHDF: s << "from HDF"; break; + case QT_FROMCSV: s << "from CSV"; break; + case QT_FROMJPEG: s << "from JPEG"; break; + case QT_FROMPNG: s << "from PNG"; break; + case QT_FROMVFF: s << "from VFF"; break; + case QT_FROMTOR: s << "from TOR"; break; + case QT_FROMDEM: s << "from DEM"; break; + default: s << "unknown conversion"; break; + } + + s << std::endl; + + QtUnaryOperation::printTree( tab, s, mode ); +} + + + +void +QtConversion::printAlgebraicExpression( ostream& s ) +{ + s << conversionType << "("; + + if( input ) + input->printAlgebraicExpression( s ); + else + s << "<nn>"; + + s << ")"; +} + + + +const QtTypeElement& +QtConversion::checkType( QtTypeTuple* typeTuple ) +{ + RMDBCLASS( "QtConversion", "checkType( QtTypeTuple* )", "qlparser", __FILE__, __LINE__ ) + + dataStreamType.setDataType( QT_TYPE_UNKNOWN ); + + // check operand branches + if( input ) + { + + // get input type + const QtTypeElement& inputType = input->checkType( typeTuple ); + + if( inputType.getDataType() != QT_MDD ) + { + RMInit::logOut << "Error: QtConversion::checkType() - operand is not of type MDD." << std::endl; + parseInfo.setErrorNo(380); + throw parseInfo; + } + + //FIXME we set for every kind of conversion the result type char + //for conversion from_DEF we don't know the result type until we parse the data + MDDBaseType* mddBaseType = new MDDBaseType( "Char", TypeFactory::mapType("Char") ); + TypeFactory::addTempType( mddBaseType ); + + dataStreamType.setType( mddBaseType ); + + if(conversionType>QT_TODEM) { + RMInit::logOut << std::endl << "QtConversion::checkType() for conversion " << conversionType << " assume the result " << std::flush; + dataStreamType.printStatus(RMInit::logOut); + RMInit::logOut << std::endl; + } + } + else + RMInit::logOut << "Error: QtConversion::checkType() - operand branch invalid." << std::endl; + + return dataStreamType; +} + +std::ostream& +operator<< (std::ostream& os, QtConversion::QtConversionType type) { + switch( type ) + { + case QtConversion::QT_TOTIFF: os << "tiff"; break; + case QtConversion::QT_TOBMP: os << "bmp"; break; + case QtConversion::QT_TOHDF: os << "hdf"; break; + case QtConversion::QT_TOCSV: os << "csv"; break; + case QtConversion::QT_TOJPEG: os << "jpeg"; break; + case QtConversion::QT_TOPNG: os << "png"; break; + case QtConversion::QT_TOVFF: os << "vff"; break; + case QtConversion::QT_TOTOR: os << "tor"; break; + case QtConversion::QT_TODEM: os << "dem"; break; + case QtConversion::QT_FROMTIFF: os << "inv_tiff"; break; + case QtConversion::QT_FROMBMP: os << "inv_bmp"; break; + case QtConversion::QT_FROMHDF: os << "inv_hdf"; break; + case QtConversion::QT_FROMCSV: os << "inv_csv"; break; + case QtConversion::QT_FROMJPEG: os << "inv_jpeg"; break; + case QtConversion::QT_FROMPNG: os << "inv_png"; break; + case QtConversion::QT_FROMVFF: os << "inv_vff"; break; + case QtConversion::QT_FROMTOR: os << "inv_tor"; break; + case QtConversion::QT_FROMDEM: os << "inv_dem"; break; + default: os << "unknown Conversion"; break; + } + + return os; +} + |