From e3c8af0c8f38a99499473c35d9dddcf5ec57451c Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Fri, 26 Feb 2021 18:41:33 +0100 Subject: [PATCH] ENH: add read/write specialization for lists of character data - read/write lists of character data in binary only. This is the only means of preserving data. If character data are written as an ASCII list, there is no means of determining if spaces or newlines are content or separators. --- applications/test/charList/Make/files | 3 + applications/test/charList/Make/options | 2 + applications/test/charList/Test-charList.C | 87 ++++++++ src/OpenFOAM/Make/files | 6 +- src/OpenFOAM/containers/Lists/List/List.H | 8 + src/OpenFOAM/containers/Lists/UList/UList.H | 18 ++ .../chars/char/{charIO.C => char.C} | 17 +- src/OpenFOAM/primitives/chars/char/char.H | 55 ++++- .../primitives/chars/lists/charList.C | 116 +++++++++++ .../primitives/chars/lists/charList.H | 56 +++++ .../primitives/chars/lists/charUList.C | 193 ++++++++++++++++++ .../chars/wchar/{wcharIO.C => wchar.C} | 0 src/OpenFOAM/primitives/chars/wchar/wchar.H | 3 +- 13 files changed, 558 insertions(+), 6 deletions(-) create mode 100644 applications/test/charList/Make/files create mode 100644 applications/test/charList/Make/options create mode 100644 applications/test/charList/Test-charList.C rename src/OpenFOAM/primitives/chars/char/{charIO.C => char.C} (87%) create mode 100644 src/OpenFOAM/primitives/chars/lists/charList.C create mode 100644 src/OpenFOAM/primitives/chars/lists/charList.H create mode 100644 src/OpenFOAM/primitives/chars/lists/charUList.C rename src/OpenFOAM/primitives/chars/wchar/{wcharIO.C => wchar.C} (100%) diff --git a/applications/test/charList/Make/files b/applications/test/charList/Make/files new file mode 100644 index 0000000000..e7b5eba75b --- /dev/null +++ b/applications/test/charList/Make/files @@ -0,0 +1,3 @@ +Test-charList.C + +EXE = $(FOAM_USER_APPBIN)/Test-charList diff --git a/applications/test/charList/Make/options b/applications/test/charList/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/test/charList/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/charList/Test-charList.C b/applications/test/charList/Test-charList.C new file mode 100644 index 0000000000..3288c3b7f0 --- /dev/null +++ b/applications/test/charList/Test-charList.C @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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 . + +Application + Test-charList + +Description + Some test of UList, List for characters + +\*---------------------------------------------------------------------------*/ + +#include "OSspecific.H" +#include "argList.H" +#include "IOstreams.H" +#include "messageStream.H" + +#include "charList.H" +#include "labelList.H" +#include "StringStream.H" +#include "ListOps.H" +#include "SubList.H" +#include "FlatOutput.H" + +#include + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noBanner(); + argList::noParallel(); + argList::noFunctionObjects(); + + #include "setRootCase.H" + + Info<< "Known compound tokens: " + << token::compound::IstreamConstructorTablePtr_->sortedToc() << nl; + + OStringStream ostr; + + { + List alphabet(64); + std::iota(alphabet.begin(), alphabet.end(), '@'); + + alphabet.writeEntry("alphabet", Info); + + ostr << alphabet; + + Info<< "wrote: " << ostr.str() << nl; + } + + { + IStringStream istr(ostr.str()); + List alphabet(istr); + + Info<< "re-read: " << alphabet << nl; + } + + return 0; +} + +// ************************************************************************* // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 8a66579f1f..5d41eddc04 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -31,8 +31,10 @@ $(bools)/Switch/Switch.C $(bools)/lists/boolList.C chars = primitives/chars -$(chars)/char/charIO.C -$(chars)/wchar/wcharIO.C +$(chars)/char/char.C +$(chars)/wchar/wchar.C +$(chars)/lists/charList.C +$(chars)/lists/charUList.C primitives/direction/directionIO.C diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H index 34202f1bdc..7dbcd5077c 100644 --- a/src/OpenFOAM/containers/Lists/List/List.H +++ b/src/OpenFOAM/containers/Lists/List/List.H @@ -353,6 +353,14 @@ public: }; +// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * // + +//- Specialized list reading for character lists which always uses +//- binary format. +template<> +Istream& List::readList(Istream& is); + + // * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * // //- Create identity map of the given length with (map[i] == i) diff --git a/src/OpenFOAM/containers/Lists/UList/UList.H b/src/OpenFOAM/containers/Lists/UList/UList.H index 2ba4a13bb7..f0a3ab0d58 100644 --- a/src/OpenFOAM/containers/Lists/UList/UList.H +++ b/src/OpenFOAM/containers/Lists/UList/UList.H @@ -551,6 +551,24 @@ public: }; +// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * // + +//- Specialized list reading for character lists which always uses +//- binary format. +template<> +Istream& UList::readList(Istream& is); + +//- Specialized writeEntry for character lists which always uses +//- binary format. +template<> +void UList::writeEntry(Ostream& os) const; + +//- Specialized writeList for character lists which always uses +//- binary format. +template<> +Ostream& UList::writeList(Ostream& os, const label /*unused*/) const; + + // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // //- Write List to Ostream, as per UList::writeList() with default length. diff --git a/src/OpenFOAM/primitives/chars/char/charIO.C b/src/OpenFOAM/primitives/chars/char/char.C similarity index 87% rename from src/OpenFOAM/primitives/chars/char/charIO.C rename to src/OpenFOAM/primitives/chars/char/char.C index b1f99fad3e..6d5802816b 100644 --- a/src/OpenFOAM/primitives/chars/char/charIO.C +++ b/src/OpenFOAM/primitives/chars/char/char.C @@ -5,7 +5,8 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -30,6 +31,20 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +const char* const Foam::pTraits::typeName = "char"; + +Foam::pTraits::pTraits(const char p) noexcept +: + p_(p) +{} + + +Foam::pTraits::pTraits(Istream& is) +{ + is >> p_; +} + + char Foam::readChar(Istream& is) { char c; diff --git a/src/OpenFOAM/primitives/chars/char/char.H b/src/OpenFOAM/primitives/chars/char/char.H index 4ac3bb747f..c8efbbc39e 100644 --- a/src/OpenFOAM/primitives/chars/char/char.H +++ b/src/OpenFOAM/primitives/chars/char/char.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -30,7 +31,7 @@ Description A character and a pointer to a character string. SourceFiles - charIO.C + char.C \*---------------------------------------------------------------------------*/ @@ -42,6 +43,7 @@ SourceFiles namespace Foam { +// Forward Declarations class Istream; class Ostream; @@ -59,7 +61,7 @@ Ostream& operator<<(Ostream& os, const char c); //- Write a nul-terminated C-string Ostream& operator<<(Ostream& os, const char* str); -//- Test for \em horizontal whitespace +//- Test for whitespace inline bool isspace(char c) { return @@ -72,6 +74,55 @@ inline bool isspace(char c) } +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "pTraits.H" + +namespace Foam +{ + +// Template specialisation for pTraits +template<> +class pTraits +{ + char p_; + +public: + + // Static Data Members + + static const char* const typeName; + + + // Constructors + + //- Copy construct from primitive + explicit pTraits(const char p) noexcept; + + //- Read construct from Istream + explicit pTraits(Istream& is); + + + // Member Functions + + //- Read access to primitive value + operator char() const noexcept + { + return p_; + } + + //- Write access to primitive value + operator char&() noexcept + { + return p_; + } +}; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/primitives/chars/lists/charList.C b/src/OpenFOAM/primitives/chars/lists/charList.C new file mode 100644 index 0000000000..95f5a1d864 --- /dev/null +++ b/src/OpenFOAM/primitives/chars/lists/charList.C @@ -0,0 +1,116 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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 "charList.H" +#include "Istream.H" +#include "Ostream.H" +#include "token.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineCompoundTypeName(List, charList); + addCompoundToRunTimeSelectionTable(List, charList); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +namespace Foam +{ + +template<> +Istream& List::readList(Istream& is) +{ + List& list = *this; + + // Anull list + list.clear(); + + is.fatalCheck(FUNCTION_NAME); + + token tok(is); + + is.fatalCheck("List::readList(Istream&) : reading first token"); + + if (tok.isCompound()) + { + // Compound: simply transfer contents + + list.transfer + ( + dynamicCast>> + ( + tok.transferCompoundToken(is) + ) + ); + } + else if (tok.isLabel()) + { + // Label: could be int(..) or just a plain '0' + + const label len = tok.labelToken(); + + // Resize to actual length read + list.resize(len); + + // Binary, always contiguous + + if (len) + { + const auto oldFmt = is.format(IOstream::BINARY); + + // read(...) includes surrounding start/end delimiters + is.read(list.data(), std::streamsize(len)); + + is.format(oldFmt); + + is.fatalCheck + ( + "List::readList(Istream&) : " + "reading binary block" + ); + } + } + else + { + FatalIOErrorInFunction(is) + << "incorrect first token, expected , found " + << tok.info() << nl + << exit(FatalIOError); + } + + return is; +} + + +} // End namespace Foam + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/chars/lists/charList.H b/src/OpenFOAM/primitives/chars/lists/charList.H new file mode 100644 index 0000000000..cc13e3fa69 --- /dev/null +++ b/src/OpenFOAM/primitives/chars/lists/charList.H @@ -0,0 +1,56 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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 . + +Typedef + Foam::charListList + +Description + A List of charList. + +\*---------------------------------------------------------------------------*/ + +#ifndef charList_H +#define charList_H + +#include "char.H" +#include "List.H" +#include "SubList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + // charUList = defined in UList.H + // charList = defined in List.H + // charSubList = defined in SubList.H + + typedef List charListList; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/chars/lists/charUList.C b/src/OpenFOAM/primitives/chars/lists/charUList.C new file mode 100644 index 0000000000..5fc94f3d61 --- /dev/null +++ b/src/OpenFOAM/primitives/chars/lists/charUList.C @@ -0,0 +1,193 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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 "charList.H" +#include "Istream.H" +#include "Ostream.H" +#include "token.H" + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + +static Ostream& writeChars +( + Ostream& os, + const char* chars, + std::streamsize count +) +{ + // Contents are binary and contiguous + os << nl << label(count) << nl; + + if (count) + { + const auto oldFmt = os.format(IOstream::BINARY); + + // write(...) includes surrounding start/end delimiters + os.write(chars, count); + + os.format(oldFmt); + } + + os.check(FUNCTION_NAME); + return os; +} + +} // End namespace Foam + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +namespace Foam +{ + +template<> +void UList::writeEntry(Ostream& os) const +{ + const std::streamsize count(this->size()); + + os << word("List"); + + if (count) + { + writeChars(os, this->cdata(), count); + } + else + { + // Zero-sized binary - Write size only + os << token::SPACE << label(0); + } +} + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +namespace Foam +{ + +template<> +Ostream& UList::writeList +( + Ostream& os, + const label /* shortLen (unused) */ +) const +{ + return writeChars(os, this->cdata(), std::streamsize(this->size())); +} + + +template<> +Istream& UList::readList(Istream& is) +{ + UList& list = *this; + + // The target list length - must match with sizes read + const label len = list.size(); + + is.fatalCheck(FUNCTION_NAME); + + token tok(is); + + is.fatalCheck("UList::readList(Istream&) : reading first token"); + + if (tok.isCompound()) + { + // Compound: simply transfer contents + + List elems; + elems.transfer + ( + dynamicCast>> + ( + tok.transferCompoundToken(is) + ) + ); + + const label inputLen = elems.size(); + + // List lengths must match + if (inputLen != len) + { + FatalIOErrorInFunction(is) + << "incorrect length for UList. Read " + << inputLen << " expected " << len + << exit(FatalIOError); + } + + this->deepCopy(elems); + } + if (tok.isLabel()) + { + // Label: could be int(..) or just a plain '0' + + const label inputLen = tok.labelToken(); + + // List lengths must match + if (inputLen != len) + { + FatalIOErrorInFunction(is) + << "incorrect length for UList. Read " + << inputLen << " expected " << len + << exit(FatalIOError); + } + + // Binary, always contiguous + + if (len) + { + const auto oldFmt = is.format(IOstream::BINARY); + + // read(...) includes surrounding start/end delimiters + is.read(list.data(), std::streamsize(len)); + + is.format(oldFmt); + + is.fatalCheck + ( + "UList::readList(Istream&) : " + "reading binary block" + ); + } + } + else + { + FatalIOErrorInFunction(is) + << "incorrect first token, expected , found " + << tok.info() << nl + << exit(FatalIOError); + } + + return is; +} + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/chars/wchar/wcharIO.C b/src/OpenFOAM/primitives/chars/wchar/wchar.C similarity index 100% rename from src/OpenFOAM/primitives/chars/wchar/wcharIO.C rename to src/OpenFOAM/primitives/chars/wchar/wchar.C diff --git a/src/OpenFOAM/primitives/chars/wchar/wchar.H b/src/OpenFOAM/primitives/chars/wchar/wchar.H index c03a1db7a8..25a80bc554 100644 --- a/src/OpenFOAM/primitives/chars/wchar/wchar.H +++ b/src/OpenFOAM/primitives/chars/wchar/wchar.H @@ -30,7 +30,7 @@ Description A wide-character and a pointer to a wide-character string. SourceFiles - wcharIO.C + wchar.C See also http://en.wikipedia.org/wiki/UTF-8 @@ -49,6 +49,7 @@ See also namespace Foam { +// Forward Declarations class Istream; class Ostream;