1 // Copyright (C) 2011-2012 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : HOMARD_DriverTools.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 // ----------------------------------------------------------------------------
24 #include "HOMARD_DriverTools.hxx"
25 #include "HOMARD_Boundary.hxx"
26 #include "HOMARD_Cas.hxx"
27 #include "HOMARD_Hypothesis.hxx"
28 #include "HOMARD_Iteration.hxx"
29 #include "HOMARD_Zone.hxx"
32 #include "utilities.h"
37 const char* const SEPARATOR = "|";
40 \brief Read next chunk of data from the string
43 The function tries to read next chunk of the data from the input string \a str.
44 The parameter \a start specifies the start position of next chunk. If the operation
45 read the chunk successfully, after its completion this parameter will refer to the
46 start position of the next chunk. The function returns resulting chunk as a string.
47 The status of the operation is returned via \a ok parameter.
49 \param str source data stream string
50 \param start start position to get next chunk
51 \param ok in this variable the status of the chunk reading operation is returned
52 \return next chunk read from the string
54 static std::string getNextChunk( const std::string& str, std::string::size_type& start, bool& ok )
56 std::string chunk = "";
58 if ( start <= str.size() ) {
59 std::string::size_type end = str.find( separator(), start );
60 chunk = str.substr( start, end == std::string::npos ? std::string::npos : end-start );
61 start = end == std::string::npos ? str.size()+1 : end + separator().size();
68 \brief Get persistence signature
69 \param type persistence entity type
70 \return persistence signature
72 std::string GetSignature( SignatureType type )
74 std::string signature = "";
76 case Case: signature = "CASE"; break;
77 case Zone: signature = "ZONE"; break;
78 case Hypothesis: signature = "HYPO"; break;
79 case Iteration: signature = "ITER"; break;
80 case Boundary: signature = "BOUNDARY"; break;
83 signature += separator();
88 \brief Get data separator
89 \return string that is used to separate data entities in the stream
91 std::string separator()
93 return std::string( SEPARATOR );
96 // =======================
98 // =======================
100 \brief Dump case to the string
101 \param cas case being dumped
102 \return string representation of the case
104 std::string Dump( const HOMARD_Cas& cas )
106 std::stringstream os;
108 MESSAGE( ". Dump du cas "<<cas.GetName());
110 os << separator() << cas.GetDirName();
111 os << separator() << cas.GetConfType();
113 std::vector<double> coor = cas.GetBoundingBox();
114 os << separator() << coor.size();
115 for ( int i = 0; i < coor.size(); i++ )
116 os << separator() << coor[i];
118 std::list<std::string> ListString = cas.GetIterations();
119 os << separator() << ListString.size();
120 std::list<std::string>::const_iterator it;
121 for ( it = ListString.begin(); it != ListString.end(); ++it )
122 os << separator() << *it;
124 ListString = cas.GetGroups();
125 os << separator() << ListString.size();
126 for ( it = ListString.begin(); it != ListString.end(); ++it )
127 os << separator() << *it;
128 ListString = cas.GetBoundaryGroup();
129 os << separator() << ListString.size();
130 for ( it = ListString.begin(); it != ListString.end(); ++it )
131 os << separator() << *it;
133 os << separator() << cas.GetPyram();
135 // MESSAGE( ". Fin avec "<<os.str());
143 \brief Dump iteration to the string
144 \param iteration iteration being dumped
145 \return string representation of the iteration
147 std::string Dump( const HOMARD_Iteration& iteration )
149 std::stringstream os;
151 MESSAGE( ". Dump de l'iteration "<<iteration.GetName());
152 os << iteration.GetName();
153 os << separator() << iteration.GetEtat();
154 os << separator() << iteration.GetNumber();
155 os << separator() << iteration.GetMeshFile();
156 os << separator() << iteration.GetMessFile();
157 os << separator() << iteration.GetMeshName();
158 os << separator() << iteration.GetFieldFile();
159 os << separator() << iteration.GetTimeStep();
160 os << separator() << iteration.GetRank();
161 os << separator() << iteration.GetIterParent();
163 std::list<std::string> ListString = iteration.GetIterations();
164 os << separator() << ListString.size();
165 std::list<std::string>::const_iterator it;
166 for ( it = ListString.begin(); it != ListString.end(); ++it )
167 os << separator() << *it;
169 os << separator() << iteration.GetHypoName();
170 os << separator() << iteration.GetCaseName();
171 os << separator() << iteration.GetDirName();
173 // MESSAGE( ". Fin avec "<<os.str());
178 // ==============================
180 \brief Dump hypothesis to the string
181 \param hypothesis hypothesis being dumped
182 \return string representation of the hypothesis
184 std::string Dump( const HOMARD_Hypothesis& hypothesis )
186 std::stringstream os;
188 MESSAGE( ". Dump de l'hypothese "<<hypothesis.GetName());
189 os << hypothesis.GetName();
190 os << separator() << hypothesis.GetCaseCreation();
191 os << separator() << hypothesis.GetAdapType();
192 os << separator() << hypothesis.GetRefinType();
193 os << separator() << hypothesis.GetUnRefType();
194 os << separator() << hypothesis.GetFieldName();
195 os << separator() << hypothesis.GetRefinThrType();
196 os << separator() << hypothesis.GetThreshR();
197 os << separator() << hypothesis.GetUnRefThrType();
198 os << separator() << hypothesis.GetThreshC();
199 os << separator() << hypothesis.GetUseField();
200 os << separator() << hypothesis.GetUseCompI();
201 os << separator() << hypothesis.GetTypeFieldInterp();
203 std::list<std::string> ListString = hypothesis.GetIterations();
204 std::list<std::string>::const_iterator it;
205 os << separator() << ListString.size();
206 for ( it = ListString.begin(); it != ListString.end(); ++it )
207 os << separator() << *it;
209 ListString = hypothesis.GetZones();
210 os << separator() << ListString.size();
211 for ( it = ListString.begin(); it != ListString.end(); ++it )
212 os << separator() << *it;
214 ListString = hypothesis.GetListComp();
215 os << separator() << ListString.size();
216 for ( it = ListString.begin(); it != ListString.end(); ++it )
217 os << separator() << *it;
219 ListString = hypothesis.GetGroups();
220 os << separator() << ListString.size();
221 for ( it = ListString.begin(); it != ListString.end(); ++it )
222 os << separator() << *it;
224 ListString = hypothesis.GetListFieldInterp();
225 os << separator() << ListString.size();
226 for ( it = ListString.begin(); it != ListString.end(); ++it )
227 os << separator() << *it;
229 os << separator() << hypothesis.GetNivMax();
230 os << separator() << hypothesis.GetDiamMin();
232 // MESSAGE( ". Fin avec "<<os.str());
237 // =========================
240 \brief Dump zone to the string
241 \param zone zone being dumped
242 \return string representation of the zone
244 std::string Dump( const HOMARD_Zone& zone )
246 std::stringstream os;
247 MESSAGE( ". Dump de la zone "<<zone.GetName());
248 os << zone.GetName();
249 os << separator() << zone.GetZoneType();
251 std::vector<double> coords = zone.GetCoords();
252 for ( int i = 0; i < coords.size(); i++ )
253 os << separator() << ( i < coords.size() ? coords[i] : 0. );
255 std::vector<double> limit = zone.GetLimit();
256 for ( int i = 0; i < 3; i++ )
257 os << separator() << ( i < limit.size() ? limit[i] : 0. );
259 std::list<std::string> hypos = zone.GetHypo();
260 os << separator() << hypos.size();
261 std::list<std::string>::const_iterator it;
262 for ( it = hypos.begin(); it != hypos.end(); ++it )
263 os << separator() << *it;
265 // MESSAGE( ". Fin avec "<<os.str());
269 // 1.5. Archivage d'une frontiere
270 // ==============================
273 \brief Dump boundary to the string
274 \param boundary boundary being dumped
275 \return string representation of the boundary
277 std::string Dump( const HOMARD_Boundary& boundary )
279 std::stringstream os;
280 MESSAGE( ". Dump de la frontiere "<<boundary.GetName());
282 int BoundaryType = boundary.GetBoundaryType() ;
284 os << boundary.GetName() ;
285 os << separator() << BoundaryType ;
286 os << separator() << boundary.GetCaseCreation() ;
288 if ( BoundaryType == 0 )
290 os << separator() << boundary.GetMeshName();
291 os << separator() << boundary.GetMeshFile();
294 std::vector<double> coor = boundary.GetCoords() ;
295 for ( int i = 0; i < coor.size(); i++ )
296 os << separator() << coor[i];
297 std::vector<double> limit = boundary.GetLimit();
298 for ( int i = 0; i < limit.size(); i++ )
299 os << separator() << limit[i];
302 std::list<std::string> ListString = boundary.GetGroups();
303 std::list<std::string>::const_iterator it;
304 os << separator() << ListString.size();
305 for ( it = ListString.begin(); it != ListString.end(); ++it )
306 os << separator() << *it;
308 // MESSAGE( ". Fin avec "<<os.str());
313 // Restauration des objets
314 // ==========================
316 // ==========================
319 \brief Restore case from the string
320 \param cas case being restored
321 \param stream string representation of the case
322 \return \c true if case is correctly restored or \c false otherwise
324 bool Restore( HOMARD_Cas& cas, const std::string& stream )
326 MESSAGE( ". Restoration du cas ");
327 std::string::size_type start = 0;
328 std::string chunk, chunkNext;
331 chunk = getNextChunk( stream, start, ok );
332 if ( !ok ) return false;
333 cas.SetName( chunk.c_str() );
335 chunk = getNextChunk( stream, start, ok );
336 if ( !ok ) return false;
337 cas.SetDirName( chunk.c_str() );
339 chunk = getNextChunk( stream, start, ok );
340 if ( !ok ) return false;
341 cas.SetConfType( atoi( chunk.c_str() ) );
343 chunk = getNextChunk( stream, start, ok );
344 if ( !ok ) return false;
346 int size = atoi( chunk.c_str() );
347 std::vector<double> boite;
348 boite.resize( size );
349 for ( int i = 0; i < size; i++ ) {
350 chunk = getNextChunk( stream, start, ok );
351 if ( !ok ) return false;
352 boite[i] = strtod( chunk.c_str(), 0 );
354 cas.SetBoundingBox( boite );
356 chunk = getNextChunk( stream, start, ok );
357 if ( !ok ) return false;
359 size = atoi( chunk.c_str() );
360 for ( int i = 0; i < size; i++ ) {
361 chunk = getNextChunk( stream, start, ok );
362 if ( !ok ) return false;
363 cas.AddIteration( chunk.c_str() );
366 chunk = getNextChunk( stream, start, ok );
367 if ( !ok ) return false;
368 size = atoi( chunk.c_str() );
369 for ( int i = 0; i < size; i++ )
371 chunk = getNextChunk( stream, start, ok );
372 if ( !ok ) return false;
373 cas.AddGroup( chunk.c_str() );
376 chunk = getNextChunk( stream, start, ok );
377 if ( !ok ) return false;
378 size = atoi( chunk.c_str() );
379 for ( int i = 0; i < size; i++ ) {
380 chunk = getNextChunk( stream, start, ok );
381 if ( !ok ) return false;
383 chunkNext = getNextChunk( stream, start, ok );
384 if ( !ok ) return false;
385 cas.AddBoundaryGroup( chunk.c_str(), chunkNext.c_str() );
388 chunk = getNextChunk( stream, start, ok );
389 if ( !ok ) return false;
390 cas.SetPyram( atoi( chunk.c_str() ) );
396 // =================================
398 \brief Restore iteration from the string
399 \param iteration iteration being restored
400 \param stream string representation of the iteration
401 \return \c true if iteration is correctly restored or \c false otherwise
403 bool Restore( HOMARD_Iteration& iteration, const std::string& stream )
405 std::string::size_type start = 0;
408 chunk = getNextChunk( stream, start, ok );
409 if ( !ok ) return false;
411 iteration.SetName( chunk.c_str() );
412 chunk = getNextChunk( stream, start, ok );
413 if ( !ok ) return false;
414 iteration.SetEtat( (bool)atoi( chunk.c_str() ) );
415 chunk = getNextChunk( stream, start, ok );
416 if ( !ok ) return false;
417 iteration.SetNumber( atoi( chunk.c_str() ) );
418 chunk = getNextChunk( stream, start, ok );
419 if ( !ok ) return false;
420 iteration.SetMeshFile( chunk.c_str() );
421 chunk = getNextChunk( stream, start, ok );
422 if ( !ok ) return false;
423 iteration.SetMessFile( chunk.c_str() );
424 chunk = getNextChunk( stream, start, ok );
425 if ( !ok ) return false;
426 iteration.SetMeshName( chunk.c_str() );
427 chunk = getNextChunk( stream, start, ok );
428 if ( !ok ) return false;
429 iteration.SetFieldFile( chunk.c_str() );
432 chunk = getNextChunk( stream, start, ok );
433 if ( !ok ) return false;
434 timestep = atoi( chunk.c_str() );
435 chunk = getNextChunk( stream, start, ok );
436 if ( !ok ) return false;
437 rank = atoi( chunk.c_str() );
438 iteration.SetTimeStepRank( timestep, rank );
439 chunk = getNextChunk( stream, start, ok );
440 if ( !ok ) return false;
441 iteration.SetIterParent( chunk.c_str() );
443 chunk = getNextChunk( stream, start, ok );
444 if ( !ok ) return false;
445 int size = atoi( chunk.c_str() );
446 for ( int i = 0; i < size; i++ ) {
447 chunk = getNextChunk( stream, start, ok );
448 if ( !ok ) return false;
449 iteration.AddIteration( chunk.c_str() );
452 chunk = getNextChunk( stream, start, ok );
453 if ( !ok ) return false;
454 iteration.SetHypoName( chunk.c_str() );
455 chunk = getNextChunk( stream, start, ok );
456 if ( !ok ) return false;
457 iteration.SetCaseName( chunk.c_str() );
458 chunk = getNextChunk( stream, start, ok );
459 if ( !ok ) return false;
460 iteration.SetDirName( chunk.c_str() );
466 // =================================
468 \brief Restore hypothesis from the string
469 \param hypothesis hypothesis being restored
470 \param stream string representation of the hypothesis
471 \return \c true if hypothesis is correctly restored or \c false otherwise
473 bool Restore( HOMARD_Hypothesis& hypothesis, const std::string& stream )
475 std::string::size_type start = 0;
476 std::string chunk, chunkNext;
479 chunk = getNextChunk( stream, start, ok );
480 if ( !ok ) return false;
481 hypothesis.SetName( chunk.c_str() );
483 chunk = getNextChunk( stream, start, ok );
484 if ( !ok ) return false;
485 hypothesis.SetCaseCreation( chunk.c_str() );
487 chunk = getNextChunk( stream, start, ok );
488 if ( !ok ) return false;
489 hypothesis.SetAdapType( atoi( chunk.c_str() ) );
491 chunk = getNextChunk( stream, start, ok );
492 if ( !ok ) return false;
493 int typeraff = atoi( chunk.c_str() );
494 chunk = getNextChunk( stream, start, ok );
495 if ( !ok ) return false;
496 int typedera = atoi( chunk.c_str() );
497 hypothesis.SetRefinTypeDera( typeraff, typedera );
499 chunk = getNextChunk( stream, start, ok );
500 if ( !ok ) return false;
501 hypothesis.SetField( chunk.c_str() );
503 chunk = getNextChunk( stream, start, ok );
504 if ( !ok ) return false;
505 int typethr = atoi( chunk.c_str() );
506 chunk = getNextChunk( stream, start, ok );
507 if ( !ok ) return false;
508 double threshr = strtod( chunk.c_str(), 0 );
509 hypothesis.SetRefinThr( typethr, threshr );
511 chunk = getNextChunk( stream, start, ok );
512 if ( !ok ) return false;
513 int typethc = atoi( chunk.c_str() );
514 chunk = getNextChunk( stream, start, ok );
515 if ( !ok ) return false;
516 double threshc = strtod( chunk.c_str(), 0 );
517 hypothesis.SetUnRefThr( typethc, threshc );
519 chunk = getNextChunk( stream, start, ok );
520 if ( !ok ) return false;
521 hypothesis.SetUseField(atoi(chunk.c_str()));
523 chunk = getNextChunk( stream, start, ok );
524 if ( !ok ) return false;
525 hypothesis.SetUseComp(atoi(chunk.c_str()));
527 chunk = getNextChunk( stream, start, ok );
528 if ( !ok ) return false;
529 hypothesis.SetTypeFieldInterp(atoi(chunk.c_str()));
531 chunk = getNextChunk( stream, start, ok );
532 if ( !ok ) return false;
533 int size = atoi( chunk.c_str() );
534 for ( int i = 0; i < size; i++ ) {
535 chunk = getNextChunk( stream, start, ok );
536 if ( !ok ) return false;
537 hypothesis.AddIteration( chunk.c_str() );
540 chunk = getNextChunk( stream, start, ok );
541 if ( !ok ) return false;
542 size = atoi( chunk.c_str() );
543 for ( int i = 0; i < size; i++ ) {
544 chunk = getNextChunk( stream, start, ok );
545 if ( !ok ) return false;
547 chunkNext = getNextChunk( stream, start, ok );
548 int typeuse = atoi( chunkNext.c_str() );
549 if ( !ok ) return false;
550 hypothesis.AddZone( chunk.c_str(), typeuse );
553 chunk = getNextChunk( stream, start, ok );
554 if ( !ok ) return false;
555 size = atoi( chunk.c_str() );
556 for ( int i = 0; i < size; i++ ) {
557 chunk = getNextChunk( stream, start, ok );
558 if ( !ok ) return false;
559 hypothesis.AddComp( chunk.c_str() );
562 chunk = getNextChunk( stream, start, ok );
563 if ( !ok ) return false;
564 size = atoi( chunk.c_str() );
565 for ( int i = 0; i < size; i++ ) {
566 chunk = getNextChunk( stream, start, ok );
567 if ( !ok ) return false;
568 hypothesis.AddGroup( chunk.c_str() );
571 chunk = getNextChunk( stream, start, ok );
572 if ( !ok ) return false;
573 size = atoi( chunk.c_str() );
574 for ( int i = 0; i < size; i++ ) {
575 chunk = getNextChunk( stream, start, ok );
576 if ( !ok ) return false;
577 hypothesis.AddFieldInterp( chunk.c_str() );
580 chunk = getNextChunk( stream, start, ok );
581 if ( !ok ) return false;
582 hypothesis.SetNivMax( atoi( chunk.c_str() ) );
584 chunk = getNextChunk( stream, start, ok );
585 if ( !ok ) return false;
586 hypothesis.SetDiamMin( strtod( chunk.c_str(), 0 ) );
593 // ============================
595 \brief Restore zone from the string
596 \param zone zone being restored
597 \param stream string representation of the zone
598 \return \c true if zone is correctly restored or \c false otherwise
600 bool Restore( HOMARD_Zone& zone, const std::string& stream )
602 std::string::size_type start = 0;
606 chunk = getNextChunk( stream, start, ok );
607 if ( !ok ) return false;
608 zone.SetName( chunk.c_str() );
610 chunk = getNextChunk( stream, start, ok );
611 if ( !ok ) return false;
612 int ZoneType = atoi( chunk.c_str() ) ;
613 zone.SetZoneType( ZoneType );
614 // Les coordonnees des zones : le nombre depend du type
615 std::vector<double> coords;
617 if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) ) { lgcoords = 6 ; }
618 else if ( ZoneType == 4 ) { lgcoords = 4 ; }
619 else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) ) { lgcoords = 8 ; }
620 else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) ) { lgcoords = 9 ; }
622 coords.resize( lgcoords );
623 for ( int i = 0; i < lgcoords; i++ ) {
624 chunk = getNextChunk( stream, start, ok );
625 if ( !ok ) return false;
626 coords[i] = strtod( chunk.c_str(), 0 );
628 if ( ZoneType == 2 or ( ZoneType >= 11 and ZoneType <= 13 ) )
629 { zone.SetBox( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5] ); }
630 else if ( ZoneType == 4 )
631 { zone.SetSphere( coords[0], coords[1], coords[2], coords[3] ); }
632 else if ( ZoneType == 5 or ( ZoneType >= 31 and ZoneType <= 33 ) )
633 { zone.SetCylinder( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7] ); }
634 else if ( ZoneType == 7 or ( ZoneType >= 61 and ZoneType <= 63 ) )
635 { zone.SetPipe( coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], coords[6], coords[7], coords[8] ); }
636 // Remarque : la taille de coords est suffisante pour les limites
637 for ( int i = 0; i < 3; i++ ) {
638 chunk = getNextChunk( stream, start, ok );
639 if ( !ok ) return false;
640 coords[i] = strtod( chunk.c_str(), 0 );
642 zone.SetLimit( coords[0], coords[1], coords[2]);
644 chunk = getNextChunk( stream, start, ok );
645 if ( !ok ) return false;
646 int size = atoi( chunk.c_str() );
647 for ( int i = 0; i < size; i++ ) {
648 chunk = getNextChunk( stream, start, ok );
649 if ( !ok ) return false;
650 zone.AddHypo( chunk.c_str() );
656 // 2.5. Restauration d'une frontiere
657 // =================================
660 \brief Restore boundary from the string
661 \param boundary boundary being restored
662 \param stream string representation of the boundary
663 \return \c true if zone is correctly restored or \c false otherwise
665 bool Restore( HOMARD_Boundary& boundary, const std::string& stream )
667 std::string::size_type start = 0;
671 chunk = getNextChunk( stream, start, ok );
672 if ( !ok ) return false;
673 boundary.SetName( chunk.c_str() );
675 chunk = getNextChunk( stream, start, ok );
676 if ( !ok ) return false;
677 int BoundaryType = atoi( chunk.c_str() ) ;
678 boundary.SetBoundaryType( BoundaryType );
680 chunk = getNextChunk( stream, start, ok );
681 if ( !ok ) return false;
682 boundary.SetCaseCreation( chunk.c_str() );
684 // Si analytique, les coordonnees des frontieres : le nombre depend du type
685 // Si discret, le maillage
687 if ( BoundaryType == 1 ) { lgcoords = 7 ; }
688 else if ( BoundaryType == 2 ) { lgcoords = 4 ; }
689 else { lgcoords = 0 ; }
693 chunk = getNextChunk( stream, start, ok );
694 if ( !ok ) return false;
695 boundary.SetMeshName( chunk.c_str() );
697 chunk = getNextChunk( stream, start, ok );
698 if ( !ok ) return false;
699 boundary.SetMeshFile( chunk.c_str() );
702 { std::vector<double> coords;
703 coords.resize( lgcoords );
704 for ( int i = 0; i < lgcoords; i++ ) {
705 chunk = getNextChunk( stream, start, ok );
706 if ( !ok ) return false;
707 coords[i] = strtod( chunk.c_str(), 0 );
709 if ( BoundaryType == 1 )
710 { boundary.SetCylinder(coords[0],coords[1],coords[2],coords[3],coords[4],coords[5],coords[6]); }
711 else if ( BoundaryType == 2 )
712 { boundary.SetSphere( coords[0], coords[1], coords[2], coords[3]); }
713 // Remarque : la taille de coords est suffisante pour les limites
714 for ( int i = 0; i < 3; i++ ) {
715 chunk = getNextChunk( stream, start, ok );
716 if ( !ok ) return false;
717 coords[i] = strtod( chunk.c_str(), 0 );
719 boundary.SetLimit( coords[0], coords[1], coords[2]);
722 chunk = getNextChunk( stream, start, ok );
723 if ( !ok ) return false;
724 int size = atoi( chunk.c_str() );
725 for ( int i = 0; i < size; i++ ) {
726 chunk = getNextChunk( stream, start, ok );
727 if ( !ok ) return false;
728 boundary.AddGroup( chunk.c_str() );
734 } // namespace HOMARD /end/