/* * 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: dem.hh * * MODULE: conversion * * CLASSES: r_Conv_DEM * * PURPOSE: * Provides interface to convert data from/to Array format to/from DEM format. * * COMMENTS: * For further support send a mail to comanl@yahoo.com * - convertTo() writes a temp file; this should be omitted for performance reasons */ static const char rcsid[] = "@(#)conversion,r_Conv_DEM: $Id: dem.cc,v 1.10 2005/09/08 12:59:26 rasdev Exp $"; #include "conversion/dem.hh" #include #include #include #include #include #include using std::istringstream; using std::istrstream; using std::string; using namespace std; #include "raslib/rminit.hh" #include "raslib/parseparams.hh" #include "raslib/primitivetype.hh" const r_Dimension r_Conv_DEM::srcIntervDim=1; const r_Dimension r_Conv_DEM::destIntervDim=2; const r_ULong r_Conv_DEM::paramMin=6; const char* r_Conv_DEM::paramSep=","; const char* r_Conv_DEM::paramEq="="; const char* r_Conv_DEM::paramFlipX="flipx"; const char* r_Conv_DEM::paramFlipY="flipy"; const char* r_Conv_DEM::paramStartX="startx"; const char* r_Conv_DEM::paramEndX="endx"; const char* r_Conv_DEM::paramResX="resx"; const char* r_Conv_DEM::paramStartY="starty"; const char* r_Conv_DEM::paramEndY="endy"; const char* r_Conv_DEM::paramResY="resy"; const r_Double r_Conv_DEM::NULL_DB = 0.; const r_Double r_Conv_DEM::ZERO_DB = FLT_MIN; const r_Double r_Conv_DEM::ZERO_DEM = 0.; r_Conv_DEM::~r_Conv_DEM( void ) { //nothing to care for } void r_Conv_DEM::initGeoBBox( r_GeoBBox& cBBox ) { //flipy is selected by default cBBox.flipy = 1; //flipx is not selected by default cBBox.flipx = 0; //geo information are initialized by default to DBL_MAX // FIXME: better defaults res=1, min=-MAX? cBBox.startx = DBL_MAX; cBBox.endx = DBL_MAX; cBBox.resx = DBL_MAX; cBBox.starty = DBL_MAX; cBBox.endy = DBL_MAX; cBBox.resy = DBL_MAX; } r_Conv_DEM::r_Conv_DEM(const char* source, const r_Minterval& lengthordomain, const r_Type* tp) throw(r_Error) : r_Convertor(source, lengthordomain, tp, true) { initGeoBBox(collBBox); } r_Conv_DEM::r_Conv_DEM(const char* source, const r_Minterval& lengthordomain, int tp) throw(r_Error) : r_Convertor(source, lengthordomain, tp) { initGeoBBox(collBBox); } bool r_Conv_DEM::decodeOptions(const char* options, r_GeoBBox& cBBox) throw() { RMInit::logOut << "r_Conv_DEM::decodeOptions(" << (options?options:"NULL") << ")" << endl; r_Parse_Params parseParams; initGeoBBox(cBBox); parseParams.add(paramFlipX, &cBBox.flipx, r_Parse_Params::param_type_int); parseParams.add(paramFlipY, &cBBox.flipy, r_Parse_Params::param_type_int); parseParams.add(paramStartX, &cBBox.startx, r_Parse_Params::param_type_double); parseParams.add(paramEndX, &cBBox.endx, r_Parse_Params::param_type_double); parseParams.add(paramResX, &cBBox.resx, r_Parse_Params::param_type_double); parseParams.add(paramStartY, &cBBox.starty, r_Parse_Params::param_type_double); parseParams.add(paramEndY, &cBBox.endy, r_Parse_Params::param_type_double); parseParams.add(paramResY, &cBBox.resy, r_Parse_Params::param_type_double); //process options r_Long processRet=parseParams.process(options); if(processRet < paramMin) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: Some required options are missing!" << endl; return false; } //check if start,res,end are present if(cBBox.startx == DBL_MAX) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: startx is not present!" << endl; return false; } if(cBBox.starty == DBL_MAX) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: starty is not present!" << endl; return false; } if(cBBox.endx == DBL_MAX) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: endx is not present!" << endl; return false; } if(cBBox.endy == DBL_MAX) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: endy is not present!" << endl; return false; } if(cBBox.resx == DBL_MAX) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: resx is not present!" << endl; return false; } if(cBBox.resy == DBL_MAX) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: resy is not present!" << endl; return false; } //check res if(!cBBox.resx) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: resx is zero!" << endl; return false; } if(!cBBox.resy) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: resy is zero!" << endl; return false; } //check start >= end if(cBBox.startx >= cBBox.endx ) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Error: startx >= endx!" << endl; return false; } if(cBBox.starty >= cBBox.endy) { RMInit::logOut << "r_Conv_DEM::decodeOptions(...) Erorr: starty >= endy!" << endl; return false; } //show parsed options RMInit::logOut.setf(std::ios::fixed); RMInit::logOut << "r_Conv_DEM::decodeOptions(...) parsed options:" << endl << " " << paramFlipX << paramEq << cBBox.flipx << " " << paramFlipY << paramEq << cBBox.flipy << endl << " " << paramStartX << paramEq << cBBox.startx << " " << paramEndX << paramEq << cBBox.endx << " " << paramResX << paramEq << cBBox.resx << endl << " " << paramStartY << paramEq << cBBox.starty << " " << paramEndY << paramEq << cBBox.endy << " " << paramResY << paramEq << cBBox.resy << endl; return true; } string r_Conv_DEM::encodeOptions(const r_GeoBBox& cBBox) throw() { std::ostringstream os; os.str(""); os.setf(std::ios::fixed); os << paramFlipX << paramEq << cBBox.flipx << paramSep << paramFlipY << paramEq << cBBox.flipy << paramSep << paramStartX << paramEq << cBBox.startx << paramSep << paramEndX << paramEq << cBBox.endx << paramSep << paramResX << paramEq << cBBox.resx << paramSep << paramStartY << paramEq << cBBox.starty << paramSep << paramEndY << paramEq << cBBox.endy << paramSep << paramResY << paramEq << cBBox.resy; RMInit::logOut << "r_Conv_DEM::encodeOptions(" << os.str() << ")" << endl; return os.str(); } void r_Conv_DEM::checkLimits() throw(r_Error) { //show processed data RMInit::logOut << "r_Conv_DEM::checkLimits() processed data:" << endl << " minx=" << min.x << " miny=" << min.y << " minh=" << min.h << endl << " maxx=" << max.x << " maxy=" << max.y << " maxh=" << max.h << endl; // printf( "r_Conv_DEM::checkLimits() processed data: minx=%8G, miny=%8G, minh=%8G, maxx=%8G, maxy=%8G, maxh=%8G\n", min.x, min.y, min.h, max.x, max.y, max.h ); if(collBBox.startx > min.x) { RMInit::logOut << "r_Conv_DEM::checkLimits() startx( " << collBBox.startx << ") > min.x (" << min.x << " )!" << endl; throw r_Error(); } if(collBBox.endx < max.x) { RMInit::logOut << "r_Conv_DEM::checkLimits() endx( " << collBBox.endx << ") < max.x (" << max.x << " )!" << endl; throw r_Error(); } if(collBBox.starty > min.y) { RMInit::logOut << "r_Conv_DEM::checkLimits() starty( " << collBBox.starty << ") > min.y (" << min.y << " )!" << endl; throw r_Error(); } if(collBBox.endy < max.y) { RMInit::logOut << "r_Conv_DEM::checkLimits() endy( " << collBBox.endy << ") < max.y (" << max.y << " )!" << endl; throw r_Error(); } } void r_Conv_DEM::readFromSrcStream() throw(r_Error) { istrstream iFile(desc.src, desc.srcInterv[0].get_extent()); string currStrRow; r_Long rowNo=0; r_Double noResx, noResy; DEMRow currRow, prevRow; min.x=min.y=min.h=DBL_MAX; max.x=max.y=max.h=-DBL_MAX; demRows.clear(); //process the lines while(!iFile.eof()) { getline(iFile, currStrRow); rowNo++; if(currStrRow.empty()) { // TALK( "r_Conv_DEM::readFromSrcStream() skipping empty line " << rowNo ); continue; } else { // have an input stream for analysing the current line // (declaring this variable here allows to have a fresh one; // had a reentrance problem with followup lines -- PB 2005-sep-08) istringstream icurrRow; icurrRow.str(currStrRow); //decode x icurrRow >> currRow.x; if(!icurrRow) { RMInit::logOut << "Error in r_Conv_DEM::readFromSrcStream():: unable to decode x in line " << rowNo << ", skipping line: " << currStrRow << endl; continue; } //decode y icurrRow >> currRow.y; if(!icurrRow) { RMInit::logOut << "Error in r_Conv_DEM::readFromSrcStream():: unable to decode y in line " << rowNo << ", skipping line: " << currStrRow << endl; continue; } //decode h icurrRow >> currRow.h; if(!icurrRow) { RMInit::logOut << "Error in r_Conv_DEM::readFromSrcStream():: unable to decode h in line " << rowNo << ", skipping line: " << currStrRow << endl; continue; } //update to support NULL value: 0. (real value) goes in FLT_MIN(db value) //because 0.(db value) represent NULL(real value). When we do export we skip NULL values. if(currRow.h == ZERO_DEM) currRow.h=ZERO_DB; //FIXME we ignore this check, because it may happen to have a incomplet dem /* //check if we have resx, resy noResx=currRow.x/collBBox.resx; if((currRow.x - noResx*collBBox.resx) > 0.) { RMInit::logOut << "r_Conv_DEM::readFromSrcStream() resolution for x on line " << rowNo << " is not " << collBBox.resx << " !" << endl; throw r_Error(); } noResy=currRow.y/collBBox.resy; if((currRow.y - noResy*collBBox.resy) > 0.) { RMInit::logOut << "r_Conv_DEM::readFromSrcStream() resolution for y on line " << rowNo << " is not " << collBBox.resy << " !" << endl; throw r_Error(); } */ //compute min, max for x,y,z min.x=std::min(min.x, currRow.x); min.y=std::min(min.y, currRow.y); min.h=std::min(min.h, currRow.h); max.x=std::max(max.x, currRow.x); max.y=std::max(max.y, currRow.y); max.h=std::max(max.h, currRow.h); //store currRow demRows.push_back(currRow); }//end if(currStrRow.empty()) }//end reading src stream if(demRows.empty()) { // TALK( "r_Conv_DEM::readFromSrcStream() desc.src stream empty." ); throw r_Error(); } // std::cout << "r_Conv_DEM::readFromSrcStream(): x=" << min.x << ":" << max.x << ", y=" << min.y << ":" << max.y << endl; //check limits checkLimits(); } void r_Conv_DEM::readToSrcStream() throw(r_Error) { r_Long x=0, y=0; r_Long xlow=0, ylow=0; r_Long xhigh=0, yhigh=0; DEMRow currRow; r_Bytes typeSize=0; r_Long offset=0; char* buffer=NULL; //initialize xlow=desc.srcInterv[0].low(); ylow=desc.srcInterv[1].low(); xhigh=desc.srcInterv[0].high(); yhigh=desc.srcInterv[1].high(); //compute min & max if (collBBox.flipx) { min.x=collBBox.endx - xhigh*collBBox.resx; max.x=collBBox.endx - xlow*collBBox.resx; } else { min.x=collBBox.startx + xlow*collBBox.resx; max.x=collBBox.startx + xhigh*collBBox.resx; } if(collBBox.flipy) { min.y=collBBox.endy - yhigh*collBBox.resy; max.y=collBBox.endy - ylow*collBBox.resy; } else { min.y=collBBox.starty + ylow*collBBox.resy; max.y=collBBox.starty + yhigh*collBBox.resy; } min.h=DBL_MAX; max.h=-DBL_MAX; //check limits checkLimits(); //prepare container demRows.clear(); typeSize=((r_Primitive_Type*)desc.srcType)->size(); buffer=new char[typeSize]; if(!buffer) { RMInit::logOut << "r_Conv_DEM::readToSrcStream() unable to claim memory !" << endl; throw r_Ememory_allocation(); } for(y=ylow; y<=yhigh; y++) { if(collBBox.flipy) currRow.y=collBBox.endy - y*collBBox.resy; else currRow.y=collBBox.starty + y*collBBox.resy; for(x=xlow; x<=xhigh; x++) { if(collBBox.flipx) currRow.x=collBBox.endx - x*collBBox.resx; else currRow.x=collBBox.startx + x*collBBox.resx; offset=desc.srcInterv.cell_offset(r_Point(x,y))*typeSize; memcpy(buffer, &desc.src[offset], typeSize); switch(desc.srcType->type_id()) { case r_Type::BOOL: currRow.h=((r_Primitive_Type*)desc.srcType)->get_boolean(buffer); break; case r_Type::CHAR: currRow.h=((r_Primitive_Type*)desc.srcType)->get_char(buffer); break; case r_Type::OCTET: currRow.h=((r_Primitive_Type*)desc.srcType)->get_octet(buffer); break; case r_Type::SHORT: currRow.h=((r_Primitive_Type*)desc.srcType)->get_short(buffer); break; case r_Type::USHORT: currRow.h=((r_Primitive_Type*)desc.srcType)->get_ushort(buffer); break; case r_Type::LONG: currRow.h=((r_Primitive_Type*)desc.srcType)->get_long(buffer); break; case r_Type::ULONG: currRow.h=((r_Primitive_Type*)desc.srcType)->get_ulong(buffer); break; case r_Type::FLOAT: currRow.h=((r_Primitive_Type*)desc.srcType)->get_float(buffer); break; case r_Type::DOUBLE: currRow.h=((r_Primitive_Type*)desc.srcType)->get_double(buffer); break; default: //write message to log RMInit::logOut << "r_Conv_DEM::readToSrcStream() srcType (" << desc.srcType->type_id() << ") unsupported !" << endl; //clean up if(buffer) { delete[] buffer; buffer=NULL; } //report error throw r_Error(); break; } min.h=std::min(min.h, currRow.h); max.h=std::max(max.h, currRow.h); demRows.push_back(currRow); } } //clean up if(buffer) { delete[] buffer; buffer=NULL; } if(demRows.empty()) { RMInit::logOut << "r_Conv_DEM::readToSrcStream() src stream is empty !" << endl; throw r_Error(); } RMInit::logOut << "r_Conv_DEM::readToSrcStream() processed interval [" << xlow << ":" << xhigh << "," << ylow << ":" << yhigh << "]" << endl; } void r_Conv_DEM::writeFromDestStream() throw(r_Error) { DEMRowVec::const_iterator iter, iterEnd; r_Long xdim, ydim, offset; r_Point currPt(destIntervDim); r_Bytes typeSize=0; //FIXME here we should modify for other type support if(desc.destType->type_id() != r_Type::DOUBLE) { RMInit::logOut << "r_Conv_DEM::writeFromDestStream() destType (" << desc.destType->type_id() << ") is not " << r_Type::DOUBLE << " !" << endl; throw r_Error(); } xdim=desc.destInterv[0].get_extent(); ydim=desc.destInterv[1].get_extent(); iter=demRows.begin(); iterEnd=demRows.end(); typeSize=((r_Primitive_Type*)desc.destType)->size(); //FIXME correction for strange effect of r_Long cast with 1e-6 while(iter != iterEnd) { if(collBBox.flipx) currPt[0]=(collBBox.endx - iter->x)/collBBox.resx + 1e-6; else currPt[0]=(iter->x - collBBox.startx)/collBBox.resx + 1e-6; if(collBBox.flipy) currPt[1]=(collBBox.endy - iter->y)/collBBox.resy + 1e-6; else currPt[1]=(iter->y - collBBox.starty)/collBBox.resy + 1e-6; ((r_Primitive_Type*)desc.destType)->set_double(&desc.dest[desc.destInterv.cell_offset(currPt)*typeSize], iter->h); ++iter; } RMInit::logOut << "r_Conv_DEM::writeFromDestStream() processed " << xdim << " x " << ydim << " elements." << endl; } void r_Conv_DEM::writeToDestStream(ofstream& oFile) throw(r_Error) { DEMRowVec::const_iterator iter, iterEnd; r_Double currH; if(!oFile.is_open()) { RMInit::logOut << "r_Conv_DEM::writeToDestStream() oFile is not opened !" << endl; throw r_Error(); } oFile.setf(std::ios::fixed); iter=demRows.begin(); iterEnd=demRows.end(); while(iter != iterEnd) { //update to support NULL value: 0. (real value) goes in FLT_MIN(db value) //because 0.(db value) represent NULL(real value). When we do export we skip NULL values. currH = iter->h; if(currH != NULL_DB) { //FIXME we have to implement different here when we change server scale algorithm if(currH == ZERO_DB) currH = ZERO_DEM; oFile << iter->x << "\t" << iter->y << "\t" << currH << endl; } ++iter; } } r_convDesc& r_Conv_DEM::convertFrom(const char* options) throw (r_Error) { bool hasSrcType=true; RMInit::logOut << "r_Conv_DEM::convertFrom(" << (options?options:"NULL") << ")" << endl; if(!desc.srcType) { desc.srcType=get_external_type(desc.baseType); hasSrcType=false; } try { RMInit::logOut << "r_Conv_DEM::convertFrom(...) src interval=" << desc.srcInterv << endl; RMInit::logOut << "r_Conv_DEM::convertFrom(...) src type=" << desc.srcType->type_id() << endl; //check options if(!decodeOptions(options, collBBox)) { RMInit::logOut << "Error in r_Conv_DEM::convertFrom(): illegal option string: " << (options?options:"(null)") << endl; throw r_Error(); } //check desc.srcInterv.dimension if(desc.srcInterv.dimension() != srcIntervDim) { RMInit::logOut << "r_Conv_DEM::convertFrom(" << (options?options:"NULL") << ") desc.srcInterv dimension (" << desc.srcInterv.dimension() << " != " << srcIntervDim << " !" << endl; throw r_Error(); } //check srcType if(!desc.srcType->isPrimitiveType()) { RMInit::logOut << "r_Conv_DEM::convertFrom(" << (options?options:"NULL") << ") desc.srcType (" << desc.srcType->type_id() << ") not supported, only primitive types !" << endl; throw r_Error(); } if(desc.srcType->isComplexType()) { RMInit::logOut << "r_Conv_DEM::convertFrom(" << (options?options:"NULL") << ") desc.srcType (" << desc.srcType->type_id() << ") not supported !" << endl; throw r_Error(); } //read src stream readFromSrcStream(); //convert from DEM to marray //--computing the marray domain desc.destInterv = r_Minterval(destIntervDim); //FIXME correction for strange efect of r_Long cast with 1e-6 if(collBBox.flipx) desc.destInterv << r_Sinterval((r_Long)((collBBox.endx - max.x)/collBBox.resx + 1e-6), (r_Long)((collBBox.endx - min.x)/collBBox.resx + 1e-6)); else desc.destInterv << r_Sinterval((r_Long)((min.x - collBBox.startx)/collBBox.resx + 1e-6), (r_Long)((max.x - collBBox.startx)/collBBox.resx + 1e-6)); if(collBBox.flipy) desc.destInterv << r_Sinterval((r_Long)((collBBox.endy - max.y)/collBBox.resy + 1e-6), (r_Long)((collBBox.endy - min.y)/collBBox.resy + 1e-6)); else desc.destInterv << r_Sinterval((r_Long)((min.y - collBBox.starty)/collBBox.resy + 1e-6), (r_Long)((max.y - collBBox.starty)/collBBox.resy + 1e-6)); RMInit::logOut << "r_Conv_DEM::convertFrom(...) dest interval=" << desc.destInterv << endl; //--creating the resulting type desc.destType = new r_Primitive_Type("Double", r_Type::DOUBLE); RMInit::logOut << "r_Conv_DEM::convertFrom(...) dest type=" << desc.destType->type_id() << endl; //--claim memory for result desc.dest = (char*)mystore.storage_alloc(desc.destInterv.cell_count() * ((r_Primitive_Type*)desc.destType)->size()); if(desc.dest==NULL) { RMInit::logOut << "r_Conv_DEM::convertFrom(" << (options?options:"NULL") << ") unable to claim memory !" << endl; throw r_Ememory_allocation(); } memset(desc.dest, 0, desc.destInterv.cell_count() * ((r_Primitive_Type*)desc.destType)->size()); //--write parsed data in desc.dest writeFromDestStream(); } catch(r_Error& err) { //cleanup if(!hasSrcType) { delete desc.srcType; desc.srcType=NULL; } //desc.destType if(desc.destType) { delete desc.destType; desc.destType=NULL; } //desc.dest if(desc.dest) { mystore.storage_free(desc.dest); desc.dest=NULL; } //report error throw; } //cleanup if(!hasSrcType) { delete desc.srcType; desc.srcType=NULL; } //return result return desc; } r_convDesc& r_Conv_DEM::convertTo(const char* options) throw (r_Error) { bool hasSrcType=true; char* pTempFileName=NULL; // name of temp file string tempFileName; // duplicate of temp file name -- heaven knows why ofstream oFile; // for writing out file FILE* pFile=NULL; // for reading back file size_t lenFile=0; // size of file as read RMInit::logOut << "r_Conv_DEM::convertTo(" << (options?options:"NULL") << ")" << endl; try { if(!desc.srcType) { desc.srcType=get_external_type(desc.baseType); hasSrcType=false; } RMInit::logOut << "r_Conv_DEM::convertTo(...) src interval=" << desc.srcInterv << endl; RMInit::logOut << "r_Conv_DEM::convertTo(...) src type=" << desc.srcType->type_id() << endl; //check options if(!decodeOptions(options, collBBox)) throw r_Error(); if(!desc.srcType->isPrimitiveType()) { RMInit::logOut << "r_Conv_DEM::convertTo(" << (options?options:"NULL") << ") desc.srcType (" << desc.srcType->type_id() << ") not supported, only primitive types !" << endl; throw r_Error(); } if(desc.srcType->isComplexType()) { RMInit::logOut << "r_Conv_DEM::convertTo(" << (options?options:"NULL") << ") desc.srcType (" << desc.srcType->type_id() << ") not supported !" << endl; throw r_Error(); } //read src data readToSrcStream(); //convert from marray to DEM; //--create the temp file //FIXME for multithread application pTempFileName=tmpnam(NULL); if(pTempFileName==NULL) { RMInit::logOut << "r_Conv_DEM::convertTo(" << (options?options:"NULL") << ") desc.srcType (" << desc.srcType->type_id() << ") unable to generate a tempory file !" << endl; throw r_Error(); } tempFileName=pTempFileName; oFile.open(tempFileName.c_str()); if(!oFile.is_open()) { RMInit::logOut << "r_Conv_DEM::convertTo(" << (options?options:"NULL") << ") desc.srcType (" << desc.srcType->type_id() << ") unable to open the tempory file !" << endl; throw r_Error(); } RMInit::logOut << "r_Conv_DEM::convertTo(...) temp file=" << tempFileName << endl; //--get DEM format writeToDestStream(oFile); oFile.close(); //--accessing the temp file if ((pFile = fopen(tempFileName.c_str(), "rb")) == NULL) { RMInit::logOut << "r_Conv_DEM::convertTo(): unable to read back file." << endl; throw r_Error(r_Error::r_Error_General); } fseek(pFile, 0, SEEK_END); lenFile = ftell(pFile); RMInit::logOut << "r_Conv_DEM::convertTo(...) dest len=" << lenFile << endl; if (!lenFile) { RMInit::logOut << "r_Conv_DEM::convertTo(): source contains only NULL values." << endl; throw r_Error( E_DEM_EMPTY ); } //--creating the resulting type desc.destType = new r_Primitive_Type("Char", r_Type::CHAR); //--computing the marray domain desc.destInterv = r_Minterval(srcIntervDim); desc.destInterv << r_Sinterval((r_Long)0, (r_Long)lenFile - 1); RMInit::logOut << "r_Conv_DEM::convertTo(...) dest interval=" << desc.destInterv << endl; RMInit::logOut << "r_Conv_DEM::convertTo(...) dest type=" << desc.destType->type_id() << endl; //--claim memory for desc.dest desc.dest = (char*)mystore.storage_alloc(lenFile); if(desc.dest==NULL) { RMInit::logOut << "r_Conv_DEM::convertTo(" << (options?options:"NULL") << ") unable to claim memory !" << endl; throw r_Ememory_allocation(); } memset(desc.dest, 0, lenFile); //--store data in desc.dest fseek(pFile, 0, SEEK_SET); fread(desc.dest, 1, lenFile, pFile); //clean up fclose(pFile); pFile=NULL; remove(pTempFileName); } catch(r_Error& err) { //cleanup if(!hasSrcType) { delete desc.srcType; desc.srcType=NULL; } //desc.destType if(desc.destType) { delete desc.destType; desc.destType=NULL; } //desc.dest if(desc.dest) { mystore.storage_free(desc.dest); desc.dest=NULL; } // close & remove file, if not done previously fclose(pFile); pFile=NULL; remove(pTempFileName); //rethrow error throw; } //clean up if(!hasSrcType) { delete desc.srcType; desc.srcType=NULL; } //return result return desc; } const char* r_Conv_DEM::get_name() const throw() { return get_name_from_data_format(r_DEM); } r_Data_Format r_Conv_DEM::get_data_format() const throw() { return r_DEM; } r_Convertor* r_Conv_DEM::clone() const throw(r_Error) { return new r_Conv_DEM(desc.src, desc.srcInterv, desc.srcType); }