1 //
2 // srecord - Manipulate EPROM load files
3 // Copyright (C) 2009-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 (at
8 // 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 GNU
13 // 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 <http://www.gnu.org/licenses/>.
17 //
18 
19 #include <srecord/input/filter/message.h>
20 #include <srecord/record.h>
21 
22 
~input_filter_message()23 srecord::input_filter_message::~input_filter_message()
24 {
25 }
26 
27 
input_filter_message(const input::pointer & a_deeper,bool a_naked)28 srecord::input_filter_message::input_filter_message(
29     const input::pointer &a_deeper,
30     bool a_naked
31 ) :
32     input_filter(a_deeper),
33     naked(a_naked),
34     buffer_pos(0),
35     have_forwarded_header(false),
36     have_given_result(false),
37     have_forwarded_start_address(false)
38 {
39 }
40 
41 
42 unsigned
get_minimum_alignment(void) const43 srecord::input_filter_message::get_minimum_alignment(void)
44     const
45 {
46     return 0;
47 }
48 
49 
50 bool
read(record & result)51 srecord::input_filter_message::read(record &result)
52 {
53     //
54     // If we haven't read the deeper input yet, read all of it into
55     // a memory buffer, then message the bytes.
56     //
57     if (buffer.empty())
58     {
59         buffer.reader(ifp, defcon_ignore, defcon_warning);
60 
61         unsigned multiple = get_minimum_alignment();
62         if (multiple >= 2 && !buffer.is_well_aligned(multiple))
63         {
64             warning
65             (
66                 "The %s filter uses %u-byte alignment, but unaligned "
67                 "data is present.  Use a \"--fill 0xNN --within <input> "
68                 "--range-padding %u\" filter *before* the %s filter to fix "
69                 "this problem.  "
70                 "See srec_info(1) for how to see the data ranges.",
71                 get_algorithm_name(),
72                 multiple,
73                 multiple,
74                 get_algorithm_name()
75             );
76         }
77 
78         if (buffer.has_holes())
79         {
80             warning
81             (
82                 "The data presented for %s calculation has at least one hole "
83                 "in it.  This is bad.  It means that the in-memory "
84                 "calculation performed by your embedded system will be "
85                 "different than the calculation performed here.  You are "
86                 "strongly advised to use the \"--fill 0xFF --over <inoput>\" "
87                 "filter *before* the %s filter to ensure both calculations are "
88                 "using the same byte values.  "
89                 "See srec_info(1) for how to see the holes.",
90                 get_algorithm_name(),
91                 get_algorithm_name()
92             );
93         }
94     }
95 
96     //
97     // Pass on the header of the deeper file.
98     //
99     if (!have_forwarded_header)
100     {
101         have_forwarded_header = true;
102         record *rp = buffer.get_header();
103         if (rp)
104         {
105             result = *rp;
106             return true;
107         }
108     }
109 
110     //
111     // Calculate the result.
112     //
113     if (!have_given_result)
114     {
115         have_given_result = true;
116         process(buffer, result);
117         return true;
118     }
119 
120     //
121     // Now forward the rest of the data.
122     //
123     if (!naked)
124     {
125         unsigned long ret_address = buffer_pos;
126         unsigned char data[64];
127         size_t nbytes = sizeof(data);
128         if (buffer.find_next_data(ret_address, data, nbytes))
129         {
130             result = record(record::type_data, ret_address, data, nbytes);
131             buffer_pos = ret_address + nbytes;
132             return true;
133         }
134     }
135 
136     //
137     // Now forward on the start address of the deeper file.  (We could
138     // have done it any time after reading the data, but we do last
139     // because that is where "real" format usually put it.)
140     //
141     if (!have_forwarded_start_address)
142     {
143         have_forwarded_start_address = true;
144         record *rp = buffer.get_execution_start_address();
145         if (rp)
146         {
147             result = *rp;
148             return true;
149         }
150     }
151 
152     //
153     // All done.
154     //
155     return false;
156 }
157 
158 
159 // vim: set ts=8 sw=4 et :
160