Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / utilities / containers / LongList / LongList.C
blobf56faa655e063c06ecde0849178c80a9b1275ac7
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | cfMesh: A library for mesh generation
4    \\    /   O peration     |
5     \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6      \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9     This file is part of cfMesh.
11     cfMesh is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 3 of the License, or (at your
14     option) any later version.
16     cfMesh is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with cfMesh.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "LongList.H"
27 #include "Ostream.H"
28 #include "token.H"
30 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
32 template<class T, Foam::label Offset>
33 void Foam::LongList<T, Offset>::writeEntry(Ostream& os) const
35     if
36     (
37         size() &&
38         token::compound::isCompound
39         (
40             "LongList<" + word(pTraits<T>::typeName) + '>'
41         )
42     )
43     {
44         os  << word("LongList<" + word(pTraits<T>::typeName) + '>') << " ";
45     }
47     os << *this;
50 template<class T, Foam::label Offset>
51 void Foam::LongList<T, Offset>::writeEntry
53     const word& keyword,
54     Ostream& os
55 ) const
57     os.writeKeyword(keyword);
58     writeEntry(os);
59     os << token::END_STATEMENT << endl;
62 template<class T, Foam::label Offset>
63 Foam::Ostream& Foam::operator<<
65     Foam::Ostream& os,
66     const Foam::LongList<T, Offset>& DL
69     if( (os.format() == IOstream::ASCII) || !contiguous<T>() )
70     {
71         if( DL.size() < 15 )
72         {
73             // Write size of list and start contents delimiter
74             os << DL.size() << token::BEGIN_LIST;
76             // Write list contents
77             forAll(DL, i)
78             {
79                 if( i != 0 ) os << token::SPACE;
80                 os << DL[i];
81             }
83             // Write end of contents delimiter
84             os << token::END_LIST;
85         }
86         else
87         {
88             // Write size of list and start contents delimiter
89             os << nl << DL.size() << nl << token::BEGIN_LIST;
91             // Write list contents
92             forAll(DL, i)
93             {
94                 os << nl << DL[i];
95             }
97             // Write end of contents delimiter
98             os << nl << token::END_LIST << nl;
99         }
100     }
101     else
102     {
103         os << nl << DL.nextFree_ << nl;
104         if( DL.nextFree_ )
105         {
106             const label blockSize = 1<<DL.shift_;
108             label currBlock(0);
109             label currPos(0);
111             while( currPos < DL.nextFree_ )
112             {
113                 const label bs =
114                     Foam::min(DL.nextFree_ - currPos, blockSize);
116                 os.write
117                 (
118                     reinterpret_cast<const char*>(DL.dataPtr_[currBlock]),
119                     bs * sizeof(T)
120                 );
122                 currPos += bs;
123                 ++currBlock;
124             }
125         }
126     }
128     // Check state of IOstream
129     os.check("Ostream& operator<<(Ostream&, const LongList&)");
131     return os;
135 template<class T, Foam::label Offset>
136 Foam::Istream& Foam::operator>>
138     Foam::Istream& is,
139     Foam::LongList<T, Offset>& DL
142     // Anull list
143     DL.setSize(0);
145     is.fatalCheck("operator>>(Istream&, LongList<T, Offset>&)");
147     token firstToken(is);
149     is.fatalCheck
150     (
151         "operator>>(Istream&, LongList<T, Offset>&) : reading first token"
152     );
154     if( firstToken.isLabel() )
155     {
156         const label size = firstToken.labelToken();
158         // Set list length to that read
159         DL.setSize(size);
161         // Read list contents depending on data format
162         if( (is.format() == IOstream::ASCII) || !contiguous<T>() )
163         {
164             // Read beginning of contents
165             char listDelimiter = is.readBeginList("List");
167             if( size == 0 )
168             {
169                 if( listDelimiter != token::BEGIN_LIST )
170                 {
171                     WarningIn
172                     (
173                         "template<class T, Foam::label Offset>"
175                         "Foam::Istream& Foam::operator>>"
176                         "("
177                             "Foam::Istream& ,"
178                             "Foam::LongList<T, Offset>& DL"
179                         ")"
180                     ) << "Missing ( after 0" << endl;
182                     return is;
183                 }
185                 listDelimiter = is.readEndList("List");
186                 if( listDelimiter != token::END_LIST )
187                 {
188                     WarningIn
189                     (
190                         "template<class T, Foam::label Offset>"
192                         "Foam::Istream& Foam::operator>>"
193                         "("
194                             "Foam::Istream& ,"
195                             "Foam::LongList<T, Offset>& DL"
196                         ")"
197                     ) << "Missing ) after 0(" << endl;
198                 }
200                 return is;
201             }
203             if( listDelimiter == token::BEGIN_LIST )
204             {
205                 for(register label i=0;i<size;++i)
206                 {
207                     is >> DL[i];
209                     is.fatalCheck
210                     (
211                         "operator>>(Istream&, List<T>&) : reading entry"
212                     );
213                 }
214             }
215             else
216             {
217                 T element;
218                 is >> element;
220                 is.fatalCheck
221                 (
222                     "operator>>(Istream&, List<T>&) : "
223                     "reading the single entry"
224                 );
226                 for(register label i=0;i<size;++i)
227                 {
228                     DL[i] = element;
229                 }
230             }
232             // Read end of contents
233             is.readEndList("List");
234         }
235         else
236         {
237             const label blockSize = (1<<DL.shift_);
239             label currBlock(0);
240             label currPos(0);
242             while( currPos < size )
243             {
244                 const label bs = Foam::min(size - currPos, blockSize);
246                 is.read
247                 (
248                     reinterpret_cast<char*>(DL.dataPtr_[currBlock]),
249                     bs * sizeof(T)
250                 );
252                 currPos += bs;
253                 ++currBlock;
254             }
256             is.fatalCheck
257             (
258                 "operator>>(Istream&, LongList<T, Offset>&)"
259                 ": reading the binary block"
260             );
261         }
262     }
263     else
264     {
265         FatalIOErrorIn("operator>>(Istream&, LongList<T, Offset>&)", is)
266             << "incorrect first token, expected <int>, found "
267             << firstToken.info()
268             << exit(FatalIOError);
269     }
271     return is;
274 template<class T, Foam::label Offset>
275 void Foam::LongList<T, Offset>::appendFromStream(Istream& is)
277     is.fatalCheck("appendFromStream(Istream& is)");
279     token firstToken(is);
281     is.fatalCheck
282     (
283         "appendFromStream(Istream& is) : reading first token"
284     );
286     if( firstToken.isLabel() )
287     {
288         const label size = firstToken.labelToken();
290         if( size == 0 )
291         {
292             Pout << "Appending empty stream" << endl;
293             return;
294         }
296         label origSize(this->size());
298         // Set list length to that read
299         setSize(origSize+size);
301         // Read list contents depending on data format
302         if( (is.format() == IOstream::ASCII) || !contiguous<T>() )
303         {
304             // Read beginning of contents
305             char listDelimiter = is.readBeginList("List");
307             if( listDelimiter == token::BEGIN_LIST )
308             {
309                 for(register label i=0;i<size;++i)
310                 {
311                     is >> this->operator[](origSize);
312                     ++origSize;
314                     is.fatalCheck
315                     (
316                         "appendFromStream(Istream& is) : reading entry"
317                     );
318                 }
319             }
320             else
321             {
322                 T element;
323                 is >> element;
325                 is.fatalCheck
326                 (
327                     "appendFromStream(Istream& is) : "
328                     "reading the single entry"
329                 );
331                 for(register label i=0;i<size;++i)
332                 {
333                     this->operator[](origSize) = element;
334                     ++origSize;
335                 }
336             }
338             // Read end of contents
339             is.readEndList("List");
340         }
341         else
342         {
343             List<T> buf(size);
344             is.read(reinterpret_cast<char*>(buf.begin()), size * sizeof(T));
346             forAll(buf, i)
347                 this->operator[](origSize++) = buf[i];
349             /*const label blockSize = 1<<shift_;
351             Info << "nextFree_ " << nextFree_ << endl;
353             //- append elements by reading binary block
354             while( origSize < nextFree_ )
355             {
356                 const label currBlock = origSize >> shift_;
357                 const label currPos = origSize & mask_;
359                 Info << "Orig size " << origSize
360                     << nl << "currBlock " << currBlock
361                     << nl << "currPos " << currPos << endl;
363                 T* data = &dataPtr_[currBlock][currPos];
365                 label bs = Foam::min(nextFree_-origSize, blockSize);
366                 bs = Foam::min(blockSize - currPos, bs);
368                 Info << "bs " << bs << endl;
370                 is.read(reinterpret_cast<char*>(data), bs * sizeof(T));
371                 origSize += bs;
372             } */
374             is.fatalCheck
375             (
376                 "appendFromStream(Istream& is)"
377                 ": reading the binary block"
378             );
379         }
380     }
381     else
382     {
383         FatalIOErrorIn("appendFromStream(Istream& is)", is)
384             << "incorrect first token, expected <int>, found "
385             << firstToken.info()
386             << exit(FatalIOError);
387     }
391 // ************************************************************************* //