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