summaryrefslogtreecommitdiff
path: root/utils/zenutils/source/shared/firmware.cpp
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2008-07-11 16:51:25 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2008-07-11 16:51:25 +0000
commitca5bb76d2b8f65aa97e50b633f828c1deb241526 (patch)
tree453a1b2de3a0dc0d0b2f7080d10d033bf8fbcdf1 /utils/zenutils/source/shared/firmware.cpp
parent141774be48940d56e3ad4dbf451d245b61d4f8b2 (diff)
downloadrockbox-ca5bb76d2b8f65aa97e50b633f828c1deb241526.tar.gz
rockbox-ca5bb76d2b8f65aa97e50b633f828c1deb241526.zip
Delete the svn:executable property and set svn:eol-style to native for all those text files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18012 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils/zenutils/source/shared/firmware.cpp')
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/firmware.cpp774
1 files changed, 387 insertions, 387 deletions
diff --git a/utils/zenutils/source/shared/firmware.cpp b/utils/zenutils/source/shared/firmware.cpp
index 7767b55d8f..811b8146b4 100755..100644
--- a/utils/zenutils/source/shared/firmware.cpp
+++ b/utils/zenutils/source/shared/firmware.cpp
@@ -1,387 +1,387 @@
1/* zenutils - Utilities for working with creative firmwares. 1/* zenutils - Utilities for working with creative firmwares.
2 * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> 2 * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com>
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19#include "firmware.h" 19#include "firmware.h"
20#include <iostream> 20#include <iostream>
21#include <stdexcept> 21#include <stdexcept>
22 22
23 23
24zen::firmware_entry::firmware_entry(bool big_endian) 24zen::firmware_entry::firmware_entry(bool big_endian)
25 : _big_endian(big_endian) 25 : _big_endian(big_endian)
26{ 26{
27} 27}
28 28
29zen::firmware_entry::firmware_entry(const firmware_entry& copy) 29zen::firmware_entry::firmware_entry(const firmware_entry& copy)
30{ 30{
31 assign(copy); 31 assign(copy);
32} 32}
33 33
34zen::firmware_entry& zen::firmware_entry::operator=(const firmware_entry& right) 34zen::firmware_entry& zen::firmware_entry::operator=(const firmware_entry& right)
35{ 35{
36 assign(right); 36 assign(right);
37 return *this; 37 return *this;
38} 38}
39 39
40 40
41bool zen::firmware_entry::read(std::istream& is) 41bool zen::firmware_entry::read(std::istream& is)
42{ 42{
43 // Read the header. 43 // Read the header.
44 is.read((char*)&_header, sizeof(firmware_header_t)); 44 is.read((char*)&_header, sizeof(firmware_header_t));
45 if (!is.good()) 45 if (!is.good())
46 return false; 46 return false;
47 47
48 // If the firmware is big-endian, swap the header values to little-endian. 48 // If the firmware is big-endian, swap the header values to little-endian.
49 if (_big_endian) 49 if (_big_endian)
50 { 50 {
51 _header.tag = shared::swap(_header.tag); 51 _header.tag = shared::swap(_header.tag);
52 if (_header.tag != 'NULL') 52 if (_header.tag != 'NULL')
53 { 53 {
54 _header.size = shared::swap(_header.size); 54 _header.size = shared::swap(_header.size);
55 } 55 }
56 } 56 }
57 57
58 // Resize the bytes buffer to the size specified in the header. 58 // Resize the bytes buffer to the size specified in the header.
59 _bytes.resize(_header.size); 59 _bytes.resize(_header.size);
60 60
61 // Read the entry contents. 61 // Read the entry contents.
62 is.read(reinterpret_cast<char*>(&_bytes[0]), 62 is.read(reinterpret_cast<char*>(&_bytes[0]),
63 _header.size); 63 _header.size);
64 64
65 return is.good(); 65 return is.good();
66} 66}
67 67
68bool zen::firmware_entry::write(std::ostream& os) const 68bool zen::firmware_entry::write(std::ostream& os) const
69{ 69{
70 // Form a header using the current size of the bytes buffer. 70 // Form a header using the current size of the bytes buffer.
71 firmware_header_t header = { 71 firmware_header_t header = {
72 _header.tag, 72 _header.tag,
73 static_cast<dword>(_bytes.size()) 73 static_cast<dword>(_bytes.size())
74 }; 74 };
75 75
76 // If the firmware is big-endian, swap the header values back into big-endian. 76 // If the firmware is big-endian, swap the header values back into big-endian.
77 if (_big_endian) 77 if (_big_endian)
78 { 78 {
79 if (header.tag != 'NULL') 79 if (header.tag != 'NULL')
80 { 80 {
81 header.size = shared::swap(header.size); 81 header.size = shared::swap(header.size);
82 } 82 }
83 header.tag = shared::swap(header.tag); 83 header.tag = shared::swap(header.tag);
84 } 84 }
85 85
86 // Write the header. 86 // Write the header.
87 os.write((const char*)&header, sizeof(firmware_header_t)); 87 os.write((const char*)&header, sizeof(firmware_header_t));
88 if (!os.good()) 88 if (!os.good())
89 return false; 89 return false;
90 90
91 // Write the entry contents. 91 // Write the entry contents.
92 os.write(reinterpret_cast<const char*>(&_bytes[0]), 92 os.write(reinterpret_cast<const char*>(&_bytes[0]),
93 static_cast<std::streamsize>(_bytes.size())); 93 static_cast<std::streamsize>(_bytes.size()));
94 94
95 return os.good(); 95 return os.good();
96} 96}
97 97
98 98
99bool zen::firmware_entry::is_big_endian() const 99bool zen::firmware_entry::is_big_endian() const
100{ 100{
101 return _big_endian; 101 return _big_endian;
102} 102}
103 103
104const zen::firmware_header_t& zen::firmware_entry::get_header() const 104const zen::firmware_header_t& zen::firmware_entry::get_header() const
105{ 105{
106 return _header; 106 return _header;
107} 107}
108zen::firmware_header_t& zen::firmware_entry::get_header() 108zen::firmware_header_t& zen::firmware_entry::get_header()
109{ 109{
110 return _header; 110 return _header;
111} 111}
112 112
113const shared::bytes& zen::firmware_entry::get_bytes() const 113const shared::bytes& zen::firmware_entry::get_bytes() const
114{ 114{
115 return _bytes; 115 return _bytes;
116} 116}
117shared::bytes& zen::firmware_entry::get_bytes() 117shared::bytes& zen::firmware_entry::get_bytes()
118{ 118{
119 return _bytes; 119 return _bytes;
120} 120}
121 121
122 122
123std::string zen::firmware_entry::get_name() const 123std::string zen::firmware_entry::get_name() const
124{ 124{
125 char name[5]; 125 char name[5];
126 *(dword*)name = shared::swap(_header.tag); 126 *(dword*)name = shared::swap(_header.tag);
127 name[4] = '\0'; 127 name[4] = '\0';
128 128
129 // Determine if all characters in the tag are printable. 129 // Determine if all characters in the tag are printable.
130 bool isprintable = true; 130 bool isprintable = true;
131 for (int i = 0; i < 4; i++) 131 for (int i = 0; i < 4; i++)
132 { 132 {
133 if (!isprint((byte)name[i])) 133 if (!isprint((byte)name[i]))
134 { 134 {
135 isprintable = false; 135 isprintable = false;
136 break; 136 break;
137 } 137 }
138 } 138 }
139 139
140 // If they are, simply return the tag as a string. 140 // If they are, simply return the tag as a string.
141 if (isprintable) 141 if (isprintable)
142 { 142 {
143 return std::string(name); 143 return std::string(name);
144 } 144 }
145 145
146 // Otherwise, encode the tag into a hexadecimal string. 146 // Otherwise, encode the tag into a hexadecimal string.
147 char buffer[11]; 147 char buffer[11];
148 sprintf(buffer, "0x%08x", _header.tag); 148 sprintf(buffer, "0x%08x", _header.tag);
149 return std::string(buffer); 149 return std::string(buffer);
150} 150}
151 151
152std::string zen::firmware_entry::get_content_name() const 152std::string zen::firmware_entry::get_content_name() const
153{ 153{
154 std::string name = get_name(); 154 std::string name = get_name();
155 if (name == "DATA") 155 if (name == "DATA")
156 { 156 {
157 name = ""; 157 name = "";
158 int nameoff = is_big_endian() ? 1 : 0; 158 int nameoff = is_big_endian() ? 1 : 0;
159 for (int i = 0; i < 16; i++) 159 for (int i = 0; i < 16; i++)
160 { 160 {
161 char c = get_bytes()[i * 2 + nameoff]; 161 char c = get_bytes()[i * 2 + nameoff];
162 if (!c) 162 if (!c)
163 break; 163 break;
164 name += c; 164 name += c;
165 } 165 }
166 } 166 }
167 else if (name == "EXT0") 167 else if (name == "EXT0")
168 { 168 {
169 name = ""; 169 name = "";
170 int nameoff = is_big_endian() ? 1 : 0; 170 int nameoff = is_big_endian() ? 1 : 0;
171 for (int i = 0; i < 12; i++) 171 for (int i = 0; i < 12; i++)
172 { 172 {
173 char c = get_bytes()[i * 2 + nameoff]; 173 char c = get_bytes()[i * 2 + nameoff];
174 if (!c) 174 if (!c)
175 break; 175 break;
176 name += c; 176 name += c;
177 } 177 }
178 } 178 }
179 return name; 179 return name;
180} 180}
181 181
182size_t zen::firmware_entry::get_content_offset() const 182size_t zen::firmware_entry::get_content_offset() const
183{ 183{
184 std::string name = get_name(); 184 std::string name = get_name();
185 if (name == "DATA") 185 if (name == "DATA")
186 { 186 {
187 return 32; 187 return 32;
188 } 188 }
189 else if (name == "EXT0") 189 else if (name == "EXT0")
190 { 190 {
191 return 24; 191 return 24;
192 } 192 }
193 return 0; 193 return 0;
194} 194}
195 195
196size_t zen::firmware_entry::calc_size() const 196size_t zen::firmware_entry::calc_size() const
197{ 197{
198 return _bytes.size() + sizeof(firmware_header_t); 198 return _bytes.size() + sizeof(firmware_header_t);
199} 199}
200 200
201 201
202void zen::firmware_entry::assign(const firmware_entry& copy) 202void zen::firmware_entry::assign(const firmware_entry& copy)
203{ 203{
204 _big_endian = copy._big_endian; 204 _big_endian = copy._big_endian;
205 _header.tag = copy._header.tag; 205 _header.tag = copy._header.tag;
206 _header.size = copy._header.size; 206 _header.size = copy._header.size;
207 _bytes.assign(copy._bytes.begin(), copy._bytes.end()); 207 _bytes.assign(copy._bytes.begin(), copy._bytes.end());
208} 208}
209 209
210 210
211 211
212zen::firmware_archive::firmware_archive(bool big_endian) 212zen::firmware_archive::firmware_archive(bool big_endian)
213 : _big_endian(big_endian) 213 : _big_endian(big_endian)
214{ 214{
215} 215}
216 216
217zen::firmware_archive::firmware_archive(const firmware_archive& copy) 217zen::firmware_archive::firmware_archive(const firmware_archive& copy)
218{ 218{
219 assign(copy); 219 assign(copy);
220} 220}
221 221
222zen::firmware_archive& zen::firmware_archive::operator=(const firmware_archive& right) 222zen::firmware_archive& zen::firmware_archive::operator=(const firmware_archive& right)
223{ 223{
224 assign(right); 224 assign(right);
225 return *this; 225 return *this;
226} 226}
227 227
228 228
229bool zen::firmware_archive::read(std::istream& is) 229bool zen::firmware_archive::read(std::istream& is)
230{ 230{
231 // Read the root entry's header. 231 // Read the root entry's header.
232 firmware_header_t root; 232 firmware_header_t root;
233 is.read((char*)&root, sizeof(firmware_header_t)); 233 is.read((char*)&root, sizeof(firmware_header_t));
234 if (!is.good()) 234 if (!is.good())
235 return false; 235 return false;
236 236
237 if ((root.tag != 'CIFF') && (root.tag != 'FFIC')) 237 if ((root.tag != 'CIFF') && (root.tag != 'FFIC'))
238 { 238 {
239 throw std::runtime_error("Invalid firmware archive format!"); 239 throw std::runtime_error("Invalid firmware archive format!");
240 } 240 }
241 241
242 _big_endian = root.tag == 'FFIC' ? true : false; 242 _big_endian = root.tag == 'FFIC' ? true : false;
243 if (_big_endian) 243 if (_big_endian)
244 { 244 {
245 root.tag = shared::swap(root.tag); 245 root.tag = shared::swap(root.tag);
246 root.size = shared::swap(root.size); 246 root.size = shared::swap(root.size);
247 } 247 }
248 248
249 // Save the current stream position. 249 // Save the current stream position.
250 std::istream::pos_type endpos = is.tellg(); 250 std::istream::pos_type endpos = is.tellg();
251 std::istream::pos_type curpos = endpos; 251 std::istream::pos_type curpos = endpos;
252 endpos += std::istream::pos_type(root.size); 252 endpos += std::istream::pos_type(root.size);
253 253
254 // Read untill the end of the root entry contents. 254 // Read untill the end of the root entry contents.
255 while (curpos < endpos) 255 while (curpos < endpos)
256 { 256 {
257 firmware_entry entry(_big_endian); 257 firmware_entry entry(_big_endian);
258 if (!entry.read(is)) 258 if (!entry.read(is))
259 return false; 259 return false;
260 260
261 _children.push_back(entry); 261 _children.push_back(entry);
262 curpos = is.tellg(); 262 curpos = is.tellg();
263 } 263 }
264 264
265 curpos = is.tellg(); 265 curpos = is.tellg();
266 is.seekg(0, std::ios::end); 266 is.seekg(0, std::ios::end);
267 endpos = is.tellg(); 267 endpos = is.tellg();
268 is.seekg(curpos); 268 is.seekg(curpos);
269 269
270 // Read untill the end of the file. 270 // Read untill the end of the file.
271 while (((size_t)curpos + sizeof(firmware_header_t)) < endpos) 271 while (((size_t)curpos + sizeof(firmware_header_t)) < endpos)
272 { 272 {
273 firmware_entry entry(_big_endian); 273 firmware_entry entry(_big_endian);
274 if (!entry.read(is)) 274 if (!entry.read(is))
275 return false; 275 return false;
276 276
277 _neighbours.push_back(entry); 277 _neighbours.push_back(entry);
278 curpos = is.tellg(); 278 curpos = is.tellg();
279 } 279 }
280 280
281 return true; 281 return true;
282} 282}
283 283
284bool zen::firmware_archive::write(std::ostream& os) const 284bool zen::firmware_archive::write(std::ostream& os) const
285{ 285{
286 // Read the root entry's header. 286 // Read the root entry's header.
287 firmware_header_t root = {'CIFF', 0}; 287 firmware_header_t root = {'CIFF', 0};
288 288
289 // Calculate the total size of all the children entries. 289 // Calculate the total size of all the children entries.
290 for (firmware_entries::const_iterator i = _children.begin(); 290 for (firmware_entries::const_iterator i = _children.begin();
291 i != _children.end(); ++i) 291 i != _children.end(); ++i)
292 { 292 {
293 root.size += i->calc_size(); 293 root.size += i->calc_size();
294 } 294 }
295 295
296 // If the firmware is big-endian, swap the header values back into big-endian. 296 // If the firmware is big-endian, swap the header values back into big-endian.
297 if (_big_endian) 297 if (_big_endian)
298 { 298 {
299 root.tag = shared::swap(root.tag); 299 root.tag = shared::swap(root.tag);
300 root.size = shared::swap(root.size); 300 root.size = shared::swap(root.size);
301 } 301 }
302 302
303 // Write the header. 303 // Write the header.
304 os.write((const char*)&root, sizeof(firmware_header_t)); 304 os.write((const char*)&root, sizeof(firmware_header_t));
305 if (!os.good()) 305 if (!os.good())
306 return false; 306 return false;
307 307
308 // Write all the child entries. 308 // Write all the child entries.
309 for (firmware_entries::const_iterator i = _children.begin(); 309 for (firmware_entries::const_iterator i = _children.begin();
310 i != _children.end(); ++i) 310 i != _children.end(); ++i)
311 { 311 {
312 if (!i->write(os)) 312 if (!i->write(os))
313 return false; 313 return false;
314 } 314 }
315 315
316 // Write all the neighbour entries. 316 // Write all the neighbour entries.
317 for (firmware_entries::const_iterator i = _neighbours.begin(); 317 for (firmware_entries::const_iterator i = _neighbours.begin();
318 i != _neighbours.end(); ++i) 318 i != _neighbours.end(); ++i)
319 { 319 {
320 if (!i->write(os)) 320 if (!i->write(os))
321 return false; 321 return false;
322 } 322 }
323 323
324 return true; 324 return true;
325} 325}
326 326
327 327
328bool zen::firmware_archive::is_big_endian() const 328bool zen::firmware_archive::is_big_endian() const
329{ 329{
330 return _big_endian; 330 return _big_endian;
331} 331}
332 332
333const zen::firmware_entries& zen::firmware_archive::get_children() const 333const zen::firmware_entries& zen::firmware_archive::get_children() const
334{ 334{
335 return _children; 335 return _children;
336} 336}
337zen::firmware_entries& zen::firmware_archive::get_children() 337zen::firmware_entries& zen::firmware_archive::get_children()
338{ 338{
339 return _children; 339 return _children;
340} 340}
341 341
342const zen::firmware_entries& zen::firmware_archive::get_neighbours() const 342const zen::firmware_entries& zen::firmware_archive::get_neighbours() const
343{ 343{
344 return _neighbours; 344 return _neighbours;
345} 345}
346zen::firmware_entries& zen::firmware_archive::get_neighbours() 346zen::firmware_entries& zen::firmware_archive::get_neighbours()
347{ 347{
348 return _neighbours; 348 return _neighbours;
349} 349}
350 350
351bool zen::firmware_archive::is_signed() const 351bool zen::firmware_archive::is_signed() const
352{ 352{
353 for (firmware_entries::const_iterator i = _neighbours.begin(); 353 for (firmware_entries::const_iterator i = _neighbours.begin();
354 i != _neighbours.end(); i++) 354 i != _neighbours.end(); i++)
355 { 355 {
356 if (i->get_name() == "NULL") 356 if (i->get_name() == "NULL")
357 return true; 357 return true;
358 } 358 }
359 return false; 359 return false;
360} 360}
361 361
362size_t zen::firmware_archive::calc_size() const 362size_t zen::firmware_archive::calc_size() const
363{ 363{
364 size_t size = sizeof(firmware_header_t); 364 size_t size = sizeof(firmware_header_t);
365 365
366 for (firmware_entries::const_iterator i = _children.begin(); 366 for (firmware_entries::const_iterator i = _children.begin();
367 i != _children.end(); i++) 367 i != _children.end(); i++)
368 { 368 {
369 size += i->calc_size(); 369 size += i->calc_size();
370 } 370 }
371 371
372 for (firmware_entries::const_iterator i = _neighbours.begin(); 372 for (firmware_entries::const_iterator i = _neighbours.begin();
373 i != _neighbours.end(); i++) 373 i != _neighbours.end(); i++)
374 { 374 {
375 size += i->calc_size(); 375 size += i->calc_size();
376 } 376 }
377 377
378 return size; 378 return size;
379} 379}
380 380
381 381
382void zen::firmware_archive::assign(const firmware_archive& copy) 382void zen::firmware_archive::assign(const firmware_archive& copy)
383{ 383{
384 _big_endian = copy._big_endian; 384 _big_endian = copy._big_endian;
385 _children.assign(copy._children.begin(), copy._children.end()); 385 _children.assign(copy._children.begin(), copy._children.end());
386 _neighbours.assign(copy._neighbours.begin(), copy._neighbours.end()); 386 _neighbours.assign(copy._neighbours.begin(), copy._neighbours.end());
387} 387}