LCOV - code coverage report
Current view: top level - alma/ASDMBinaries - SDMDataObjectReader.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 11 516 2.1 %
Date: 2025-08-21 08:01:32 Functions: 1 26 3.8 %

          Line data    Source code
       1             : #include <alma/ASDMBinaries/SDMDataObjectReader.h>
       2             : 
       3             : #include <iostream>
       4             : #include <iomanip>
       5             : #include <unistd.h>
       6             : #include <sys/types.h>
       7             : #include <sys/mman.h>
       8             : #include <fcntl.h>
       9             : #include <sys/stat.h>
      10             : #include <errno.h>
      11             : #include <cstring>
      12             : #include <exception>
      13             : #include <sstream>
      14             : #include <cstring> //strerror
      15             : 
      16             : #include <alma/ASDMBinaries/CommonDefines.h>
      17             : 
      18             : #if defined( __APPLE__ )
      19             :    #include <AvailabilityMacros.h>
      20             : // 10.5 defines stat64 but Tiger does NOT
      21             :    #if defined(MAC_OS_X_VERSION_10_4) && ! defined(MAC_OS_X_VERSION_10_5)
      22             :       #define  stat64  stat
      23             :       #define fstat64 fstat
      24             :    #endif
      25             : #endif
      26             : 
      27             : using namespace CorrelationModeMod;
      28             : using namespace CorrelatorTypeMod;
      29             : using namespace PrimitiveDataTypeMod;
      30             : using namespace ProcessorTypeMod;
      31             : 
      32             : using namespace std;
      33             : 
      34             : namespace asdmbinaries {
      35             : 
      36             :   const string SDMDataObjectReader::MIMEBOUNDARY_1  = $MIMEBOUNDARY1;
      37             :   const string SDMDataObjectReader::MIMEBOUNDARY_2  = $MIMEBOUNDARY2;
      38             : 
      39             : #ifndef WITHOUT_BOOST
      40             :   const boost::regex SDMDataObjectReader::CONTENTIDBINREGEXP(" <([a-zA-Z]+)_([_0-9]+)\\.bin>");
      41             :   const boost::regex SDMDataObjectReader::CONTENTIDBINREGEXP1(" <([a-zA-Z]+)_([0-9]+)\\.bin>");
      42             :   const boost::regex SDMDataObjectReader::CONTENTIDBINREGEXP2(" <([a-zA-Z]+)_([0-9]+)_([0-9]+)\\.bin>");
      43             :   //  const boost::regex SDMDataObjectReader::CONTENTIDSUBSETREGEXP(" <(Subset)_([0-9]+)\\.xml>");
      44             :   const boost::regex SDMDataObjectReader::CONTENTIDSUBSETREGEXP(" <(Subset)_([0-9]+)(_[0-9]+)?\\.xml>");
      45             :   const boost::regex SDMDataObjectReader::CONTENTIDDATASTRUCTUREREGEXP(" <DataStructure.xml>");
      46             : #else
      47             :   const std::regex SDMDataObjectReader::CONTENTIDBINREGEXP(" <([a-zA-Z]+)_([_0-9]+)\\.bin>");
      48             :   const std::regex SDMDataObjectReader::CONTENTIDBINREGEXP1(" <([a-zA-Z]+)_([0-9]+)\\.bin>");
      49             :   const std::regex SDMDataObjectReader::CONTENTIDBINREGEXP2(" <([a-zA-Z]+)_([0-9]+)_([0-9]+)\\.bin>");
      50             :   //  const std::regex SDMDataObjectReader::CONTENTIDSUBSETREGEXP(" <(Subset)_([0-9]+)\\.xml>");
      51             :   const std::regex SDMDataObjectReader::CONTENTIDSUBSETREGEXP(" <(Subset)_([0-9]+)(_[0-9]+)?\\.xml>");
      52             :   const std::regex SDMDataObjectReader::CONTENTIDDATASTRUCTUREREGEXP(" <DataStructure.xml>");
      53             : #endif
      54             :   set<string> SDMDataObjectReader::BINATTACHNAMES;
      55             :   map<string, SDMDataObjectReader::BINATTACHCODES> SDMDataObjectReader::name2code;
      56             :   const bool SDMDataObjectReader::initClass_ = SDMDataObjectReader::initClass();
      57             : 
      58             :   // SDMDataObjectReader:: methods
      59             :   //
      60           0 :   SDMDataObjectReader::SDMDataObjectReader() {
      61           0 :     init();
      62           0 :   }
      63             : 
      64           0 :   SDMDataObjectReader::~SDMDataObjectReader() {
      65           0 :     done();
      66           0 :   }
      67             : 
      68          11 :   bool SDMDataObjectReader::initClass() {
      69          11 :     char* binAttachNamesC[] = {(char *) "actualDurations", (char *) "actualTimes", (char *) "autoData", (char *) "flags", (char *) "crossData", (char *) "zeroLags", 0};
      70          77 :     for (int i = 0; binAttachNamesC[i]; i++) {
      71          66 :       BINATTACHNAMES.insert(string(binAttachNamesC[i]));
      72             :     }
      73             : 
      74          11 :     name2code["actualDurations"] = ACTUALDURATIONS;
      75          11 :     name2code["actualTimes"]     = ACTUALTIMES;
      76          11 :     name2code["autoData"]        = AUTODATA;
      77          11 :     name2code["flags"]           = FLAGS;
      78          11 :     name2code["crossData"]       = CROSSDATA;
      79          11 :     name2code["zeroLags"]        = ZEROLAGS;
      80             : 
      81          11 :     return true;
      82             :   }
      83             : 
      84           0 :   void SDMDataObjectReader::init() {
      85           0 :     filedes_ = 0;
      86           0 :     data_ = (char *) 0;
      87           0 :     position_ = 0;
      88           0 :     lastPosition_ = 0;
      89           0 :     endPosition_ = 0;
      90             :     
      91           0 :     read_ = UNKNOWN_;
      92             : 
      93           0 :     integrationNum_ = 0;
      94           0 :   }
      95             : 
      96           0 :   string::size_type SDMDataObjectReader::find(const string& s) {
      97             : 
      98             :     while (true) {
      99           0 :       while ((position_ < endPosition_) && (data_[position_++] != s.at(0))) {;}
     100             :       
     101           0 :       if (position_ == endPosition_) return string::npos;
     102             : 
     103           0 :       string::size_type lastPosition_ = position_;      
     104           0 :       unsigned long long int i = 1;
     105             : 
     106           0 :       while ((position_ < endPosition_) && (i < s.length())) {
     107           0 :         if (s.at(i) != data_[position_]) break;
     108           0 :         i++;
     109           0 :         position_++;
     110             :       }
     111             :       
     112           0 :       if (i == s.length()) return (position_ - s.length());
     113             :       
     114           0 :       if (position_ == endPosition_) return string::npos;
     115             :       
     116           0 :       position_ = lastPosition_; //+1;
     117           0 :     }
     118             :   }
     119             :     
     120           0 :   bool SDMDataObjectReader::compare(const string& s) {
     121           0 :     string::size_type index = position_;
     122             : 
     123           0 :     unsigned int i = 0;
     124           0 :     while ((index < endPosition_) && (i < s.length()) && (s.at(i++) == data_[index++])) {
     125             :       ;
     126             :     }
     127           0 :     return (i == s.length());
     128             :   }
     129             : 
     130           0 :   bool SDMDataObjectReader::EOD() {
     131           0 :     return position_ >= endPosition_;
     132             :   }
     133             : 
     134             : 
     135           0 :   string SDMDataObjectReader::extractXMLHeader(const string& boundary) {
     136             :     // cout << "Entering extractXMLHeader"  << endl;
     137             : 
     138           0 :     string boundary_ = "\n--"+boundary;
     139             : 
     140           0 :     unsigned long int positionBeg = 0;
     141           0 :     unsigned long int positionEnd = 0;
     142             : 
     143             :     // We assume that we are at the first character of the body.
     144           0 :     positionBeg = position_;
     145             : 
     146             :     // Look for the next boundary supposed to be found right after an the XML header. 
     147           0 :     if ( (positionEnd = find(boundary_)) == string::npos) {
     148           0 :       ostringstream eos;
     149           0 :       eos << "A second MIME boundary '" << boundary <<"' could not be found in the MIME message after position " << positionBeg << ".";      
     150           0 :       throw SDMDataObjectReaderException(eos.str());      
     151           0 :     }
     152             : 
     153           0 :     string xmlPart = string(data_+positionBeg, positionEnd-positionBeg);
     154             :   
     155             :     // cout << "Found XML Header : " << xmlPart << endl;
     156             :     // cout << "Exiting extractXMLHeader"  << endl;
     157             : 
     158           0 :     return xmlPart;
     159           0 :   }
     160             : 
     161             : 
     162           0 :   void SDMDataObjectReader::tokenize(const string& str,
     163             :                                      vector<string>& tokens,
     164             :                                      const string& delimiters) {
     165             :     // Skip delimiters at beginning.
     166           0 :     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
     167             :     // Find first "non-delimiter".
     168           0 :     string::size_type pos     = str.find_first_of(delimiters, lastPos);
     169             :     
     170           0 :     while (string::npos != pos || string::npos != lastPos) {
     171             :       // Found a token, add it to the vector.
     172           0 :       tokens.push_back(str.substr(lastPos, pos - lastPos));
     173             :       // Skip delimiters.  Note the "not_of"
     174           0 :       lastPos = str.find_first_not_of(delimiters, pos);
     175             :       // Find next "non-delimiter"
     176           0 :       pos = str.find_first_of(delimiters, lastPos);
     177             :     }    
     178           0 :   }
     179             : 
     180             : 
     181           0 :   void SDMDataObjectReader::getFields(const string& header, map<string, string>& fields) {
     182             :     // We are at the last character of the line preceding the 1st field declaration.
     183           0 :     istringstream iss;
     184           0 :     iss.str(header);
     185           0 :     string line;
     186             : 
     187           0 :     getline(iss, line); // skip an nl
     188             :     
     189             :     // Split each line into field-name, field-value
     190           0 :     while (getline(iss, line)) {
     191           0 :       vector<string> nv;
     192           0 :       tokenize(line, nv, ":");
     193           0 :       if (nv.size() < 2) {
     194           0 :         ostringstream oss;
     195           0 :         oss << "Invalid field in a MIME header '" << header << "', integration #" << integrationNum_;
     196           0 :         throw SDMDataObjectReaderException (oss.str());
     197           0 :       }
     198           0 :       fields[nv.at(0)] = nv.at(1);
     199           0 :     }
     200           0 :   }
     201             : 
     202           0 :   string SDMDataObjectReader::getContentID() {
     203             :     // We are at the beginning of an attachment right after its opening boundary.
     204           0 :     string::size_type lastPosition = position_;
     205             :     
     206             :     // Now let's extract the header (which is followed by two successive nl nl)
     207             :     string::size_type endHeader;
     208           0 :     if ( (endHeader = find ("\n\n")) == string::npos) {
     209           0 :       throw SDMDataObjectReaderException("Could not find the end of a MIME header");
     210             :     }
     211             : 
     212           0 :     string header(data_+lastPosition, (endHeader - lastPosition));
     213             :     
     214           0 :     map<string, string> fields;
     215           0 :     getFields(header, fields);
     216             : 
     217             :     // Look for the Content-ID field
     218           0 :     map<string, string>::iterator iter = fields.find("Content-ID");
     219           0 :     if (iter == fields.end()) {
     220           0 :       ostringstream oss;
     221           0 :       oss << "'Content-ID' field is missing the MIME header of an attachment (approx. char position = " << position_ << ").";
     222           0 :       throw SDMDataObjectReaderException(oss.str());
     223           0 :     }
     224           0 :     return iter->second;
     225           0 :   }
     226             : 
     227           0 :   string SDMDataObjectReader::getContentLocation() {
     228             :     // We are at the beginning of an attachment right after its opening boundary.
     229           0 :     string::size_type lastPosition = position_;
     230             :     
     231             :     // Now let's extract the header (which is followed by two successive nl nl)
     232             :     string::size_type endHeader;
     233           0 :     if ( (endHeader = find ("\n\n")) == string::npos) {
     234           0 :       throw SDMDataObjectReaderException("Could not find the end of a MIME header");
     235             :     }
     236             : 
     237           0 :     string header(data_+lastPosition, (endHeader - lastPosition));
     238             :     
     239           0 :     map<string, string> fields;
     240           0 :     getFields(header, fields);
     241             : 
     242             :     // Look for the Content-Location field
     243           0 :     map<string, string>::iterator iter = fields.find("Content-Location");
     244           0 :     if (iter == fields.end()) {
     245           0 :       ostringstream oss;
     246           0 :       oss << "'Content-Location' field is missing the MIME header of an attachment (approx. char position = " << position_ << ").";
     247           0 :       throw SDMDataObjectReaderException(oss.str());
     248           0 :     }
     249           0 :     return iter->second;    
     250           0 :   }
     251             : 
     252           0 :   void SDMDataObjectReader::processBinaryAttachment(const string& boundary, const SDMDataSubset& sdmDataSubset) {
     253             : 
     254           0 :     string contentLocation = getContentLocation();
     255             : 
     256             :     // Extract the attachment name and the integration number.
     257             : #ifndef WITHOUT_BOOST
     258             :     boost::cmatch what;
     259             :     boost::regex r(" *" + sdmDataSubset.projectPath()+"(actualDurations|actualTimes|autoData|flags|crossData|zeroLags)\\.bin");
     260             :     if (boost::regex_match(contentLocation.c_str(), what, r)) {
     261             :     }
     262             : #else
     263           0 :     std::cmatch what;
     264           0 :     std::regex r(" *" + sdmDataSubset.projectPath()+"(actualDurations|actualTimes|autoData|flags|crossData|zeroLags)\\.bin");
     265           0 :     if (std::regex_match(contentLocation.c_str(), what, r)) {
     266             :     }
     267             : #endif
     268             :     else {
     269           0 :       ostringstream oss;
     270           0 :       oss << "Invalid Content-Location field '" << contentLocation <<"' in MIME header of an attachment (approx. char position = " << position_ << ").";
     271           0 :       throw SDMDataObjectReaderException(oss.str());
     272           0 :     } 
     273             : 
     274             :     // We are at the first byte of the body of the binary attachment.
     275           0 :     string::size_type startAttachPosition = position_;  // mcaillat
     276             : 
     277             :     // Now look for its closing boundary (or opening boundary of the next one if any).
     278           0 :     string boundary_ = "\n--"+boundary;
     279             :     string::size_type endAttachPosition;
     280           0 :     if ( (endAttachPosition = find(boundary_)) == string::npos) { 
     281           0 :       ostringstream eos;
     282           0 :       eos << "A MIME boundary '" << boundary << "' terminating a binary attachment starting approx. at character " << startAttachPosition <<" could not be found.";
     283           0 :       throw SDMDataObjectReaderException(eos.str());
     284           0 :     }
     285             : 
     286             :     // Compute the length of the attachment.
     287           0 :     string::size_type length = endAttachPosition - startAttachPosition;
     288             :     
     289             : 
     290             : 
     291           0 :     switch (name2code[what[1]]) {
     292           0 :     case ACTUALDURATIONS:
     293           0 :       actualDurations_ = (ACTUALDURATIONSTYPE *) (data_ + startAttachPosition);
     294           0 :       nActualDurations_ = length / sizeof (ACTUALDURATIONSTYPE);
     295           0 :       attachmentFlags.set(ACTUALDURATIONS);
     296             :       //cout << "actualDurations =" << (unsigned long int) actualDurations_ << ", nActualDurations = " << nActualDurations_ << endl;
     297           0 :       break;
     298           0 :     case ACTUALTIMES:
     299           0 :       actualTimes_ = (ACTUALTIMESTYPE *) (data_ + startAttachPosition);
     300           0 :       nActualTimes_ = length / sizeof( ACTUALTIMESTYPE);
     301           0 :       attachmentFlags.set(ACTUALTIMES);
     302             :       //cout << "actualTimes =" << (unsigned long int) actualTimes_ << ", nActualTimes = " << nActualTimes_ << endl;
     303           0 :       break;
     304           0 :     case AUTODATA:
     305           0 :       autoData_ = (AUTODATATYPE *) (data_ + startAttachPosition);
     306           0 :       nAutoData_ = length / sizeof(AUTODATATYPE);
     307           0 :       attachmentFlags.set(AUTODATA);
     308             :       //cout << "autoData =" << (unsigned long int) autoData_ << ", nAutoData = " << nAutoData_ << endl;
     309           0 :       break;
     310           0 :     case FLAGS:
     311           0 :       flags_ = (const FLAGSTYPE *) (data_ + startAttachPosition);
     312           0 :       nFlags_ = length / sizeof(FLAGSTYPE);
     313           0 :       attachmentFlags.set(FLAGS);
     314             :       //cout << "flags =" << (unsigned long int) flags_ << ", nFlags = " << nFlags_ << endl;
     315           0 :       break;
     316           0 :     case CROSSDATA:
     317           0 :       shortCrossData_ = 0;
     318           0 :       longCrossData_  = 0;
     319           0 :       floatCrossData_ = 0;
     320           0 :       switch (sdmDataSubset.crossDataType()) {
     321           0 :       case INT16_TYPE:
     322           0 :         shortCrossData_  = (const SHORTCROSSDATATYPE*) (data_ + startAttachPosition);
     323           0 :         nCrossData_ = length / sizeof (SHORTCROSSDATATYPE);
     324             :         //cout << "shortCrossData = " << (unsigned long int) shortCrossData_ << ", nShortCrossData = " << nCrossData_ << endl;
     325           0 :         break;
     326             :         
     327           0 :       case INT32_TYPE:
     328           0 :         longCrossData_  = (const INTCROSSDATATYPE*) (data_ + startAttachPosition);
     329           0 :         nCrossData_ = length / sizeof (INTCROSSDATATYPE);
     330             :         //cout << "longCrossData = " << (unsigned long int) longCrossData_ << ", nLongCrossData = " << nCrossData_ << endl;
     331           0 :         break;
     332             : 
     333           0 :       case FLOAT32_TYPE:
     334           0 :         floatCrossData_ = (const FLOATCROSSDATATYPE*) (data_ + startAttachPosition);
     335           0 :         nCrossData_ = length / sizeof (FLOATCROSSDATATYPE);
     336           0 :         break;
     337             :        
     338           0 :       default:
     339           0 :         ostringstream eos;
     340           0 :         eos << "'" << CPrimitiveDataType::toString(sdmDataSubset.crossDataType())
     341           0 :             << "' is not a valid primitive data type for CROSSDATA";
     342           0 :         throw SDMDataObjectReaderException(eos.str());  
     343             :         // cout << "Unrecognized type for cross data" << endl;
     344             :       } 
     345           0 :       attachmentFlags.set(CROSSDATA);
     346           0 :       break;
     347           0 :     case ZEROLAGS:
     348           0 :       zeroLags_ = (ZEROLAGSTYPE *) (data_ + startAttachPosition);
     349           0 :       nZeroLags_ = length / sizeof(ZEROLAGSTYPE) ;
     350           0 :       attachmentFlags.set(ZEROLAGS);
     351             :       //cout << "zeroLags =" << (unsigned long int) zeroLags_ << ", nZeroLags = " << nZeroLags_ << endl;
     352           0 :       break;
     353             : 
     354           0 :     default:
     355             :       //cout << "Unrecognized code" << endl;
     356           0 :       break;
     357             :     }
     358             :     // cout << "found a binary attachment" << endl;
     359           0 :   }
     360             :   
     361           0 :   void SDMDataObjectReader::processMIMESDMDataHeader() {
     362             :     // cout << "Entering processMIMESDMDataHeader" << endl;
     363           0 :     string sdmDataHeader = extractXMLHeader(MIMEBOUNDARY_1);
     364           0 :     parser_.parseMemoryHeader(sdmDataHeader, sdmDataObject_);
     365             :     // cout << "Exiting processMIMESDMDataHeader" << endl;
     366           0 :   }
     367             : 
     368           0 :   void SDMDataObjectReader::processMIMESDMDataSubsetHeader(SDMDataSubset& sdmDataSubset) {
     369             :     // cout << "Entering processMIMESDMDataSubsetHeader" << endl;
     370           0 :     string sdmDataSubsetHeader = extractXMLHeader(MIMEBOUNDARY_2);
     371           0 :     if (sdmDataSubset.owner_->isCorrelation())
     372           0 :       parser_.parseMemoryCorrSubsetHeader(sdmDataSubsetHeader, sdmDataSubset);
     373             :     else 
     374           0 :       parser_.parseMemoryTPSubsetHeader(sdmDataSubsetHeader, sdmDataSubset);
     375             :     // cout << "Exiting processMIMESDMDataSubsetHeader" << endl;
     376           0 :   }
     377             : 
     378           0 :   void SDMDataObjectReader::processMIMEIntegration() {
     379             :     // cout << "Entering processMIMEIntegration" << endl;
     380             : 
     381             :     // We are 1 character beyond the end of --<MIMEBOUNDARY_2>
     382           0 :     string contentLocation = getContentLocation();
     383             : 
     384             : #ifndef WITHOUT_BOOST
     385             :     boost::regex r(" *" + sdmDataObject_.projectPath() + "([[:digit:]]+/){1,2}" + "desc.xml");;
     386             :     ostringstream oss;
     387             :     
     388             :     // Extract the Subset name and the integration [, subintegration] number.
     389             :     boost::cmatch what;
     390             :     if (!boost::regex_match(contentLocation.c_str(), what, r)) {
     391             :       ostringstream oss;
     392             :       oss << "Invalid Content-Location field '" << contentLocation <<"' in MIME header of a Subset (approx. char position = " << position_ << ").";
     393             :       throw SDMDataObjectReaderException(oss.str());
     394             :     } 
     395             : #else
     396           0 :     std::regex r(" *" + sdmDataObject_.projectPath() + "([[:digit:]]+/){1,2}" + "desc.xml");;
     397           0 :     ostringstream oss;
     398             :     
     399             :     // Extract the Subset name and the integration [, subintegration] number.
     400           0 :     std::cmatch what;
     401           0 :     if (!std::regex_match(contentLocation.c_str(), what, r)) {
     402           0 :       ostringstream oss;
     403           0 :       oss << "Invalid Content-Location field '" << contentLocation <<"' in MIME header of a Subset (approx. char position = " << position_ << ").";
     404           0 :       throw SDMDataObjectReaderException(oss.str());
     405           0 :     } 
     406             : #endif
     407             :     
     408           0 :     SDMDataSubset integration(&sdmDataObject_);
     409             :     
     410             :     // The SDMDataSubset header.
     411           0 :     processMIMESDMDataSubsetHeader(integration);
     412             :     
     413           0 :     if (integration.aborted_) {
     414             :       // The [sub]integration has been aborted. Just append its header, without trying to get binary attachment.    
     415           0 :       sdmDataObject_.append(integration);
     416             :     }
     417             :     else {
     418             :       // This is regular [sub]integration, process its binary attachments.
     419           0 :       attachmentFlags.reset();
     420           0 :       while (!EOD() && !compare("--")) {
     421           0 :         processBinaryAttachment(MIMEBOUNDARY_2, integration);
     422             :       } 
     423             :     
     424           0 :       if (EOD()) 
     425           0 :         throw SDMDataObjectReaderException("Unexpected end of data");
     426             : 
     427             :       // Now check if the binary attachments found are compatible with the correlation mode
     428             :       // and if their sizes are equal to what is announced in the global header.
     429             :     
     430           0 :       if (!attachmentFlags.test(ACTUALDURATIONS)) {
     431             :         // No actualdurations attachment found, ok then set everything to 0.
     432           0 :         integration.actualDurations_  = 0;
     433           0 :         integration.nActualDurations_ = 0;
     434             :       }
     435             :       else {
     436           0 :         if (nActualDurations_ != sdmDataObject_.dataStruct().actualDurations().size()) {
     437           0 :           ostringstream oss;
     438           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     439           0 :           oss << "zize of 'actualDuration' attachment (" << nActualDurations_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().actualDurations().size() << ")";
     440           0 :           throw SDMDataObjectReaderException(oss.str());
     441           0 :         }
     442             : 
     443           0 :         integration.actualDurations_  = actualDurations_;
     444           0 :         integration.nActualDurations_ = nActualDurations_; 
     445             :       }
     446             : 
     447           0 :       if (!attachmentFlags.test(ACTUALTIMES)) {
     448             :         // No actualtimes attachment found, ok then set everything to 0.
     449           0 :         integration.actualTimes_  = 0;
     450           0 :         integration.nActualTimes_ = 0;
     451             :       }
     452             :       else {
     453           0 :         if (nActualTimes_ != sdmDataObject_.dataStruct().actualTimes().size()) {
     454           0 :           ostringstream oss;
     455           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     456           0 :           oss << "size of 'actualTimes' attachment (" << nActualTimes_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().actualTimes().size() << ")";
     457           0 :           throw SDMDataObjectReaderException(oss.str());
     458           0 :         } 
     459           0 :         integration.actualTimes_  = actualTimes_;
     460           0 :         integration.nActualTimes_ = nActualTimes_;
     461             :       } 
     462             : 
     463             :       // The flags are optional. They may be absent.
     464           0 :       if (!attachmentFlags.test(FLAGS)) {
     465             :         // No flags binary attachment found, ok then set everything to 0.
     466           0 :         integration.flags_  = 0;
     467           0 :         integration.nFlags_ = 0;
     468             :       }
     469             :       else {
     470             :         // flags found
     471             :         // Check size conformity
     472           0 :         if (nFlags_ != sdmDataObject_.dataStruct().flags().size()) {
     473           0 :           ostringstream oss;
     474           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     475           0 :           oss << "size of 'flags' attachment (" << nFlags_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().flags().size() << ")";
     476           0 :           throw SDMDataObjectReaderException(oss.str());
     477           0 :         } 
     478             : 
     479             :         // Set pointer and size
     480           0 :         integration.flags_ = flags_;
     481           0 :         integration.nFlags_ = nFlags_;
     482             :       }
     483             : 
     484             : 
     485             :       //
     486             :       // The presence of crossData and autoData depends on the correlation mode.
     487             : 
     488             :       // crossDataTypeSize is not currently used
     489             :       // unsigned int crossDataTypeSize;    
     490           0 :       switch (sdmDataObject_.correlationMode()) {  
     491           0 :       case CROSS_ONLY:
     492           0 :         if (!attachmentFlags.test(CROSSDATA)) {
     493           0 :           ostringstream oss;
     494           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     495           0 :           oss << "a binary attachment 'crossData' was expected in integration #" << integrationNum_;
     496           0 :           throw SDMDataObjectReaderException(oss.str());
     497           0 :         }
     498             : 
     499             :       
     500           0 :         if (nCrossData_ != sdmDataObject_.dataStruct().crossData().size()) {
     501           0 :           ostringstream oss;
     502           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     503           0 :           oss << "size of 'crossData' attachment (" << nCrossData_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().crossData().size() << ")";
     504           0 :           throw SDMDataObjectReaderException(oss.str());
     505           0 :         }
     506             :       
     507             :       
     508           0 :         if (attachmentFlags.test(AUTODATA)) {
     509           0 :           ostringstream oss;
     510           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     511           0 :           oss << "found an unexpected attachment 'autoData' in integration #" << integrationNum_ << ".";
     512           0 :           throw SDMDataObjectReaderException(oss.str());
     513           0 :         }
     514             : 
     515           0 :         integration.shortCrossData_ = 0;
     516           0 :         integration.longCrossData_  = 0;
     517           0 :         integration.floatCrossData_ = 0;
     518           0 :         integration.nCrossData_     = 0;
     519           0 :         switch (integration.crossDataType()) {
     520           0 :         case INT32_TYPE:
     521           0 :           integration.longCrossData_    = longCrossData_;
     522           0 :           integration.nCrossData_       = nCrossData_; 
     523           0 :           break;
     524             : 
     525           0 :         case INT16_TYPE:
     526           0 :           integration.shortCrossData_   = shortCrossData_;
     527           0 :           integration.nCrossData_       = nCrossData_; 
     528           0 :           break;
     529             : 
     530           0 :         case FLOAT32_TYPE:
     531           0 :           integration.floatCrossData_   = floatCrossData_;
     532           0 :           integration.nCrossData_       = nCrossData_;
     533           0 :           break;
     534             : 
     535           0 :         default:
     536           0 :           throw SDMDataObjectReaderException("'"+CPrimitiveDataType::name(integration.crossDataType())+"' unexpected here.");
     537             :         } 
     538           0 :         break;
     539             :       
     540           0 :       case AUTO_ONLY:
     541           0 :         if (!attachmentFlags.test(AUTODATA)) {
     542           0 :           ostringstream oss;
     543           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     544           0 :           oss << "a binary attachment 'autoData' was expected.";
     545           0 :           throw SDMDataObjectReaderException(oss.str());
     546           0 :         }
     547           0 :         if (nAutoData_ != sdmDataObject_.dataStruct().autoData().size()) {
     548           0 :           ostringstream oss;
     549           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     550           0 :           oss << "size of 'autoData' attachment (" << nAutoData_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().autoData().size() << ")";
     551           0 :           throw SDMDataObjectReaderException(oss.str());
     552           0 :         }
     553             :       
     554             :       
     555           0 :         if (attachmentFlags.test(CROSSDATA)) {
     556           0 :           ostringstream oss;
     557           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     558           0 :           oss << "found an unexpected attachment 'crossData'";
     559           0 :           throw SDMDataObjectReaderException(oss.str());
     560           0 :         }
     561             : 
     562           0 :         integration.autoData_    = autoData_;
     563           0 :         integration.nAutoData_   = nAutoData_; 
     564             : 
     565           0 :         break;
     566             :       
     567           0 :       case CROSS_AND_AUTO:
     568           0 :         if (!attachmentFlags.test(AUTODATA)) {
     569           0 :           ostringstream oss;
     570           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     571           0 :           oss << "a binary attachment 'autoData' was expected.";
     572           0 :           throw SDMDataObjectReaderException(oss.str());
     573           0 :         }
     574           0 :         if (nAutoData_ != sdmDataObject_.dataStruct().autoData().size()) {
     575           0 :           ostringstream oss;
     576           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     577           0 :           oss << "size of 'autoData' attachment (" << nAutoData_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().autoData().size() << ")";
     578           0 :           throw SDMDataObjectReaderException(oss.str());
     579           0 :         }
     580             :       
     581           0 :         if (!attachmentFlags.test(CROSSDATA)) {
     582           0 :           ostringstream oss;
     583           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     584           0 :           oss << "a binary attachment 'crossData' was expected.";
     585           0 :           throw SDMDataObjectReaderException(oss.str());
     586           0 :         }
     587             : 
     588             :         // crossDataTypeSize is not currently used, skip this block
     589             :         // switch (integration.crossDataType()) {
     590             :         // case INT32_TYPE:
     591             :         //   crossDataTypeSize = sizeof(INTCROSSDATATYPE);
     592             :         //   break;
     593             :         // case INT16_TYPE:
     594             :         //   crossDataTypeSize = sizeof(SHORTCROSSDATATYPE);
     595             :         //   break;
     596             :         // case FLOAT32_TYPE:
     597             :         //   crossDataTypeSize = sizeof(FLOATCROSSDATATYPE);
     598             :         //  break;
     599             :         // default:
     600             :         //   throw SDMDataObjectReaderException("'"+CPrimitiveDataType::name(integration.crossDataType())+"' unexpected here.");
     601             :         // }
     602             : 
     603           0 :         if (nCrossData_ != sdmDataObject_.dataStruct().crossData().size()) {
     604           0 :           ostringstream oss;
     605           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     606           0 :           oss << "size of 'crossData' attachment (" << nCrossData_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().crossData().size() << ")";
     607           0 :           throw SDMDataObjectReaderException(oss.str());
     608           0 :         }
     609             :         
     610             : 
     611           0 :         integration.shortCrossData_ = 0;
     612           0 :         integration.longCrossData_  = 0;
     613           0 :         integration.floatCrossData_ = 0;
     614           0 :         integration.nCrossData_     = 0;
     615           0 :         switch (integration.crossDataType()) {
     616           0 :         case INT32_TYPE:
     617           0 :           integration.longCrossData_    = longCrossData_;
     618           0 :           integration.nCrossData_       = nCrossData_; 
     619           0 :           break;
     620             :         
     621           0 :         case INT16_TYPE:
     622           0 :           integration.shortCrossData_   = shortCrossData_;
     623           0 :           integration.nCrossData_       = nCrossData_; 
     624           0 :           break;
     625             : 
     626           0 :         case FLOAT32_TYPE:
     627           0 :           integration.floatCrossData_   = floatCrossData_;
     628           0 :           integration.nCrossData_       = nCrossData_;
     629           0 :           break;
     630             : 
     631           0 :         default:
     632           0 :           throw SDMDataObjectReaderException("Data subset '"+contentLocation+"': '"+CPrimitiveDataType::name(integration.crossDataType())+"' unexpected here.");
     633             :         } 
     634             :         
     635           0 :         integration.autoData_    = autoData_;
     636           0 :         integration.nAutoData_   = nAutoData_; 
     637             :         
     638             :         
     639           0 :         break;
     640           0 :       default:
     641           0 :         throw SDMDataObjectReaderException("Data subset '"+contentLocation+"': unrecognized correlation mode");
     642             :         break;
     643             :       }
     644             :       
     645             :       
     646           0 :       if (attachmentFlags.test(ZEROLAGS)) {
     647             :         // Refuse the zeroLags attachment if it's not a Correlator or if the correlator is a CORRELATOR_FX (ACA).
     648           0 :         if ((sdmDataObject_.processorType_ != CORRELATOR) || (sdmDataObject_.correlatorType() == FX))
     649           0 :           throw SDMDataObjectReaderException("zeroLags are not expected from a correlator CORRELATOR_FX");
     650             : 
     651           0 :         if (nZeroLags_ != sdmDataObject_.dataStruct().zeroLags().size()) {
     652           0 :           ostringstream oss;
     653           0 :           oss << "Data subset '"<<contentLocation<<"': ";
     654           0 :           oss << "size of 'zeroLags' attachment (" << nZeroLags_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().zeroLags().size() << ")";
     655           0 :           throw SDMDataObjectReaderException(oss.str());
     656           0 :         }
     657           0 :         integration.zeroLags_  = zeroLags_;
     658           0 :         integration.nZeroLags_ = nZeroLags_;      
     659             :       }
     660             :     
     661           0 :     sdmDataObject_.append(integration);
     662             :   }
     663             : 
     664           0 :     if (!compare("--\n--"+MIMEBOUNDARY_1))
     665           0 :       throw SDMDataObjectReaderException("Data subset '"+contentLocation+"': expecting a '--"+MIMEBOUNDARY_1+"' at the end of a data subset");
     666             :     
     667           0 :     find("--\n--"+MIMEBOUNDARY_1);
     668             :     // cout << "Exiting processMIMEIntegration" << endl;    
     669           0 :   }
     670             : 
     671           0 :   void SDMDataObjectReader::processMIMEIntegrations() {
     672             :     // cout << "Entering processMIMEIntegrations" << endl;
     673             : 
     674           0 :     while (!compare("--")) {
     675             :       // We are one character beyond the last character of --<MIMEBOUNDARY_1>
     676             :       // Let's ignore the MIME Header right after the  --<MIMEBOUNDARY_1> 
     677             :       // and move to the next --<MIMEBOUNDARY_2>
     678           0 :       if (find("--"+MIMEBOUNDARY_2) == string::npos)
     679           0 :         throw SDMDataObjectReaderException("Expecting a boundary '--"+MIMEBOUNDARY_2+"' at this position");
     680             : 
     681             :       //Process the next integration.
     682           0 :       integrationNum_++;
     683           0 :       processMIMEIntegration() ;
     684             :     }
     685             : 
     686             :     // cout << "Exiting processMIMEIntegrations" << endl;
     687           0 :   }
     688             : 
     689           0 :   void SDMDataObjectReader::processMIMESubscan() {
     690             :     //    cout << "Entering processMIMESubscan" << endl;
     691             : 
     692             :     // We are one character beyond the last character of --<MIMEBOUNDARY_1>
     693             :     // Let's ignore the MIME Header right after the  --<MIMEBOUNDARY_1> 
     694             :     // and move to the next --<MIMEBOUNDARY_2>
     695             :     // We are 1 character beyond the end of --<MIMEBOUNDARY_2>
     696           0 :     if (find("--"+MIMEBOUNDARY_2) == string::npos)
     697           0 :       throw SDMDataObjectReaderException("Expecting a boundary '--"+MIMEBOUNDARY_2+"' at this position");
     698             : 
     699             : 
     700           0 :     string contentLocation = getContentLocation();
     701             :     // cout << contentLocation << endl;
     702             : #ifndef WITHOUT_BOOST
     703             :     boost::regex r(" *"+sdmDataObject_.projectPath() + "desc.xml");
     704             :     
     705             :     // Extract the Subset name and the suffix number (which must be equal to 1).
     706             :     boost::cmatch what;
     707             :     if (!boost::regex_match(contentLocation.c_str(), what, r)) {
     708             :       ostringstream oss;
     709             :       oss << "Invalid Content-Location field '" << contentLocation <<"' in MIME header of the subset";
     710             :       throw SDMDataObjectReaderException(oss.str());
     711             :     } 
     712             : #else
     713           0 :     std::regex r(" *"+sdmDataObject_.projectPath() + "desc.xml");
     714             :     
     715             :     // Extract the Subset name and the suffix number (which must be equal to 1).
     716           0 :     std::cmatch what;
     717           0 :     if (!std::regex_match(contentLocation.c_str(), what, r)) {
     718           0 :       ostringstream oss;
     719           0 :       oss << "Invalid Content-Location field '" << contentLocation <<"' in MIME header of the subset";
     720           0 :       throw SDMDataObjectReaderException(oss.str());
     721           0 :     } 
     722             : #endif
     723             : 
     724           0 :     SDMDataSubset subscan(&sdmDataObject_);
     725             : 
     726             :     // The SDMDataSubset header.
     727           0 :     processMIMESDMDataSubsetHeader(subscan);
     728             :     
     729             : 
     730             :     // Process the binary attachments.
     731           0 :     attachmentFlags.reset();
     732           0 :     integrationNum_++;
     733           0 :     while(!EOD() && !compare("--")) {
     734           0 :       processBinaryAttachment(MIMEBOUNDARY_2, subscan);
     735             :     }
     736             : 
     737           0 :     if (EOD()) throw SDMDataObjectReaderException("Unexpected end of data");
     738             :     
     739             :     // Now check if the binary attachments found are compatible with the correlation mode.
     740             :     // and if their sizes are equal to what is announced in the global header.
     741             : 
     742             :     // Start with the only mandatory attachment : autoData.
     743           0 :     if (!attachmentFlags.test(AUTODATA)) {
     744           0 :       ostringstream oss;
     745           0 :       oss << "Binary attachment 'autoData' was expected in integration #" << integrationNum_;
     746           0 :       throw SDMDataObjectReaderException(oss.str());
     747           0 :     }
     748           0 :     if (nAutoData_ != sdmDataObject_.dataStruct().autoData().size()) {
     749           0 :       ostringstream oss;
     750           0 :       oss << "Size of 'autoData' attachment (" << nAutoData_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().autoData().size() << ")";
     751           0 :       throw SDMDataObjectReaderException(oss.str());
     752           0 :     }
     753             :     
     754           0 :     subscan.autoData_    = autoData_;
     755           0 :     subscan.nAutoData_   = nAutoData_; 
     756             :     
     757             : 
     758             :     // And now consider the optional attachments.
     759             : 
     760             :     // The actualDurations are optional. They may be absent.
     761           0 :     if (!attachmentFlags.test(ACTUALDURATIONS)) {
     762             :       // No actualDurations binary attachment found, ok then set everything to 0.
     763           0 :       subscan.actualDurations_  = 0;
     764           0 :       subscan.nActualDurations_ = 0;
     765             :     }
     766             :     else {
     767             :       // actualDurations found
     768             :       // Check size conformity
     769           0 :       if (nActualDurations_ != sdmDataObject_.dataStruct().actualDurations().size()) {
     770           0 :         ostringstream oss;
     771           0 :         oss << "Size of 'actualDurations' attachment (" << nActualDurations_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().actualDurations().size() << ")";
     772           0 :         throw SDMDataObjectReaderException(oss.str());
     773           0 :       } 
     774             : 
     775             :       // Set pointer and size
     776           0 :       subscan.actualDurations_ = actualDurations_;
     777           0 :       subscan.nActualDurations_ = nActualDurations_;
     778             :     }
     779             : 
     780             : 
     781             :     // The actualTimes are optional. They may be absent.
     782           0 :     if (!attachmentFlags.test(ACTUALTIMES)) {
     783             :       // No actualTimes binary attachment found, ok then set everything to 0.
     784           0 :       subscan.actualTimes_  = 0;
     785           0 :       subscan.nActualTimes_ = 0;
     786             :     }
     787             :     else {
     788             :       // actualTimes found
     789             :       // Check size conformity
     790           0 :       if (nActualTimes_ != sdmDataObject_.dataStruct().actualTimes().size()) {
     791           0 :         ostringstream oss;
     792           0 :         oss << "Size of 'actualTimes' attachment (" << nActualTimes_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().actualTimes().size() << ")";
     793           0 :         throw SDMDataObjectReaderException(oss.str());
     794           0 :       } 
     795             : 
     796             :       // Set pointer and size
     797           0 :       subscan.actualTimes_ = actualTimes_;
     798           0 :       subscan.nActualTimes_ = nActualTimes_;
     799             :     }
     800             : 
     801             : 
     802             :     // The flags are optional. They may be absent.
     803           0 :     if (!attachmentFlags.test(FLAGS)) {
     804             :       // No flags binary attachment found, ok then set everything to 0.
     805           0 :       subscan.flags_  = 0;
     806           0 :       subscan.nFlags_ = 0;
     807             :     }
     808             :     else {
     809             :       // flags found
     810             :       // Check size conformity
     811           0 :       if (nFlags_ != sdmDataObject_.dataStruct().flags().size()) {
     812           0 :         ostringstream oss;
     813           0 :         oss << "Size of 'flags' attachment (" << nFlags_ << ") is not equal to the size announced in the header (" << sdmDataObject_.dataStruct().flags().size() << ")";
     814           0 :         throw SDMDataObjectReaderException(oss.str());
     815           0 :       } 
     816             : 
     817             :       // Set pointer and size
     818           0 :       subscan.flags_ = flags_;
     819           0 :       subscan.nFlags_ = nFlags_;
     820             :     }
     821             : 
     822             :     // And finally let's check that no unexpected binary attachment was found.
     823           0 :     if (attachmentFlags.test(CROSSDATA))  {
     824           0 :       ostringstream oss;
     825           0 :       oss << "Found an unexpected attachment 'crossData' in the binary attachments.";
     826           0 :       throw SDMDataObjectReaderException(oss.str());
     827           0 :     }
     828             : 
     829             :     
     830           0 :     if (attachmentFlags.test(ZEROLAGS))  {
     831           0 :       ostringstream oss;
     832           0 :       oss << "Found an unexpected attachment 'zeroLags' in the binary attachments.";
     833           0 :       throw SDMDataObjectReaderException(oss.str());
     834           0 :     }
     835             : 
     836           0 :     sdmDataObject_.tpDataSubset(subscan);
     837             : 
     838             : 
     839           0 :     if (!compare("--\n--"+MIMEBOUNDARY_1))
     840           0 :       throw SDMDataObjectReaderException("Expecting a '--"+MIMEBOUNDARY_1+"' at the end of a data subset");
     841             :     
     842           0 :     find("--\n--"+MIMEBOUNDARY_1);    
     843           0 :   }
     844             : 
     845           0 :   void SDMDataObjectReader::processMIME() {
     846             :     //    cout << "Entering processMIME" << endl;
     847             :     // Let's find the opening boundary
     848           0 :     if (find("--"+MIMEBOUNDARY_1) == string::npos)
     849           0 :       throw SDMDataObjectReaderException("Expecting a first boundary '--"+MIMEBOUNDARY_1+"'.");
     850             : 
     851             :    // Check the Content-Location of the MIME header ...but do nothing special with it...
     852           0 :     string contentLocation=getContentLocation();
     853             :    
     854             :     // Detect SDMDataHeader.
     855           0 :     processMIMESDMDataHeader();
     856             : 
     857             :     // Do we have packed data (i.e. only one SDMDataSubset grouping all the integrations) or one integration per SDMDataSubset (i.e. per timestamp) ?
     858           0 :     if (sdmDataObject_.hasPackedData()) {
     859           0 :       processMIMESubscan();
     860             :     }
     861             :     else {
     862           0 :       processMIMEIntegrations();
     863             :     }
     864             : 
     865             :     
     866             :     // if (sdmDataObject_.isCorrelation()) {
     867             :     //   // Process integrations.
     868             :     //   processMIMEIntegrations();
     869             :     // }
     870             :     // else if (sdmDataObject_.isTP()){
     871             :     //   // cout << "TP data" << endl;
     872             :     //   if (sdmDataObject_.dimensionality() == 0) {
     873             :     //  processMIMESubscan();
     874             :     //   }
     875             :     //   else {
     876             :     //  processMIMEIntegrations();
     877             :     //   }
     878             :     // }
     879             :     // else {
     880             :     //   // cout << "Unrecognized type of binary data." << endl;
     881             :     // }
     882             :     //cout << "Exiting processMIME" << endl;
     883           0 :   }
     884             : 
     885           0 :   const SDMDataObject & SDMDataObjectReader::read(const char * buffer, unsigned long int size, bool fromFile) {
     886           0 :     if (!fromFile) read_  = MEMORY_;
     887             : 
     888             :     // Set up all sensitive pointers and sizes.
     889           0 :     data_        = (char *)buffer;
     890           0 :     dataSize_    = size;
     891           0 :     position_    = 0;
     892           0 :     endPosition_ = size;
     893             : 
     894             :     // And process the MIME message
     895           0 :     sdmDataObject_.valid_ = true;
     896           0 :     processMIME();
     897             : 
     898           0 :     sdmDataObject_.owns();
     899           0 :     return sdmDataObject_;
     900             :   }
     901             : 
     902           0 :   const SDMDataObject& SDMDataObjectReader::ref() const {
     903           0 :     if (read_ == UNKNOWN_) 
     904           0 :       throw SDMDataObjectReaderException("a reference to an SDMDataObject cannot be obtained as long as the method 'read' has not been called.");
     905           0 :     return sdmDataObject_;
     906             :   }
     907             : 
     908           0 :   const SDMDataObject* SDMDataObjectReader::ptr() const {
     909           0 :     if (read_ == UNKNOWN_) 
     910           0 :       throw SDMDataObjectReaderException("a reference to an SDMDataObject cannot be obtained as long as the method 'read' has not been called.");
     911           0 :     return &sdmDataObject_;
     912             :   }
     913             : 
     914           0 :   void SDMDataObjectReader::done() {
     915           0 :     switch (read_) {
     916           0 :     case UNKNOWN_:
     917             :     case MEMORY_:
     918           0 :       break;
     919           0 :     case FILE_:
     920           0 :       munmap((caddr_t) data_, dataSize_);
     921           0 :       close(filedes_);
     922           0 :       break;
     923             :     }
     924           0 :     sdmDataObject_.done();
     925           0 :     read_ = UNKNOWN_;
     926           0 :   }
     927             : 
     928           0 :   const SDMDataObject& SDMDataObjectReader::sdmDataObject() {
     929           0 :     return sdmDataObject_;
     930             :   }
     931             : 
     932             : 
     933           0 :   const SDMDataObject & SDMDataObjectReader::read(string filename) {
     934             : 
     935             :     struct stat fattr; // stat64 fattr;
     936             : 
     937             :     unsigned long int filesize;
     938           0 :     char* data = 0;
     939             :     // Open the file.
     940           0 :     errno = 0;
     941             : #ifdef __APPLE__
     942             :     if ( (filedes_ = open(filename.c_str(), O_RDONLY )) == -1) {
     943             : #else
     944           0 :     if ( (filedes_ = open(filename.c_str(), O_RDONLY | O_LARGEFILE)) == -1) {
     945             : #endif
     946           0 :       string message(strerror(errno));
     947           0 :       throw SDMDataObjectReaderException("Could not open file '" + filename + "'. The message was '" + message + "'");
     948           0 :     }
     949           0 :     read_ = FILE_;
     950             :     
     951             :     // Get its size.
     952           0 :     errno = 0;
     953           0 :     int status = fstat(filedes_,&fattr); // fstat64(filedes_,&fattr);
     954           0 :     if (status == -1) {
     955           0 :       string message(strerror(errno));
     956           0 :       throw SDMDataObjectReaderException("Could not retrieve size of file '" + filename + "'. The message was '" + message + "'");
     957           0 :     }
     958           0 :     filesize = fattr.st_size;
     959             : 
     960             :     // Map it to virtual memory address space.
     961           0 :     errno = 0;
     962             : 
     963           0 :     data = (char *) mmap((caddr_t)0, filesize, PROT_READ, MAP_SHARED, filedes_, (off_t)0);
     964           0 :     if ( ((unsigned long) data) == 0xffffffff) {      
     965           0 :       string message(strerror(errno));
     966           0 :       throw SDMDataObjectReaderException("Could not map file '" + filename + "' to memory. The message was '" + message + "'");
     967           0 :     }
     968             :     
     969             :     // cout << "Successfully mapped file." << endl;
     970             :     // And delegate to the other read (memory buffer) method.
     971           0 :     return read(data, filesize, true);
     972             :   }
     973             : 
     974             :   // SDMDataObjectReader::
     975             : 
     976             : } // namespace asdmbinaries
     977             : 

Generated by: LCOV version 1.16