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