/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- 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 { FatalIOErrorIn ( "CompactIOList::readFromStream()", is ) << "unexpected class name " << headerClassName() << " expected " << typeName << " or " << IOList::typeName << endl << " while reading object " << name() << exit(FatalIOError); } } template bool Foam::CompactIOList::overflows() const { label size = 0; forAll(*this, i) { 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) { if ( io.readOpt() == IOobject::MUST_READ || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { readFromStream(); } } template Foam::CompactIOList::CompactIOList ( const IOobject& io, const label size ) : regIOobject(io) { if ( io.readOpt() == IOobject::MUST_READ || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { readFromStream(); } else { List::setSize(size); } } template Foam::CompactIOList::CompactIOList ( const IOobject& io, const List& list ) : regIOobject(io) { if ( io.readOpt() == IOobject::MUST_READ || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { readFromStream(); } else { List::operator=(list); } } template Foam::CompactIOList::CompactIOList ( const IOobject& io, const Xfer >& list ) : regIOobject(io) { List::transfer(list()); if ( io.readOpt() == IOobject::MUST_READ || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { readFromStream(); } } // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * // template Foam::CompactIOList::~CompactIOList() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template bool Foam::CompactIOList::writeObject ( IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp ) const { if (fmt == IOstream::ASCII) { // Change type to be non-compact format type const word oldTypeName = typeName; const_cast(typeName) = IOList::typeName; bool good = regIOobject::writeObject(fmt, ver, cmp); // Change type back const_cast(typeName) = oldTypeName; return good; } else if (overflows()) { WarningIn ( "CompactIOList::writeObject" "(IOstream::streamFormat, IOstream::versionNumber" ", IOstream::compressionType) const" ) << "Overall number of elements of CompactIOList of size " << this->size() << " overflows the representation of a label" << endl << " Switching to ascii writing" << endl; // Change type to be non-compact format type const word oldTypeName = typeName; const_cast(typeName) = IOList::typeName; bool good = regIOobject::writeObject(IOstream::ASCII, ver, cmp); // Change type back const_cast(typeName) = oldTypeName; return good; } else { return regIOobject::writeObject(fmt, ver, cmp); } } 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); } template void Foam::CompactIOList::operator=(const List& 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++) { label prev = start[i-1]; start[i] = prev+L[i-1].size(); if (start[i] < prev) { FatalIOErrorIn ( "operator<<" "(Ostream& os, const CompactIOList&)", 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; } // ************************************************************************* //