/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2015-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "CompactIOList.H" #include "labelList.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template void Foam::CompactIOList::readFromStream() { Istream& is = readStream(word::null); if (headerClassName() == IOList::typeName) { is >> static_cast&>(*this); close(); } else if (headerClassName() == typeName) { is >> *this; close(); } else { FatalIOErrorInFunction(is) << "unexpected class name " << headerClassName() << " expected " << typeName << " or " << IOList::typeName << endl << " while reading object " << name() << exit(FatalIOError); } } template bool Foam::CompactIOList::readContents() { if ( readOpt() == IOobject::MUST_READ || (readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { readFromStream(); return true; } return false; } template bool Foam::CompactIOList::overflows() const { label size = 0; forAll(*this, i) { const label oldSize = size; size += this->operator[](i).size(); if (size < oldSize) { return true; } } return false; } // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // template Foam::CompactIOList::CompactIOList(const IOobject& io) : regIOobject(io) { readContents(); } template Foam::CompactIOList::CompactIOList ( const IOobject& io, Foam::zero ) : regIOobject(io) { readContents(); } template Foam::CompactIOList::CompactIOList ( const IOobject& io, const label len ) : regIOobject(io) { if (!readContents()) { List::resize(len); } } template Foam::CompactIOList::CompactIOList ( const IOobject& io, const UList& content ) : regIOobject(io) { if (!readContents()) { List::operator=(content); } } template Foam::CompactIOList::CompactIOList ( const IOobject& io, List&& content ) : regIOobject(io) { List::transfer(content); readContents(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template bool Foam::CompactIOList::writeObject ( IOstreamOption streamOpt, const bool valid ) const { if ( streamOpt.format() == IOstream::BINARY && overflows() ) { streamOpt.format(IOstream::ASCII); WarningInFunction << "Overall number of elements of CompactIOList of size " << this->size() << " overflows the representation of a label" << nl << " Switching to ascii writing" << endl; } if (streamOpt.format() == IOstream::ASCII) { // Change type to be non-compact format type const word oldTypeName(typeName); const_cast(typeName) = IOList::typeName; bool good = regIOobject::writeObject(streamOpt, valid); // Change type back const_cast(typeName) = oldTypeName; return good; } return regIOobject::writeObject(streamOpt, valid); } template bool Foam::CompactIOList::writeData(Ostream& os) const { return (os << *this).good(); } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template void Foam::CompactIOList::operator= ( const CompactIOList& rhs ) { List::operator=(rhs); } // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // template Foam::Istream& Foam::operator>> ( Foam::Istream& is, Foam::CompactIOList& L ) { // Read compact const labelList start(is); const List elems(is); // Convert L.setSize(start.size()-1); forAll(L, i) { T& subList = L[i]; label index = start[i]; subList.setSize(start[i+1] - index); forAll(subList, j) { subList[j] = elems[index++]; } } return is; } template Foam::Ostream& Foam::operator<< ( Foam::Ostream& os, const Foam::CompactIOList& L ) { // Keep ascii writing same. if (os.format() == IOstream::ASCII) { os << static_cast&>(L); } else { // Convert to compact format labelList start(L.size()+1); start[0] = 0; for (label i = 1; i < start.size(); i++) { const label prev = start[i-1]; start[i] = prev+L[i-1].size(); if (start[i] < prev) { FatalIOErrorInFunction(os) << "Overall number of elements " << start[i] << " of CompactIOList of size " << L.size() << " overflows the representation of a label" << endl << "Please recompile with a larger representation" << " for label" << exit(FatalIOError); } } List elems(start[start.size()-1]); label elemI = 0; forAll(L, i) { const T& subList = L[i]; forAll(subList, j) { elems[elemI++] = subList[j]; } } os << start << elems; } return os; } // ************************************************************************* //