summaryrefslogtreecommitdiff
path: root/gruel/src/lib/pmt
diff options
context:
space:
mode:
Diffstat (limited to 'gruel/src/lib/pmt')
-rw-r--r--gruel/src/lib/pmt/Makefile.am10
-rw-r--r--gruel/src/lib/pmt/pmt_io.cc10
-rw-r--r--gruel/src/lib/pmt/pmt_serialize.cc107
3 files changed, 117 insertions, 10 deletions
diff --git a/gruel/src/lib/pmt/Makefile.am b/gruel/src/lib/pmt/Makefile.am
index d3efc1afa..0c8e12dc3 100644
--- a/gruel/src/lib/pmt/Makefile.am
+++ b/gruel/src/lib/pmt/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2008,2009,2010 Free Software Foundation, Inc.
+# Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -48,7 +48,7 @@ python_built_sources = $(GENERATED_H) $(GENERATED_CC)
PMT_SERIAL_TAGS_H = $(abs_top_builddir)/gruel/src/include/gruel/pmt_serial_tags.h
BUILT_SOURCES = $(python_built_sources) $(PMT_SERIAL_TAGS_H)
-EXTRA_DIST = $(code_generator)
+EXTRA_DIST += $(code_generator)
# ----------------------------------------------------------------
@@ -99,7 +99,7 @@ gen_sources_deps = $(core_generator)
par_gen_command = PYTHONPATH=$(top_srcdir)/gruel/src/lib/pmt srcdir=$(srcdir) $(PYTHON) $(srcdir)/generate_unv.py
include $(top_srcdir)/Makefile.par.gen
-# Rule to create the build header file using GUILE
+# Rule to create the build header file using python
# Doesn't need parallel protections because there is a single target
-$(PMT_SERIAL_TAGS_H): $(srcdir)/../../scheme/gnuradio/gen-serial-tags.scm $(srcdir)/../../scheme/gnuradio/pmt-serial-tags.scm
- $(RUN_GUILE) $(srcdir)/../../scheme/gnuradio/gen-serial-tags.scm $(srcdir)/../../scheme/gnuradio/pmt-serial-tags.scm $(PMT_SERIAL_TAGS_H)
+$(PMT_SERIAL_TAGS_H): $(top_srcdir)/gruel/src/scheme/gnuradio/gen-serial-tags.py $(top_srcdir)/gruel/src/scheme/gnuradio/pmt-serial-tags.scm
+ $(PYTHON) $^ $@
diff --git a/gruel/src/lib/pmt/pmt_io.cc b/gruel/src/lib/pmt/pmt_io.cc
index b909c1b64..1214ff588 100644
--- a/gruel/src/lib/pmt/pmt_io.cc
+++ b/gruel/src/lib/pmt/pmt_io.cc
@@ -26,6 +26,7 @@
#include <gruel/pmt.h>
#include "pmt_int.h"
#include <sstream>
+#include <iostream>
namespace pmt {
@@ -156,3 +157,12 @@ pmt_deserialize(std::istream &source)
}
} /* namespace pmt */
+
+
+void
+pmt::pmt_print(pmt_t v)
+{
+ std::cout << pmt_write_string(v) << std::endl;
+}
+
+
diff --git a/gruel/src/lib/pmt/pmt_serialize.cc b/gruel/src/lib/pmt/pmt_serialize.cc
index 937423a93..184a31e6b 100644
--- a/gruel/src/lib/pmt/pmt_serialize.cc
+++ b/gruel/src/lib/pmt/pmt_serialize.cc
@@ -59,6 +59,26 @@ serialize_untagged_u32(unsigned int i, std::streambuf &sb)
return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
}
+static bool
+serialize_untagged_f64(double i, std::streambuf &sb)
+{
+ typedef union {
+ double id;
+ uint64_t ii;
+ } iu_t;
+ iu_t iu;
+ iu.id = i;
+ sb.sputc((iu.ii >> 56) & 0xff);
+ sb.sputc((iu.ii >> 48) & 0xff);
+ sb.sputc((iu.ii >> 40) & 0xff);
+ sb.sputc((iu.ii >> 32) & 0xff);
+ sb.sputc((iu.ii >> 24) & 0xff);
+ sb.sputc((iu.ii >> 16) & 0xff);
+ sb.sputc((iu.ii >> 8) & 0xff);
+ return sb.sputc((iu.ii >> 0) & 0xff) != std::streambuf::traits_type::eof();
+}
+
+
#if 0
// always writes big-endian
static bool
@@ -163,6 +183,41 @@ deserialize_untagged_u64(uint64_t *ip, std::streambuf &sb)
}
#endif
+static bool
+deserialize_untagged_f64(double *ip, std::streambuf &sb)
+{
+ std::streambuf::traits_type::int_type t;
+
+ typedef union {
+ double id;
+ uint64_t ii;
+ } iu_t;
+
+ iu_t iu;
+
+ t = sb.sbumpc();
+ iu.ii = t & 0xff;
+
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+
+ *ip = iu.id;
+ return t != std::streambuf::traits_type::eof();
+}
+
+
/*
* Write portable byte-serial representation of \p obj to \p sb
*
@@ -172,7 +227,7 @@ bool
pmt_serialize(pmt_t obj, std::streambuf &sb)
{
bool ok = true;
-
+
tail_recursion:
if (pmt_is_bool(obj)){
@@ -217,11 +272,21 @@ pmt_serialize(pmt_t obj, std::streambuf &sb)
return ok;
}
- if (pmt_is_real(obj))
- throw pmt_notimplemented("pmt_serialize (real)", obj);
+ if (pmt_is_real(obj)){
+ float i = pmt_to_double(obj);
+ ok = serialize_untagged_u8(PST_DOUBLE, sb);
+ ok &= serialize_untagged_f64(i, sb);
+ return ok;
+ }
+
+ if (pmt_is_complex(obj)){
+ std::complex<double> i = pmt_to_complex(obj);
+ ok = serialize_untagged_u8(PST_COMPLEX, sb);
+ ok &= serialize_untagged_f64(i.real(), sb);
+ ok &= serialize_untagged_f64(i.imag(), sb);
+ return ok;
+ }
- if (pmt_is_complex(obj))
- throw pmt_notimplemented("pmt_serialize (complex)", obj);
}
if (pmt_is_vector(obj))
@@ -251,6 +316,7 @@ pmt_deserialize(std::streambuf &sb)
uint16_t u16;
uint32_t u32;
//uint32_t u64;
+ double f64;
static char tmpbuf[1024];
if (!deserialize_untagged_u8(&tag, sb))
@@ -285,7 +351,18 @@ pmt_deserialize(std::streambuf &sb)
return parse_pair(sb);
case PST_DOUBLE:
+ if(!deserialize_untagged_f64(&f64, sb))
+ goto error;
+ return pmt_from_double( f64 );
+
case PST_COMPLEX:
+ {
+ double r,i;
+ if(!deserialize_untagged_f64(&r, sb) && !deserialize_untagged_f64(&i, sb))
+ goto error;
+ return pmt_make_rectangular( r,i );
+ }
+
case PST_VECTOR:
case PST_DICT:
case PST_UNIFORM_VECTOR:
@@ -302,6 +379,26 @@ pmt_deserialize(std::streambuf &sb)
throw pmt_exception("pmt_deserialize: malformed input stream", PMT_F);
}
+
+/*
+ * provide a simple string accessor to the serialized pmt form
+ */
+std::string pmt_serialize_str(pmt_t obj){
+ std::stringbuf sb;
+ pmt_serialize(obj, sb);
+ return sb.str();
+}
+
+
+/*
+ * provide a simple string accessor to the deserialized pmt form
+ */
+pmt_t pmt_deserialize_str(std::string s){
+ std::stringbuf sb(s);
+ return pmt_deserialize(sb);
+}
+
+
/*
* This is a mostly non-recursive implementation that allows us to
* deserialize very long lists w/o exhausting the evaluation stack.