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