srecord  1.65.0
record.h
Go to the documentation of this file.
1 //
2 // srecord - manipulate eprom load files
3 // Copyright (C) 1998, 1999, 2001-2003, 2005-2011 Peter Miller
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // 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 (at your
8 // option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 // 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 <http://www.gnu.org/licenses/>.
17 //
18 
19 #ifndef SRECORD_RECORD_H
20 #define SRECORD_RECORD_H
21 
22 #include <cstddef>
23 #include <stdint.h>
24 
25 #include <srecord/endian.h>
26 
27 namespace srecord {
28 
29 /**
30  * The srecord::record class is used to represent a data record read
31  * from a file. (It is not limited to any particular file format.)
32  * The records may be of various types.
33  */
34 class record
35 {
36 public:
37  /**
38  * The destructor. It isn't virtual, so don't derive anything
39  * from this class.
40  */
42 
43  /**
44  * The type of the various record types.
45  */
46  enum type_t
47  {
53  };
54 
55  /**
56  * The type of record addresses.
57  */
58  typedef uint32_t address_t;
59 
60  /**
61  * The type of record data values.
62  */
63  typedef uint8_t data_t;
64 
65  /**
66  * The default constructor. The record will have an
67  * indeterminate type, zero address, and no data.
68  */
69  record();
70 
71  /**
72  * The copy constructor.
73  */
74  record(const record &);
75 
76  /**
77  * A constructor. The record will have the given type, a zero
78  * address and no data.
79  */
81 
82  /**
83  * A constructor. The record will have the given type, the
84  * given address and no data.
85  */
87 
88  /**
89  * A constructor. The record will have the given type, the
90  * given address and a copy of the given data.
91  *
92  * @param the_type
93  * What kind of record this is
94  * @param the_address
95  * The memory address of the first byte of data, the rest
96  * increase by one each.
97  * @param the_data
98  * The bytes of data for the record.
99  * @param the_data_length
100  * How long the data is.
101  * assert(the_data_length < max_data_length);
102  */
103  record(type_t the_type, address_t the_address, const data_t *the_data,
104  size_t the_data_length);
105 
106  /**
107  * The assignment operator.
108  */
110 
111  /**
112  * The get_address method is used to get the address of the
113  * record.
114  */
115  address_t get_address(void) const { return address; }
116 
117  /**
118  * The get_address_end method is used to get the address "off
119  * the end" of this record.
120  */
121  address_t get_address_end(void) const { return (address + length); }
122 
123  /**
124  * The address_range_fits_into_n_bits method is used to test whether or
125  * not this record's address range fits within the given number of bits.
126  *
127  * @param nbits
128  * The number of bits, e.g. 16
129  * @returns
130  * true if the address range will fit, or false if it will not fit
131  */
132  bool address_range_fits_into_n_bits(unsigned nbits) const;
133 
134  /**
135  * The set_address method is used to set the address of the
136  * record.
137  */
138  void set_address(address_t arg) { address = arg; }
139 
140  /**
141  * The get_length method is used to get the length (number of
142  * bytes) of the record data.
143  */
144  size_t get_length(void) const { return length; }
145 
146  /**
147  * The set_length method is used to set the number of data
148  * bytes in the record data.
149  *
150  * @param arg
151  * The new record length. Note that you can reduce the
152  * length, but you can't increase it.
153  */
154  void
155  set_length(size_t arg)
156  {
157  if (arg < length)
158  length = arg;
159  }
160 
161  /**
162  * The get_data method is used to get a ponter to the baseof
163  * the record data.
164  *
165  * Note: Accessing beyond get_length() bytes will give an
166  * undefined value.
167  */
168  const data_t *get_data(void) const { return data; }
169 
170  /**
171  * The get_data method is used to fetch the nth data value.
172  *
173  * Note: For perfoemance reasons, no range checking is
174  * performed. Accessing beyond get_length() bytes will give
175  * an undefined value.
176  *
177  * @param n
178  * The index into the data array, zero based.
179  * Values when n is in excess of @p length are undefined.
180  */
181  int get_data(size_t n) const { return data[n]; }
182 
183  /**
184  * The is_all_zero method is used to determin if the record
185  * contains data bytes which are all zero.
186  */
187  bool is_all_zero(void) const;
188 
189  /**
190  * The set_data method is used to set values in the data array.
191  * No range checking is performed. The record length is not
192  * consulted or adjusted.
193  *
194  * @param n
195  * The index into the data array, zero based.
196  * Results when n is in excess of @p length are undefined.
197  * @param d
198  * The new data value.
199  */
200  void set_data(size_t n, data_t d) { data[n] = d; }
201 
202  /**
203  * The set_data_extend method is used to set values in the data array.
204  * The record length is adjusted if necessary.
205  *
206  * @param n
207  * The index into the data array, zero based.
208  * If this is beyond @p length, then @p length will be extended.
209  * assert(n < max_data_length);
210  * @param d
211  * The new data value.
212  */
213  void set_data_extend(size_t n, data_t d);
214 
215  /**
216  * The get_type method is used to get the type of the record.
217  */
218  type_t get_type(void) const { return type; }
219 
220  /**
221  * The set_type method is used to set the type of the record.
222  */
223  void set_type(type_t arg) { type = arg; }
224 
225  /**
226  * The maximum_data_length method is used to determine the
227  * maximum data length possible within a record, for a given
228  * address.
229  *
230  * @param addr
231  * The address of the record. Some formats trade data size of
232  * address size, for a constant maximum line length.
233  */
234  static size_t maximum_data_length(address_t addr);
235 
236  /**
237  * The decode_big_endian method is used to extract 'len'
238  * bytes from the given 'data' and assemble a big-endian value
239  * (most significant byte first).
240  *
241  * @param data
242  * The data to be decodes
243  * @param len
244  * Length of the data, in bytes
245  * @returns
246  * the decoded value
247  */
248  static address_t decode_big_endian(const data_t *data, size_t len);
249 
250  /**
251  * The decode_little_endian method is used to extract 'len' bytes
252  * from the given 'data' and assemble a little-endian value (least
253  * significant byte first).
254  *
255  * @param data
256  * The data to be decodes
257  * @param len
258  * Length of the data, in bytes
259  * @returns
260  * the decoded value
261  */
262  static address_t decode_little_endian(const data_t *data, size_t len);
263 
264  /**
265  * The decode method is used to extract 'len' bytes
266  * from the given 'data' and assemble a valu
267  *
268  * @param data
269  * The data to be decodes
270  * @param len
271  * Length of the data, in bytes
272  * @param end
273  * The byte order of the data.
274  * @returns
275  * the decoded value
276  */
277  static address_t
278  decode(const data_t *data, size_t len, endian_t end)
279  {
280  return
281  (
282  end == endian_big
283  ?
284  decode_big_endian(data, len)
285  :
286  decode_little_endian(data, len)
287  );
288  }
289 
290  /**
291  * The encode_big_endian method is used to break down 'val' into
292  * 'len' bytes of 'data' orderdd big-endian (most significan
293  * byte first).
294  *
295  * @param data
296  * Where to place the encoded data
297  * @param val
298  * The value to be encoded
299  * @param len
300  * The number of bytes to use to encode the data.
301  * Bits above the 8*len resolution will be discarded.
302  */
303  static void encode_big_endian(data_t *data, address_t val, size_t len);
304 
305  /**
306  * The encode_little_endian method is used to break down
307  * 'val' into 'len' bytes of 'data' orderdd big-endian (least
308  * significan byte first).
309  *
310  * @param data
311  * Where to place the encoded data
312  * @param val
313  * The value to be encoded
314  * @param len
315  * The number of bytes to use to encode the data.
316  * Bits above the 8*len resolution will be discarded.
317  */
318  static void encode_little_endian(data_t *data, address_t val, size_t len);
319 
320  /**
321  * The encode method is used to break down 'val' into 'len' bytes
322  * of 'data'
323  *
324  * @param data
325  * Where to place the encoded data
326  * @param val
327  * The value to be encoded
328  * @param len
329  * The number of bytes to use to encode the data.
330  * Bits above the 8*len resolution will be discarded.
331  * @param end
332  * The byte order
333  */
334  static void
335  encode(data_t *data, address_t val, size_t len, endian_t end)
336  {
337  if (end == endian_big)
338  encode_big_endian(data, val, len);
339  else
340  encode_little_endian(data, val, len);
341  }
342 
343  enum {
344  /**
345  * The max_data_length is the largest number of data bytes
346  * which any record can hold.
347  */
349 
350 private:
351  /**
352  * The type instance variable is used to remember the type of
353  * the record.
354  */
355  type_t type;
356 
357  /**
358  * The address instance variable is used to remember the address
359  * of the record.
360  */
361  address_t address;
362 
363  /**
364  * The length instance variable is used to remember the number
365  * of valid bytes in the #data array.
366  */
367  size_t length;
368 
369  /**
370  * The data instance variable is used to remember the data
371  * of the record. Only the first #length bytes are valid,
372  * the rest are undefined.
373  */
374  data_t data[max_data_length];
375 };
376 
377 };
378 
379 #endif // SRECORD_RECORD_H
The srecord::record class is used to represent a data record read from a file.
Definition: record.h:35
static address_t decode(const data_t *data, size_t len, endian_t end)
The decode method is used to extract 'len' bytes from the given 'data' and assemble a valu.
Definition: record.h:278
@ max_data_length
The max_data_length is the largest number of data bytes which any record can hold.
Definition: record.h:348
type_t get_type(void) const
The get_type method is used to get the type of the record.
Definition: record.h:218
size_t get_length(void) const
The get_length method is used to get the length (number of bytes) of the record data.
Definition: record.h:144
static address_t decode_big_endian(const data_t *data, size_t len)
The decode_big_endian method is used to extract 'len' bytes from the given 'data' and assemble a big-...
record(type_t, address_t)
A constructor.
record(const record &)
The copy constructor.
int get_data(size_t n) const
The get_data method is used to fetch the nth data value.
Definition: record.h:181
address_t get_address(void) const
The get_address method is used to get the address of the record.
Definition: record.h:115
record(type_t the_type, address_t the_address, const data_t *the_data, size_t the_data_length)
A constructor.
void set_type(type_t arg)
The set_type method is used to set the type of the record.
Definition: record.h:223
void set_data(size_t n, data_t d)
The set_data method is used to set values in the data array.
Definition: record.h:200
type_t
The type of the various record types.
Definition: record.h:47
@ type_data_count
Definition: record.h:51
@ type_execution_start_address
Definition: record.h:52
bool address_range_fits_into_n_bits(unsigned nbits) const
The address_range_fits_into_n_bits method is used to test whether or not this record's address range ...
record(type_t)
A constructor.
bool is_all_zero(void) const
The is_all_zero method is used to determin if the record contains data bytes which are all zero.
uint8_t data_t
The type of record data values.
Definition: record.h:63
void set_data_extend(size_t n, data_t d)
The set_data_extend method is used to set values in the data array.
~record()
The destructor.
const data_t * get_data(void) const
The get_data method is used to get a ponter to the baseof the record data.
Definition: record.h:168
static size_t maximum_data_length(address_t addr)
The maximum_data_length method is used to determine the maximum data length possible within a record,...
static address_t decode_little_endian(const data_t *data, size_t len)
The decode_little_endian method is used to extract 'len' bytes from the given 'data' and assemble a l...
static void encode(data_t *data, address_t val, size_t len, endian_t end)
The encode method is used to break down 'val' into 'len' bytes of 'data'.
Definition: record.h:335
record()
The default constructor.
address_t get_address_end(void) const
The get_address_end method is used to get the address "off the end" of this record.
Definition: record.h:121
void set_length(size_t arg)
The set_length method is used to set the number of data bytes in the record data.
Definition: record.h:155
record & operator=(const record &)
The assignment operator.
uint32_t address_t
The type of record addresses.
Definition: record.h:58
static void encode_big_endian(data_t *data, address_t val, size_t len)
The encode_big_endian method is used to break down 'val' into 'len' bytes of 'data' orderdd big-endia...
void set_address(address_t arg)
The set_address method is used to set the address of the record.
Definition: record.h:138
static void encode_little_endian(data_t *data, address_t val, size_t len)
The encode_little_endian method is used to break down 'val' into 'len' bytes of 'data' orderdd big-en...
endian_t
Definition: endian.h:27
@ endian_big
Definition: endian.h:28