desktop: fixed signed comparison bug, and fixed seconds/minutes bug
[barry/progweb.git] / src / dp_codinfo.cc
blob008c39b19062af5d86450e63308e428b7e0507c3
1 /**
2 * @file dp_codinfo.cc
3 * @author Nicolas VIVIEN
4 * @date 2009-08-01
6 * @note CopyRight Nicolas VIVIEN
8 * @brief COD debug file parser
9 * RIM's JDE generates several files when you build a COD application.
10 * Indeed, with the COD files for the device, we have a ".debug" file.
11 * This file is usefull to debug an application from JVM.
12 * This tool is a parser to understand these ".debug" files.
14 * @par Modifications
15 * - 2009/08/01 : N. VIVIEN
16 * - First release
18 * @par Licences
19 * Copyright (C) 2009-2010, Nicolas VIVIEN
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30 * See the GNU General Public License in the COPYING file at the
31 * root directory of this project for more details.
35 #include <fstream>
36 #include <iomanip>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <string.h>
42 #include "dp_parser.h"
43 #include "dp_codinfo.h"
44 #include "ios_state.h"
45 #include "debug.h"
48 #define COD_DEBUG_APPNAME_HEADERFIELD 0x0
49 #define COD_DEBUG_UNIQUEID_HEADERFIELD 0x8
51 #define COD_DEBUG_NONE_FIELD 0x0
52 #define COD_DEBUG_BOOLEAN_FIELD 0x1
53 #define COD_DEBUG_BYTE_FIELD 0x2
54 #define COD_DEBUG_CHAR_FIELD 0x3
55 #define COD_DEBUG_SHORT_FIELD 0x4
56 #define COD_DEBUG_INT_FIELD 0x5
57 #define COD_DEBUG_LONG_FIELD 0x6
58 #define COD_DEBUG_CLASS_FIELD 0x7
59 #define COD_DEBUG_ARRAY_FIELD 0x8
60 #define COD_DEBUG_VOID_FIELD 0xA
61 #define COD_DEBUG_DOUBLE_FIELD 0xC
64 using namespace std;
67 namespace Barry {
69 namespace JDG {
72 // Public API
73 //------------
75 #define DEBUG_FILE_EXT ".debug"
78 void SearchDebugFile(DebugFileList &list)
80 DIR *path;
81 struct dirent *entry;
83 path = opendir(".");
85 while( (entry = readdir(path)) ) {
86 int offset;
88 if (strlen(entry->d_name) < strlen(DEBUG_FILE_EXT))
89 continue;
91 offset = strlen(entry->d_name) - strlen(DEBUG_FILE_EXT);
93 if (!strcmp(entry->d_name + offset, DEBUG_FILE_EXT)) {
94 ifstream file(entry->d_name);
96 CodInfo info;
98 // Parse header section
99 info.ParseHeaderSection(file);
101 // Add element to list
102 list.AddElement(info.GetUniqueId(), info.GetAppName(), entry->d_name);
106 closedir(path);
110 bool LoadDebugInfo(const DebugFileList &list, const char *filename, CodInfo &info)
112 if (filename == NULL)
113 return false;
115 DebugFileList::const_iterator b = list.begin();
117 for( ; b != list.end(); b++ ) {
118 const DebugFileEntry &entry = (*b);
120 if( entry.fileName == filename ) {
121 info.LoadDebugFile(filename);
122 return true;
126 return false;
130 bool LoadDebugInfo(const DebugFileList &list, const uint32_t uniqueId, const std::string module, CodInfo &info)
132 DebugFileList::const_iterator b = list.begin();
134 for( ; b != list.end(); b++ ) {
135 const DebugFileEntry &entry = (*b);
137 if ((entry.uniqueId == uniqueId) && (entry.appName == module)) {
138 info.LoadDebugFile(entry.fileName.c_str());
139 return true;
143 return false;
147 // DebugFileList class
148 //------------------------
150 void DebugFileList::AddElement(uint32_t uniqueid,
151 const std::string &appname,
152 const std::string &filename)
154 DebugFileEntry entry;
156 entry.uniqueId = uniqueid;
157 entry.appName = appname;
158 entry.fileName = filename;
160 push_back(entry);
164 void DebugFileList::Dump(std::ostream &os) const
166 ios_format_state state(os);
168 const_iterator i = begin(), e = end();
170 os << " UniqueID " << "|";
171 os << " Module Name " << "|";
172 os << " File Name " << endl;
174 os << "------------+";
175 os << "--------------------------+";
176 os << "--------------------------";
177 os << endl;
179 for( ; i != e; ++i ) {
180 (*i).Dump(os);
185 void DebugFileEntry::Dump(std::ostream &os) const
187 ios_format_state state(os);
189 os << " 0x" << setfill('0') << setw(8) << hex << uniqueId << " |";
190 os << " " << appName << setfill(' ') << setw(24) << " |";
191 os << " " << fileName << endl;
195 // ClassList class
196 //---------------------------
199 void ClassList::CreateDefaultEntries()
201 ClassEntry entry;
203 // 1
204 entry.classPath = "com.rim.resources";
205 entry.className = "net_rim_rimsecuridlibRIMResources";
206 push_back(entry);
208 // 2
209 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
210 entry.className = "RimSecurIDLib";
211 push_back(entry);
213 // 3
214 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
215 entry.className = "RimDatabaseFullException";
216 push_back(entry);
218 // 4
219 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
220 entry.className = "RimDecryptFailException";
221 push_back(entry);
223 // 5
224 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
225 entry.className = "RimDuplicateNameException";
226 push_back(entry);
228 // 6
229 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
230 entry.className = "RimDuplicateTokenException";
231 push_back(entry);
233 // 7
234 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
235 entry.className = "RimInvalidParamException";
236 push_back(entry);
238 // 8
239 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
240 entry.className = "RimSecurIDLib";
241 push_back(entry);
243 // 9
244 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
245 entry.className = "RimWrongDeviceIDException";
246 push_back(entry);
248 // 10
249 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
250 entry.className = "RimWrongFormFactorException";
251 push_back(entry);
255 // CodInfo class
256 //------------------------
258 bool CodInfo::LoadDebugFile(const char *filename)
260 uint32_t field;
262 if (filename == NULL)
263 return false;
265 ifstream file(filename);
267 // Parse header file
268 ParseHeaderSection(file);
270 // Parse type area zone
271 ParseTypeSection(file);
273 // FIXME : ???
274 field = ParseInteger(file); // Read 0x0
275 field = ParseInteger(file); // Read 0x1
277 // FIXME : ???
278 field = ParseInteger(file); // Read 0x0
279 field = ParseInteger(file); // Read 0x0 or 0xA
281 if (field == 0xA) {
282 // Parse ressource area zone
283 ParseResourceSection(file);
286 return true;
290 uint32_t CodInfo::GetUniqueId()
292 return uniqueId;
296 string CodInfo::GetAppName()
298 return appName;
302 // Private API - Section parsing
303 //-------------------------------
305 void CodInfo::ParseHeaderSection(istream &input)
307 uint32_t type;
309 type = ParseNextHeaderField(input);
311 if (type != COD_DEBUG_UNIQUEID_HEADERFIELD)
312 return;
314 type = ParseNextHeaderField(input);
316 if (type != COD_DEBUG_APPNAME_HEADERFIELD)
317 return;
321 void CodInfo::ParseTypeSection(istream &input)
323 uint32_t type;
324 uint32_t count;
325 uint32_t nbr, check;
327 // Read number of declared type content into this section
328 nbr = ParseInteger(input);
330 // Read each object
331 count = 0;
333 while (!input.eof()) {
334 type = ParseNextTypeField(input);
336 if (type == COD_DEBUG_NONE_FIELD)
337 break;
339 count++;
342 // Read again number of declared type content into this section
343 // We have to find the same value
344 check = ParseInteger(input);
346 // Checking...
347 dout("Nbr = " << dec << nbr << " / Count = " << dec << count << " / check = " << check);
351 void CodInfo::ParseResourceSection(istream &input)
353 uint32_t len;
354 uint32_t type;
355 uint32_t unknown01;
356 uint32_t unknown02;
357 uint32_t unknown03;
358 uint32_t unknown04;
359 uint32_t unknown05;
360 uint32_t unknown06;
361 uint32_t unknown07;
363 string name;
365 // type = 1
366 for (int i=0; i<10; i++) {
367 type = ParseInteger(input);
369 len = ParseInteger(input);
370 name = ParseString(input, len);
372 unknown01 = ParseInteger(input);
373 unknown02 = ParseInteger(input);
374 unknown03 = ParseInteger(input);
376 dout("JDGCodInfo::parseRessource"
377 << "\n Name : " << name
378 << "\n unknown01 : " << hex << unknown01
379 << "\n unknown02 : " << hex << unknown02
380 << "\n unknown03 : " << hex << unknown03);
383 // type = 2
384 type = ParseInteger(input);
386 len = ParseInteger(input);
387 name = ParseString(input, len);
389 unknown01 = ParseInteger(input);
390 unknown02 = ParseInteger(input);
391 unknown03 = ParseInteger(input);
392 unknown04 = ParseInteger(input);
393 unknown05 = ParseInteger(input);
394 unknown06 = ParseInteger(input);
395 unknown07 = ParseInteger(input);
397 dout("JDGCodInfo::parseRessource"
398 << "\n Name : " << name
399 << "\n unknown01 : " << hex << unknown01
400 << "\n unknown02 : " << hex << unknown02
401 << "\n unknown03 : " << hex << unknown03
402 << "\n unknown04 : " << hex << unknown04
403 << "\n unknown05 : " << hex << unknown05
404 << "\n unknown06 : " << hex << unknown06
405 << "\n unknown07 : " << hex << unknown07);
407 // type = 1
408 type = ParseInteger(input);
410 len = ParseInteger(input);
411 name = ParseString(input, len);
413 unknown01 = ParseInteger(input);
414 unknown02 = ParseInteger(input);
415 unknown03 = ParseInteger(input);
416 unknown04 = ParseInteger(input);
418 dout("JDGCodInfo::parseRessource"
419 << "\n Name : " << name
420 << "\n unknown01 : " << hex << unknown01
421 << "\n unknown02 : " << hex << unknown02
422 << "\n unknown03 : " << hex << unknown03
423 << "\n unknown04 : " << hex << unknown04);
425 // type = 0
426 type = ParseInteger(input);
428 len = ParseInteger(input);
429 name = ParseString(input, len);
431 unknown01 = ParseInteger(input);
432 unknown02 = ParseInteger(input);
433 unknown03 = ParseInteger(input);
434 unknown04 = ParseInteger(input);
435 unknown05 = ParseInteger(input);
437 dout("JDGCodInfo::parseRessource"
438 << "\n Name : " << name
439 << "\n unknown01 : " << hex << unknown01
440 << "\n unknown02 : " << hex << unknown02
441 << "\n unknown03 : " << hex << unknown03
442 << "\n unknown04 : " << hex << unknown04
443 << "\n unknown05 : " << hex << unknown05);
448 // Private API - Field parsing
449 //-------------------------------
452 uint32_t CodInfo::ParseNextHeaderField(istream &input)
454 uint32_t type = ParseInteger(input);
456 switch (type) {
457 case COD_DEBUG_UNIQUEID_HEADERFIELD:
458 ParseUniqueId(input);
459 break;
461 case COD_DEBUG_APPNAME_HEADERFIELD:
462 ParseAppName(input);
463 break;
465 default:
466 type = 0xFFFFFFFF;
469 return type;
473 uint32_t CodInfo::ParseNextTypeField(istream &input)
475 uint32_t type = ParseInteger(input);
477 switch (type) {
478 case COD_DEBUG_NONE_FIELD:
479 break;
481 case COD_DEBUG_BOOLEAN_FIELD:
482 ParseBoolean(input);
483 break;
485 case COD_DEBUG_BYTE_FIELD:
486 ParseByte(input);
487 break;
489 case COD_DEBUG_CHAR_FIELD:
490 ParseChar(input);
491 break;
493 case COD_DEBUG_SHORT_FIELD:
494 ParseShort(input);
495 break;
497 case COD_DEBUG_INT_FIELD:
498 ParseInt(input);
499 break;
501 case COD_DEBUG_LONG_FIELD:
502 ParseLong(input);
503 break;
505 case COD_DEBUG_CLASS_FIELD:
506 ParseClass(input);
507 break;
509 case COD_DEBUG_ARRAY_FIELD:
510 ParseArray(input);
511 break;
513 case COD_DEBUG_VOID_FIELD:
514 ParseVoid(input);
515 break;
517 case COD_DEBUG_DOUBLE_FIELD:
518 ParseDouble(input);
519 break;
521 default:
522 dout("Type unknown ! " << hex << type);
523 type = 0xFFFFFFFF;
526 return type;
530 void CodInfo::ParseUniqueId(istream &input)
532 uniqueId = ParseInteger(input);
536 void CodInfo::ParseAppName(istream &input)
538 uint32_t len = ParseInteger(input);
540 appName = ParseString(input, len);
544 void CodInfo::ParseBoolean(istream &input)
546 uint32_t len = ParseInteger(input);
548 string str = ParseString(input, len);
550 dout("JDG::CodInfo::ParseBoolean\n name : " << str);
554 void CodInfo::ParseByte(istream &input)
556 uint32_t len = ParseInteger(input);
558 string str = ParseString(input, len);
560 dout("JDG::CodInfo::ParseByte\n name : " << str);
564 void CodInfo::ParseChar(istream &input)
566 uint32_t len = ParseInteger(input);
568 string str = ParseString(input, len);
570 dout("JDG::CodInfo::ParseChar\n name : " << str);
574 void CodInfo::ParseShort(istream &input)
576 uint32_t len = ParseInteger(input);
578 string str = ParseString(input, len);
580 dout("JDG::CodInfo::ParseShort\n name : " << str);
584 void CodInfo::ParseInt(istream &input)
586 uint32_t len = ParseInteger(input);
588 string str = ParseString(input, len);
590 dout("JDG::CodInfo::ParseInt\n name : " << str);
594 void CodInfo::ParseLong(istream &input)
596 uint32_t len = ParseInteger(input);
598 string str = ParseString(input, len);
600 dout("JDG::CodInfo::ParseLong\n name : " << str);
604 void CodInfo::ParseClass(istream &input)
606 uint32_t len;
608 ClassEntry object;
610 dout("JDG::CodInfo::ParseClass");
612 len = ParseInteger(input);
614 object.className = ParseString(input, len);
616 object.type = ParseInteger(input);
617 object.unknown02 = ParseInteger(input);
618 object.unknown03 = ParseInteger(input);
619 object.id = ParseInteger(input);
621 len = ParseInteger(input);
623 if (len == 0)
624 object.classPath = "com.barry." + appName;
625 else if (len != 0xFFFFFF)
626 object.classPath = ParseString(input, len);
628 len = ParseInteger(input);
630 object.sourceFile = ParseString(input, len);
632 object.unknown05 = ParseInteger(input);
633 object.unknown06 = ParseInteger(input);
634 object.unknown07 = ParseInteger(input);
635 object.unknown08 = ParseInteger(input);
637 classList.push_back(object);
639 dout("\n name : " << object.className
640 << "\n path : " << object.classPath
641 << "\n type : " << hex << object.type
642 << "\n unknown02 : " << hex << object.unknown02
643 << "\n unknown03 : " << hex << object.unknown03
644 << "\n id : " << hex << object.id
645 << "\n source file : " << object.sourceFile
646 << "\n unknown05 : " << hex << object.unknown05
647 << "\n unknown06 : " << hex << object.unknown06
648 << "\n unknown07 : " << hex << object.unknown07
649 << "\n unknown08 : " << hex << object.unknown08);
653 void CodInfo::ParseArray(istream &input)
655 uint32_t len = ParseInteger(input);
657 string str = ParseString(input, len);
659 dout("JDG::CodInfo::ParseArray\n name : " << str);
663 void CodInfo::ParseVoid(istream &input)
665 uint32_t len = ParseInteger(input);
667 string str = ParseString(input, len);
669 dout("JDG::CodInfo::ParseVoid\n name : " << str);
673 void CodInfo::ParseDouble(istream &input)
675 uint32_t len = ParseInteger(input);
677 string str = ParseString(input, len);
679 dout("JDG::CodInfo::ParseDouble\n name : " << str);
683 void CodInfo::ParseType2(istream &input) {
684 uint32_t value;
685 uint32_t len = ParseInteger(input);
687 string str = ParseString(input, len);
689 dout("Type2 : " << str);
691 value = ParseInteger(input);
692 value = ParseInteger(input);
693 value = ParseInteger(input);
694 value = ParseInteger(input);
695 value = ParseInteger(input);
696 value = ParseInteger(input);
699 } // namespace JDG
701 } // namespace Barry