summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-run-waveform/test_xyzzy.cc84
-rw-r--r--gr-run-waveform/xyzzy.cc48
-rw-r--r--gr-run-waveform/xyzzy.h6
3 files changed, 134 insertions, 4 deletions
diff --git a/gr-run-waveform/test_xyzzy.cc b/gr-run-waveform/test_xyzzy.cc
index efd76b6cb..85f794b31 100644
--- a/gr-run-waveform/test_xyzzy.cc
+++ b/gr-run-waveform/test_xyzzy.cc
@@ -27,12 +27,17 @@
#include <fstream>
#include <libguile.h>
#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
// Include our definitions
#include "xyzzy.h"
using namespace std;
+boost::uint8_t hex2digit(boost::uint8_t digit);
+boost::shared_array<boost::uint8_t> hex2mem(const std::string &str);
+
int
main(int argc, char *argv[])
{
@@ -44,7 +49,7 @@ main(int argc, char *argv[])
12,
hi
};
-
+
if (XYZZY::read_string(entry) == hello) {
cout << "PASSED: XYZZY::read_string(struct string_entry &)" << endl;
} else {
@@ -60,6 +65,25 @@ main(int argc, char *argv[])
// Test other methods
XYZZY xyzzy;
+ string fake_magic("-XyZzY-");
+ boost::shared_array<boost::uint8_t> fake_header_data = hex2mem(
+ "00 00 00 1c 00 00 05 e8 00 00 00 bd 00 00 06 04 00 21 ee 58");
+ boost::shared_array<boost::uint8_t> fake_header(new boost::uint8_t[28]);
+ std::copy(fake_magic.begin(), fake_magic.end(), fake_header.get());
+ std::copy(fake_header_data.get(), fake_header_data.get() + 20, fake_header.get() + 8);
+
+ boost::shared_ptr<struct header> head = xyzzy.read_header(fake_header.get());
+ if ((head->magic == fake_magic)
+ && (head->offset_to_directory == 0)
+ && (head->size_of_directory == 0)
+ && (head->number_of_dir_entries == 1835008)
+ && (head->offset_to_strings == 0)
+ && (head->size_of_strings == 1280)) {
+ cout << "PASSED: XYZZY::read_header()" << endl;
+ } else {
+ cout << "FAILED: XYZZY::read_header()" << endl;
+ }
+
if (xyzzy.init()) {
cout << "PASSED: XYZZY::init()" << endl;
} else {
@@ -79,3 +103,61 @@ main(int argc, char *argv[])
// SCM xyzzy_make_read_only_port(const std::string &filespec)
}
+
+/// \brief Convert a Hex digit into it's decimal value.
+///
+/// @param digit The digit as a hex value
+///
+/// @return The byte as a decimal value.
+boost::uint8_t
+hex2digit (boost::uint8_t digit)
+{
+ if (digit == 0)
+ return 0;
+
+ if (digit >= '0' && digit <= '9')
+ return digit - '0';
+ if (digit >= 'a' && digit <= 'f')
+ return digit - 'a' + 10;
+ if (digit >= 'A' && digit <= 'F')
+ return digit - 'A' + 10;
+
+ // shouldn't ever get this far
+ return -1;
+}
+
+/// \brief Encode a Buffer from a hex string.
+///
+/// @param str A hex string, ex... "00 03 05 0a"
+///
+/// @return A reference to a Buffer in host endian format. This is
+/// primary used only for testing to create binary data
+/// from an easy to read and edit format.
+boost::shared_array<boost::uint8_t>
+hex2mem(const std::string &str)
+{
+// GNASH_REPORT_FUNCTION;
+ size_t count = str.size();
+
+ size_t size = (count/3) + 4;
+ boost::uint8_t ch = 0;
+
+ boost::uint8_t *ptr = const_cast<boost::uint8_t *>
+ (reinterpret_cast<const boost::uint8_t *>(str.c_str()));
+ boost::uint8_t *end = ptr + count;
+
+ boost::shared_array<boost::uint8_t> data(new boost::uint8_t[count]);
+
+ for (size_t i=0; ptr<end; i++) {
+ if (*ptr == ' ') { // skip spaces.
+ ptr++;
+ continue;
+ }
+ ch = hex2digit(*ptr++) << 4;
+ ch |= hex2digit(*ptr++);
+ data[i] = ch;
+ i++;
+ }
+
+ return data;
+}
diff --git a/gr-run-waveform/xyzzy.cc b/gr-run-waveform/xyzzy.cc
index ecb692643..95dc83d2d 100644
--- a/gr-run-waveform/xyzzy.cc
+++ b/gr-run-waveform/xyzzy.cc
@@ -27,6 +27,7 @@
#include <fstream>
#include <libguile.h>
#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
// Include our definitions
#include "xyzzy.h"
@@ -49,8 +50,8 @@ XYZZY::~XYZZY()
bool
XYZZY::init()
{
- _filespec = PKGLIBDIR;
- _filespec += '/';
+ _filespec = DATAROOTDIR;
+ _filespec += "/gnuradio/gr-run-waveform/";
_filespec += "filesystem.dat";
return init(_filespec);
};
@@ -58,6 +59,18 @@ XYZZY::init()
bool
XYZZY::init(const std::string &file)
{
+ ifstream in(file.c_str(), ios_base::binary|ios_base::in);
+ if (!in) {
+ cerr << ("run_waveform: couldn't open data file: ") << file << endl;
+ return SCM_BOOL_F;
+ }
+
+ size_t length = sizeof(struct header);
+ char head[length];
+ in.read(head, length);
+
+ read_header(reinterpret_cast<boost::uint8_t *>(&head));
+
return false;
};
@@ -91,6 +104,37 @@ XYZZY::read_string(struct string_entry & entry)
return read_string(entry.base, entry.length);
}
+boost::shared_ptr<struct header>
+XYZZY::read_header(boost::uint8_t *header)
+{
+ boost::shared_ptr<struct header> newhead(new struct header);
+
+ struct header *ptr = reinterpret_cast<struct header *>(header);
+
+ std::copy(header, header + 8, newhead->magic);
+
+ newhead->offset_to_directory = __builtin_bswap32(ptr->offset_to_directory);
+ newhead->size_of_directory = __builtin_bswap32(ptr->size_of_directory);
+ newhead->number_of_dir_entries = __builtin_bswap32(ptr->number_of_dir_entries);
+ newhead->offset_to_strings = __builtin_bswap32(ptr->offset_to_strings);
+ newhead->size_of_strings = __builtin_bswap32(ptr->size_of_strings);
+
+ return newhead;
+}
+
+boost::shared_ptr<struct directory_entry>
+XYZZY::read_dir_entry(boost::uint8_t *entry)
+{
+ boost::shared_ptr<struct directory_entry> newdir(new struct directory_entry);
+ struct directory_entry *ptr = reinterpret_cast<struct directory_entry *>(entry);
+
+ newdir->offset_to_name = __builtin_bswap32(ptr->offset_to_name);
+ newdir->offset_to_name = __builtin_bswap32(ptr->offset_to_name);
+
+return newdir;
+}
+
+// C linkage for guile
extern "C" {
static XYZZY datafile;
diff --git a/gr-run-waveform/xyzzy.h b/gr-run-waveform/xyzzy.h
index effb348d2..d56e48763 100644
--- a/gr-run-waveform/xyzzy.h
+++ b/gr-run-waveform/xyzzy.h
@@ -30,6 +30,7 @@
#include <iostream>
#include <fstream>
#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
#include <libguile.h>
@@ -89,10 +90,13 @@ public:
/// Parse a string data structure
static std::string read_string(boost::uint8_t *entry, size_t length);
static std::string read_string(struct string_entry &entry);
+
+ boost::shared_ptr<struct header> read_header(boost::uint8_t *header);
+
+ boost::shared_ptr<struct directory_entry> read_dir_entry(boost::uint8_t *header);
private:
std::string _filespec;
- struct header _header;
std::map<std::string, directory_entry> _directories;
};