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