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