diff --git a/LCS/Blob/include/Blob/BlobSTL.h b/LCS/Blob/include/Blob/BlobSTL.h new file mode 100644 index 0000000000000000000000000000000000000000..b49a9b001733e9a68bad278210a9473c881c460a --- /dev/null +++ b/LCS/Blob/include/Blob/BlobSTL.h @@ -0,0 +1,137 @@ +//# BlobSTL.h: Blob handling for STL sequences +//# +//# Copyright (C) 2007 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program 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 2 of the License, or +//# (at your option) any later version. +//# +//# This program 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 this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef LOFAR_BLOB_BLOBSTL_H +#define LOFAR_BLOB_BLOBSTL_H + +// \file +// Blob handling for STL sequences + +#include <Blob/BlobOStream.h> +#include <Blob/BlobIStream.h> +#include <map> +#include <list> +#include <set> +#include <queue> +#include <deque> + +namespace LOFAR +{ + +// \ingroup %pkgname% + + // Define functions to write a map into a blob and to read it back. + // The map is preceeded by the header 'map<T,U>', where T and U are + // the type names as defined in TypeNames.h. + // Type names are only defined for the basic types. Other types + // are set to 'unknown'. + // <group> + // \name Write a map. + template<typename T, typename U> + BlobOStream& operator<< (BlobOStream&, const std::map<T,U>&); + + // \name Read back a map. + template<typename T, typename U> + BlobIStream& operator>> (BlobIStream&, std::map<T,U>&); + // </group> + + + // Define helper functions to write any STL sequence into a blob and to + // read it back. + // The sequence is preceeded by the header 'array<T>', where T is + // the type name of Seq::value_type as defined in TypeNames.h. + // Type names are only defined for the basic types. Other types + // are set to 'unknown'. + // All sequences are written in the same way (as 1-dim arrays). It means + // that they can be read back using any other sequence type. + // <group> + // \name Write a sequence. + template<typename Seq> + void sequenceToBlob (BlobOStream&, const Seq&); + + // \name Read back a sequence. + template<typename Seq> + void sequenceFromBlob (BlobOStream&, const Seq&); + // </group> + + + // Define helper functions to write an STL sequence into a blob and to + // read it back. + // The sequence is preceeded by the header 'array<T>', where T is + // the type name of T as defined in TypeNames.h. + // Type names are only defined for the basic types. Other types + // are set to 'unknown'. + // All sequences are written in the same way (as 1-dim arrays). It means + // that they can be read back in any other sequence type (including + // AIPS++ and Blitz arrays). + // <note> STL vectors are handled by BlobArray.h. </note> + // <group> + // \name Write a list. + template<typename T> + BlobOStream& operator<< (BlobOStream& bs, const std::list<T>& seq) + { sequenceToBlob (bs, seq); return bs; } + + // \name Read back a list. + template<typename T> + BlobIStream& operator>> (BlobIStream& bs, std::list<T>& seq) + { sequenceFromBlob (bs, seq); return bs; } + + // \name Write a set. + template<typename T> + BlobOStream& operator<< (BlobOStream& bs, const std::set<T>& seq) + { sequenceToBlob (bs, seq); return bs; } + + // \name Read back a set. + template<typename T> + BlobIStream& operator>> (BlobIStream& bs, std::set<T>& seq) + { sequenceFromBlob (bs, seq); return bs; } + + // \name Write a queue. + template<typename T> + BlobOStream& operator<< (BlobOStream& bs, const std::queue<T>& seq) + { sequenceToBlob (bs, seq); return bs; } + + // \name Read back a queue. + template<typename T> + BlobIStream& operator>> (BlobIStream& bs, std::queue<T>& seq) + { sequenceFromBlob (bs, seq); return bs; } + + // \name Write a deque. + template<typename T> + BlobOStream& operator<< (BlobOStream& bs, const std::deque<T>& seq) + { sequenceToBlob (bs, seq); return bs; } + + // \name Read back a deque. + template<typename T> + BlobIStream& operator>> (BlobIStream& bs, std::deque<T>& seq) + { sequenceFromBlob (bs, seq); return bs; } + // </group> + +} // end namespace LOFAR + + +#include <Blob/BlobSTL.tcc> + +using LOFAR::operator<<; +using LOFAR::operator>>; + +#endif diff --git a/LCS/Blob/include/Blob/BlobSTL.tcc b/LCS/Blob/include/Blob/BlobSTL.tcc new file mode 100644 index 0000000000000000000000000000000000000000..6092e868bf884318d8cee3f86738022b5f8ba3c2 --- /dev/null +++ b/LCS/Blob/include/Blob/BlobSTL.tcc @@ -0,0 +1,99 @@ +//# BlobSTL.tcc: Blob handling for STLs +//# +//# Copyright (C) 2007 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program 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 2 of the License, or +//# (at your option) any later version. +//# +//# This program 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 this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef LOFAR_BLOB_BLOBSTL_TCC +#define LOFAR_BLOB_BLOBSTL_TCC + +#include <Blob/BlobSTL.h> +#include <Blob/BlobArray.h> +#include <Common/TypeNames.h> + +namespace LOFAR +{ + template<typename T, typename U> + BlobOStream& operator<< (BlobOStream& bs, const std::map<T,U>& m) + { + bs.putStart ("map<" + typeName((T*)0) + ',' + typeName((U*)0) + '>', 1); + bs << static_cast<uint32>(m.size()); + for (typename std::map<T,U>::const_iterator it=m.begin(); + it!=m.end(); + ++it) { + bs << it->first << it->second; + } + bs.putEnd(); + return bs; + } + + template<typename T, typename U> + BlobIStream& operator>> (BlobIStream& bs, std::map<T,U>& m) + { + bs.getStart ("map<" + typeName((T*)0) + ',' + typeName((U*)0) + '>'); + m.clear(); + uint32 size; + bs >> size; + T t; + U u; + for (uint32 i=0; i<size; ++i) { + bs >> t >> u; + m[t] = u; + } + bs.getEnd(); + return bs; + } + + template<typename Seq> + void sequenceToBlob (BlobOStream& bs, const Seq& s) + { + uint32 n = s.size(); + putBlobArrayHeader (bs, true, + LOFAR::typeName((const typename Seq::value_type**)0), + &n, 1, true, 1); + for (typename Seq::const_iterator it=s.begin(); + it!=s.end(); + ++it) { + bs << *it; + } + bs.putEnd(); + } + + template<typename Seq> + void sequenceFromBlob (BlobIStream& bs, Seq& s) + { + bs.getStart (LOFAR::typeName((const typename Seq::value_type**)0)); + bool fortranOrder; + uint16 ndim; + uint nalign = getBlobArrayStart (bs, fortranOrder, ndim); + ASSERT(ndim == 1); + uint32 size; + getBlobArrayShape (bs, &size, 1, false, nalign); + typename Seq::value_type t; + s.clear(); + for (uint32 i=0; i<size; ++i) { + bs >> t; + s.push_back (t); + } + bs.getEnd(); + } + +} // end namespace LOFAR + +#endif diff --git a/LCS/Blob/include/Blob/Makefile.am b/LCS/Blob/include/Blob/Makefile.am index 22920ce1cc5c4d234261632f79b1716f37084b08..0da6631f2e7e1378f9bbedccc0567121f54f9378 100644 --- a/LCS/Blob/include/Blob/Makefile.am +++ b/LCS/Blob/include/Blob/Makefile.am @@ -21,6 +21,8 @@ pkginclude_HEADERS = \ BlobOBufString.h \ BlobOBufVector.h \ BlobOStream.h \ + BlobSTL.h \ + BlobSTL.tcc \ BlobStreamable.h \ BlobString.h \ BlobStringTraits.h \ diff --git a/LCS/Blob/test/Makefile.am b/LCS/Blob/test/Makefile.am index 03c473e25b8b7d8221a239be4e090795a2176eae..499e8e73a9de450d153f2b5b2b23785e56cc9fb2 100644 --- a/LCS/Blob/test/Makefile.am +++ b/LCS/Blob/test/Makefile.am @@ -1,16 +1,16 @@ -check_PROGRAMS = tBlobString tBlobStream tBlobArray tBlobField \ - tBlobAipsIO tKeyValueMap +check_PROGRAMS = tBlobString tBlobStream tBlobArray tBlobSTL \ + tBlobField tBlobAipsIO tKeyValueMap # programs to run through supplied checktools -CHECKTOOLPROGS = tBlobString tBlobStream tBlobArray tBlobField \ - tBlobAipsIO tKeyValueMap -#ENDCHECKTOOLPROGS +CHECKTOOLPROGS = tBlobString tBlobStream tBlobArray tBlobSTL + tBlobField tBlobAipsIO tKeyValueMap TESTSCRIPTS = \ + tBlobString_test.sh \ + tBlobStream_test.sh \ tBlobArray_test.sh \ + tBlobSTL_test.sh \ tBlobField_test.sh \ - tBlobStream_test.sh \ - tBlobString_test.sh \ tBlobAipsIO_test.sh \ tKeyValueMap_test.sh @@ -33,6 +33,10 @@ tBlobArray_SOURCES = tBlobArray.cc tBlobArray_LDADD = ../src/libblob.la tBlobArray_DEPENDENCIES = ../src/libblob.la $(LOFAR_DEPEND) +tBlobSTL_SOURCES = tBlobSTL.cc +tBlobSTL_LDADD = ../src/libblob.la +tBlobSTL_DEPENDENCIES = ../src/libblob.la $(LOFAR_DEPEND) + tBlobField_SOURCES = tBlobField.cc tBlobField_LDADD = ../src/libblob.la tBlobField_DEPENDENCIES = ../src/libblob.la $(LOFAR_DEPEND) diff --git a/LCS/Blob/test/tBlobSTL.cc b/LCS/Blob/test/tBlobSTL.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c8b0b48f4e5ee4c99dd7c8966ab99472aa05149 --- /dev/null +++ b/LCS/Blob/test/tBlobSTL.cc @@ -0,0 +1,140 @@ +//# tBlobSTL.cc: Test program for BlobSTL functions +//# +//# Copyright (C) 2007 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program 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 2 of the License, or +//# (at your option) any later version. +//# +//# This program 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 this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +//# Always #include <lofar_config.h> first! +#include <lofar_config.h> + +#include <Blob/BlobSTL.h> +#include <Blob/BlobArray.h> +#include <Blob/BlobOBufStream.h> +#include <Blob/BlobIBufStream.h> +#include <Blob/BlobOBufString.h> +#include <Blob/BlobIBufString.h> +#include <Blob/BlobOBufNull.h> +#include <iostream> +#include <fstream> + +using namespace LOFAR; + +void doOut (BlobOBuffer& bb) +{ + BlobOStream bs(bb); + bs.putStart ("test", 1); + // Write a vector and set into the blob. + std::vector<double> seq1(3); + seq1[0] = double(2); + seq1[1] = double(1e10); + seq1[2] = double(-3.1); + bs << seq1; + std::list<std::string> seq2; + seq2.push_back ("s1"); + seq2.push_back ("st2"); + bs << seq2; + // Write maps. + std::map<std::string, std::list<std::string> > m; + m["k1"] = seq2; + seq2.push_back ("str3"); + m["k2"] = seq2; + bs << m; + std::map<int, std::vector<int> > m2; + bs << m2; // also test empty map + bs.putEnd(); +} + +void doIn (BlobIBuffer& bb) +{ + BlobIStream bs(bb); + bs.getStart ("test"); + // Read the vector from the blob as a deque and check if it is correct. + std::deque<double> seq1; + seq1.push_back (1); // should be cleared by operator>> + bs >> seq1; + ASSERT (seq1.size() == 3); + ASSERT (seq1[0] == double(2)); + ASSERT (seq1[1] == double(1e10)); + ASSERT (seq1[2] == double(-3.1)); + // Read the list as a vector. + std::vector<std::string> seq2; + seq2.push_back (""); // should be cleared by operator>> + bs >> seq2; + ASSERT (seq2.size() == 2); + ASSERT (seq2[0] == "s1"); + ASSERT (seq2[1] == "st2"); + // Read the first map. + std::map<std::string, std::vector<std::string> > m; + bs >> m; + std::map<std::string, std::vector<std::string> >::const_iterator it; + it = m.find("k1"); + ASSERT (it != m.end()); + ASSERT (it->second.size() == 2); + ASSERT (it->second[0] == "s1"); + ASSERT (it->second[1] == "st2"); + it = m.find("k2"); + ASSERT (it != m.end()); + ASSERT (it->second.size() == 3); + ASSERT (it->second[0] == "s1"); + ASSERT (it->second[1] == "st2"); + ASSERT (it->second[2] == "str3"); + it = m.find("k3"); + ASSERT (it == m.end()); + // Read the second map. + std::map<int, std::list<int> > m2; + m2[1] = std::list<int>(); // should be cleared by operator>> + bs >> m2; + ASSERT (m2.empty()); + bs.getEnd(); +} + +int main() +{ + try { + INIT_LOGGER("tBlobSTL"); + { + { + // Create the blob in a file. + std::ofstream os ("tBlobArray_tmp.dat"); + BlobOBufStream bob(os); + doOut (bob); + } + { + // Read it back from the file. + std::ifstream is ("tBlobArray_tmp.dat"); + BlobIBufStream bib(is); + doIn (bib); + } + } + { + // Create the blob in memory. + BlobString str(BlobStringType(false)); + BlobOBufString bob(str); + doOut (bob); + BlobIBufString bib(str); + doIn (bib); + } + } catch (std::exception& x) { + std::cout << "Unexpected exception: " << x.what() << std::endl; + return 1; + } + std::cout << "OK" << std::endl; + return 0; +} + diff --git a/LCS/Blob/test/tBlobSTL_test.sh b/LCS/Blob/test/tBlobSTL_test.sh new file mode 100755 index 0000000000000000000000000000000000000000..593a23bd311a169b1e805c4c3960b55766f5bda4 --- /dev/null +++ b/LCS/Blob/test/tBlobSTL_test.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$lofar_sharedir/runtest.sh tBlobSTL 2>&1 > tBlobSTL_test.log