Salome HOME
Merge branch 'V9_9_BR'
[modules/smesh.git] / src / SMESHUtils / SMESH_BoostTxtArchive.cxx
1 // Copyright (C) 2007-2022  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 // File      : SMESH_BoostTxtArchive.cxx
23 // Created   : Thu Aug  5 21:19:31 2021
24 // Author    : Edward AGAPOV (eap)
25
26 #include "SMESH_BoostTxtArchive.hxx"
27
28 #include <cctype>
29 #include <sstream>
30 #include <boost/archive/text_oarchive.hpp>
31
32
33 using namespace SMESHUtils;
34
35 BoostTxtArchive::BoostTxtArchive( const std::string& s ):
36   myArchiveReader( nullptr ),
37   myString( s ),
38   myStringFixed( false ),
39   myStream( nullptr ),
40   myOwnStream( true )
41 {
42   myStream = new std::istringstream( myString );
43   makeReader();
44 }
45
46 BoostTxtArchive::BoostTxtArchive( std::istream& stream ):
47   myArchiveReader( nullptr ),
48   myStringFixed( false ),
49   myStream( &stream ),
50   myOwnStream( false )
51 {
52   if ( std::istringstream * sstrm = dynamic_cast< std::istringstream* >( &stream ))
53     myString = sstrm->str();
54
55   makeReader();
56 }
57
58 BoostTxtArchive::~BoostTxtArchive()
59 {
60   delete myArchiveReader; myArchiveReader = nullptr;
61   if ( myOwnStream )
62     delete myStream;
63 }
64
65 void BoostTxtArchive::makeReader()
66 {
67   myArchiveReader = nullptr;
68   try
69   {
70     myArchiveReader = new boost::archive::text_iarchive( *myStream );
71   }
72   catch (...)
73   {
74     if ( fixString() )
75       try
76       {
77         myArchiveReader = new boost::archive::text_iarchive( *myStream );
78       }
79       catch(...)
80       {
81         myArchiveReader = nullptr;
82       }
83   }
84 }
85
86 namespace
87 {
88   //================================================================================
89   /*!
90    * \brief Return archive created by current version of boost::archive
91    */
92   //================================================================================
93
94   std::string getCurrentVersionArchive( BoostTxtArchive & bta)
95   {
96     std::ostringstream strm;
97     boost::archive::text_oarchive archive( strm );
98     archive << bta;
99     return strm.str();
100   }
101 }
102
103 //================================================================================
104 /*!
105  * \brief Change boost::archive library version in myString to be equal to
106  *        the current library version
107  *  \return bool - return true if the version is changed
108  */
109 //================================================================================
110
111 bool BoostTxtArchive::fixString()
112 {
113   if ( myStringFixed )
114     return false;
115   myStringFixed = true;
116
117   const char*     sub = "serialization::archive ";
118   const size_t subLen = 23;
119
120   size_t where1 = myString.find( sub );
121   if ( where1 == std::string::npos )
122     return false;
123
124   std::string nowString = getCurrentVersionArchive( *this );
125   size_t where2 = nowString.find( sub );
126   if ( where2 == std::string::npos )
127     return false;
128
129   bool sameVersion = true;
130   for ( size_t i1 = where1 + subLen, i2 = where2 + subLen;
131         i2 < nowString.size();
132         ++i1, ++i2 )
133   {
134     if ( myString[ i1 ] != nowString[ i2 ] )
135     {
136       sameVersion = false;
137       myString[ i1 ] = nowString[ i2 ];
138     }
139     if ( isspace( myString[ i1 ]))
140       break;
141   }
142
143   if ( !sameVersion )
144   {
145     if ( myOwnStream )
146       delete myStream;
147     myStream    = new std::istringstream( myString );
148     myOwnStream = true;
149   }
150
151   return !sameVersion;
152 }