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