/* * 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 . */ /************************************************************* * * * 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 #ifndef CPPSTDLIB #include // STL #else #include 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 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 << ""; 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; }