Salome HOME
abd7bbd333305f5882af970f165a80d4d893c48c
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeParameter.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SALOMEDSImpl_AttributeParameter.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26 //
27 #include "SALOMEDSImpl_AttributeParameter.hxx"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <sstream>
32 #include <sstream>
33
34
35 // Purpose: Each character in the string is replaced by 3 characters: '%' and hex number 
36 //          of the character (2 characters)
37 std::string convertString(const std::string& S)
38 {
39   size_t length = S.size(); 
40   if ( length == 0 )
41     return "0";
42   char c[3], *buffer = new char[length*3+1];
43   buffer[length*3] = (char)0;
44   for(int i = 0, pos = 0; i<(int)length; i++, pos+=3) { //TODO: mismatch signed/unsigned
45     int val = (int)S[i];
46     buffer[pos] = '%';
47     sprintf(c, "%.2x", val);
48     buffer[pos+1] = c[0]; 
49     buffer[pos+2] = c[1];
50   }
51
52   std::string RS(buffer); 
53   delete [] buffer;
54   return RS;
55 }
56
57 //Restors a string converted by the function convertString
58 std::string restoreString(const std::string& S)
59 {
60   size_t length = S.size();
61   if ( length == 1 )
62     return "";
63   char c[3], *buffer = new char[length/3+1];
64   buffer[length/3] = (char)0;
65   for(int i = 0, pos = 0; i<(int)length; i+=3, pos++) { //TODO: mismatch signed/unsigned
66     c[0] = S[i+1];
67     c[1] = S[i+2];
68     c[2] = (char)0;
69     int val = strtol(c, NULL, 16);
70     buffer[pos] = (char)val;
71   }
72
73   std::string RS(buffer); 
74   delete [] buffer;
75   return RS;
76 }
77
78 //=======================================================================
79 /*!
80  * Function : GetID
81  * Purpose  : Returns GUID of the attribute
82  */
83 //=======================================================================
84 const std::string& SALOMEDSImpl_AttributeParameter::GetID ()
85 {
86   static std::string ParemeterID ("BA75F3A1-E40B-46b8-8D24-B1D3C3BB1A8C");
87   return ParemeterID;
88 }   
89
90 //=======================================================================
91 /*!
92  * Function : Set
93  * Purpose  : Adds an attribute to the label
94  */
95 //=======================================================================
96 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_AttributeParameter::Set (const DF_Label& L) 
97 {
98   SALOMEDSImpl_AttributeParameter* A = NULL;
99   if (!(A=(SALOMEDSImpl_AttributeParameter*)L.FindAttribute(SALOMEDSImpl_AttributeParameter::GetID()))) {
100     A = new  SALOMEDSImpl_AttributeParameter(); 
101     L.AddAttribute(A);
102   }
103
104   return A;
105 }
106
107 //=======================================================================
108 /*!
109  * Function : SetInt
110  * Purpose  : Associates a integer value with the ID
111  */
112 //=======================================================================
113 void SALOMEDSImpl_AttributeParameter::SetInt(const std::string& theID, const int& theValue)
114 {
115   CheckLocked();
116
117   if(theID.size() == 0) return;
118
119   Backup();
120
121   _ints[theID] = theValue;
122
123   SetModifyFlag(); 
124 }
125
126 //=======================================================================
127 /*!
128  * Function : GetInt
129  * Purpose  : Returns a int value associated with the given ID
130  */
131 //=======================================================================
132 int SALOMEDSImpl_AttributeParameter::GetInt(const std::string& theID)
133 {
134   if(!IsSet(theID, PT_INTEGER)) throw DFexception("Invalid ID");
135   return _ints[theID];
136 }
137
138 //=======================================================================
139 /*!
140  * Function : SetReal
141  * Purpose  : Associates a double value with the ID
142  */
143 //=======================================================================
144 void SALOMEDSImpl_AttributeParameter::SetReal(const std::string& theID, const double& theValue)
145 {
146   CheckLocked();
147
148   if(theID.size() == 0) return;
149
150   Backup();
151
152   _reals[theID] = theValue;
153
154   SetModifyFlag(); 
155 }
156
157 //=======================================================================
158 /*!
159  * Function : GetReal
160  * Purpose  : Returns a double value associated with the given ID
161  */
162 //=======================================================================
163 double SALOMEDSImpl_AttributeParameter::GetReal(const std::string& theID)
164 {
165   if(!IsSet(theID, PT_REAL)) throw DFexception("Invalid ID");
166   return _reals[theID];
167 }
168
169 //=======================================================================
170 /*!
171  * Function : SetString
172  * Purpose  : Associates a string with the ID
173  */
174 //=======================================================================
175 void SALOMEDSImpl_AttributeParameter::SetString(const std::string& theID, const std::string& theValue)
176 {
177   CheckLocked();
178
179   if(theID.size() == 0) return;
180
181   Backup();
182
183   _strings[theID] = theValue;
184
185   SetModifyFlag(); 
186 }
187
188 //=======================================================================
189 /*!
190  * Function : GetString
191  * Purpose  : Returns a string associated with the given ID
192  */
193 //=======================================================================
194 std::string SALOMEDSImpl_AttributeParameter::GetString(const std::string& theID)
195 {
196   if(!IsSet(theID, PT_STRING)) throw DFexception("Invalid ID");
197   return _strings[theID];
198 }
199
200 //=======================================================================
201 /*!
202  * Function : SetBool
203  * Purpose  : Associates a bool value with the ID
204  */
205 //=======================================================================
206 void SALOMEDSImpl_AttributeParameter::SetBool(const std::string& theID, const bool& theValue)
207 {
208   CheckLocked();
209
210   if(theID.size() == 0) return;
211
212   Backup();
213
214   _bools[theID] = theValue;
215
216   SetModifyFlag(); 
217 }
218
219 //=======================================================================
220 /*!
221  * Function : GetBool
222  * Purpose  : Returns a bool value associated with the ID
223  */
224 //=======================================================================
225 bool SALOMEDSImpl_AttributeParameter::GetBool(const std::string& theID)
226 {
227   if(!IsSet(theID, PT_BOOLEAN)) throw DFexception("Invalid ID");
228   return _bools[theID];
229 }
230
231 //=======================================================================
232 /*!
233  * Function : SetRealArray
234  * Purpose  : Associates an array of double values with the given ID
235  */
236 //=======================================================================
237 void SALOMEDSImpl_AttributeParameter::SetRealArray(const std::string& theID, const std::vector<double>& theArray)
238 {
239   CheckLocked();
240
241   if(theID.size() == 0) return;
242
243   Backup();
244
245   _realarrays[theID] = theArray;
246
247   SetModifyFlag(); 
248 }
249
250 //=======================================================================
251 /*!
252  * Function : GetRealArray
253  * Purpose  : Returns double values associated with the ID
254  */
255 //=======================================================================
256 std::vector<double> SALOMEDSImpl_AttributeParameter::GetRealArray(const std::string& theID)
257 {
258   if(!IsSet(theID, PT_REALARRAY)) throw DFexception("Invalid ID");
259   return _realarrays[theID];
260 }
261  
262
263 //=======================================================================
264 /*!
265  * Function : SetIntArray
266  * Purpose  : Associates an array of int values with the given ID
267  */
268 //=======================================================================
269 void SALOMEDSImpl_AttributeParameter::SetIntArray(const std::string& theID, const std::vector<int>& theArray)
270 {
271   CheckLocked();
272
273   if(theID.size() == 0) return;
274
275   Backup();
276
277   _intarrays[theID] = theArray;
278
279   SetModifyFlag(); 
280 }
281
282 //=======================================================================
283 /*!
284  * Function : GetIntArray
285  * Purpose  : Returns int values associated with the ID
286  */
287 //=======================================================================
288 std::vector<int> SALOMEDSImpl_AttributeParameter::GetIntArray(const std::string& theID)
289 {
290   if(!IsSet(theID, PT_INTARRAY)) throw DFexception("Invalid ID");
291   return _intarrays[theID];
292 }
293  
294
295 //=======================================================================
296 /*!
297  * Function : SetStrArray
298  * Purpose  : Associates an array of string values with the given ID
299  */
300 //=======================================================================
301 void SALOMEDSImpl_AttributeParameter::SetStrArray(const std::string& theID, const std::vector<std::string>& theArray)
302 {
303   CheckLocked();
304
305   if(theID.size() == 0) return;
306
307   Backup();
308
309   _strarrays[theID] = theArray;
310
311   SetModifyFlag(); 
312 }
313
314 //=======================================================================
315 /*!
316  * Function : GetStrArray
317  * Purpose  : Returns string values associated with the ID
318  */
319 //=======================================================================
320 std::vector<std::string> SALOMEDSImpl_AttributeParameter::GetStrArray(const std::string& theID)
321 {
322   if(!IsSet(theID, PT_STRARRAY)) throw DFexception("Invalid ID");
323   return _strarrays[theID];
324 }
325  
326
327 //=======================================================================
328 /*!
329  * Function : IsSet
330  * Purpose  : Returns true if for the ID of given type was assigned \n
331  *            a value in the attribute
332  */
333 //=======================================================================
334 bool SALOMEDSImpl_AttributeParameter::IsSet(const std::string& theID, const Parameter_Types theType)
335 {
336   switch(theType) {
337   case PT_INTEGER: {
338     if(_ints.find(theID) != _ints.end()) return true;
339     break;
340   }
341   case PT_REAL: {
342     if(_reals.find(theID) != _reals.end()) return true;
343     break;
344   }
345   case PT_BOOLEAN: {
346     if(_bools.find(theID) != _bools.end()) return true;
347     break;
348   }
349   case PT_STRING: {
350     if(_strings.find(theID) != _strings.end()) return true;
351     break;
352   }
353   case PT_REALARRAY: {
354     if(_realarrays.find(theID) != _realarrays.end()) return true;
355     break;
356   }
357   case PT_INTARRAY: {
358     if(_intarrays.find(theID) != _intarrays.end()) return true;
359     break;
360   }
361   case PT_STRARRAY: {
362     if(_strarrays.find(theID) != _strarrays.end()) return true;
363     break;
364   }
365   default: return false;
366   }
367
368   return false;
369 }
370
371 //=======================================================================
372 /*!
373  * Function : RemoveID
374  * Purpose  : Removes a parameter with given ID
375  */
376 //=======================================================================
377 bool SALOMEDSImpl_AttributeParameter::RemoveID(const std::string& theID, const Parameter_Types theType)
378 {
379   Backup();
380   SetModifyFlag(); 
381
382   switch(theType) {
383   case PT_INTEGER: {
384     if(_ints.erase(theID)) return true;
385     break;
386   }
387   case PT_REAL: {
388     if(_reals.erase(theID)) return true;
389     break;
390   }
391   case PT_BOOLEAN: {
392     if(_bools.erase(theID)) return true;
393     break;
394   }
395   case PT_STRING: {
396     if(_strings.erase(theID)) return true;
397     break;
398   }
399   case PT_REALARRAY: {
400     if(_realarrays.erase(theID)) return true;
401     break;
402   }
403   case PT_INTARRAY: {
404     if(_intarrays.erase(theID)) return true;
405     break;
406   }
407   case PT_STRARRAY: {
408     if(_strarrays.erase(theID)) return true;
409     break;
410   }
411   default: return false;
412   }
413
414
415   return false;
416 }
417
418
419 //=======================================================================
420 /*!
421  * Function : GetFather
422  * Purpose  : Returns a father attribute for this attribute
423  */
424 //=======================================================================
425 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_AttributeParameter::GetFather()
426 {
427   SALOMEDSImpl_AttributeParameter* aFather = 0;
428   DF_Label L = Label();
429   if(L.IsRoot()) return aFather;
430
431   while(!L.IsRoot()) {
432     L = L.Father();
433     if((aFather=(SALOMEDSImpl_AttributeParameter*)L.FindAttribute(SALOMEDSImpl_AttributeParameter::GetID()))) break; 
434   }
435
436   return aFather;
437 }
438
439 //=======================================================================
440 /*!
441  * Function : HasFather
442  * Purpose  : Returns True if the attribute has a father attribute
443  */
444 //=======================================================================
445 bool SALOMEDSImpl_AttributeParameter::HasFather()
446 {
447   DF_Label L = Label();
448   if(L.IsRoot()) return false;
449   while(!L.IsRoot()) {
450     L = L.Father();
451     if(L.IsAttribute(SALOMEDSImpl_AttributeParameter::GetID())) return true; 
452   }
453
454   return false;
455 }
456
457 //=======================================================================
458 /*!
459  * Function : IsRoot
460  * Purpose  : Returns True is the attribute is highest in an hierarchy
461  */
462 //=======================================================================
463 bool SALOMEDSImpl_AttributeParameter::IsRoot()
464 {
465   return ((HasFather())?false:true);
466 }           
467
468 //=======================================================================
469 /*!
470  * Function : Clear
471  * Purpose  : Clears the content of the attribute
472  */
473 //=======================================================================
474 void SALOMEDSImpl_AttributeParameter::Clear()
475 {
476   Backup();
477
478   _ints.clear();
479   _reals.clear();
480   _bools.clear();
481   _strings.clear();
482   _realarrays.clear();
483   _intarrays.clear();
484   _strarrays.clear();
485
486   SetModifyFlag(); 
487 }
488
489 //=======================================================================
490 /*!
491  * Function : GetIDs
492  * Purpose  : Returns an array of all ID's of the given type
493  */
494 //=======================================================================
495 std::vector<std::string> SALOMEDSImpl_AttributeParameter::GetIDs(const Parameter_Types theType)
496 {
497   
498   std::vector<std::string> anArray;
499   int i = 0;
500
501   switch(theType) {
502   case PT_INTEGER: {
503     if(_ints.size()) {
504       anArray.resize(_ints.size());
505       for(std::map<std::string,int>::const_iterator p = _ints.begin(); p != _ints.end(); p++, i++) 
506         anArray[i] =  p->first;
507     }
508     break;
509   }
510   case PT_REAL: {
511     if(_reals.size()) {
512       anArray.resize(_reals.size());
513       for(std::map<std::string,double>::const_iterator p = _reals.begin(); p != _reals.end(); p++, i++) 
514         anArray[i] = p->first;
515     }
516     break;
517   }
518   case PT_BOOLEAN: {
519     if(_bools.size()) {
520       anArray.resize(_bools.size());
521       for(std::map<std::string,bool>::const_iterator p = _bools.begin(); p != _bools.end(); p++, i++) 
522         anArray[i] = p->first;
523     }
524     break;
525   }
526   case PT_STRING: {
527     if(_strings.size()) {
528       anArray.resize(_strings.size());
529       for(std::map<std::string,std::string>::const_iterator p = _strings.begin(); p!= _strings.end(); p++, i++) 
530         anArray[i] = p->first;
531     }
532     break;
533   }
534   case PT_REALARRAY: {
535     if(_realarrays.size()) {
536       anArray.resize(_realarrays.size());
537       for(std::map< std::string, std::vector<double> >::const_iterator p = _realarrays.begin(); p!= _realarrays.end(); p++, i++) 
538         anArray[i] = p->first;
539     }
540     break;
541   }
542   case PT_INTARRAY: {
543     if(_intarrays.size()) {
544       anArray.resize(_intarrays.size());
545       for(std::map< std::string, std::vector<int> >::const_iterator p = _intarrays.begin(); p!= _intarrays.end(); p++, i++) 
546         anArray[i] = p->first;
547     }
548     break;
549   }
550   case PT_STRARRAY: {
551     if(_strarrays.size()) {
552       anArray.resize(_strarrays.size());
553       for(std::map< std::string, std::vector<std::string> >::const_iterator p = _strarrays.begin(); p!= _strarrays.end(); p++, i++) 
554         anArray[i] = p->first;
555     }
556     break;
557   }
558   default: return anArray;
559   }
560
561   return anArray;
562 }
563
564 //=======================================================================
565 /*!
566  * Function : ID
567  * Purpose  : Rteurns an GUID of the attribute
568  */
569 //=======================================================================
570 const std::string& SALOMEDSImpl_AttributeParameter::ID () const { return GetID(); } 
571
572
573 DF_Attribute* SALOMEDSImpl_AttributeParameter::NewEmpty () const
574 {  
575   return new SALOMEDSImpl_AttributeParameter(); 
576 }
577
578 //=======================================================================
579 /*!
580  * Function : Restore
581  * Purpose  : Restors the content of the attribute from another
582  */
583 //=======================================================================
584 void SALOMEDSImpl_AttributeParameter::Restore(DF_Attribute* with) 
585 {
586   SALOMEDSImpl_AttributeParameter* A = dynamic_cast<SALOMEDSImpl_AttributeParameter*>(with);
587   _ints.clear();
588   _reals.clear();
589   _bools.clear();
590   _strings.clear();
591   _realarrays.clear();
592   _intarrays.clear();
593   _strarrays.clear();
594   
595   for(std::map<std::string,int>::const_iterator p = A->_ints.begin(); p!= A->_ints.end(); p++)
596     if(p->first.size()) _ints[p->first] = p->second;
597   for(std::map<std::string,double>::const_iterator p = A->_reals.begin(); p!= A->_reals.end(); p++) 
598     if(p->first.size()) _reals[p->first] = p->second;
599   for(std::map<std::string,bool>::const_iterator p = A->_bools.begin(); p!= A->_bools.end(); p++) 
600     if(p->first.size()) _bools[p->first] = p->second;
601   for(std::map<std::string,std::string>::const_iterator p = A->_strings.begin(); p!= A->_strings.end(); p++) 
602     if(p->first.size()) _strings[p->first] = p->second;
603   for(std::map< std::string,std::vector<double> >::const_iterator p = A->_realarrays.begin(); p!= A->_realarrays.end(); p++) 
604     if(p->first.size()) _realarrays[p->first] = p->second;  
605   for(std::map< std::string,std::vector<int> >::const_iterator p = A->_intarrays.begin(); p!= A->_intarrays.end(); p++) 
606     if(p->first.size()) _intarrays[p->first] = p->second;  
607   for(std::map< std::string,std::vector<std::string> >::const_iterator p = A->_strarrays.begin(); p!= A->_strarrays.end(); p++) 
608     if(p->first.size()) _strarrays[p->first] = p->second; 
609 }
610
611 //=======================================================================
612 /*!
613  * Function : Paste
614  * Purpose  : Pastes the content of attribute to another
615  */
616 //=======================================================================
617 void SALOMEDSImpl_AttributeParameter::Paste (DF_Attribute* into)
618 {
619   into->Restore(this);
620 }
621
622 //=======================================================================
623 /*!
624  * Function : Save
625  * Purpose  : Saves a content of the attribute as a string
626  */
627 //=======================================================================
628 std::string SALOMEDSImpl_AttributeParameter::Save() 
629
630   std::ostringstream buffer;
631   char *tmpBuffer = new char[255];
632
633   buffer << _ints.size() << " ";
634   for(std::map<std::string,int>::const_iterator p = _ints.begin(); p != _ints.end(); p++) {
635     buffer << convertString(p->first) << " " << p->second << " ";
636   }
637
638   buffer << _reals.size() << " ";
639   for(std::map<std::string,double>::const_iterator p =_reals.begin(); p != _reals.end(); p++) {
640     sprintf(tmpBuffer, "%.64e", p->second);
641     buffer << convertString(p->first) << " " << tmpBuffer << " ";
642   }
643
644   buffer << _bools.size() << " ";
645   for(std::map<std::string,bool>::const_iterator p = _bools.begin(); p != _bools.end(); p++) {
646     buffer << convertString(p->first) << " " << p->second << " ";
647   }
648
649   buffer << _strings.size() << " ";
650   for(std::map<std::string,std::string>::const_iterator p = _strings.begin(); p != _strings.end(); p++) {
651     buffer << convertString(p->first) << " " <<  convertString(p->second) << " ";
652   }
653
654   buffer << _realarrays.size() << " ";
655   for(std::map< std::string,std::vector<double> >::const_iterator p = _realarrays.begin(); p != _realarrays.end(); p++) {
656     std::vector<double> v(p->second);
657     sprintf(tmpBuffer, " %s %d ", convertString(p->first).c_str(), (int)v.size());
658     buffer << tmpBuffer;
659     for(size_t i = 0; i<v.size(); i++) {
660       sprintf(tmpBuffer, " %.64e ", v[i]);
661       buffer << tmpBuffer;
662     }
663   }
664
665   buffer << _intarrays.size() << " ";
666   for(std::map< std::string,std::vector<int> >::const_iterator p = _intarrays.begin(); p != _intarrays.end(); p++) {
667     std::vector<int> v(p->second);
668     sprintf(tmpBuffer, " %s %d ", convertString(p->first).c_str(), (int)v.size());
669     buffer << tmpBuffer;
670     for(size_t i = 0; i<v.size(); i++) {
671       sprintf(tmpBuffer, " %d ", v[i]);
672       buffer << tmpBuffer;
673     }
674   }
675
676   buffer << _strarrays.size() << " ";
677   for(std::map< std::string,std::vector<std::string> >::const_iterator p = _strarrays.begin(); p != _strarrays.end(); p++) {
678     std::vector<std::string> v(p->second);
679     sprintf(tmpBuffer, " %s %d ", convertString(p->first).c_str(), (int)v.size());
680     buffer << tmpBuffer;
681     for(size_t i = 0; i<v.size(); i++) {
682       buffer << " " << convertString(v[i]) << " ";
683     }
684   }
685
686   delete [] tmpBuffer;
687
688   std::string AS = buffer.str();
689
690   return AS;
691 }
692
693 //=======================================================================
694 /*!
695  * Function : Load
696  * Purpose  : Restores the attribute from the string
697  */
698 //=======================================================================
699 void SALOMEDSImpl_AttributeParameter::Load(const std::string& theValue)
700 {
701   Backup();
702
703   _ints.clear();
704   _reals.clear();
705   _bools.clear();
706   _strings.clear();
707   _realarrays.clear();
708   _intarrays.clear();
709
710   std::istringstream buffer(theValue.c_str());
711
712   int size, val, ival;
713   double val2;
714   std::string s, id;
715
716   buffer >> size;
717   for(int i = 1; i<=size; i++) {
718     buffer >> id >> val;
719     _ints[restoreString(id)] = val;
720   }
721
722   buffer >> size;
723   for(int i = 1; i<=size; i++) {
724     buffer >> id >> val2;
725     _reals[restoreString(id)] = val2;
726   }
727
728   buffer >> size;
729   for(int i = 1; i<=size; i++) {
730     buffer >> id >> val;
731     _bools[restoreString(id)] = val;
732   }
733
734   buffer >> size;
735   for(int i = 1; i<=size; i++) {
736     buffer >> id >> s;
737     _strings[restoreString(id)] = restoreString(s);
738   }
739   
740   buffer >> size;
741   for(int i = 1; i<=size; i++) {
742     buffer >> id >> val;
743     std::vector<double> v;
744     v.resize(val);
745     for(int j = 0; j<val; j++) {
746       buffer >> val2;
747       v[j] = val2;
748     }
749     _realarrays[restoreString(id)] = v;
750   }
751
752   buffer >> size;
753   for(int i = 1; i<=size; i++) {
754     buffer >> id >> val;
755     std::vector<int> v;
756     v.resize(val);
757     for(int j = 0; j<val; j++) {
758       buffer >> ival;
759       v[j] = ival;
760     }
761     _intarrays[restoreString(id)] = v;
762   }
763   
764   buffer >> size;
765   for(int i = 1; i<=size; i++) {
766     buffer >> id >> val;
767     std::vector<std::string> v;
768     v.resize(val);
769     for(int j = 0; j<val; j++) {
770       buffer >> s;
771       v[j] = restoreString(s);
772     }
773     _strarrays[restoreString(id)] = v;
774   }
775