LCOV - code coverage report
Current view: top level - alma/ASDMBinaries - SDMDataObjectReader.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 191 516 37.0 %
Date: 2024-12-11 20:54:31 Functions: 19 26 73.1 %

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

Generated by: LCOV version 1.16