1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/* -*- c++ -*- */
/*
* Copyright 2004 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio 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 3, or (at your option)
* any later version.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef _XYZZY_H_
#define _XYZZY_H_ 1
#include <libguile.h>
#ifdef __cplusplus
#include <cstdio>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
using namespace std;
// - Special case filenames that start with /-xyzzy-/... and search for
// and load them using the single file. We'd stick "/-zyzzy-" first
// in the default load-path.
// - Create a C read-only "port" that "reads" from the string in the file.
// (See guile docs on creating new kinds of ports)
// - Override the default implementation of "primitive-load" and "%search-load-path"
// to make that happen. See load.c in the guile source code. Figure
// out how to get the override done before guile is fully
// initialized. (Guile loads ice-9/boot9.scm to start itself up. We'd
// need to redirect before then.)
struct header {
char magic[8];
boost::uint32_t offset_to_directory; // byte offset from start of file
boost::uint32_t size_of_directory; // bytes
boost::uint32_t number_of_dir_entries;
boost::uint32_t offset_to_strings; // byte offset from start of file
boost::uint32_t size_of_strings; // bytes
};
struct directory_entry {
boost::uint32_t offset_to_name; // from start of strings
boost::uint32_t offset_to_contents; // from start of strings
};
// Each string starts with a uint32_t length, followed by length bytes.
// There is no trailing \0 in the string.
struct string_entry {
boost::uint32_t length;
boost::uint8_t *base;
};
class XYZZY {
public:
XYZZY();
~XYZZY();
// Initialize with the data file produced by gen-xyzzy.
bool init();
bool init(const std::string &filespec);
// Does a file with name 'filename' exist in magic filesystem?
bool file_exists(const std::string &filespec);
// Return a C port that will read the file contents
SCM make_read_only_port(const std::string &filespec);
/// 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);
static std::string read_string(std::ifstream &stream);
// Read the header of the datafile
boost::shared_ptr<struct header> read_header(boost::uint8_t *header);
boost::shared_ptr<struct directory_entry> read_dir_entry(boost::uint8_t *header);
std::string &get_contents(const std::string &filespec) { return _contents[filespec]; };
private:
std::string _filespec;
std::map<std::string, std::string> _contents;
};
// C linkage bindings for Guile
extern "C" {
#endif
// These are the callbacks for thw guile ports
int xyzzy_fill_input (SCM port);
void xyzzy_write (SCM port, const void *data, size_t size);
void xyzzy_flush (SCM port);
int xyzzy_close (SCM port);
// Initialize with the data file produced by gen-xyzzy.
int xyzzy_init(char *filename);
// Does a file with name 'filename' exist in magic filesystem?
int xyzzy_file_exists(char *filename);
// Return a C port that will read the file contents
SCM xyzzy_make_read_only_port(char *filename);
#ifdef __cplusplus
} // end of extern C
#endif
#endif // _XYZZY_H_ 1
|