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