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