menu: added new Keywords tag to .desktop files
[barry.git] / src / dp_codinfo.cc
blob567d073fa67c005a5cd6174d296cada480afcb37
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 "i18n.h"
36 #include <fstream>
37 #include <iomanip>
39 #include <sys/types.h>
40 #include <dirent.h>
41 #include <string.h>
43 #include "dp_parser.h"
44 #include "dp_codinfo.h"
45 #include "ios_state.h"
46 #include "debug.h"
49 #define COD_DEBUG_APPNAME_HEADERFIELD 0x0
50 #define COD_DEBUG_UNIQUEID_HEADERFIELD 0x8
52 #define COD_DEBUG_NONE_FIELD 0x0
53 #define COD_DEBUG_BOOLEAN_FIELD 0x1
54 #define COD_DEBUG_BYTE_FIELD 0x2
55 #define COD_DEBUG_CHAR_FIELD 0x3
56 #define COD_DEBUG_SHORT_FIELD 0x4
57 #define COD_DEBUG_INT_FIELD 0x5
58 #define COD_DEBUG_LONG_FIELD 0x6
59 #define COD_DEBUG_CLASS_FIELD 0x7
60 #define COD_DEBUG_ARRAY_FIELD 0x8
61 #define COD_DEBUG_VOID_FIELD 0xA
62 #define COD_DEBUG_DOUBLE_FIELD 0xC
65 using namespace std;
68 namespace Barry {
70 namespace JDG {
73 // Public API
74 //------------
76 #define DEBUG_FILE_EXT ".debug"
79 void SearchDebugFile(DebugFileList &list)
81 DIR *path;
82 struct dirent *entry;
84 path = opendir(".");
86 while( (entry = readdir(path)) ) {
87 int offset;
89 if (strlen(entry->d_name) < strlen(DEBUG_FILE_EXT))
90 continue;
92 offset = strlen(entry->d_name) - strlen(DEBUG_FILE_EXT);
94 if (!strcmp(entry->d_name + offset, DEBUG_FILE_EXT)) {
95 ifstream file(entry->d_name);
97 CodInfo info;
99 // Parse header section
100 info.ParseHeaderSection(file);
102 // Add element to list
103 list.AddElement(info.GetUniqueId(), info.GetAppName(), entry->d_name);
107 closedir(path);
111 bool LoadDebugInfo(const DebugFileList &list, const char *filename, CodInfo &info)
113 if (filename == NULL)
114 return false;
116 DebugFileList::const_iterator b = list.begin();
118 for( ; b != list.end(); b++ ) {
119 const DebugFileEntry &entry = (*b);
121 if( entry.fileName == filename ) {
122 info.LoadDebugFile(filename);
123 return true;
127 return false;
131 bool LoadDebugInfo(const DebugFileList &list, const uint32_t uniqueId, const std::string module, CodInfo &info)
133 DebugFileList::const_iterator b = list.begin();
135 for( ; b != list.end(); b++ ) {
136 const DebugFileEntry &entry = (*b);
138 if ((entry.uniqueId == uniqueId) && (entry.appName == module)) {
139 info.LoadDebugFile(entry.fileName.c_str());
140 return true;
144 return false;
148 // DebugFileList class
149 //------------------------
151 void DebugFileList::AddElement(uint32_t uniqueid,
152 const std::string &appname,
153 const std::string &filename)
155 DebugFileEntry entry;
157 entry.uniqueId = uniqueid;
158 entry.appName = appname;
159 entry.fileName = filename;
161 push_back(entry);
165 void DebugFileList::Dump(std::ostream &os) const
167 ios_format_state state(os);
169 const_iterator i = begin(), e = end();
171 os << _(" UniqueID ") << "|";
172 os << _(" Module Name ") << "|";
173 os << _(" File Name ") << endl;
175 os << "------------+";
176 os << "--------------------------+";
177 os << "--------------------------";
178 os << endl;
180 for( ; i != e; ++i ) {
181 (*i).Dump(os);
186 void DebugFileEntry::Dump(std::ostream &os) const
188 ios_format_state state(os);
190 os << " 0x" << setfill('0') << setw(8) << hex << uniqueId << " |";
191 os << " " << appName << setfill(' ') << setw(24) << " |";
192 os << " " << fileName << endl;
196 // ClassList class
197 //---------------------------
200 void ClassList::CreateDefaultEntries()
202 ClassEntry entry;
204 // 1
205 entry.classPath = "com.rim.resources";
206 entry.className = "net_rim_rimsecuridlibRIMResources";
207 push_back(entry);
209 // 2
210 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
211 entry.className = "RimSecurIDLib";
212 push_back(entry);
214 // 3
215 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
216 entry.className = "RimDatabaseFullException";
217 push_back(entry);
219 // 4
220 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
221 entry.className = "RimDecryptFailException";
222 push_back(entry);
224 // 5
225 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
226 entry.className = "RimDuplicateNameException";
227 push_back(entry);
229 // 6
230 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
231 entry.className = "RimDuplicateTokenException";
232 push_back(entry);
234 // 7
235 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
236 entry.className = "RimInvalidParamException";
237 push_back(entry);
239 // 8
240 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
241 entry.className = "RimSecurIDLib";
242 push_back(entry);
244 // 9
245 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
246 entry.className = "RimWrongDeviceIDException";
247 push_back(entry);
249 // 10
250 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
251 entry.className = "RimWrongFormFactorException";
252 push_back(entry);
256 // CodInfo class
257 //------------------------
259 bool CodInfo::LoadDebugFile(const char *filename)
261 uint32_t field;
263 if (filename == NULL)
264 return false;
266 ifstream file(filename);
268 // Parse header file
269 ParseHeaderSection(file);
271 // Parse type area zone
272 ParseTypeSection(file);
274 // FIXME : ???
275 field = ParseInteger(file); // Read 0x0
276 field = ParseInteger(file); // Read 0x1
278 // FIXME : ???
279 field = ParseInteger(file); // Read 0x0
280 field = ParseInteger(file); // Read 0x0 or 0xA
282 if (field == 0xA) {
283 // Parse ressource area zone
284 ParseResourceSection(file);
287 return true;
291 uint32_t CodInfo::GetUniqueId()
293 return uniqueId;
297 string CodInfo::GetAppName()
299 return appName;
303 // Private API - Section parsing
304 //-------------------------------
306 void CodInfo::ParseHeaderSection(istream &input)
308 uint32_t type;
310 type = ParseNextHeaderField(input);
312 if (type != COD_DEBUG_UNIQUEID_HEADERFIELD)
313 return;
315 type = ParseNextHeaderField(input);
317 if (type != COD_DEBUG_APPNAME_HEADERFIELD)
318 return;
322 void CodInfo::ParseTypeSection(istream &input)
324 uint32_t type;
325 uint32_t count;
326 uint32_t nbr, check;
328 // Read number of declared type content into this section
329 nbr = ParseInteger(input);
331 // Read each object
332 count = 0;
334 while (!input.eof()) {
335 type = ParseNextTypeField(input);
337 if (type == COD_DEBUG_NONE_FIELD)
338 break;
340 count++;
343 // Read again number of declared type content into this section
344 // We have to find the same value
345 check = ParseInteger(input);
347 // Checking... this code only exists in __DEBUG_MODE__ only, so
348 // make sure unused variables are always "used"
349 (void)nbr;
350 (void)check;
351 dout("Nbr = " << dec << nbr << " / Count = " << dec << count << " / check = " << check);
355 void CodInfo::ParseResourceSection(istream &input)
357 uint32_t len;
358 uint32_t type;
359 uint32_t unknown01;
360 uint32_t unknown02;
361 uint32_t unknown03;
362 uint32_t unknown04;
363 uint32_t unknown05;
364 uint32_t unknown06;
365 uint32_t unknown07;
367 string name;
369 // type = 1
370 for (int i=0; i<10; i++) {
371 type = ParseInteger(input);
373 len = ParseInteger(input);
374 name = ParseString(input, len);
376 unknown01 = ParseInteger(input);
377 unknown02 = ParseInteger(input);
378 unknown03 = ParseInteger(input);
380 dout("JDGCodInfo::parseRessource"
381 << "\n Name : " << name
382 << "\n unknown01 : " << hex << unknown01
383 << "\n unknown02 : " << hex << unknown02
384 << "\n unknown03 : " << hex << unknown03);
387 // type = 2
388 type = ParseInteger(input);
390 len = ParseInteger(input);
391 name = ParseString(input, len);
393 unknown01 = ParseInteger(input);
394 unknown02 = ParseInteger(input);
395 unknown03 = ParseInteger(input);
396 unknown04 = ParseInteger(input);
397 unknown05 = ParseInteger(input);
398 unknown06 = ParseInteger(input);
399 unknown07 = ParseInteger(input);
401 dout("JDGCodInfo::parseRessource"
402 << "\n Name : " << name
403 << "\n unknown01 : " << hex << unknown01
404 << "\n unknown02 : " << hex << unknown02
405 << "\n unknown03 : " << hex << unknown03
406 << "\n unknown04 : " << hex << unknown04
407 << "\n unknown05 : " << hex << unknown05
408 << "\n unknown06 : " << hex << unknown06
409 << "\n unknown07 : " << hex << unknown07);
411 // type = 1
412 type = ParseInteger(input);
414 len = ParseInteger(input);
415 name = ParseString(input, len);
417 unknown01 = ParseInteger(input);
418 unknown02 = ParseInteger(input);
419 unknown03 = ParseInteger(input);
420 unknown04 = ParseInteger(input);
422 dout("JDGCodInfo::parseRessource"
423 << "\n Name : " << name
424 << "\n unknown01 : " << hex << unknown01
425 << "\n unknown02 : " << hex << unknown02
426 << "\n unknown03 : " << hex << unknown03
427 << "\n unknown04 : " << hex << unknown04);
429 // type = 0
430 type = ParseInteger(input);
432 len = ParseInteger(input);
433 name = ParseString(input, len);
435 unknown01 = ParseInteger(input);
436 unknown02 = ParseInteger(input);
437 unknown03 = ParseInteger(input);
438 unknown04 = ParseInteger(input);
439 unknown05 = ParseInteger(input);
441 dout("JDGCodInfo::parseRessource"
442 << "\n Name : " << name
443 << "\n unknown01 : " << hex << unknown01
444 << "\n unknown02 : " << hex << unknown02
445 << "\n unknown03 : " << hex << unknown03
446 << "\n unknown04 : " << hex << unknown04
447 << "\n unknown05 : " << hex << unknown05);
449 // make sure that unused variables are always "used" when
450 // not in __DEBUG_MODE__
451 (void)type;
452 (void)unknown01;
453 (void)unknown02;
454 (void)unknown03;
455 (void)unknown04;
456 (void)unknown05;
457 (void)unknown06;
458 (void)unknown07;
463 // Private API - Field parsing
464 //-------------------------------
467 uint32_t CodInfo::ParseNextHeaderField(istream &input)
469 uint32_t type = ParseInteger(input);
471 switch (type) {
472 case COD_DEBUG_UNIQUEID_HEADERFIELD:
473 ParseUniqueId(input);
474 break;
476 case COD_DEBUG_APPNAME_HEADERFIELD:
477 ParseAppName(input);
478 break;
480 default:
481 type = 0xFFFFFFFF;
484 return type;
488 uint32_t CodInfo::ParseNextTypeField(istream &input)
490 uint32_t type = ParseInteger(input);
492 switch (type) {
493 case COD_DEBUG_NONE_FIELD:
494 break;
496 case COD_DEBUG_BOOLEAN_FIELD:
497 ParseBoolean(input);
498 break;
500 case COD_DEBUG_BYTE_FIELD:
501 ParseByte(input);
502 break;
504 case COD_DEBUG_CHAR_FIELD:
505 ParseChar(input);
506 break;
508 case COD_DEBUG_SHORT_FIELD:
509 ParseShort(input);
510 break;
512 case COD_DEBUG_INT_FIELD:
513 ParseInt(input);
514 break;
516 case COD_DEBUG_LONG_FIELD:
517 ParseLong(input);
518 break;
520 case COD_DEBUG_CLASS_FIELD:
521 ParseClass(input);
522 break;
524 case COD_DEBUG_ARRAY_FIELD:
525 ParseArray(input);
526 break;
528 case COD_DEBUG_VOID_FIELD:
529 ParseVoid(input);
530 break;
532 case COD_DEBUG_DOUBLE_FIELD:
533 ParseDouble(input);
534 break;
536 default:
537 dout("Type unknown ! " << hex << type);
538 type = 0xFFFFFFFF;
541 return type;
545 void CodInfo::ParseUniqueId(istream &input)
547 uniqueId = ParseInteger(input);
551 void CodInfo::ParseAppName(istream &input)
553 uint32_t len = ParseInteger(input);
555 appName = ParseString(input, len);
559 void CodInfo::ParseBoolean(istream &input)
561 uint32_t len = ParseInteger(input);
563 string str = ParseString(input, len);
565 dout("JDG::CodInfo::ParseBoolean\n name : " << str);
569 void CodInfo::ParseByte(istream &input)
571 uint32_t len = ParseInteger(input);
573 string str = ParseString(input, len);
575 dout("JDG::CodInfo::ParseByte\n name : " << str);
579 void CodInfo::ParseChar(istream &input)
581 uint32_t len = ParseInteger(input);
583 string str = ParseString(input, len);
585 dout("JDG::CodInfo::ParseChar\n name : " << str);
589 void CodInfo::ParseShort(istream &input)
591 uint32_t len = ParseInteger(input);
593 string str = ParseString(input, len);
595 dout("JDG::CodInfo::ParseShort\n name : " << str);
599 void CodInfo::ParseInt(istream &input)
601 uint32_t len = ParseInteger(input);
603 string str = ParseString(input, len);
605 dout("JDG::CodInfo::ParseInt\n name : " << str);
609 void CodInfo::ParseLong(istream &input)
611 uint32_t len = ParseInteger(input);
613 string str = ParseString(input, len);
615 dout("JDG::CodInfo::ParseLong\n name : " << str);
619 void CodInfo::ParseClass(istream &input)
621 uint32_t len;
623 ClassEntry object;
625 dout("JDG::CodInfo::ParseClass");
627 len = ParseInteger(input);
629 object.className = ParseString(input, len);
631 object.type = ParseInteger(input);
632 object.unknown02 = ParseInteger(input);
633 object.unknown03 = ParseInteger(input);
634 object.id = ParseInteger(input);
636 len = ParseInteger(input);
638 if (len == 0)
639 object.classPath = "com.barry." + appName;
640 else if (len != 0xFFFFFF)
641 object.classPath = ParseString(input, len);
643 len = ParseInteger(input);
645 object.sourceFile = ParseString(input, len);
647 object.unknown05 = ParseInteger(input);
648 object.unknown06 = ParseInteger(input);
649 object.unknown07 = ParseInteger(input);
650 object.unknown08 = ParseInteger(input);
652 classList.push_back(object);
654 dout("\n name : " << object.className
655 << "\n path : " << object.classPath
656 << "\n type : " << hex << object.type
657 << "\n unknown02 : " << hex << object.unknown02
658 << "\n unknown03 : " << hex << object.unknown03
659 << "\n id : " << hex << object.id
660 << "\n source file : " << object.sourceFile
661 << "\n unknown05 : " << hex << object.unknown05
662 << "\n unknown06 : " << hex << object.unknown06
663 << "\n unknown07 : " << hex << object.unknown07
664 << "\n unknown08 : " << hex << object.unknown08);
668 void CodInfo::ParseArray(istream &input)
670 uint32_t len = ParseInteger(input);
672 string str = ParseString(input, len);
674 dout("JDG::CodInfo::ParseArray\n name : " << str);
678 void CodInfo::ParseVoid(istream &input)
680 uint32_t len = ParseInteger(input);
682 string str = ParseString(input, len);
684 dout("JDG::CodInfo::ParseVoid\n name : " << str);
688 void CodInfo::ParseDouble(istream &input)
690 uint32_t len = ParseInteger(input);
692 string str = ParseString(input, len);
694 dout("JDG::CodInfo::ParseDouble\n name : " << str);
698 void CodInfo::ParseType2(istream &input) {
699 uint32_t value;
700 uint32_t len = ParseInteger(input);
702 string str = ParseString(input, len);
704 dout("Type2 : " << str);
706 value = ParseInteger(input);
707 value = ParseInteger(input);
708 value = ParseInteger(input);
709 value = ParseInteger(input);
710 value = ParseInteger(input);
711 value = ParseInteger(input);
714 } // namespace JDG
716 } // namespace Barry