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