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