From e564a9810fe1937be7028b0d880bcd2e50d58085 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@Germany> Date: Mon, 9 Aug 2010 17:27:09 +0200 Subject: [PATCH] ENH: add IO support for PackedList, PackedBoolList --- .../test/PackedList1/PackedListTest1.C | 82 ++--- .../test/PackedList3/PackedListTest3.C | 3 +- .../test/PackedList4/PackedListTest4.C | 36 +- src/OpenFOAM/Make/files | 2 +- src/OpenFOAM/containers/Lists/List/ListIO.C | 2 +- .../Lists/PackedList/PackedBoolList.C | 322 ++++++++++++++++++ .../Lists/PackedList/PackedBoolList.H | 44 ++- .../Lists/PackedList/PackedBoolListI.H | 8 + .../containers/Lists/PackedList/PackedList.C | 205 +++++++++++ .../containers/Lists/PackedList/PackedList.H | 28 +- .../db/IOstreams/Sstreams/readHexLabel.C | 5 +- 11 files changed, 686 insertions(+), 51 deletions(-) diff --git a/applications/test/PackedList1/PackedListTest1.C b/applications/test/PackedList1/PackedListTest1.C index 5e1902f3828..461db541586 100644 --- a/applications/test/PackedList1/PackedListTest1.C +++ b/applications/test/PackedList1/PackedListTest1.C @@ -42,42 +42,42 @@ int main(int argc, char *argv[]) Info<< "\ntest allocation with value\n"; PackedList<3> list1(5,1); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign uniform value\n"; list1 = 3; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign uniform value (with overflow)\n"; list1 = -1; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest zero\n"; list1 = 0; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest set() with default argument (max_value)\n"; list1.set(1); list1.set(3); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest unset() with in-range and out-of-range\n"; list1.unset(3); list1.unset(100000); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign between references\n"; list1[2] = 3; list1[4] = list1[2]; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign between references, with chaining\n"; list1[0] = list1[4] = 1; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign between references, with chaining and auto-vivify\n"; list1[1] = list1[8] = list1[10] = list1[14] = 2; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest operator== between references\n"; @@ -126,7 +126,7 @@ int main(int argc, char *argv[]) { const PackedList<3>& constLst = list1; Info<< "\ntest operator[] const with out-of-range index\n"; - constLst.print(Info); + constLst.print(Info, true); if (constLst[20]) { Info<< "[20] is true (unexpected)\n"; @@ -136,7 +136,7 @@ int main(int argc, char *argv[]) Info<< "[20] is false (expected) list size should be unchanged " << "(const)\n"; } - constLst.print(Info); + constLst.print(Info, true); Info<< "\ntest operator[] non-const with out-of-range index\n"; if (list1[20]) @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) Info<< "[20] is false (expected) but list was resized?? " << "(non-const)\n"; } - list1.print(Info); + list1.print(Info, true); } @@ -157,85 +157,85 @@ int main(int argc, char *argv[]) { Info<< "[20] is false, as expected\n"; } - list1.print(Info); + list1.print(Info, true); Info<< "\ntest resize with value (without reallocation)\n"; list1.resize(8, list1.max_value()); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest flip() function\n"; list1.flip(); - list1.print(Info); + list1.print(Info, true); Info<< "\nre-flip()\n"; list1.flip(); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest set() function\n"; list1.set(1, 5); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign bool\n"; list1 = false; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest assign bool\n"; list1 = true; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest resize without value (with reallocation)\n"; list1.resize(12); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest resize with value (with reallocation)\n"; list1.resize(25, list1.max_value()); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest resize smaller (should not touch allocation)\n"; list1.resize(8); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest append() operation\n"; list1.append(2); list1.append(3); list1.append(4); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest reserve() operation\n"; list1.reserve(32); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest shrink() operation\n"; list1.shrink(); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest setCapacity() operation\n"; list1.setCapacity(15); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest setCapacity() operation\n"; list1.setCapacity(100); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest operator[] assignment\n"; list1[16] = 5; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest operator[] assignment with auto-vivify\n"; list1[36] = list1.max_value(); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest setCapacity smaller\n"; list1.setCapacity(24); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest resize much smaller\n"; list1.resize(150); - list1.print(Info); + list1.print(Info, true); Info<< "\ntest trim\n"; list1.trim(); - list1.print(Info); + list1.print(Info, true); // add in some misc values list1[31] = 1; @@ -250,7 +250,7 @@ int main(int argc, char *argv[]) Info<< "iterator:" << iter() << "\n"; iter() = 5; iter.print(Info); - list1.print(Info); + list1.print(Info, true); iter = list1[31]; Info<< "iterator:" << iter() << "\n"; @@ -259,7 +259,7 @@ int main(int argc, char *argv[]) Info<< "\ntest get() method\n"; Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n"; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest iterator indexing\n"; Info<< "cend() "; @@ -267,7 +267,7 @@ int main(int argc, char *argv[]) { Info<< "\ntest assignment of iterator\n"; - list1.print(Info); + list1.print(Info, true); Info<< "cend()\n"; list1.end().print(Info); PackedList<3>::iterator cit = list1[100]; @@ -304,16 +304,16 @@ int main(int argc, char *argv[]) Info<< "size after write:" << list1.size() << "\n"; Info<< "list[45]:" << list1[45] << "\n"; list1[49] = list1[100]; - list1.print(Info); + list1.print(Info, true); Info<< "\ntest copy constructor + append\n"; PackedList<3> list2(list1); list2.append(4); Info<< "source list:\n"; - list1.print(Info); + list1.print(Info, true); Info<< "destination list:\n"; - list2.print(Info); + list2.print(Info, true); Info<< "\ntest pattern that fills all bits\n"; PackedList<4> list3(8, 8); @@ -323,10 +323,12 @@ int main(int argc, char *argv[]) list3[pos--] = list3.max_value(); list3[pos--] = 0; list3[pos--] = list3.max_value(); - list3.print(Info); + list3.print(Info, true); Info<< "removed final value: " << list3.remove() << endl; - list3.print(Info); + list3.print(Info, true); + + Info<<"list: " << list3 << endl; List<bool> list4(16, false); diff --git a/applications/test/PackedList3/PackedListTest3.C b/applications/test/PackedList3/PackedListTest3.C index 5ff6ee8644b..7b27ffda09a 100644 --- a/applications/test/PackedList3/PackedListTest3.C +++ b/applications/test/PackedList3/PackedListTest3.C @@ -33,7 +33,6 @@ Description #include "StaticHashTable.H" #include "cpuTime.H" #include <vector> -#include "PackedList.H" #include "PackedBoolList.H" using namespace Foam; @@ -57,7 +56,7 @@ int main(int argc, char *argv[]) { if ((i % nReport) == 0 && i) { - Info<< "i:" << i << " in " << timer.cpuTimeIncrement() << " s" + Info<< "i:" << i << " in " << timer.cpuTimeIncrement() << " s" <<endl; } packed[i] = 1; diff --git a/applications/test/PackedList4/PackedListTest4.C b/applications/test/PackedList4/PackedListTest4.C index 7271a3f1dd2..d1e4e5b143d 100644 --- a/applications/test/PackedList4/PackedListTest4.C +++ b/applications/test/PackedList4/PackedListTest4.C @@ -30,6 +30,7 @@ Description #include "uLabel.H" #include "IOstreams.H" #include "PackedBoolList.H" +#include "IStringStream.H" using namespace Foam; @@ -45,7 +46,7 @@ int main(int argc, char *argv[]) list1[i] = i % 2; } - Info<< "\nalternative bit pattern\n"; + Info<< "\nalternating bit pattern\n"; list1.print(Info, true); PackedBoolList list2 = ~list1; @@ -117,6 +118,39 @@ int main(int argc, char *argv[]) (list3 -= list2Labels).print(Info, true); } + + PackedBoolList list4 + ( + IStringStream + ( + "(AB 05 10 0F F0)" + )() + ); + + Info<< "\ntest Istream constructor\n"; + + list4.print(Info, true); + Info<< list4 << " indices: " << list4.used()() <<endl; + + Info<< "\nassign from labelList\n"; + list4 = labelList + ( + IStringStream + ( + "(0 1 2 3 12 13 14 15 17 19 20 21)" + )() + ); + + list4.print(Info, true); + Info<< list4 << " indices: " << list4.used()() <<endl; + + Info<< "\nread from Istream\n"; + IStringStream("(0f 3a)")() >> list4; + + list4.print(Info, true); + Info<< list4 << " indices: " << list4.used()() <<endl; + + return 0; } diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index bc4369cf48e..30289870e38 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -67,7 +67,7 @@ containers/HashTables/HashTable/HashTableCore.C containers/HashTables/StaticHashTable/StaticHashTableCore.C containers/Lists/SortableList/ParSortableListName.C containers/Lists/PackedList/PackedListName.C -containers/Lists/PackedList/APackedBoolList.C +containers/Lists/PackedList/PackedBoolList.C containers/Lists/ListOps/ListOps.C containers/LinkedLists/linkTypes/SLListBase/SLListBase.C containers/LinkedLists/linkTypes/DLListBase/DLListBase.C diff --git a/src/OpenFOAM/containers/Lists/List/ListIO.C b/src/OpenFOAM/containers/Lists/List/ListIO.C index 984971ecc46..a70cc8f9e6b 100644 --- a/src/OpenFOAM/containers/Lists/List/ListIO.C +++ b/src/OpenFOAM/containers/Lists/List/ListIO.C @@ -135,7 +135,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L) << exit(FatalIOError); } - // Putback the openning bracket + // Putback the opening bracket is.putBack(firstToken); // Now read as a singly-linked list diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C index f393e144daa..548d21414de 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C @@ -24,9 +24,51 @@ License \*---------------------------------------------------------------------------*/ #include "PackedBoolList.H" +#include "IOstreams.H" +#include <cctype> + +// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * * // + +// table-lookup instead of printf("%02x", char) +//! @cond localScope +static const char hexLookup[] = +{ + "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f" + "505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" +}; + + +// number of bytes required to pack nElem +static inline unsigned int packedBytes(const Foam::label nElem) +{ + return (nElem + CHAR_BIT - 1) / CHAR_BIT; +} +//! @endcond + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::PackedBoolList::PackedBoolList(Istream &is) +: + PackedList<1>() +{ + is >> *this; +} + // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // @@ -232,6 +274,286 @@ Foam::PackedBoolList::operator^=(const PackedList<1>& lst) return *this; } +// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * // + +Foam::Istream& Foam::operator>> +( + Istream& istr, + PackedBoolList& lst +) +{ + // Takes into account that 'a' (or 'A') is 10 + static const label alphaOffset = toupper('A') - 10; + // Takes into account that '0' is 0 + static const label zeroOffset = int('0'); + + ISstream& is = dynamicCast<ISstream>(istr); + + lst.clear(); + is.fatalCheck("operator>>(Istream&, PackedBoolList&)"); + + token firstTok(is); + is.fatalCheck + ( + "operator>>(Istream&, PackedBoolList&) : reading first token" + ); + + if (firstTok.isLabel()) + { + const label sz = firstTok.labelToken(); + + // Set list length to that read + lst.resize(sz); + + // Read list contents as ASCII + + // Read beginning of contents + const char delimiter = is.readBeginList("PackedBoolList"); + + if (sz) + { + if (delimiter == token::BEGIN_LIST) + { + // number of bytes when packed: + unsigned int nBytes = packedBytes(lst.size()); + + for (label i=0, storeI=0; i < sz; ++storeI) + { + PackedList<1>::StorageType& stored = lst.storage()[storeI]; + + // byte-wise read + for + ( + unsigned byte=0; + byte < sizeof(PackedList<1>::StorageType); + ++byte + ) + { + PackedList<1>::StorageType result = 0; + char c = 0; + + // Get next non-whitespace character + while (is.get(c) && isspace(c)) + {} + + for (label nibble=0; nibble < 2; ++nibble) + { + if (!isxdigit(c)) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedBoolList&) : " + "reading first token", + is + ) + << "Illegal hex digit: '" << c << "'" + << exit(FatalIOError); + } + + result <<= 4; + + if (isdigit(c)) + { + result += int(c) - zeroOffset; + } + else + { + result += toupper(c) - alphaOffset; + } + + // Get character for the lower part of the byte + if (!nibble) + { + is.get(c); + } + } + + stored |= result << (byte*CHAR_BIT); + + if (!--nBytes) + { + break; + } + } + i += PackedList<1>::packing(); + } + + // trim possible trailing junk + // mask off the final partial segment + { + const unsigned int off = sz % PackedList<1>::packing(); + if (off) + { + const unsigned int seg = sz / PackedList<1>::packing(); + + lst.storage()[seg] &= PackedList<1>::maskLower(off); + } + } + + + // skip over all trailing whitespace and zeroes + char c = 0; + while (is.get(c) && (isspace(c) || c == '0')) + {} + + // put back for later readEndList() to deal with + is.putback(c); + } + else + { + const label val = readLabel(is); + + is.fatalCheck + ( + "operator>>(Istream&, PackedBoolList&) : " + "reading the single entry" + ); + + lst = val; + } + } + + // Read end of contents + is.readEndList("PackedList"); + } + else if (firstTok.isPunctuation()) + { + if (firstTok.pToken() != token::BEGIN_LIST) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedBoolList&)", + is + ) + << "incorrect first token, expected '(', found " + << firstTok.info() + << exit(FatalIOError); + } + + char c = '('; + + for (label storeI=0; c && c != ')'; ++storeI) + { + lst.resize((storeI+1)*PackedList<1>::packing()); + + PackedList<1>::StorageType& stored = lst.storage()[storeI]; + + // byte-wise read + for + ( + unsigned byte=0; + byte < sizeof(PackedList<1>::StorageType); + ++byte + ) + { + PackedList<1>::StorageType result = 0; + c = 0; + + // Get next non-whitespace character + while (is.get(c) && isspace(c)) + {} + + if (!c || c == ')') + { + break; + } + + for (label nibble=0; nibble < 2; ++nibble) + { + if (!isxdigit(c)) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedBoolList&)", + is + ) + << "Illegal hex digit: '" << c << "'" + << exit(FatalIOError); + } + + result *= 16; + + if (isdigit(c)) + { + result += int(c) - zeroOffset; + } + else + { + result += toupper(c) - alphaOffset; + } + + // Get character for the lower part of the byte + if (!nibble) + { + is.get(c); + } + } + + stored |= result << (byte*CHAR_BIT); + } + } + + // put back for later readEndList() to deal with + is.putback(c); + + // Read end of contents + is.readEndList("PackedList"); + } + else + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedBoolList&)", + is + ) + << "incorrect first token, expected <int> or '(', found " + << firstTok.info() + << exit(FatalIOError); + } + + return is; +} + + +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const PackedBoolList& lst +) +{ + const label sz = lst.size(); + + unsigned int nBytes = packedBytes(sz); + + os << sz << token::BEGIN_LIST; + + for (label storeI=0; nBytes; ++storeI) + { + PackedList<1>::StorageType stored = lst.storage()[storeI]; + + for + ( + unsigned byte=0; + byte < sizeof(PackedList<1>::StorageType); + ++byte + ) + { + os << hexLookup[((stored & 0xFF) << 1)] + << hexLookup[((stored & 0xFF) << 1) + 1]; + + if (!--nBytes) + { + break; + } + stored >>= 8; + } + } + + os << token::END_LIST; + + return os; +} + // * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H index 1d2b19ac078..cf0ba7d6a56 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H @@ -27,6 +27,31 @@ Class Description A bit-packed bool list +Note + The input/output format differs from that of Foam::PackedBoolList in + that it is also packed. The input/output is always byte-wise, with + the lowest bytes first. + + Thus this label sequence + @code + 0 1 2 3 12 13 14 15 17 19 20 21 + @endcode + which has this bit representation: + @code + ..........111-1-1111--------1111 + @endcode + and this internal representation + @code + 0x003AF00F + @endcode + would be read/written in one of these formats: + @code + 22(0f f0 3a) + 22(0ff03a) + @endcode + Whitespace can be used to separate byte values, but must not appear + within a byte itself. + SourceFiles PackedBoolListI.H PackedBoolList.C @@ -47,6 +72,16 @@ SeeAlso namespace Foam { +// Forward declaration of classes +class Istream; +class Ostream; + +// Forward declaration of friend functions and operators +class PackedBoolList; +Istream& operator>>(Istream&, PackedBoolList&); +Ostream& operator<<(Ostream&, const PackedBoolList&); + + /*---------------------------------------------------------------------------*\ Class PackedBoolList Declaration \*---------------------------------------------------------------------------*/ @@ -55,7 +90,6 @@ class PackedBoolList : public PackedList<1> { - // Private Member Functions //- Modulo is everything that is not in lst @@ -72,7 +106,6 @@ class PackedBoolList template<class LabelListType> label unsetFromIndices(const LabelListType& indices); - public: // Constructors @@ -80,6 +113,9 @@ public: //- Construct null inline PackedBoolList(); + //- Construct from Istream + PackedBoolList(Istream&); + //- Construct with given size, initializes list to 0 explicit inline PackedBoolList(const label size); @@ -217,6 +253,10 @@ public: //- Remove entries from this list inline PackedBoolList& operator-=(const UIndirectList<label>&); + // IOstream Operators + + friend Istream& operator>>(Istream&, PackedBoolList&); + friend Ostream& operator<<(Ostream&, const PackedBoolList&); }; diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H index f9a7f383e41..754590a864d 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H @@ -73,6 +73,14 @@ inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1> >& lst) {} +inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst) +: + PackedList<1>() +{ + operator=(lst); +} + + inline Foam::PackedBoolList::PackedBoolList(const UList<label>& indices) : PackedList<1>(indices.size(), 0u) diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C index b077c1c54b9..cb80e6db02b 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C @@ -24,6 +24,8 @@ License \*---------------------------------------------------------------------------*/ #include "PackedList.H" +#include "IOstreams.H" + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -40,6 +42,16 @@ Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val) } +template<unsigned nBits> +Foam::PackedList<nBits>::PackedList(Istream& is) +: + StorageList(), + size_(0) +{ + is >> *this; +} + + template<unsigned nBits> Foam::PackedList<nBits>::PackedList(const UList<label>& lst) : @@ -290,4 +302,197 @@ Foam::PackedList<nBits>::operator=(const UList<label>& lst) } +// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * // + +template<unsigned nBits> +Foam::Istream& Foam::operator>> +( + Istream& is, + PackedList<nBits>& lst +) +{ + lst.clear(); + is.fatalCheck("operator>>(Istream&, PackedList<nBits>&)"); + + token firstTok(is); + is.fatalCheck + ( + "operator>>(Istream&, PackedList<nBits>&) : reading first token" + ); + + if (firstTok.isLabel()) + { + const label sz = firstTok.labelToken(); + + // Set list length to that read + lst.setSize(sz); + + { + // Read beginning of contents + const char delimiter = is.readBeginList("List"); + + if (sz) + { + unsigned int val; + + if (delimiter == token::BEGIN_LIST) + { + for (register label i=0; i<sz; ++i) + { + is >> val; + + if (val > lst.max_value()) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedList<nBits>&)", + is + ) + << "out-of-range value: " + << val << " > " << lst.max_value() + << exit(FatalIOError); + } + + is.fatalCheck + ( + "operator>>(Istream&, PackedList<nBits>&) : " + "reading entry" + ); + } + } + else + { + is >> val; + + is.fatalCheck + ( + "operator>>(Istream&, PackedList<nBits>&) : " + "reading the single entry" + ); + + if (val > lst.max_value()) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedList<nBits>&)", + is + ) + << "out-of-range value: " + << val << " > " << lst.max_value() + << exit(FatalIOError); + } + + // assign for all entries + lst = val; + } + } + + // Read end of contents + is.readEndList("PackedList<nBits>"); + } + } + else if (firstTok.isPunctuation()) + { + if (firstTok.pToken() != token::BEGIN_LIST) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedList<nBits>&)", + is + ) + << "incorrect first token, expected '(', found " + << firstTok.info() + << exit(FatalIOError); + } + + token nextTok(is); + is.fatalCheck("operator>>(Istream&, PackedList<nBits>&)"); + + unsigned int val; + + while + ( + !(nextTok.isPunctuation() && nextTok.pToken() == token::END_LIST) + ) + { + is.putBack(nextTok); + is >> val; + lst.append(val); + + if (val > lst.max_value()) + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedList<nBits>&)", + is + ) + << "out-of-range value: " + << val << " > " << lst.max_value() + << exit(FatalIOError); + } + + is >> nextTok; + is.fatalCheck("operator>>(Istream&, PackedList<nBits>&)"); + } + } + else + { + FatalIOErrorIn + ( + "operator>>(Istream&, PackedList<nBits>&)", + is + ) + << "incorrect first token, expected <int> or '(', found " + << firstTok.info() + << exit(FatalIOError); + } + + return is; +} + + +template<unsigned nBits> +Foam::Ostream& Foam::operator<< +( + Ostream& os, + PackedList<nBits>& lst +) +{ + if (lst.size() < 11) + { + // Write size and start delimiter + os << lst.size() << token::BEGIN_LIST; + + // Write contents + forAll(lst, i) + { + if (i) + { + os << token::SPACE; + } + os << lst[i]; + } + + // Write end delimiter + os << token::END_LIST; + } + else + { + // Write size and start delimiter + os << nl << lst.size() << nl << token::BEGIN_LIST; + + // Write contents + forAll(lst, i) + { + os << nl << lst[i]; + } + + // Write end delimiter + os << nl << token::END_LIST << nl; + } + + return os; +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index 2adb939e4d3..897544eb4d3 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -96,11 +96,17 @@ SourceFiles namespace Foam { +// Forward declaration of classes +class Istream; +class Ostream; + // Forward declaration of friend functions and operators template<unsigned nBits> class PackedList; -// template<unsigned nBits> -// Ostream& operator<<(Ostream&, const PackedList<nBits>&); +template<unsigned nBits> +Istream& operator>>(Istream&, PackedList<nBits>&); +template<unsigned nBits> +Ostream& operator<<(Ostream&, const PackedList<nBits>&); /*---------------------------------------------------------------------------*\ @@ -180,6 +186,9 @@ public: //- Construct with given size and value for all elements PackedList(const label size, const unsigned val); + //- Construct from Istream + PackedList(Istream&); + //- Copy constructor inline PackedList(const PackedList<nBits>&); @@ -516,6 +525,21 @@ public: //- const_iterator set to beyond the end of the PackedList inline const_iterator end() const; + + // IOstream Operators + + friend Istream& operator>> <nBits> + ( + Istream&, + PackedList<nBits>& + ); + + friend Ostream& operator<< <nBits> + ( + Ostream&, + const PackedList<nBits>& + ); + }; diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C b/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C index 4cf39c34a7f..432ab8ac171 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C @@ -22,11 +22,12 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Description - Read of a non-delimited hex label + Read a non-delimited hex label \*---------------------------------------------------------------------------*/ #include "readHexLabel.H" +#include <cctype> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -55,7 +56,7 @@ Foam::label Foam::readHexLabel(ISstream& is) << exit(FatalIOError); } - result *= 16; + result <<= 4; if (isdigit(c)) { -- GitLab