srecord: memory.h Source File

srecord 1.65.0

Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1//
2// srecord - manipulate eprom load files
3// Copyright (C) 1998-2003, 2006-2008, 2010, 2012-2014 Peter Miller
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation; either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with this program. If not, see
17// <http://www.gnu.org/licenses/>.
18//
19
20#ifndef SRECORD_MEMORY_H
21#define SRECORD_MEMORY_H
22
23#include <string>
24
25#include <srecord/defcon.h>
26#include <srecord/input.h>
27#include <srecord/memory/chunk.h>
28#include <srecord/memory/walker.h>
29#include <srecord/string.h>
30
31namespace srecord {
32
33class record; // forward
34
35/**
36 * The srecord::memory class is used to simulate memory contents.
37 * This allows staging of reord adta, and also validation of contents.
38 */
39 class memory
40{
41public:
42 /**
43 * The default constructor.
44 */
45 memory();
46
47 /**
48 * The copy constructor.
49 */
50 memory(const memory &);
51
52 /**
53 * The assignment operator.
54 */
55 memory &operator=(const memory &);
56
57 /**
58 * The destructor.
59 */
60 ~memory();
61
62 /**
63 * The set method is used to set the byte at the given `address'
64 * to the given `value'.
65 *
66 * Uses the find() method to locate the chunk, and then calls
67 * the memory_chunk::set method, to set the byte within
68 * the chunk.
69 */
70 void set(unsigned long address, int value);
71
72 /**
73 * The get method is used to fetch the value of the byte at
74 * the given 'address'.
75 *
76 * If you fo a get on an address which has not been set() yet,
77 * the results are undefined.
78 *
79 * Uses the find() method to locate the chunk, and then calls
80 * the memory_chunk::get method, to get the byte within
81 * the chunk.
82 */
83 int get(unsigned long address) const;
84
85 /**
86 * The set_p method is used to determine whether the byte at
87 * the given address has been set() yet. Returns true if
88 * already set, false if never been set.
89 *
90 * Uses the find() method to locate the chunk, and then calls
91 * the memory_chunk::set_p method, to get the status of
92 * the byte within the chunk.
93 */
94 bool set_p(unsigned long address) const;
95
96 /**
97 * The walk method is used to apply a memory_walker derived
98 * class to every byte of memory.
99 */
100 void walk(memory_walker::pointer) const;
101
102 /**
103 * The reader method is used to read the given `input' source
104 * into memory. This method may be called multiple times,
105 * for multiple input files.
106 *
107 * If the input format supports headers, and the file has a
108 * header, the first header will be remembered, if set_header()
109 * was not called previously.
110 *
111 * @param input
112 * The source of the byte stream
113 * @param redundant_bytes
114 * ignore: do nothing
115 * warning: issue a warning and continue (default)
116 * error: issuse a atal error message, and exit failure.
117 * @param contradictory_bytes
118 * If the value at any address is set more than once,
119 * Thid argument controls what happeens.
120 * ignore: do nothing
121 * warning: issue a warning and continue (default)
122 * error: issuse a atal error message, and exit failure (default).
123 */
124 void reader(const input::pointer &input, defcon_t redundant_bytes,
125 defcon_t contradictory_bytes);
126
127 /**
128 * The equal method may be used to determine if two memory
129 * instances are equal.
130 */
131 static bool equal(const memory &, const memory &);
132
133 /**
134 * The compare method may be used to determine if two memory
135 * instances are equal. Verbose messages concerning the exact
136 * differences are printed if they are not equal.
137 */
138 static bool compare(const memory &, const memory &);
139
140 /**
141 * The find_next_data method may be used to locate data at or
142 * following the `address' given. Returns false if there is
143 * no data meeting this criteria.
144 *
145 * If there is data, the `address' will be set to the start
146 * address of the data block. At most `nbytes' of data will
147 * be transfetrred into the `data' array. Then `nbytes' wil
148 * be set to the number of bytes transferred. Returns true.
149 *
150 * Calls the find_next_chunk() method.
151 */
152 bool find_next_data(unsigned long &address, void *data,
153 size_t &nbytes) const;
154
155 /**
156 * The get_header method is used to determine the value of the
157 * header record set by either the reader() or set_header()
158 * methods. If neither has set a header, a NULL is returned.
159 */
160 record *get_header(void) const;
161
162 /**
163 * The set_header method may be used to set the header command.
164 *
165 * @param value
166 * The `value' string, to set the header. The user may use URL
167 * encoding for of the more interesting non-printable byte values
168 * (eg. "%3F").
169 */
170 void set_header(const std::string &value);
171
172 /**
173 * The get_execution_start_address method is used to determine the
174 * value of the execution start address record set by either the
175 * reader() or set_execution_start_address() methods. If neither
176 * has set an execution start address, NULL is returned.
177 */
178 record *get_execution_start_address(void) const;
179
180 /**
181 * The set_execution_start_address method may be used to set the
182 * execution start address record.
183 */
184 void set_execution_start_address(unsigned long value);
185
186 /**
187 * The has_holes method may be used to determine whether or not the
188 * memory data has "holes" in it.
189 *
190 * @returns
191 * true if the memory data is not continuous (has at least
192 * one hole), false if the memory data is continuous (has no
193 * holes).
194 */
195 bool has_holes(void) const;
196
197 /**
198 * The get_lower_bound method is used to obtain the lower bound
199 * (lowest address) of the memory image.
200 */
201 unsigned long get_lower_bound() const;
202
203 /**
204 * The get_upper_bound method is used to obtain the upper bound
205 * (maximum address plus one) of the memory image.
206 */
207 unsigned long get_upper_bound() const;
208
209 /**
210 * The is_well_aligned method is used to test whether or not
211 * all of the data in the memory buffer is well aligned, on the
212 * given byte boundary.
213 *
214 * @param multiple
215 * The desired byte alignment.
216 *
217 * @note
218 * This isn't about holes, it's about the beginnings and
219 * endings of each consecitice run of bytes.
220 */
221 bool is_well_aligned(unsigned multiple) const;
222
223 /**
224 * The empty method is used to determine whether or not this memory
225 * image has no data in it.
226 */
227 bool
228 empty(void)
229 const
230 {
231 return (nchunks == 0);
232 }
233
234private:
235 /**
236 * The nchunks instance variable is used to member how large
237 * our pool of memory chunks is. It is always <= nchunks_max;
238 */
239 mutable int nchunks;
240
241 /**
242 * The max_chunks instance variable is used to rememberf the
243 * size of the chunk array, which holds the pool of memory chunks.
244 */
245 mutable int nchunks_max;
246
247 /**
248 * The chunk instance variable is used to hold the pointer to
249 * the base of the chunk array. These chunks remember the
250 * settings of the various bytes. By using a sparse array,
251 * we can cope with arbitrary memory usages.
252 */
253 mutable memory_chunk **chunk;
254
255 /**
256 * The find method is used to find the chunk which contains
257 * the given `address'. The chunk will be created if it
258 * doesn't exist.
259 *
260 * Called by the get(), set() and set_p() methods.
261 */
262 memory_chunk *find(unsigned long address) const;
263
264 /**
265 * The cache instance variable is used to accellerate the find()
266 * method, based on the fact that most memory accesses are
267 * sequential, in the same chunk.
268 */
269 mutable memory_chunk *cache;
270
271 /**
272 * The find_next_chunk method is used to visit each and every
273 * byte, in cases where the walk() method is not appropriate.
274 * Called by the find_next_data() method.
275 */
276 memory_chunk *find_next_chunk(unsigned long) const;
277
278 /**
279 * The find_next_chunk_index instance variable is used by
280 * the find_next_chunk() method to keep track of where it is
281 * positioned across the chunk array.
282 */
283 mutable int find_next_chunk_index;
284
285 /**
286 * The header instance variable is used to track the file header.
287 * It is set by the reader() and set_header() methods. It is
288 * read by the get_header() method.
289 */
290 record *header;
291
292 /**
293 * The execution_start_address instance variable is used to track
294 * the execution start address. It is set by the reader() and
295 * set_execution_start_address() methods. It is read by the
296 * get_execution_start_address() method.
297 */
298 record *execution_start_address;
299
300 /**
301 * The clear method is used to discard all data, as if when
302 * the instance was first constructed. Alsu used by the destructor.
303 */
304 void clear(void);
305
306 /**
307 * The copy method is used to copy the chunks from the `src' into
308 * this object. Only to be used the the assignment operator.
309 */
310 void copy(const memory &src);
311};
312
313};
314
315/**
316 * The equality operator. Used to test if two srecord::memory objects
317 * are equal. Calls the srecord::memory::equal() method.
318 */
319 bool operator == (const srecord::memory &, const srecord::memory &);
320
321/**
322 * The inequality operator. Used to test if two srecord::memory objects
323 * are not equal. Calls the srecord::memory::equal() method.
324 */
325 bool operator != (const srecord::memory &, const srecord::memory &);
326
327// vim: set ts=8 sw=4 et :
328#endif // SRECORD_MEMORY_H
chunk.h
srecord::input
The srecord::input class is used to represent an abstract EPROM load file source.
Definition input.h:39
srecord::input::pointer
std::shared_ptr< input > pointer
Definition input.h:41
srecord::memory_chunk
The srecord::memory_chunk class is used to represent portion of memory.
Definition chunk.h:34
srecord::memory_walker::pointer
std::shared_ptr< memory_walker > pointer
Definition walker.h:36
srecord::memory
The srecord::memory class is used to simulate memory contents.
Definition memory.h:40
srecord::memory::set_execution_start_address
void set_execution_start_address(unsigned long value)
The set_execution_start_address method may be used to set the execution start address record.
srecord::memory::compare
static bool compare(const memory &, const memory &)
The compare method may be used to determine if two memory instances are equal.
srecord::memory::get_upper_bound
unsigned long get_upper_bound() const
The get_upper_bound method is used to obtain the upper bound (maximum address plus one) of the memory...
srecord::memory::empty
bool empty(void) const
The empty method is used to determine whether or not this memory image has no data in it.
Definition memory.h:228
srecord::memory::get
int get(unsigned long address) const
The get method is used to fetch the value of the byte at the given 'address'.
srecord::memory::get_execution_start_address
record * get_execution_start_address(void) const
The get_execution_start_address method is used to determine the value of the execution start address ...
srecord::memory::memory
memory(const memory &)
The copy constructor.
srecord::memory::set_header
void set_header(const std::string &value)
The set_header method may be used to set the header command.
srecord::memory::is_well_aligned
bool is_well_aligned(unsigned multiple) const
The is_well_aligned method is used to test whether or not all of the data in the memory buffer is wel...
srecord::memory::walk
void walk(memory_walker::pointer) const
The walk method is used to apply a memory_walker derived class to every byte of memory.
srecord::memory::~memory
~memory()
The destructor.
srecord::memory::memory
memory()
The default constructor.
srecord::memory::equal
static bool equal(const memory &, const memory &)
The equal method may be used to determine if two memory instances are equal.
srecord::memory::set
void set(unsigned long address, int value)
The set method is used to set the byte at the given ‘address’ to the given ‘value’.
srecord::memory::get_header
record * get_header(void) const
The get_header method is used to determine the value of the header record set by either the reader() ...
srecord::memory::operator=
memory & operator=(const memory &)
The assignment operator.
srecord::memory::find_next_data
bool find_next_data(unsigned long &address, void *data, size_t &nbytes) const
The find_next_data method may be used to locate data at or following the ‘address’ given.
srecord::memory::reader
void reader(const input::pointer &input, defcon_t redundant_bytes, defcon_t contradictory_bytes)
The reader method is used to read the given ‘input’ source into memory.
srecord::memory::set_p
bool set_p(unsigned long address) const
The set_p method is used to determine whether the byte at the given address has been set() yet.
srecord::memory::has_holes
bool has_holes(void) const
The has_holes method may be used to determine whether or not the memory data has "holes" in it.
srecord::memory::get_lower_bound
unsigned long get_lower_bound() const
The get_lower_bound method is used to obtain the lower bound (lowest address) of the memory image.
srecord::record
The srecord::record class is used to represent a data record read from a file.
Definition record.h:35
defcon.h
input.h
operator!=
bool operator!=(const srecord::memory &, const srecord::memory &)
The inequality operator.
operator==
bool operator==(const srecord::memory &, const srecord::memory &)
The equality operator.
srecord
Definition adler16.h:25
srecord::defcon_t
defcon_t
Definition defcon.h:26
string.h
walker.h