[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r4839 - gnuradio/branches/developers/eb/ibu/pmt/src/li
From: |
eb |
Subject: |
[Commit-gnuradio] r4839 - gnuradio/branches/developers/eb/ibu/pmt/src/lib |
Date: |
Sun, 1 Apr 2007 15:05:45 -0600 (MDT) |
Author: eb
Date: 2007-04-01 15:05:44 -0600 (Sun, 01 Apr 2007)
New Revision: 4839
Modified:
gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serial_tags.dat
gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serialize.cc
gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.cc
gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.h
Log:
useful subset of serialize/deserialize is working
Modified: gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serial_tags.dat
===================================================================
--- gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serial_tags.dat
2007-04-01 20:51:52 UTC (rev 4838)
+++ gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serial_tags.dat
2007-04-01 21:05:44 UTC (rev 4839)
@@ -21,18 +21,18 @@
;;; definitions of tag values used for marshalling pmt data
-(pst-true #x00)
-(pst-false #x01)
-(pst-symbol #x02) ; untagged-int16 n; followed by n bytes of symbol
name
-(pst-int32 #x03)
-(pst-double #x04)
-(pst-complex #x05) ; complex<double>: real, imag
-(pst-null #x06)
-(pst-pair #x07) ; followed by two objects
-(pst-vector #x08) ; untagged-int32 n; followed by n objects
-(pst-dict #x09) ; untagged-int32 n; followed by n key/value tuples
+(pst-true #x00)
+(pst-false #x01)
+(pst-symbol #x02) ; untagged-int16 n; followed by n bytes of
symbol name
+(pst-int32 #x03)
+(pst-double #x04)
+(pst-complex #x05) ; complex<double>: real, imag
+(pst-null #x06)
+(pst-pair #x07) ; followed by two objects
+(pst-vector #x08) ; untagged-int32 n; followed by n objects
+(pst-dict #x09) ; untagged-int32 n; followed by n key/value
tuples
-(pst-uniform-vector #x0a)
+(pst-uniform-vector #x0a)
;; u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c32, c64
;;
@@ -41,7 +41,7 @@
;; untagged-int32 n-items
;; untagged-uint8 npad
;; npad bytes of zeros to align binary data
-;; followed by n-items binary numeric items
+;; n-items binary numeric items
;;
;; uvi:
;; +-+-+-+-+-+-+-+-+
@@ -70,3 +70,7 @@
(uvi-c32 #x0a)
(uvi-c64 #x0b)
+
+(pst-comment #x3b) ; ascii ';'
+(pst-comment-end #x0a) ; ascii '\n'
+
Modified: gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serialize.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serialize.cc
2007-04-01 20:51:52 UTC (rev 4838)
+++ gnuradio/branches/developers/eb/ibu/pmt/src/lib/pmt_serialize.cc
2007-04-01 21:05:44 UTC (rev 4839)
@@ -27,6 +27,8 @@
#include "pmt_int.h"
#include "pmt_serial_tags.h"
+static pmt_t parse_pair(std::streambuf &sb);
+
// ----------------------------------------------------------------
// output primitives
// ----------------------------------------------------------------
@@ -157,19 +159,22 @@
/*
* Write portable byte-serial representation of \p obj to \p sb
+ *
+ * N.B., Circular structures cause infinite recursion.
*/
bool
pmt_serialize(pmt_t obj, std::streambuf &sb)
{
bool ok = true;
- // tail_recursion:
+ tail_recursion:
- if (pmt_eq(obj, PMT_BOOL_T))
- return serialize_untagged_u8(PST_TRUE, sb);
-
- if (pmt_eq(obj, PMT_BOOL_F))
- return serialize_untagged_u8(PST_FALSE, sb);
+ if (pmt_is_bool(obj)){
+ if (pmt_eq(obj, PMT_BOOL_T))
+ return serialize_untagged_u8(PST_TRUE, sb);
+ else
+ return serialize_untagged_u8(PST_FALSE, sb);
+ }
if (pmt_is_null(obj))
return serialize_untagged_u8(PST_NULL, sb);
@@ -184,32 +189,161 @@
return ok;
}
+ if (pmt_is_pair(obj)){
+ ok = serialize_untagged_u8(PST_PAIR, sb);
+ ok &= pmt_serialize(pmt_car(obj), sb);
+ if (!ok)
+ return false;
+ obj = pmt_cdr(obj);
+ goto tail_recursion;
+ }
+
if (pmt_is_number(obj)){
if (pmt_is_integer(obj)){
- int i = (int) pmt_to_long(obj); // FIXME: trouble on values bigger than
32-bits
+ long i = pmt_to_long(obj);
+ if (sizeof(long) > 4){
+ if (i < -2147483648 || i > 2147483647)
+ throw pmt_notimplemented("pmt_serialize (64-bit integers)", obj);
+ }
ok = serialize_untagged_u8(PST_INT32, sb);
ok &= serialize_untagged_u32(i, sb);
return ok;
}
if (pmt_is_real(obj))
- throw pmt_notimplemented("pmt_serialize for real", obj);
+ throw pmt_notimplemented("pmt_serialize (real)", obj);
if (pmt_is_complex(obj))
- throw pmt_notimplemented("pmt_serialize for complex", obj);
-
+ throw pmt_notimplemented("pmt_serialize (complex)", obj);
}
- throw pmt_notimplemented("pmt_serialize for ???", obj);
+ if (pmt_is_vector(obj))
+ throw pmt_notimplemented("pmt_serialize (vector)", obj);
+
+ if (pmt_is_uniform_vector(obj))
+ throw pmt_notimplemented("pmt_serialize (uniform-vector)", obj);
+
+ if (pmt_is_dict(obj))
+ throw pmt_notimplemented("pmt_serialize (dict)", obj);
+
+
+ throw pmt_notimplemented("pmt_serialize (?)", obj);
}
-
/*
* Create obj from portable byte-serial representation
+ *
+ * Returns next obj from streambuf, or PMT_EOF at end of file.
+ * Throws exception on malformed input.
*/
pmt_t
pmt_deserialize(std::streambuf &sb)
{
- return PMT_EOF;
+ uint8_t tag;
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint32_t u64;
+ static char tmpbuf[1024];
+
+ if (!deserialize_untagged_u8(&tag, sb))
+ return PMT_EOF;
+
+ switch (tag){
+ case PST_TRUE:
+ return PMT_BOOL_T;
+
+ case PST_FALSE:
+ return PMT_BOOL_F;
+
+ case PST_NULL:
+ return PMT_NIL;
+
+ case PST_SYMBOL:
+ if (!deserialize_untagged_u16(&u16, sb))
+ goto error;
+ if (u16 > sizeof(tmpbuf))
+ throw pmt_notimplemented("pmt_deserialize: very long symbol",
+ PMT_BOOL_F);
+ if (sb.sgetn(tmpbuf, u16) != u16)
+ goto error;
+ return pmt_intern(std::string(tmpbuf, u16));
+
+ case PST_INT32:
+ if (!deserialize_untagged_u32(&u32, sb))
+ goto error;
+ return pmt_from_long((int32_t) u32);
+
+ case PST_PAIR:
+ return parse_pair(sb);
+
+ case PST_DOUBLE:
+ case PST_COMPLEX:
+ case PST_VECTOR:
+ case PST_DICT:
+ case PST_UNIFORM_VECTOR:
+ case PST_COMMENT:
+ throw pmt_notimplemented("pmt_deserialize: tag value = ",
+ pmt_from_long(tag));
+
+ default:
+ throw pmt_exception("pmt_deserialize: malformed input stream, tag value =
",
+ pmt_from_long(tag));
+ }
+
+ error:
+ throw pmt_exception("pmt_deserialize: malformed input stream", PMT_BOOL_F);
}
+
+/*
+ * This is a mostly non-recursive implementation that allows us to
+ * deserialize very long lists w/o exhausting the evaluation stack.
+ *
+ * On entry we've already eaten the PST_PAIR tag.
+ */
+pmt_t
+parse_pair(std::streambuf &sb)
+{
+ uint8_t tag;
+ pmt_t val, expr, lastnptr, nptr;
+
+ //
+ // Keep appending nodes until we get a non-PAIR cdr.
+ //
+ lastnptr = PMT_NIL;
+ while (1){
+ expr = pmt_deserialize(sb); // read the car
+
+ nptr = pmt_cons(expr, PMT_NIL); // build new cell
+ if (pmt_is_null(lastnptr))
+ val = nptr;
+ else
+ pmt_set_cdr(lastnptr, nptr);
+ lastnptr = nptr;
+
+ if (!deserialize_untagged_u8(&tag, sb)) // get tag of cdr
+ throw pmt_exception("pmt_deserialize: malformed input stream",
PMT_BOOL_F);
+
+ if (tag == PST_PAIR)
+ continue; // keep on looping...
+
+ if (tag == PST_NULL){
+ expr = PMT_NIL;
+ break;
+ }
+
+ //
+ // default: push tag back and use pmt_deserialize to get the cdr
+ //
+ sb.sungetc();
+ expr = pmt_deserialize(sb);
+ break;
+ }
+
+ //
+ // At this point, expr contains the value of the final cdr in the list.
+ //
+ pmt_set_cdr(lastnptr, expr);
+ return val;
+}
Modified: gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.cc
===================================================================
--- gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.cc
2007-04-01 20:51:52 UTC (rev 4838)
+++ gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.cc
2007-04-01 21:05:44 UTC (rev 4839)
@@ -24,6 +24,7 @@
#include <cppunit/TestAssert.h>
#include <pmt.h>
#include <stdio.h>
+#include <sstream>
void
qa_pmt_prims::test_symbols()
@@ -293,3 +294,51 @@
CPPUNIT_ASSERT_EQUAL(std::string("k0"), pmt_write_string(k0));
}
+
+void
+qa_pmt_prims::test_serialize()
+{
+ std::stringbuf sb; // fake channel
+ pmt_t a = pmt_intern("a");
+ pmt_t b = pmt_intern("b");
+ pmt_t c = pmt_intern("c");
+
+ sb.str(""); // reset channel to empty
+
+ // write stuff to channel
+
+ pmt_serialize(PMT_NIL, sb);
+ pmt_serialize(pmt_intern("foobarvia"), sb);
+ pmt_serialize(pmt_from_long(123456789), sb);
+ pmt_serialize(pmt_from_long(-123456789), sb);
+ pmt_serialize(pmt_cons(PMT_NIL, PMT_NIL), sb);
+ pmt_serialize(pmt_cons(a, b), sb);
+ pmt_serialize(pmt_list1(a), sb);
+ pmt_serialize(pmt_list2(a, b), sb);
+ pmt_serialize(pmt_list3(a, b, c), sb);
+ pmt_serialize(pmt_list3(a, pmt_list3(c, b, a), c), sb);
+ pmt_serialize(PMT_BOOL_T, sb);
+ pmt_serialize(PMT_BOOL_F, sb);
+
+ // read it back
+
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_NIL));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_intern("foobarvia")));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(123456789)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(-123456789)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(PMT_NIL, PMT_NIL)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(a, b)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list1(a)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list2(a, b)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list3(a, b, c)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list3(a, pmt_list3(c, b,
a), c)));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_BOOL_T));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_BOOL_F));
+
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_EOF)); // last item
+
+
+ // FIXME add tests for real, complex, vector, uniform-vector, dict
+ // FIXME add tests for malformed input too.
+
+}
Modified: gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.h
===================================================================
--- gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.h
2007-04-01 20:51:52 UTC (rev 4838)
+++ gnuradio/branches/developers/eb/ibu/pmt/src/lib/qa_pmt_prims.h
2007-04-01 21:05:44 UTC (rev 4839)
@@ -39,6 +39,7 @@
CPPUNIT_TEST(test_misc);
CPPUNIT_TEST(test_dict);
CPPUNIT_TEST(test_io);
+ CPPUNIT_TEST(test_serialize);
CPPUNIT_TEST_SUITE_END();
private:
@@ -53,6 +54,7 @@
void test_misc();
void test_dict();
void test_io();
+ void test_serialize();
};
#endif /* INCLUDED_QA_PMT_PRIMS_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r4839 - gnuradio/branches/developers/eb/ibu/pmt/src/lib,
eb <=