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