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