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