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