/*************************************************************************** * Copyright (C) 2006 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "coff_archive.h" //---------------------------------------------------------------------------- Coff::Member::Member(const TQByteArray &data, uint &offset, Log::Base &log) { // parse header TQString s; if ( !getString(data, offset, 256, log, s) ) return; int i = s.find('/'); if ( i==-1 ) { log.log(Log::LineType::Error, i18n("Member name not terminated by '/' (\"%1\").").tqarg(s)); return; } _name = s.mid(0, i); if ( !getString(data, offset, 12, log, s) ) return; // mtime if ( !getString(data, offset, 10, log, s) ) return; i = s.find('l'); if ( i==-1 ) { log.log(Log::LineType::Error, i18n("File size not terminated by 'l' (\"%1\").").tqarg(s)); return; } bool ok; _nbBytes = s.mid(0, i).toUInt(&ok); if ( !ok ) { log.log(Log::LineType::Error, i18n("Wrong format for file size \"%1\".").tqarg(s)); return; } TQ_UINT32 v; if ( !getULong(data, offset, 2, log, v) ) return; log.log(Log::DebugLevel::Extra, i18n("Magic number: %1").tqarg(toHexLabel(v, 4))); // if ( v!=0x600A ) { // log.log(Log::LineType::Error, i18n("Wrong magic for Microchip archive (\"%1\").").tqarg(toHexLabel(v, 4))); // return; // } offset += _nbBytes; } //---------------------------------------------------------------------------- Coff::Archive::Archive(const PURL::Url &url) : Base(url) {} bool Coff::Archive::parse(Log::Base &log) { TQByteArray data; uint offset = 0, symbolEnd = 0; Member *symbol = 0; if ( !initParse(CoffType::Archive, data, offset, log) ) return false; for (;;) { if ( offset==uint(data.count()) ) break; // end of archive uint start = offset; Member *member = new Member(data, offset, log); if ( log.hasError() ) return false; if ( member->name().isEmpty() ) { symbolEnd = offset; symbol = member; } else { _members[member->name()] = member; _offsets[start] = member; } } if (symbol) { if ( !readSymbols(data, symbolEnd - symbol->nbBytes(), log) ) return false; delete symbol; } return true; } Coff::Archive::~Archive() { TQMap::const_iterator it; for (it=_members.begin(); it!=_members.end(); ++it) delete it.data(); } bool Coff::Archive::readSymbols(const TQByteArray &data, uint offset, Log::Base &log) { TQ_UINT32 nb; if ( !getULong(data, offset, 4, log, nb) ) return false; TQValueVector members(nb); for (uint i=0; i::const_iterator it; for (it=members().begin(); it!=members().end(); ++it) keys.append(it.key(), i18n("size: %1 bytes").tqarg(it.data()->nbBytes())); return keys; } Log::KeyList Coff::Archive::symbolsInformation() const { Log::KeyList keys(i18n("Symbols:")); TQMap::const_iterator it; for (it=symbols().begin(); it!=symbols().end(); ++it) keys.append(it.key(), it.data()->name()); return keys; }