LCOV - code coverage report
Current view: top level - alma/ASDM - SeeingTable.cc (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 19 402 4.7 %
Date: 2023-11-06 10:06:49 Functions: 5 36 13.9 %

          Line data    Source code
       1             : 
       2             : /*
       3             :  * ALMA - Atacama Large Millimeter Array
       4             :  * (c) European Southern Observatory, 2002
       5             :  * (c) Associated Universities Inc., 2002
       6             :  * Copyright by ESO (in the framework of the ALMA collaboration),
       7             :  * Copyright by AUI (in the framework of the ALMA collaboration),
       8             :  * All rights reserved.
       9             :  * 
      10             :  * This library is free software; you can redistribute it and/or
      11             :  * modify it under the terms of the GNU Lesser General Public
      12             :  * License as published by the Free software Foundation; either
      13             :  * version 2.1 of the License, or (at your option) any later version.
      14             :  * 
      15             :  * This library is distributed in the hope that it will be useful,
      16             :  * but WITHOUT ANY WARRANTY, without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :  * Lesser General Public License for more details.
      19             :  * 
      20             :  * You should have received a copy of the GNU Lesser General Public
      21             :  * License along with this library; if not, write to the Free Software
      22             :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      23             :  * MA 02111-1307  USA
      24             :  *
      25             :  * Warning!
      26             :  *  -------------------------------------------------------------------- 
      27             :  * | This is generated code!  Do not modify this file.                  |
      28             :  * | If you do, all changes will be lost when the file is re-generated. |
      29             :  *  --------------------------------------------------------------------
      30             :  *
      31             :  * File SeeingTable.cpp
      32             :  */
      33             : #include <alma/ASDM/ConversionException.h>
      34             : #include <alma/ASDM/DuplicateKey.h>
      35             : #include <alma/ASDM/OutOfBoundsException.h>
      36             : 
      37             : using asdm::ConversionException;
      38             : using asdm::DuplicateKey;
      39             : using asdm::OutOfBoundsException;
      40             : 
      41             : #include <alma/ASDM/ASDM.h>
      42             : #include <alma/ASDM/SeeingTable.h>
      43             : #include <alma/ASDM/SeeingRow.h>
      44             : #include <alma/ASDM/Parser.h>
      45             : 
      46             : using asdm::ASDM;
      47             : using asdm::SeeingTable;
      48             : using asdm::SeeingRow;
      49             : using asdm::Parser;
      50             : 
      51             : #include <iostream>
      52             : #include <fstream>
      53             : #include <iterator>
      54             : #include <sstream>
      55             : #include <set>
      56             : #include <algorithm>
      57             : using namespace std;
      58             : 
      59             : #include <alma/ASDM/Misc.h>
      60             : using namespace asdm;
      61             : 
      62             : #include <libxml/parser.h>
      63             : #include <libxml/tree.h>
      64             : 
      65             : #ifndef WITHOUT_BOOST
      66             : #include "boost/filesystem/operations.hpp"
      67             : #include <boost/algorithm/string.hpp>
      68             : #else
      69             : #include <sys/stat.h>
      70             : #endif
      71             : 
      72             : namespace asdm {
      73             :         // The name of the entity we will store in this table.
      74             :         static string entityNameOfSeeing = "Seeing";
      75             :         
      76             :         // An array of string containing the names of the columns of this table.
      77             :         // The array is filled in the order : key, required value, optional value.
      78             :         //
      79             :         static string attributesNamesOfSeeing_a[] = {
      80             :                 
      81             :                         "timeInterval"
      82             :                 
      83             :                 
      84             :                         , "numBaseLength"
      85             :                 
      86             :                         , "baseLength"
      87             :                 
      88             :                         , "phaseRms"
      89             :                 
      90             :                         , "seeing"
      91             :                 
      92             :                         , "exponent"
      93             :                                 
      94             :                                 
      95             :         };
      96             :         
      97             :         // A vector of string whose content is a copy of the strings in the array above.
      98             :         //
      99             :         static vector<string> attributesNamesOfSeeing_v (attributesNamesOfSeeing_a, attributesNamesOfSeeing_a + sizeof(attributesNamesOfSeeing_a) / sizeof(attributesNamesOfSeeing_a[0]));
     100             : 
     101             :         // An array of string containing the names of the columns of this table.
     102             :         // The array is filled in the order where the names would be read by default in the XML header of a file containing
     103             :         // the table exported in binary mode.
     104             :         //      
     105             :         static string attributesNamesInBinOfSeeing_a[] = {
     106             :     
     107             :          "timeInterval" , "numBaseLength" , "baseLength" , "phaseRms" , "seeing" , "exponent" 
     108             :         ,
     109             :         
     110             :     
     111             :         };
     112             :                                         
     113             :         // A vector of string whose content is a copy of the strings in the array above.
     114             :         //
     115             :         static vector<string> attributesNamesInBinOfSeeing_v(attributesNamesInBinOfSeeing_a, attributesNamesInBinOfSeeing_a + sizeof(attributesNamesInBinOfSeeing_a) / sizeof(attributesNamesInBinOfSeeing_a[0]));                
     116             :         
     117             : 
     118             :         // The array of attributes (or column) names that make up key key.
     119             :         //
     120             :         string keyOfSeeing_a[] = {
     121             :         
     122             :                 "timeInterval"
     123             :                  
     124             :         };
     125             :          
     126             :         // A vector of strings which are copies of those stored in the array above.
     127             :         vector<string> keyOfSeeing_v(keyOfSeeing_a, keyOfSeeing_a + sizeof(keyOfSeeing_a) / sizeof(keyOfSeeing_a[0]));
     128             : 
     129             :         /**
     130             :          * Return the list of field names that make up key key
     131             :          * as a const reference to a vector of strings.
     132             :          */     
     133           0 :         const vector<string>& SeeingTable::getKeyName() {
     134           0 :                 return keyOfSeeing_v;
     135             :         }
     136             : 
     137             : 
     138         110 :         SeeingTable::SeeingTable(ASDM &c) : container(c) {
     139             : 
     140             :                 // Define a default entity.
     141         110 :                 entity.setEntityId(EntityId("uid://X0/X0/X0"));
     142         110 :                 entity.setEntityIdEncrypted("na");
     143         110 :                 entity.setEntityTypeName("SeeingTable");
     144         110 :                 entity.setEntityVersion("1");
     145         110 :                 entity.setInstanceVersion("1");
     146             :                 
     147             :                 // Archive XML
     148         110 :                 archiveAsBin = false;
     149             :                 
     150             :                 // File XML
     151         110 :                 fileAsBin = false;
     152             :                 
     153             :                 // By default the table is considered as present in memory
     154         110 :                 presentInMemory = true;
     155             :                 
     156             :                 // By default there is no load in progress
     157         110 :                 loadInProgress = false;
     158         110 :         }
     159             :         
     160             : /**
     161             :  * A destructor for SeeingTable.
     162             :  */
     163         220 :         SeeingTable::~SeeingTable() {
     164         110 :                 for (unsigned int i = 0; i < privateRows.size(); i++) 
     165           0 :                         delete(privateRows.at(i));
     166         220 :         }
     167             : 
     168             :         /**
     169             :          * Container to which this table belongs.
     170             :          */
     171           0 :         ASDM &SeeingTable::getContainer() const {
     172           0 :                 return container;
     173             :         }
     174             : 
     175             :         /**
     176             :          * Return the number of rows in the table.
     177             :          */
     178          39 :         unsigned int SeeingTable::size() const {
     179          39 :                 if (presentInMemory) 
     180          39 :                         return privateRows.size();
     181             :                 else
     182           0 :                         return declaredSize;
     183             :         }
     184             :         
     185             :         /**
     186             :          * Return the name of this table.
     187             :          */
     188        1016 :         string SeeingTable::getName() const {
     189        1016 :                 return entityNameOfSeeing;
     190             :         }
     191             :         
     192             :         /**
     193             :          * Return the name of this table.
     194             :          */
     195           0 :         string SeeingTable::name() {
     196           0 :                 return entityNameOfSeeing;
     197             :         }
     198             :         
     199             :         /**
     200             :          * Return the the names of the attributes (or columns) of this table.
     201             :          */
     202           0 :         const vector<string>& SeeingTable::getAttributesNames() { return attributesNamesOfSeeing_v; }
     203             :         
     204             :         /**
     205             :          * Return the the names of the attributes (or columns) of this table as they appear by default
     206             :          * in an binary export of this table.
     207             :          */
     208           0 :         const vector<string>& SeeingTable::defaultAttributesNamesInBin() { return attributesNamesInBinOfSeeing_v; }
     209             : 
     210             :         /**
     211             :          * Return this table's Entity.
     212             :          */
     213           0 :         Entity SeeingTable::getEntity() const {
     214           0 :                 return entity;
     215             :         }
     216             : 
     217             :         /**
     218             :          * Set this table's Entity.
     219             :          */
     220           0 :         void SeeingTable::setEntity(Entity e) {
     221           0 :                 this->entity = e; 
     222           0 :         }
     223             :         
     224             :         //
     225             :         // ====> Row creation.
     226             :         //
     227             :         
     228             :         /**
     229             :          * Create a new row.
     230             :          */
     231           0 :         SeeingRow *SeeingTable::newRow() {
     232           0 :                 return new SeeingRow (*this);
     233             :         }
     234             :         
     235             : 
     236             :         /**
     237             :          * Create a new row initialized to the specified values.
     238             :          * @return a pointer on the created and initialized row.
     239             :         
     240             :          * @param timeInterval 
     241             :         
     242             :          * @param numBaseLength 
     243             :         
     244             :          * @param baseLength 
     245             :         
     246             :          * @param phaseRms 
     247             :         
     248             :          * @param seeing 
     249             :         
     250             :          * @param exponent 
     251             :         
     252             :      */
     253           0 :         SeeingRow* SeeingTable::newRow(ArrayTimeInterval timeInterval, int numBaseLength, std::vector<Length > baseLength, std::vector<Angle > phaseRms, float seeing, float exponent){
     254           0 :                 SeeingRow *row = new SeeingRow(*this);
     255             :                         
     256           0 :                 row->setTimeInterval(timeInterval);
     257             :                         
     258           0 :                 row->setNumBaseLength(numBaseLength);
     259             :                         
     260           0 :                 row->setBaseLength(baseLength);
     261             :                         
     262           0 :                 row->setPhaseRms(phaseRms);
     263             :                         
     264           0 :                 row->setSeeing(seeing);
     265             :                         
     266           0 :                 row->setExponent(exponent);
     267             :         
     268           0 :                 return row;             
     269             :         }       
     270             :         
     271             : 
     272             : 
     273           0 : SeeingRow* SeeingTable::newRow(SeeingRow* row) {
     274           0 :         return new SeeingRow(*this, row);
     275             : }
     276             : 
     277             :         //
     278             :         // Append a row to its table.
     279             :         //
     280             : 
     281             :         
     282             :         
     283             :                 
     284             :                   
     285           0 :         SeeingRow* SeeingTable::add(SeeingRow* x) {
     286           0 :                 SeeingRow* aRow = getRowByKey(
     287             :                 
     288           0 :                         x->getTimeInterval()
     289             :                 
     290             :                 );
     291             :                 // There is a row with x's key section return it.
     292           0 :                 if (aRow) throw DuplicateKey("Duplicate key exception in ", "SeeingTable");
     293             :                 
     294             :                 // Insert the row x in the table in such a way that the vector row is sorted
     295             :                 // by ascending values on timeInterval.getStart().
     296           0 :                 return insertByStartTime(x, row);
     297             :         }
     298             :                 
     299             :         
     300             :                 
     301           0 :         void SeeingTable::addWithoutCheckingUnique(SeeingRow * x) {
     302           0 :                 SeeingRow * dummy = checkAndAdd(x, true); // We require the check for uniqueness to be skipped.
     303             :                                                            // by passing true in the second parameter
     304             :                                                            // whose value by default is false.
     305             :                 // this statement is never executed, but it hides the unused return value from the compiler to silence that warning.
     306             :                 if (false) cout << (unsigned long long) dummy;
     307           0 :         }
     308             :         
     309             : 
     310             : 
     311             : 
     312             :         // 
     313             :         // A private method to append a row to its table, used by input conversion
     314             :         // methods, with row uniqueness.
     315             :         //
     316             : 
     317             :         
     318             :         
     319             :                 
     320             :                 
     321             :                         
     322           0 :         SeeingRow*  SeeingTable::checkAndAdd(SeeingRow* x, bool /* skipCheckUniqueness */ ) {
     323           0 :                 if (getRowByKey(
     324             :                 
     325           0 :                         x->getTimeInterval()
     326             :                                 
     327           0 :                 )) throw DuplicateKey("Duplicate key exception in ", "SeeingTable");
     328             : 
     329           0 :                 return insertByStartTime(x, row);
     330             :         }
     331             :                                         
     332             :                 
     333             : 
     334             : 
     335             : 
     336             :         //
     337             :         // A private method to brutally append a row to its table, without checking for row uniqueness.
     338             :         //
     339             : 
     340           0 :         void SeeingTable::append(SeeingRow *x) {
     341           0 :                 privateRows.push_back(x);
     342           0 :                 x->isAdded(true);
     343           0 :         }
     344             : 
     345             : 
     346             : 
     347             : 
     348             : 
     349           0 :          vector<SeeingRow *> SeeingTable::get() {
     350           0 :                 checkPresenceInMemory();
     351           0 :             return privateRows;
     352             :          }
     353             :          
     354           0 :          const vector<SeeingRow *>& SeeingTable::get() const {
     355           0 :                 const_cast<SeeingTable&>(*this).checkPresenceInMemory();      
     356           0 :             return privateRows;
     357             :          }       
     358             :                 
     359             : 
     360             : 
     361             : 
     362             : 
     363             :         
     364             : 
     365             :         
     366             :         
     367             :                 
     368             :         
     369             : 
     370             : 
     371             :         
     372             :                 
     373             :                 
     374             :                         
     375             :                         
     376             : /*
     377             :  ** Returns a SeeingRow* given a key.
     378             :  ** @return a pointer to the row having the key whose values are passed as parameters, or 0 if
     379             :  ** no row exists for that key.
     380             :  **
     381             :  */
     382           0 :         SeeingRow* SeeingTable::getRowByKey(ArrayTimeInterval timeInterval)  {
     383           0 :         checkPresenceInMemory();
     384           0 :         SeeingRow* aRow = 0;
     385           0 :                 for (unsigned int i = 0; i < privateRows.size(); i++) {
     386           0 :                         aRow = row.at(i);
     387           0 :                         if (aRow->timeInterval.contains(timeInterval.getStart())) return aRow;
     388             :                 }
     389           0 :                 return 0;               
     390             :         }
     391             :                         
     392             :                 
     393             :                 
     394             :                 
     395             :         
     396             : 
     397             : 
     398             : 
     399             : #ifndef WITHOUT_ACS
     400             :         using asdmIDL::SeeingTableIDL;
     401             : #endif
     402             : 
     403             : #ifndef WITHOUT_ACS
     404             :         // Conversion Methods
     405             : 
     406             :         SeeingTableIDL *SeeingTable::toIDL() {
     407             :                 SeeingTableIDL *x = new SeeingTableIDL ();
     408             :                 unsigned int nrow = size();
     409             :                 x->row.length(nrow);
     410             :                 vector<SeeingRow*> v = get();
     411             :                 for (unsigned int i = 0; i < nrow; ++i) {
     412             :                         //x->row[i] = *(v[i]->toIDL());
     413             :                         v[i]->toIDL(x->row[i]);
     414             :                 }
     415             :                 return x;
     416             :         }
     417             :         
     418             :         void SeeingTable::toIDL(asdmIDL::SeeingTableIDL& x) const {
     419             :                 unsigned int nrow = size();
     420             :                 x.row.length(nrow);
     421             :                 vector<SeeingRow*> v = get();
     422             :                 for (unsigned int i = 0; i < nrow; ++i) {
     423             :                         v[i]->toIDL(x.row[i]);
     424             :                 }
     425             :         }       
     426             : #endif
     427             :         
     428             : #ifndef WITHOUT_ACS
     429             :         void SeeingTable::fromIDL(SeeingTableIDL x) {
     430             :                 unsigned int nrow = x.row.length();
     431             :                 for (unsigned int i = 0; i < nrow; ++i) {
     432             :                         SeeingRow *tmp = newRow();
     433             :                         tmp->setFromIDL(x.row[i]);
     434             :                         // checkAndAdd(tmp);
     435             :                         add(tmp);
     436             :                 }
     437             :         }       
     438             : #endif
     439             : 
     440             :         
     441           0 :         string SeeingTable::toXML()  {
     442           0 :                 string buf;
     443             : 
     444           0 :                 buf.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> ");
     445           0 :                 buf.append("<SeeingTable xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sng=\"http://Alma/XASDM/SeeingTable\" xsi:schemaLocation=\"http://Alma/XASDM/SeeingTable http://almaobservatory.org/XML/XASDM/4/SeeingTable.xsd\" schemaVersion=\"4\" schemaRevision=\"-1\">\n");
     446             :         
     447           0 :                 buf.append(entity.toXML());
     448           0 :                 string s = container.getEntity().toXML();
     449             :                 // Change the "Entity" tag to "ContainerEntity".
     450           0 :                 buf.append("<Container" + s.substr(1,s.length() - 1)+" ");
     451           0 :                 vector<SeeingRow*> v = get();
     452           0 :                 for (unsigned int i = 0; i < v.size(); ++i) {
     453             :                         try {
     454           0 :                                 buf.append(v[i]->toXML());
     455           0 :                         } catch (const NoSuchRow &e) {
     456             :                         }
     457           0 :                         buf.append("  ");
     458             :                 }               
     459           0 :                 buf.append("</SeeingTable> ");
     460           0 :                 return buf;
     461             :         }
     462             : 
     463             :         
     464           0 :         string SeeingTable::getVersion() const {
     465           0 :                 return version;
     466             :         }
     467             :         
     468             : 
     469           0 :         void SeeingTable::fromXML(string& tableInXML)  {
     470             :                 //
     471             :                 // Look for a version information in the schemaVersion of the XML
     472             :                 //
     473             :                 xmlDoc *doc;
     474             : #if LIBXML_VERSION >= 20703
     475           0 :         doc = xmlReadMemory(tableInXML.data(), tableInXML.size(), "XMLTableHeader.xml", NULL, XML_PARSE_NOBLANKS|XML_PARSE_HUGE);
     476             : #else
     477             :                 doc = xmlReadMemory(tableInXML.data(), tableInXML.size(), "XMLTableHeader.xml", NULL, XML_PARSE_NOBLANKS);
     478             : #endif
     479           0 :                 if ( doc == NULL )
     480           0 :                         throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "Seeing");
     481             :                 
     482           0 :                 xmlNode* root_element = xmlDocGetRootElement(doc);
     483           0 :                 if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
     484           0 :                 throw ConversionException("Failed to retrieve the root element in the DOM structure.", "Seeing");
     485             :                 
     486           0 :         xmlChar * propValue = xmlGetProp(root_element, (const xmlChar *) "schemaVersion");
     487           0 :         if ( propValue != 0 ) {
     488           0 :                 version = string( (const char*) propValue);
     489           0 :                 xmlFree(propValue);             
     490             :         }
     491             :                                                                         
     492           0 :                 Parser xml(tableInXML);
     493           0 :                 if (!xml.isStr("<SeeingTable")) 
     494           0 :                         error();
     495             :                 // cout << "Parsing a SeeingTable" << endl;
     496           0 :                 string s = xml.getElement("<Entity","/>");
     497           0 :                 if (s.length() == 0) 
     498           0 :                         error();
     499           0 :                 Entity e;
     500           0 :                 e.setFromXML(s);
     501           0 :                 if (e.getEntityTypeName() != "SeeingTable")
     502           0 :                         error();
     503           0 :                 setEntity(e);
     504             :                 // Skip the container's entity; but, it has to be there.
     505           0 :                 s = xml.getElement("<ContainerEntity","/>");
     506           0 :                 if (s.length() == 0) 
     507           0 :                         error();
     508             : 
     509             :                 // Get each row in the table.
     510           0 :                 s = xml.getElementContent("<row>","</row>");
     511             :                 SeeingRow *row;
     512           0 :                 if (getContainer().checkRowUniqueness()) {
     513             :                         try {
     514           0 :                                 while (s.length() != 0) {
     515           0 :                                         row = newRow();
     516           0 :                                         row->setFromXML(s);
     517           0 :                                         checkAndAdd(row);
     518           0 :                                         s = xml.getElementContent("<row>","</row>");
     519             :                                 }
     520             :                                 
     521             :                         }
     522           0 :                         catch (const DuplicateKey &e1) {
     523           0 :                                 throw ConversionException(e1.getMessage(),"SeeingTable");
     524             :                         } 
     525           0 :                         catch (const UniquenessViolationException &e1) {
     526           0 :                                 throw ConversionException(e1.getMessage(),"SeeingTable");     
     527             :                         }
     528           0 :                         catch (...) {
     529             :                                 // cout << "Unexpected error in SeeingTable::checkAndAdd called from SeeingTable::fromXML " << endl;
     530             :                         }
     531             :                 }
     532             :                 else {
     533             :                         try {
     534           0 :                                 while (s.length() != 0) {
     535           0 :                                         row = newRow();
     536           0 :                                         row->setFromXML(s);
     537           0 :                                         addWithoutCheckingUnique(row);
     538           0 :                                         s = xml.getElementContent("<row>","</row>");
     539             :                                 }
     540             :                         }
     541           0 :                         catch (const DuplicateKey &e1) {
     542           0 :                                 throw ConversionException(e1.getMessage(),"SeeingTable");
     543             :                         } 
     544           0 :                         catch (...) {
     545             :                                 // cout << "Unexpected error in SeeingTable::addWithoutCheckingUnique called from SeeingTable::fromXML " << endl;
     546             :                         }
     547             :                 }                               
     548             :                                 
     549             :                                 
     550           0 :                 if (!xml.isStr("</SeeingTable>")) 
     551           0 :                 error();
     552             :                 
     553             :                 //Does not change the convention defined in the model.  
     554             :                 //archiveAsBin = false;
     555             :                 //fileAsBin = false;
     556             : 
     557             :                 // clean up the xmlDoc pointer
     558           0 :                 if ( doc != NULL ) xmlFreeDoc(doc);
     559             :                 
     560           0 :         }
     561             : 
     562             :         
     563           0 :         void SeeingTable::error()  {
     564           0 :                 throw ConversionException("Invalid xml document","Seeing");
     565             :         }
     566             :         
     567             :         
     568           0 :         string SeeingTable::MIMEXMLPart(const asdm::ByteOrder* byteOrder) {
     569           0 :                 string UID = getEntity().getEntityId().toString();
     570           0 :                 string withoutUID = UID.substr(6);
     571           0 :                 string containerUID = getContainer().getEntity().getEntityId().toString();
     572           0 :                 ostringstream oss;
     573           0 :                 oss << "<?xml version='1.0'  encoding='ISO-8859-1'?>";
     574           0 :                 oss << "\n";
     575           0 :                 oss << "<SeeingTable xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sng=\"http://Alma/XASDM/SeeingTable\" xsi:schemaLocation=\"http://Alma/XASDM/SeeingTable http://almaobservatory.org/XML/XASDM/4/SeeingTable.xsd\" schemaVersion=\"4\" schemaRevision=\"-1\">\n";
     576           0 :                 oss<< "<Entity entityId='"<<UID<<"' entityIdEncrypted='na' entityTypeName='SeeingTable' schemaVersion='1' documentVersion='1'/>\n";
     577           0 :                 oss<< "<ContainerEntity entityId='"<<containerUID<<"' entityIdEncrypted='na' entityTypeName='ASDM' schemaVersion='1' documentVersion='1'/>\n";
     578           0 :                 oss << "<BulkStoreRef file_id='"<<withoutUID<<"' byteOrder='"<<byteOrder->toString()<<"' />\n";
     579           0 :                 oss << "<Attributes>\n";
     580             : 
     581           0 :                 oss << "<timeInterval/>\n"; 
     582           0 :                 oss << "<numBaseLength/>\n"; 
     583           0 :                 oss << "<baseLength/>\n"; 
     584           0 :                 oss << "<phaseRms/>\n"; 
     585           0 :                 oss << "<seeing/>\n"; 
     586           0 :                 oss << "<exponent/>\n"; 
     587             : 
     588           0 :                 oss << "</Attributes>\n";         
     589           0 :                 oss << "</SeeingTable>\n";
     590             : 
     591           0 :                 return oss.str();                               
     592             :         }
     593             :         
     594           0 :         string SeeingTable::toMIME(const asdm::ByteOrder* byteOrder) {
     595           0 :                 EndianOSStream eoss(byteOrder);
     596             :                 
     597           0 :                 string UID = getEntity().getEntityId().toString();
     598             :                 
     599             :                 // The MIME Header
     600           0 :                 eoss <<"MIME-Version: 1.0";
     601           0 :                 eoss << "\n";
     602           0 :                 eoss << "Content-Type: Multipart/Related; boundary='MIME_boundary'; type='text/xml'; start= '<header.xml>'";
     603           0 :                 eoss <<"\n";
     604           0 :                 eoss <<"Content-Description: Correlator";
     605           0 :                 eoss <<"\n";
     606           0 :                 eoss <<"alma-uid:" << UID;
     607           0 :                 eoss <<"\n";
     608           0 :                 eoss <<"\n";            
     609             :                 
     610             :                 // The MIME XML part header.
     611           0 :                 eoss <<"--MIME_boundary";
     612           0 :                 eoss <<"\n";
     613           0 :                 eoss <<"Content-Type: text/xml; charset='ISO-8859-1'";
     614           0 :                 eoss <<"\n";
     615           0 :                 eoss <<"Content-Transfer-Encoding: 8bit";
     616           0 :                 eoss <<"\n";
     617           0 :                 eoss <<"Content-ID: <header.xml>";
     618           0 :                 eoss <<"\n";
     619           0 :                 eoss <<"\n";
     620             :                 
     621             :                 // The MIME XML part content.
     622           0 :                 eoss << MIMEXMLPart(byteOrder);
     623             : 
     624             :                 // The MIME binary part header
     625           0 :                 eoss <<"--MIME_boundary";
     626           0 :                 eoss <<"\n";
     627           0 :                 eoss <<"Content-Type: binary/octet-stream";
     628           0 :                 eoss <<"\n";
     629           0 :                 eoss <<"Content-ID: <content.bin>";
     630           0 :                 eoss <<"\n";
     631           0 :                 eoss <<"\n";    
     632             :                 
     633             :                 // The MIME binary content
     634           0 :                 entity.toBin(eoss);
     635           0 :                 container.getEntity().toBin(eoss);
     636           0 :                 eoss.writeInt((int) privateRows.size());
     637           0 :                 for (unsigned int i = 0; i < privateRows.size(); i++) {
     638           0 :                         privateRows.at(i)->toBin(eoss);      
     639             :                 }
     640             :                 
     641             :                 // The closing MIME boundary
     642           0 :                 eoss << "\n--MIME_boundary--";
     643           0 :                 eoss << "\n";
     644             :                 
     645           0 :                 return eoss.str();      
     646             :         }
     647             : 
     648             :         
     649           0 :         void SeeingTable::setFromMIME(const string & mimeMsg) {
     650           0 :     string xmlPartMIMEHeader = "Content-ID: <header.xml>\n\n";
     651             :     
     652           0 :     string binPartMIMEHeader = "--MIME_boundary\nContent-Type: binary/octet-stream\nContent-ID: <content.bin>\n\n";
     653             :     
     654             :     // Detect the XML header.
     655           0 :     string::size_type loc0 = mimeMsg.find(xmlPartMIMEHeader, 0);
     656           0 :     if ( loc0 == string::npos) {
     657             :       // let's try with CRLFs
     658           0 :       xmlPartMIMEHeader = "Content-ID: <header.xml>\r\n\r\n";
     659           0 :       loc0 = mimeMsg.find(xmlPartMIMEHeader, 0);
     660           0 :       if  ( loc0 == string::npos ) 
     661           0 :               throw ConversionException("Failed to detect the beginning of the XML header", "Seeing");
     662             :     }
     663             : 
     664           0 :     loc0 += xmlPartMIMEHeader.size();
     665             :     
     666             :     // Look for the string announcing the binary part.
     667           0 :     string::size_type loc1 = mimeMsg.find( binPartMIMEHeader, loc0 );
     668             :     
     669           0 :     if ( loc1 == string::npos ) {
     670           0 :       throw ConversionException("Failed to detect the beginning of the binary part", "Seeing");
     671             :     }
     672             :     
     673             :     //
     674             :     // Extract the xmlHeader and analyze it to find out what is the byte order and the sequence
     675             :     // of attribute names.
     676             :     //
     677           0 :     string xmlHeader = mimeMsg.substr(loc0, loc1-loc0);
     678             :     xmlDoc *doc;
     679           0 :     doc = xmlReadMemory(xmlHeader.data(), xmlHeader.size(), "BinaryTableHeader.xml", NULL, XML_PARSE_NOBLANKS);
     680           0 :     if ( doc == NULL ) 
     681           0 :       throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "Seeing");
     682             :     
     683             :    // This vector will be filled by the names of  all the attributes of the table
     684             :    // in the order in which they are expected to be found in the binary representation.
     685             :    //
     686           0 :     vector<string> attributesSeq;
     687             :       
     688           0 :     xmlNode* root_element = xmlDocGetRootElement(doc);
     689           0 :     if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
     690           0 :       throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "Seeing");
     691             :     
     692           0 :     const ByteOrder* byteOrder=0;
     693           0 :     if ( string("ASDMBinaryTable").compare((const char*) root_element->name) == 0) {
     694             :       // Then it's an "old fashioned" MIME file for tables.
     695             :       // Just try to deserialize it with Big_Endian for the bytes ordering.
     696           0 :       byteOrder = asdm::ByteOrder::Big_Endian;
     697             :       
     698             :          //
     699             :     // Let's consider a  default order for the sequence of attributes.
     700             :     //
     701             :     
     702             :          
     703           0 :     attributesSeq.push_back("timeInterval") ; 
     704             :          
     705           0 :     attributesSeq.push_back("numBaseLength") ; 
     706             :          
     707           0 :     attributesSeq.push_back("baseLength") ; 
     708             :          
     709           0 :     attributesSeq.push_back("phaseRms") ; 
     710             :          
     711           0 :     attributesSeq.push_back("seeing") ; 
     712             :          
     713           0 :     attributesSeq.push_back("exponent") ; 
     714             :         
     715             :         
     716             :      
     717             :     
     718             :     
     719             :     // And decide that it has version == "2"
     720           0 :     version = "2";         
     721             :      }
     722           0 :     else if (string("SeeingTable").compare((const char*) root_element->name) == 0) {
     723             :       // It's a new (and correct) MIME file for tables.
     724             :       //
     725             :       // 1st )  Look for a BulkStoreRef element with an attribute byteOrder.
     726             :       //
     727           0 :       xmlNode* bulkStoreRef = 0;
     728           0 :       xmlNode* child = root_element->children;
     729             :       
     730           0 :       if (xmlHasProp(root_element, (const xmlChar*) "schemaVersion")) {
     731           0 :         xmlChar * value = xmlGetProp(root_element, (const xmlChar *) "schemaVersion");
     732           0 :         version = string ((const char *) value);
     733           0 :         xmlFree(value); 
     734             :       }
     735             :       
     736             :       // Skip the two first children (Entity and ContainerEntity).
     737           0 :       bulkStoreRef = (child ==  0) ? 0 : ( (child->next) == 0 ? 0 : child->next->next );
     738             :       
     739           0 :       if ( bulkStoreRef == 0 || (bulkStoreRef->type != XML_ELEMENT_NODE)  || (string("BulkStoreRef").compare((const char*) bulkStoreRef->name) != 0))
     740           0 :         throw ConversionException ("Could not find the element '/SeeingTable/BulkStoreRef'. Invalid XML header '"+ xmlHeader + "'.", "Seeing");
     741             :         
     742             :       // We found BulkStoreRef, now look for its attribute byteOrder.
     743           0 :       _xmlAttr* byteOrderAttr = 0;
     744           0 :       for (struct _xmlAttr* attr = bulkStoreRef->properties; attr; attr = attr->next) 
     745           0 :           if (string("byteOrder").compare((const char*) attr->name) == 0) {
     746           0 :            byteOrderAttr = attr;
     747           0 :            break;
     748             :          }
     749             :       
     750           0 :       if (byteOrderAttr == 0) 
     751           0 :              throw ConversionException("Could not find the element '/SeeingTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader +"'.", "Seeing");
     752             :       
     753           0 :       string byteOrderValue = string((const char*) byteOrderAttr->children->content);
     754           0 :       if (!(byteOrder = asdm::ByteOrder::fromString(byteOrderValue)))
     755           0 :                 throw ConversionException("No valid value retrieved for the element '/SeeingTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader + "'.", "Seeing");
     756             :                 
     757             :          //
     758             :          // 2nd) Look for the Attributes element and grab the names of the elements it contains.
     759             :          //
     760           0 :          xmlNode* attributes = bulkStoreRef->next;
     761           0 :      if ( attributes == 0 || (attributes->type != XML_ELEMENT_NODE)  || (string("Attributes").compare((const char*) attributes->name) != 0))     
     762           0 :         throw ConversionException ("Could not find the element '/SeeingTable/Attributes'. Invalid XML header '"+ xmlHeader + "'.", "Seeing");
     763             :  
     764           0 :         xmlNode* childOfAttributes = attributes->children;
     765             :         
     766           0 :         while ( childOfAttributes != 0 && (childOfAttributes->type == XML_ELEMENT_NODE) ) {
     767           0 :                 attributesSeq.push_back(string((const char*) childOfAttributes->name));
     768           0 :                 childOfAttributes = childOfAttributes->next;
     769             :     }
     770             :     }
     771             :     // Create an EndianISStream from the substring containing the binary part.
     772           0 :     EndianISStream eiss(mimeMsg.substr(loc1+binPartMIMEHeader.size()), byteOrder);
     773             :     
     774           0 :     entity = Entity::fromBin((EndianIStream&) eiss);
     775             :     
     776             :     // We do nothing with that but we have to read it.
     777           0 :     Entity containerEntity = Entity::fromBin((EndianIStream&) eiss);
     778             : 
     779             :         // Let's read numRows but ignore it and rely on the value specified in the ASDM.xml file.    
     780           0 :     int numRows = ((EndianIStream&) eiss).readInt();
     781           0 :     if ((numRows != -1)                        // Then these are *not* data produced at the EVLA.
     782           0 :         && ((unsigned int) numRows != this->declaredSize )) { // Then the declared size (in ASDM.xml) is not equal to the one 
     783             :                                                // written into the binary representation of the table.
     784           0 :                 cout << "The a number of rows ('" 
     785             :                          << numRows
     786           0 :                          << "') declared in the binary representation of the table is different from the one declared in ASDM.xml ('"
     787           0 :                          << this->declaredSize
     788           0 :                          << "'). I'll proceed with the value declared in ASDM.xml"
     789           0 :                          << endl;
     790             :     }                                           
     791             : 
     792           0 :         if (getContainer().checkRowUniqueness()) {
     793             :         try {
     794           0 :                 for (uint32_t i = 0; i < this->declaredSize; i++) {
     795           0 :                                 SeeingRow* aRow = SeeingRow::fromBin((EndianIStream&) eiss, *this, attributesSeq);
     796           0 :                                 checkAndAdd(aRow);
     797             :                 }
     798             :         }
     799           0 :         catch (const DuplicateKey &e) {
     800             :                 throw ConversionException("Error while writing binary data , the message was "
     801           0 :                                 + e.getMessage(), "Seeing");
     802             :         }
     803           0 :         catch (const TagFormatException &e) {
     804             :                  throw ConversionException("Error while reading binary data , the message was "
     805           0 :                                 + e.getMessage(), "Seeing");
     806             :         }
     807             :     }
     808             :     else {
     809           0 :                 for (uint32_t i = 0; i < this->declaredSize; i++) {
     810           0 :                         SeeingRow* aRow = SeeingRow::fromBin((EndianIStream&) eiss, *this, attributesSeq);
     811           0 :                         append(aRow);
     812             :         }       
     813             :     }
     814             :     //Does not change the convention defined in the model.      
     815             :     //archiveAsBin = true;
     816             :     //fileAsBin = true;
     817           0 :     if ( doc != NULL ) xmlFreeDoc(doc);
     818             : 
     819           0 :         }
     820             :         
     821           0 :         void SeeingTable::setUnknownAttributeBinaryReader(const string& attributeName, BinaryAttributeReaderFunctor* barFctr) {
     822             :                 //
     823             :                 // Is this attribute really unknown ?
     824             :                 //
     825           0 :                 for (vector<string>::const_iterator iter = attributesNamesOfSeeing_v.begin(); iter != attributesNamesOfSeeing_v.end(); iter++) {
     826           0 :                         if ((*iter).compare(attributeName) == 0) 
     827           0 :                                 throw ConversionException("the attribute '"+attributeName+"' is known you can't override the way it's read in the MIME binary file containing the table.", "Seeing"); 
     828             :                 }
     829             :                 
     830             :                 // Ok then register the functor to activate when an unknown attribute is met during the reading of a binary table?
     831           0 :                 unknownAttributes2Functors[attributeName] = barFctr;
     832           0 :         }
     833             :         
     834           0 :         BinaryAttributeReaderFunctor* SeeingTable::getUnknownAttributeBinaryReader(const string& attributeName) const {
     835           0 :                 map<string, BinaryAttributeReaderFunctor*>::const_iterator iter = unknownAttributes2Functors.find(attributeName);
     836           0 :                 return (iter == unknownAttributes2Functors.end()) ? 0 : iter->second;
     837             :         }
     838             : 
     839             :         
     840           0 :         void SeeingTable::toFile(string directory) {
     841           0 :                 if (!directoryExists(directory.c_str()) &&
     842           0 :                         !createPath(directory.c_str())) {
     843           0 :                         throw ConversionException("Could not create directory " , directory);
     844             :                 }
     845             : 
     846           0 :                 string fileName = directory + "/Seeing.xml";
     847           0 :                 ofstream tableout(fileName.c_str(),ios::out|ios::trunc);
     848           0 :                 if (tableout.rdstate() == ostream::failbit)
     849           0 :                         throw ConversionException("Could not open file " + fileName + " to write ", "Seeing");
     850           0 :                 if (fileAsBin) 
     851           0 :                         tableout << MIMEXMLPart();
     852             :                 else
     853           0 :                         tableout << toXML() << endl;
     854           0 :                 tableout.close();
     855           0 :                 if (tableout.rdstate() == ostream::failbit)
     856           0 :                         throw ConversionException("Could not close file " + fileName, "Seeing");
     857             : 
     858           0 :                 if (fileAsBin) {
     859             :                         // write the bin serialized
     860           0 :                         string fileName = directory + "/Seeing.bin";
     861           0 :                         ofstream tableout(fileName.c_str(),ios::out|ios::trunc);
     862           0 :                         if (tableout.rdstate() == ostream::failbit)
     863           0 :                                 throw ConversionException("Could not open file " + fileName + " to write ", "Seeing");
     864           0 :                         tableout << toMIME() << endl;
     865           0 :                         tableout.close();
     866           0 :                         if (tableout.rdstate() == ostream::failbit)
     867           0 :                                 throw ConversionException("Could not close file " + fileName, "Seeing");
     868             :                 }
     869           0 :         }
     870             : 
     871             :         
     872           0 :         void SeeingTable::setFromFile(const string& directory) {
     873             : #ifndef WITHOUT_BOOST
     874             :     if (boost::filesystem::exists(boost::filesystem::path(uniqSlashes(directory + "/Seeing.xml"))))
     875             :       setFromXMLFile(directory);
     876             :     else if (boost::filesystem::exists(boost::filesystem::path(uniqSlashes(directory + "/Seeing.bin"))))
     877             :       setFromMIMEFile(directory);
     878             : #else 
     879             :     // alternative in Misc.h
     880           0 :     if (file_exists(uniqSlashes(directory + "/Seeing.xml")))
     881           0 :       setFromXMLFile(directory);
     882           0 :     else if (file_exists(uniqSlashes(directory + "/Seeing.bin")))
     883           0 :       setFromMIMEFile(directory);
     884             : #endif
     885             :     else
     886           0 :       throw ConversionException("No file found for the Seeing table", "Seeing");
     887           0 :         }                       
     888             : 
     889             :         
     890           0 :   void SeeingTable::setFromMIMEFile(const string& directory) {
     891           0 :     string tablePath ;
     892             :     
     893           0 :     tablePath = directory + "/Seeing.bin";
     894           0 :     ifstream tablefile(tablePath.c_str(), ios::in|ios::binary);
     895           0 :     if (!tablefile.is_open()) { 
     896           0 :       throw ConversionException("Could not open file " + tablePath, "Seeing");
     897             :     }
     898             :     // Read in a stringstream.
     899           0 :     stringstream ss; ss << tablefile.rdbuf();
     900             :     
     901           0 :     if (tablefile.rdstate() == istream::failbit || tablefile.rdstate() == istream::badbit) {
     902           0 :       throw ConversionException("Error reading file " + tablePath,"Seeing");
     903             :     }
     904             :     
     905             :     // And close.
     906           0 :     tablefile.close();
     907           0 :     if (tablefile.rdstate() == istream::failbit)
     908           0 :       throw ConversionException("Could not close file " + tablePath,"Seeing");
     909             :     
     910           0 :     setFromMIME(ss.str());
     911           0 :   }     
     912             : /* 
     913             :   void SeeingTable::openMIMEFile (const string& directory) {
     914             :                 
     915             :         // Open the file.
     916             :         string tablePath ;
     917             :     tablePath = directory + "/Seeing.bin";
     918             :     ifstream tablefile(tablePath.c_str(), ios::in|ios::binary);
     919             :     if (!tablefile.is_open())
     920             :       throw ConversionException("Could not open file " + tablePath, "Seeing");
     921             :       
     922             :         // Locate the xmlPartMIMEHeader.
     923             :     string xmlPartMIMEHeader = "CONTENT-ID: <HEADER.XML>\n\n";
     924             :     CharComparator comparator;
     925             :     istreambuf_iterator<char> BEGIN(tablefile.rdbuf());
     926             :     istreambuf_iterator<char> END;
     927             :     istreambuf_iterator<char> it = search(BEGIN, END, xmlPartMIMEHeader.begin(), xmlPartMIMEHeader.end(), comparator);
     928             :     if (it == END) 
     929             :         throw ConversionException("failed to detect the beginning of the XML header", "Seeing");
     930             :     
     931             :     // Locate the binaryPartMIMEHeader while accumulating the characters of the xml header.     
     932             :     string binPartMIMEHeader = "--MIME_BOUNDARY\nCONTENT-TYPE: BINARY/OCTET-STREAM\nCONTENT-ID: <CONTENT.BIN>\n\n";
     933             :     string xmlHeader;
     934             :         CharCompAccumulator compaccumulator(&xmlHeader, 100000);
     935             :         ++it;
     936             :         it = search(it, END, binPartMIMEHeader.begin(), binPartMIMEHeader.end(), compaccumulator);
     937             :         if (it == END) 
     938             :                 throw ConversionException("failed to detect the beginning of the binary part", "Seeing");
     939             :         
     940             :         cout << xmlHeader << endl;
     941             :         //
     942             :         // We have the xmlHeader , let's parse it.
     943             :         //
     944             :         xmlDoc *doc;
     945             :     doc = xmlReadMemory(xmlHeader.data(), xmlHeader.size(), "BinaryTableHeader.xml", NULL, XML_PARSE_NOBLANKS);
     946             :     if ( doc == NULL ) 
     947             :       throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "Seeing");
     948             :     
     949             :    // This vector will be filled by the names of  all the attributes of the table
     950             :    // in the order in which they are expected to be found in the binary representation.
     951             :    //
     952             :     vector<string> attributesSeq(attributesNamesInBinOfSeeing_v);
     953             :       
     954             :     xmlNode* root_element = xmlDocGetRootElement(doc);
     955             :     if ( root_element == NULL || root_element->type != XML_ELEMENT_NODE )
     956             :       throw ConversionException("Failed to parse the xmlHeader into a DOM structure.", "Seeing");
     957             :     
     958             :     const ByteOrder* byteOrder=0;
     959             :     if ( string("ASDMBinaryTable").compare((const char*) root_element->name) == 0) {
     960             :       // Then it's an "old fashioned" MIME file for tables.
     961             :       // Just try to deserialize it with Big_Endian for the bytes ordering.
     962             :       byteOrder = asdm::ByteOrder::Big_Endian;
     963             :         
     964             :       // And decide that it has version == "2"
     965             :     version = "2";         
     966             :      }
     967             :     else if (string("SeeingTable").compare((const char*) root_element->name) == 0) {
     968             :       // It's a new (and correct) MIME file for tables.
     969             :       //
     970             :       // 1st )  Look for a BulkStoreRef element with an attribute byteOrder.
     971             :       //
     972             :       xmlNode* bulkStoreRef = 0;
     973             :       xmlNode* child = root_element->children;
     974             :       
     975             :       if (xmlHasProp(root_element, (const xmlChar*) "schemaVersion")) {
     976             :         xmlChar * value = xmlGetProp(root_element, (const xmlChar *) "schemaVersion");
     977             :         version = string ((const char *) value);
     978             :         xmlFree(value); 
     979             :       }
     980             :       
     981             :       // Skip the two first children (Entity and ContainerEntity).
     982             :       bulkStoreRef = (child ==  0) ? 0 : ( (child->next) == 0 ? 0 : child->next->next );
     983             :       
     984             :       if ( bulkStoreRef == 0 || (bulkStoreRef->type != XML_ELEMENT_NODE)  || (string("BulkStoreRef").compare((const char*) bulkStoreRef->name) != 0))
     985             :         throw ConversionException ("Could not find the element '/SeeingTable/BulkStoreRef'. Invalid XML header '"+ xmlHeader + "'.", "Seeing");
     986             :         
     987             :       // We found BulkStoreRef, now look for its attribute byteOrder.
     988             :       _xmlAttr* byteOrderAttr = 0;
     989             :       for (struct _xmlAttr* attr = bulkStoreRef->properties; attr; attr = attr->next) 
     990             :           if (string("byteOrder").compare((const char*) attr->name) == 0) {
     991             :            byteOrderAttr = attr;
     992             :            break;
     993             :          }
     994             :       
     995             :       if (byteOrderAttr == 0) 
     996             :              throw ConversionException("Could not find the element '/SeeingTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader +"'.", "Seeing");
     997             :       
     998             :       string byteOrderValue = string((const char*) byteOrderAttr->children->content);
     999             :       if (!(byteOrder = asdm::ByteOrder::fromString(byteOrderValue)))
    1000             :                 throw ConversionException("No valid value retrieved for the element '/SeeingTable/BulkStoreRef/@byteOrder'. Invalid XML header '" + xmlHeader + "'.", "Seeing");
    1001             :                 
    1002             :          //
    1003             :          // 2nd) Look for the Attributes element and grab the names of the elements it contains.
    1004             :          //
    1005             :          xmlNode* attributes = bulkStoreRef->next;
    1006             :      if ( attributes == 0 || (attributes->type != XML_ELEMENT_NODE)  || (string("Attributes").compare((const char*) attributes->name) != 0))     
    1007             :         throw ConversionException ("Could not find the element '/SeeingTable/Attributes'. Invalid XML header '"+ xmlHeader + "'.", "Seeing");
    1008             :  
    1009             :         xmlNode* childOfAttributes = attributes->children;
    1010             :         
    1011             :         while ( childOfAttributes != 0 && (childOfAttributes->type == XML_ELEMENT_NODE) ) {
    1012             :                 attributesSeq.push_back(string((const char*) childOfAttributes->name));
    1013             :                 childOfAttributes = childOfAttributes->next;
    1014             :     }
    1015             :     }
    1016             :     // Create an EndianISStream from the substring containing the binary part.
    1017             :     EndianIFStream eifs(&tablefile, byteOrder);
    1018             :     
    1019             :     entity = Entity::fromBin((EndianIStream &) eifs);
    1020             :     
    1021             :     // We do nothing with that but we have to read it.
    1022             :     Entity containerEntity = Entity::fromBin((EndianIStream &) eifs);
    1023             : 
    1024             :         // Let's read numRows but ignore it and rely on the value specified in the ASDM.xml file.    
    1025             :     int numRows = eifs.readInt();
    1026             :     if ((numRows != -1)                        // Then these are *not* data produced at the EVLA.
    1027             :         && ((unsigned int) numRows != this->declaredSize )) { // Then the declared size (in ASDM.xml) is not equal to the one 
    1028             :                                                // written into the binary representation of the table.
    1029             :                 cout << "The a number of rows ('" 
    1030             :                          << numRows
    1031             :                          << "') declared in the binary representation of the table is different from the one declared in ASDM.xml ('"
    1032             :                          << this->declaredSize
    1033             :                          << "'). I'll proceed with the value declared in ASDM.xml"
    1034             :                          << endl;
    1035             :     }
    1036             :     // clean up xmlDoc pointer
    1037             :     if ( doc != NULL ) xmlFreeDoc(doc);    
    1038             :   } 
    1039             :  */
    1040             : 
    1041             :         
    1042           0 : void SeeingTable::setFromXMLFile(const string& directory) {
    1043           0 :     string tablePath ;
    1044             :     
    1045           0 :     tablePath = directory + "/Seeing.xml";
    1046             :     
    1047             :     /*
    1048             :     ifstream tablefile(tablePath.c_str(), ios::in|ios::binary);
    1049             :     if (!tablefile.is_open()) { 
    1050             :       throw ConversionException("Could not open file " + tablePath, "Seeing");
    1051             :     }
    1052             :       // Read in a stringstream.
    1053             :     stringstream ss;
    1054             :     ss << tablefile.rdbuf();
    1055             :     
    1056             :     if  (tablefile.rdstate() == istream::failbit || tablefile.rdstate() == istream::badbit) {
    1057             :       throw ConversionException("Error reading file '" + tablePath + "'", "Seeing");
    1058             :     }
    1059             :     
    1060             :     // And close
    1061             :     tablefile.close();
    1062             :     if (tablefile.rdstate() == istream::failbit)
    1063             :       throw ConversionException("Could not close file '" + tablePath + "'", "Seeing");
    1064             : 
    1065             :     // Let's make a string out of the stringstream content and empty the stringstream.
    1066             :     string xmlDocument = ss.str(); ss.str("");
    1067             :         
    1068             :     // Let's make a very primitive check to decide
    1069             :     // whether the XML content represents the table
    1070             :     // or refers to it via a <BulkStoreRef element.
    1071             :     */
    1072             :     
    1073           0 :     string xmlDocument;
    1074             :     try {
    1075           0 :         xmlDocument = getContainer().getXSLTransformer()(tablePath);
    1076           0 :         if (getenv("ASDM_DEBUG")) cout << "About to read " << tablePath << endl;
    1077             :     }
    1078           0 :     catch (const XSLTransformerException &e) {
    1079           0 :         throw ConversionException("Caugth an exception whose message is '" + e.getMessage() + "'.", "Seeing");
    1080             :     }
    1081             :     
    1082           0 :     if (xmlDocument.find("<BulkStoreRef") != string::npos)
    1083           0 :       setFromMIMEFile(directory);
    1084             :     else
    1085           0 :       fromXML(xmlDocument);
    1086           0 :   }
    1087             : 
    1088             :         
    1089             : 
    1090             :         
    1091             : 
    1092             :                         
    1093             :         
    1094             :                 
    1095             :                 
    1096             :         /**
    1097             :          * Insert a SeeingRow* in a vector of SeeingRow* so that it's ordered by ascending start time.
    1098             :          *
    1099             :          * @param SeeingRow* x . The pointer to be inserted.
    1100             :          * @param vector <SeeingRow*>& row. A reference to the vector where to insert x.
    1101             :          *
    1102             :          */
    1103           0 :          SeeingRow* SeeingTable::insertByStartTime(SeeingRow* x, vector<SeeingRow*>& row) {
    1104             :                                 
    1105           0 :                 vector <SeeingRow*>::iterator theIterator;
    1106             :                 
    1107           0 :                 ArrayTime start = x->timeInterval.getStart();
    1108             : 
    1109             :         // Is the row vector empty ?
    1110           0 :         if (row.size() == 0) {
    1111           0 :                 row.push_back(x);
    1112           0 :                 privateRows.push_back(x);
    1113           0 :                 x->isAdded(true);
    1114           0 :                 return x;
    1115             :         }
    1116             :         
    1117             :         // Optimization for the case of insertion by ascending time.
    1118           0 :         SeeingRow* last = *(row.end()-1);
    1119             :         
    1120           0 :         if ( start > last->timeInterval.getStart() ) {
    1121             :                 //
    1122             :                 // Modify the duration of last if and only if the start time of x
    1123             :                 // is located strictly before the end time of last.
    1124             :                 //
    1125           0 :                         if ( start < (last->timeInterval.getStart() + last->timeInterval.getDuration()))               
    1126           0 :                         last->timeInterval.setDuration(start - last->timeInterval.getStart());
    1127           0 :                 row.push_back(x);
    1128           0 :                 privateRows.push_back(x);
    1129           0 :                 x->isAdded(true);
    1130           0 :                 return x;
    1131             :         }
    1132             :         
    1133             :         // Optimization for the case of insertion by descending time.
    1134           0 :         SeeingRow* first = *(row.begin());
    1135             :         
    1136           0 :         if ( start < first->timeInterval.getStart() ) {
    1137             :                         //
    1138             :                         // Modify the duration of x if and only if the start time of first
    1139             :                         // is located strictly before the end time of x.
    1140             :                         //
    1141           0 :                         if ( first->timeInterval.getStart() < (start + x->timeInterval.getDuration()) )                        
    1142           0 :                         x->timeInterval.setDuration(first->timeInterval.getStart() - start);
    1143           0 :                 row.insert(row.begin(), x);
    1144           0 :                 privateRows.push_back(x);
    1145           0 :                 x->isAdded(true);
    1146           0 :                 return x;
    1147             :         }
    1148             :         
    1149             :         // Case where x has to be inserted inside row; let's use a dichotomy
    1150             :         // method to find the insertion index.
    1151           0 :                 unsigned int k0 = 0;
    1152           0 :                 unsigned int k1 = row.size() - 1;
    1153             :         
    1154           0 :                 while (k0 != (k1 - 1)) {
    1155           0 :                         if (start == row[k0]->timeInterval.getStart()) {
    1156           0 :                                 if (row[k0]->equalByRequiredValue(x))
    1157           0 :                                         return row[k0];
    1158             :                                 else
    1159           0 :                                         throw DuplicateKey("DuplicateKey exception in ", "SeeingTable");    
    1160             :                         }
    1161           0 :                         else if (start == row[k1]->timeInterval.getStart()) {
    1162           0 :                                 if (row[k1]->equalByRequiredValue(x))
    1163           0 :                                         return row[k1];
    1164             :                                 else
    1165           0 :                                         throw DuplicateKey("DuplicateKey exception in ", "SeeingTable");    
    1166             :                         }
    1167             :                         else {
    1168           0 :                                 if (start <= row[(k0+k1)/2]->timeInterval.getStart())
    1169           0 :                                         k1 = (k0 + k1) / 2;
    1170             :                                 else
    1171           0 :                                         k0 = (k0 + k1) / 2;                             
    1172             :                         }       
    1173             :                 }
    1174             : 
    1175           0 :                 if (start == row[k0]->timeInterval.getStart()) {
    1176           0 :                         if (row[k0]->equalByRequiredValue(x))
    1177           0 :                                 return row[k0];
    1178             :                         else
    1179           0 :                                 throw DuplicateKey("DuplicateKey exception in ", "SeeingTable");    
    1180             :                 }
    1181           0 :                 else if (start == row[k1]->timeInterval.getStart()) {
    1182           0 :                         if (row[k1]->equalByRequiredValue(x))
    1183           0 :                                 return row[k1];
    1184             :                         else
    1185           0 :                                 throw DuplicateKey("DuplicateKey exception in ", "SeeingTable");    
    1186             :                 }       
    1187             : 
    1188           0 :                 row[k0]->timeInterval.setDuration(start-row[k0]->timeInterval.getStart());
    1189           0 :                 x->timeInterval.setDuration(row[k0+1]->timeInterval.getStart() - start);
    1190           0 :                 row.insert(row.begin()+(k0+1), x);
    1191           0 :                 privateRows.push_back(x);
    1192           0 :                 x->isAdded(true);
    1193           0 :                 return x;   
    1194             :     } 
    1195             :         
    1196             :         
    1197             :         
    1198             : 
    1199             :         
    1200             : } // End namespace asdm
    1201             :  

Generated by: LCOV version 1.16