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