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