Updated the resources support with the unmodified Haiku version.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34251 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-11-25 17:19:14 +00:00
parent d3ed58a7c9
commit 4d8a54be0d
5 changed files with 751 additions and 431 deletions
+220
View File
@@ -0,0 +1,220 @@
/*
* Copyright 2001-2007, Ingo Weinhold, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _AUTO_DELETER_H
#define _AUTO_DELETER_H
/*! Scope-based automatic deletion of objects/arrays.
ObjectDeleter - deletes an object
ArrayDeleter - deletes an array
MemoryDeleter - free()s malloc()ed memory
CObjectDeleter - calls an arbitrary specified destructor function
*/
#include <stdlib.h>
namespace BPrivate {
// AutoDeleter
template<typename C, typename DeleteFunc>
class AutoDeleter {
public:
inline AutoDeleter()
: fObject(NULL)
{
}
inline AutoDeleter(C *object)
: fObject(object)
{
}
inline ~AutoDeleter()
{
fDelete(fObject);
}
inline void SetTo(C *object)
{
if (object != fObject) {
fDelete(fObject);
fObject = object;
}
}
inline void Unset()
{
SetTo(NULL);
}
inline void Delete()
{
SetTo(NULL);
}
inline C *Get() const
{
return fObject;
}
inline C *Detach()
{
C *object = fObject;
fObject = NULL;
return object;
}
protected:
C *fObject;
DeleteFunc fDelete;
};
// ObjectDeleter
template<typename C>
struct ObjectDelete
{
inline void operator()(C *object)
{
delete object;
}
};
template<typename C>
struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> >
{
ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {}
ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {}
};
// ArrayDeleter
template<typename C>
struct ArrayDelete
{
inline void operator()(C *array)
{
delete[] array;
}
};
template<typename C>
struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> >
{
ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {}
ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {}
};
// MemoryDeleter
struct MemoryDelete
{
inline void operator()(void *memory)
{
free(memory);
}
};
struct MemoryDeleter : AutoDeleter<void, MemoryDelete >
{
MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {}
MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {}
};
// CObjectDeleter
template<typename Type, typename DestructorReturnType>
struct CObjectDelete
{
inline void operator()(Type *object)
{
if (fDestructor != NULL && object != NULL)
fDestructor(object);
}
template<typename Destructor>
inline void operator=(Destructor destructor)
{
fDestructor = destructor;
}
private:
DestructorReturnType (*fDestructor)(Type*);
};
template<typename Type, typename DestructorReturnType = void>
struct CObjectDeleter
: AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> >
{
typedef AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> > Base;
template<typename Destructor>
CObjectDeleter(Destructor destructor) : Base()
{
Base::fDelete = destructor;
}
template<typename Destructor>
CObjectDeleter(Type *object, Destructor destructor) : Base(object)
{
Base::fDelete = destructor;
}
};
// MethodDeleter
template<typename Type, typename DestructorReturnType>
struct MethodDelete
{
inline void operator()(Type *object)
{
if (fDestructor && object != NULL)
(object->*fDestructor)();
}
template<typename Destructor>
inline void operator=(Destructor destructor)
{
fDestructor = destructor;
}
private:
DestructorReturnType (Type::*fDestructor)();
};
template<typename Type, typename DestructorReturnType = void>
struct MethodDeleter
: AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> >
{
typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base;
template<typename Destructor>
MethodDeleter(Destructor destructor) : Base()
{
Base::fDelete = destructor;
}
template<typename Destructor>
MethodDeleter(Type *object, Destructor destructor) : Base(object)
{
Base::fDelete = destructor;
}
};
} // namespace BPrivate
using BPrivate::ObjectDeleter;
using BPrivate::ArrayDeleter;
using BPrivate::MemoryDeleter;
using BPrivate::CObjectDeleter;
using BPrivate::MethodDeleter;
#endif // _AUTO_DELETER_H
+35 -48
View File
@@ -1,14 +1,30 @@
// Elf.h /*
* Copyright 2002-2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _ELF_H #ifndef _ELF_H
#define _ELF_H #define _ELF_H
#include <SupportDefs.h>
// types // types
typedef uint32 Elf32_Addr; typedef uint32 Elf32_Addr;
typedef uint16 Elf32_Half;
typedef uint32 Elf32_Off; typedef uint32 Elf32_Off;
typedef uint16 Elf32_Half;
typedef int32 Elf32_Sword; typedef int32 Elf32_Sword;
typedef uint32 Elf32_Word; typedef uint32 Elf32_Word;
typedef uint32 Elf32_Xword;
typedef int32 Elf32_Sxword;
typedef uint64 Elf64_Addr;
typedef uint64 Elf64_Off;
typedef uint16 Elf64_Half;
typedef int32 Elf64_Sword;
typedef uint32 Elf64_Word;
typedef uint64 Elf64_Xword;
typedef int64 Elf64_Sxword;
// e_ident indices // e_ident indices
#define EI_MAG0 0 #define EI_MAG0 0
@@ -21,23 +37,9 @@ typedef uint32 Elf32_Word;
#define EI_PAD 7 #define EI_PAD 7
#define EI_NIDENT 16 #define EI_NIDENT 16
// object file header // e_ident EI_VERSION values
typedef struct { #define EV_NONE 0
unsigned char e_ident[EI_NIDENT]; #define EV_CURRENT 1
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
// e_ident EI_CLASS and EI_DATA values // e_ident EI_CLASS and EI_DATA values
#define ELFCLASSNONE 0 #define ELFCLASSNONE 0
@@ -47,18 +49,6 @@ typedef struct {
#define ELFDATA2LSB 1 #define ELFDATA2LSB 1
#define ELFDATA2MSB 2 #define ELFDATA2MSB 2
// program header
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
// p_type // p_type
#define PT_NULL 0 #define PT_NULL 0
#define PT_LOAD 1 #define PT_LOAD 1
@@ -70,20 +60,6 @@ typedef struct {
#define PT_LOPROC 0x70000000 #define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff #define PT_HIPROC 0x7fffffff
// section header
typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
// sh_type values // sh_type values
#define SHT_NULL 0 #define SHT_NULL 0
#define SHT_PROGBITS 1 #define SHT_PROGBITS 1
@@ -102,6 +78,17 @@ typedef struct {
#define SHT_LOUSER 0x80000000 #define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff #define SHT_HIUSER 0xffffffff
// 32 bit definitions
#undef _ELFX_BITS
#define _ELFX_BITS 32
#include <ElfX.h>
// 64 bit definitions
#undef _ELFX_BITS
#define _ELFX_BITS 64
#include <ElfX.h>
#undef _ELFX_BITS
#endif // _ELF_H #endif // _ELF_H
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright 2002-2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
// No header guard: The file is included twice by <Elf.h> and must not be
// included elsewhere. The _ELFX_BITS macro must be define before inclusion.
#undef ElfX
#if _ELFX_BITS == 32
# define ElfX(x) Elf32_##x
#elif _ELFX_BITS == 64
# define ElfX(x) Elf64_##x
#endif
// object file header
typedef struct {
unsigned char e_ident[EI_NIDENT];
ElfX(Half) e_type;
ElfX(Half) e_machine;
ElfX(Word) e_version;
ElfX(Addr) e_entry;
ElfX(Off) e_phoff;
ElfX(Off) e_shoff;
ElfX(Word) e_flags;
ElfX(Half) e_ehsize;
ElfX(Half) e_phentsize;
ElfX(Half) e_phnum;
ElfX(Half) e_shentsize;
ElfX(Half) e_shnum;
ElfX(Half) e_shstrndx;
} ElfX(Ehdr);
// program header
typedef struct {
ElfX(Word) p_type;
#if _ELFX_BITS == 64
ElfX(Word) p_flags;
#endif
ElfX(Off) p_offset;
ElfX(Addr) p_vaddr;
ElfX(Addr) p_paddr;
ElfX(Xword) p_filesz;
ElfX(Xword) p_memsz;
#if _ELFX_BITS == 32
ElfX(Word) p_flags;
#endif
ElfX(Xword) p_align;
} ElfX(Phdr);
// section header
typedef struct {
ElfX(Word) sh_name;
ElfX(Word) sh_type;
ElfX(Xword) sh_flags;
ElfX(Addr) sh_addr;
ElfX(Off) sh_offset;
ElfX(Xword) sh_size;
ElfX(Word) sh_link;
ElfX(Word) sh_info;
ElfX(Xword) sh_addralign;
ElfX(Xword) sh_entsize;
} ElfX(Shdr);
#undef ElfX
+69 -39
View File
@@ -1,31 +1,37 @@
//---------------------------------------------------------------------- /*
// This software is part of the OpenBeOS distribution and is covered * Copyright 2002-2009, Ingo Weinhold, [email protected].
// by the OpenBeOS license. * Distributed under the terms of the MIT License.
//--------------------------------------------------------------------- */
#ifndef _RESOURCE_FILE_H
#define _RESOURCE_FILE_H
/*! /*!
\file ResourceFile.h \file ResourceFile.h
ResourceFile interface declaration. ResourceFile interface declaration.
*/ */
#ifndef _RESOURCE_FILE_H
#define _RESOURCE_FILE_H
#include <ByteOrder.h> #include <ByteOrder.h>
#include "OffsetFile.h" #include "OffsetFile.h"
struct resource_info; struct resource_info;
struct PEFContainerHeader; struct PEFContainerHeader;
namespace BPrivate { namespace BPrivate {
namespace Storage { namespace Storage {
class Exception; class Exception;
struct MemArea; struct MemArea;
class ResourceItem; class ResourceItem;
struct resource_parse_info; struct resource_parse_info;
class ResourcesContainer; class ResourcesContainer;
/*! /*!
\class ResourceFile \class ResourceFile
\brief Represents a file capable of containing resources. \brief Represents a file capable of containing resources.
@@ -58,21 +64,33 @@ public:
status_t InitCheck() const; status_t InitCheck() const;
status_t InitContainer(ResourcesContainer& container); status_t InitContainer(ResourcesContainer& container);
status_t ReadResource(ResourceItem &resource, bool force = false); status_t ReadResource(ResourceItem& resource,
status_t ReadResources(ResourcesContainer &container, bool force = false); bool force = false);
status_t ReadResources(ResourcesContainer& container,
bool force = false);
status_t WriteResources(ResourcesContainer& container); status_t WriteResources(ResourcesContainer& container);
private: private:
void _InitFile(BFile& file, bool clobber); void _InitFile(BFile& file, bool clobber);
void _InitELFFile(BFile& file); void _InitELFFile(BFile& file);
void _InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader);
template<typename ElfHeader, typename ElfProgramHeader,
typename ElfSectionHeader>
void _InitELFXFile(BFile& file, uint64 fileSize);
void _InitPEFFile(BFile& file,
const PEFContainerHeader& pefHeader);
void _ReadHeader(resource_parse_info& parseInfo); void _ReadHeader(resource_parse_info& parseInfo);
void _ReadIndex(resource_parse_info& parseInfo); void _ReadIndex(resource_parse_info& parseInfo);
bool _ReadIndexEntry(resource_parse_info &parseInfo, int32 index, bool _ReadIndexEntry(resource_parse_info& parseInfo,
uint32 tableOffset, bool peekAhead); int32 index, uint32 tableOffset,
bool peekAhead);
void _ReadInfoTable(resource_parse_info& parseInfo); void _ReadInfoTable(resource_parse_info& parseInfo);
bool _ReadInfoTableEnd(const void *data, int32 dataSize); bool _ReadInfoTableEnd(const void* data,
const void *_ReadResourceInfo(resource_parse_info &parseInfo, int32 dataSize);
const void* _ReadResourceInfo(
resource_parse_info& parseInfo,
const MemArea& area, const MemArea& area,
const resource_info* info, type_code type, const resource_info* info, type_code type,
bool* readIndices); bool* readIndices);
@@ -80,10 +98,12 @@ private:
status_t _WriteResources(ResourcesContainer& container); status_t _WriteResources(ResourcesContainer& container);
status_t _MakeEmptyResourceFile(); status_t _MakeEmptyResourceFile();
inline int16 _GetInt16(int16 value); inline int16 _GetInt(int16 value) const;
inline uint16 _GetUInt16(uint16 value); inline uint16 _GetInt(uint16 value) const;
inline int32 _GetInt32(int32 value); inline int32 _GetInt(int32 value) const;
inline uint32 _GetUInt32(uint32 value); inline uint32 _GetInt(uint32 value) const;
inline int64 _GetInt(int64 value) const;
inline uint64 _GetInt(uint64 value) const;
private: private:
OffsetFile fFile; OffsetFile fFile;
@@ -92,41 +112,51 @@ private:
bool fEmptyResources; bool fEmptyResources;
}; };
// _GetInt16
inline inline int16
int16 ResourceFile::_GetInt(int16 value) const
ResourceFile::_GetInt16(int16 value)
{ {
return (fHostEndianess ? value : B_SWAP_INT16(value)); return fHostEndianess ? value : (int16)B_SWAP_INT16((uint16)value);
} }
// _GetUInt16
inline inline uint16
uint16 ResourceFile::_GetInt(uint16 value) const
ResourceFile::_GetUInt16(uint16 value)
{ {
return (fHostEndianess ? value : B_SWAP_INT16(value)); return fHostEndianess ? value : B_SWAP_INT16(value);
} }
// _GetInt32
inline inline int32
int32 ResourceFile::_GetInt(int32 value) const
ResourceFile::_GetInt32(int32 value)
{ {
return (fHostEndianess ? value : B_SWAP_INT32(value)); return fHostEndianess ? value : (int32)B_SWAP_INT32((uint32)value);
} }
// _GetUInt32
inline inline uint32
uint32 ResourceFile::_GetInt(uint32 value) const
ResourceFile::_GetUInt32(uint32 value)
{ {
return (fHostEndianess ? value : B_SWAP_INT32(value)); return fHostEndianess ? value : B_SWAP_INT32(value);
} }
inline int64
ResourceFile::_GetInt(int64 value) const
{
return fHostEndianess ? value : (int64)B_SWAP_INT64((uint64)value);
}
inline uint64
ResourceFile::_GetInt(uint64 value) const
{
return fHostEndianess ? value : B_SWAP_INT64(value);
}
}; // namespace Storage }; // namespace Storage
}; // namespace BPrivate }; // namespace BPrivate
#endif // _RESOURCE_FILE_H #endif // _RESOURCE_FILE_H
+197 -182
View File
@@ -1,42 +1,46 @@
/* /*
* Copyright 2002-2006, Haiku Inc. * Copyright 2002-2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Ingo Weinhold, [email protected]
*/ */
/*! /*!
\file ResourceFile.cpp \file ResourceFile.cpp
ResourceFile implementation. ResourceFile implementation.
*/ */
#include <ResourceFile.h> #include <ResourceFile.h>
#include <algorithm> #include <algorithm>
#include <new> #include <new>
#include <stdio.h> #include <stdio.h>
#include "Elf.h" #include <AutoDeleter.h>
#include "Exception.h"
#include "Pef.h" #include <Elf.h>
#include "ResourceItem.h" #include <Exception.h>
#include "ResourcesContainer.h" #include <Pef.h>
#include "ResourcesDefs.h" #include <ResourceItem.h>
#include <ResourcesContainer.h>
#include <ResourcesDefs.h>
//#include <Warnings.h>
namespace BPrivate { namespace BPrivate {
namespace Storage { namespace Storage {
// ELF defs // ELF defs
static const uint32 kMaxELFHeaderSize = sizeof(Elf32_Ehdr) + 32; static const uint32 kMaxELFHeaderSize
= std::max(sizeof(Elf32_Ehdr), sizeof(Elf64_Ehdr)) + 32;
static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' }; static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
// sanity bounds // sanity bounds
static const uint32 kMaxResourceCount = 10000; static const uint32 kMaxResourceCount = 10000;
static const uint32 kELFMaxResourceAlignment = 1024 * 1024 * 10; // 10 MB static const uint32 kELFMaxResourceAlignment = 1024 * 1024 * 10; // 10 MB
// recognized file types (indices into kFileTypeNames) // recognized file types (indices into kFileTypeNames)
enum { enum {
FILE_TYPE_UNKNOWN = 0, FILE_TYPE_UNKNOWN = 0,
@@ -47,6 +51,7 @@ enum {
FILE_TYPE_EMPTY = 5, FILE_TYPE_EMPTY = 5,
}; };
const char* kFileTypeNames[] = { const char* kFileTypeNames[] = {
"unknown", "unknown",
"x86 resource file", "x86 resource file",
@@ -56,17 +61,17 @@ const char *kFileTypeNames[] = {
"empty file", "empty file",
}; };
// debugging // debugging
//#define DBG(x) x //#define DBG(x) x
#define DBG(x) #define DBG(x)
#define OUT printf #define OUT printf
// helper functions/classes // #pragma mark - helper functions/classes
// read_exactly
static static void
void
read_exactly(BPositionIO& file, off_t position, void* buffer, size_t size, read_exactly(BPositionIO& file, off_t position, void* buffer, size_t size,
const char* errorMessage = NULL) const char* errorMessage = NULL)
{ {
@@ -82,9 +87,8 @@ read_exactly(BPositionIO &file, off_t position, void *buffer, size_t size,
} }
} }
// write_exactly
static static void
void
write_exactly(BPositionIO& file, off_t position, const void* buffer, write_exactly(BPositionIO& file, off_t position, const void* buffer,
size_t size, const char* errorMessage = NULL) size_t size, const char* errorMessage = NULL)
{ {
@@ -100,18 +104,16 @@ write_exactly(BPositionIO &file, off_t position, const void *buffer,
} }
} }
// align_value
template<typename TV, typename TA> template<typename TV, typename TA>
static inline static inline TV
TV
align_value(const TV& value, const TA& alignment) align_value(const TV& value, const TA& alignment)
{ {
return ((value + alignment - 1) / alignment) * alignment; return ((value + alignment - 1) / alignment) * alignment;
} }
// calculate_checksum
static static uint32
uint32
calculate_checksum(const void* data, uint32 size) calculate_checksum(const void* data, uint32 size)
{ {
uint32 checkSum = 0; uint32 checkSum = 0;
@@ -120,7 +122,7 @@ calculate_checksum(const void *data, uint32 size)
const uint8* current = csData; const uint8* current = csData;
for (; current < dataEnd; current += 4) { for (; current < dataEnd; current += 4) {
uint32 word = 0; uint32 word = 0;
int32 bytes = min_c(4L, (int32)(dataEnd - current)); int32 bytes = std::min((int32)4, (int32)(dataEnd - current));
for (int32 i = 0; i < bytes; i++) for (int32 i = 0; i < bytes; i++)
word = (word << 8) + current[i]; word = (word << 8) + current[i];
checkSum += word; checkSum += word;
@@ -128,25 +130,22 @@ calculate_checksum(const void *data, uint32 size)
return checkSum; return checkSum;
} }
// skip_bytes
static inline static inline const void*
const void*
skip_bytes(const void* buffer, int32 offset) skip_bytes(const void* buffer, int32 offset)
{ {
return (const char*)buffer + offset; return (const char*)buffer + offset;
} }
// skip_bytes
static inline static inline void*
void*
skip_bytes(void* buffer, int32 offset) skip_bytes(void* buffer, int32 offset)
{ {
return (char*)buffer + offset; return (char*)buffer + offset;
} }
// fill_pattern
static static void
void
fill_pattern(uint32 byteOffset, void* _buffer, uint32 count) fill_pattern(uint32 byteOffset, void* _buffer, uint32 count)
{ {
uint32* buffer = (uint32*)_buffer; uint32* buffer = (uint32*)_buffer;
@@ -154,26 +153,23 @@ fill_pattern(uint32 byteOffset, void *_buffer, uint32 count)
buffer[i] = kUnusedResourceDataPattern[(byteOffset / 4 + i) % 3]; buffer[i] = kUnusedResourceDataPattern[(byteOffset / 4 + i) % 3];
} }
// fill_pattern
static static void
void
fill_pattern(const void* dataBegin, void* buffer, uint32 count) fill_pattern(const void* dataBegin, void* buffer, uint32 count)
{ {
fill_pattern((char*)buffer - (const char*)dataBegin, buffer, count); fill_pattern((char*)buffer - (const char*)dataBegin, buffer, count);
} }
// fill_pattern
static static void
void
fill_pattern(const void* dataBegin, void* buffer, const void* bufferEnd) fill_pattern(const void* dataBegin, void* buffer, const void* bufferEnd)
{ {
fill_pattern(dataBegin, buffer, fill_pattern(dataBegin, buffer,
((const char*)bufferEnd - (char*)buffer) / 4); ((const char*)bufferEnd - (char*)buffer) / 4);
} }
// check_pattern
static static bool
bool
check_pattern(uint32 byteOffset, void* _buffer, uint32 count, check_pattern(uint32 byteOffset, void* _buffer, uint32 count,
bool hostEndianess) bool hostEndianess)
{ {
@@ -189,7 +185,10 @@ check_pattern(uint32 byteOffset, void *_buffer, uint32 count,
return result; return result;
} }
// MemArea
// #pragma mark -
struct MemArea { struct MemArea {
MemArea(const void* data, uint32 size) : data(data), size(size) {} MemArea(const void* data, uint32 size) : data(data), size(size) {}
@@ -204,26 +203,7 @@ struct MemArea {
uint32 size; uint32 size;
}; };
// AutoDeleter
template<typename C>
struct AutoDeleter {
AutoDeleter(C *object, bool array = false) : object(object), array(array)
{
}
~AutoDeleter()
{
if (array)
delete[] object;
else
delete object;
}
C* object;
bool array;
};
// resource_parse_info
struct resource_parse_info { struct resource_parse_info {
off_t file_size; off_t file_size;
int32 resource_count; int32 resource_count;
@@ -234,22 +214,25 @@ struct resource_parse_info {
}; };
// constructor // #pragma mark -
ResourceFile::ResourceFile() ResourceFile::ResourceFile()
: fFile(), :
fFile(),
fFileType(FILE_TYPE_UNKNOWN), fFileType(FILE_TYPE_UNKNOWN),
fHostEndianess(true), fHostEndianess(true),
fEmptyResources(true) fEmptyResources(true)
{ {
} }
// destructor
ResourceFile::~ResourceFile() ResourceFile::~ResourceFile()
{ {
Unset(); Unset();
} }
// SetTo
status_t status_t
ResourceFile::SetTo(BFile* file, bool clobber) ResourceFile::SetTo(BFile* file, bool clobber)
{ {
@@ -269,25 +252,24 @@ ResourceFile::SetTo(BFile *file, bool clobber)
return error; return error;
} }
// Unset
void void
ResourceFile::Unset() ResourceFile::Unset()
{ {
// file
fFile.Unset(); fFile.Unset();
fFileType = FILE_TYPE_UNKNOWN; fFileType = FILE_TYPE_UNKNOWN;
fHostEndianess = true; fHostEndianess = true;
fEmptyResources = true; fEmptyResources = true;
} }
// InitCheck
status_t status_t
ResourceFile::InitCheck() const ResourceFile::InitCheck() const
{ {
return fFile.InitCheck(); return fFile.InitCheck();
} }
// InitContainer
status_t status_t
ResourceFile::InitContainer(ResourcesContainer& container) ResourceFile::InitContainer(ResourcesContainer& container)
{ {
@@ -321,7 +303,7 @@ ResourceFile::InitContainer(ResourcesContainer &container)
return error; return error;
} }
// ReadResource
status_t status_t
ResourceFile::ReadResource(ResourceItem& resource, bool force) ResourceFile::ReadResource(ResourceItem& resource, bool force)
{ {
@@ -350,7 +332,7 @@ ResourceFile::ReadResource(ResourceItem &resource, bool force)
return error; return error;
} }
// ReadResources
status_t status_t
ResourceFile::ReadResources(ResourcesContainer& container, bool force) ResourceFile::ReadResources(ResourcesContainer& container, bool force)
{ {
@@ -365,7 +347,7 @@ ResourceFile::ReadResources(ResourcesContainer &container, bool force)
return error; return error;
} }
// WriteResources
status_t status_t
ResourceFile::WriteResources(ResourcesContainer& container) ResourceFile::WriteResources(ResourcesContainer& container)
{ {
@@ -382,7 +364,6 @@ ResourceFile::WriteResources(ResourcesContainer &container)
} }
// _InitFile
void void
ResourceFile::_InitFile(BFile& file, bool clobber) ResourceFile::_InitFile(BFile& file, bool clobber)
{ {
@@ -461,22 +442,29 @@ ResourceFile::_InitFile(BFile &file, bool clobber)
} }
} }
// _InitELFFile
void void
ResourceFile::_InitELFFile(BFile& file) ResourceFile::_InitELFFile(BFile& file)
{ {
status_t error = B_OK; status_t error = B_OK;
// get the file size // get the file size
off_t fileSize = 0; off_t fileSize = 0;
error = file.GetSize(&fileSize); error = file.GetSize(&fileSize);
if (error != B_OK) if (error != B_OK)
throw Exception(error, "Failed to get the file size."); throw Exception(error, "Failed to get the file size.");
// read ELF header
Elf32_Ehdr fileHeader; // read the ELF headers e_ident field
read_exactly(file, 0, &fileHeader, sizeof(Elf32_Ehdr), unsigned char identification[EI_NIDENT];
"Failed to read ELF header."); read_exactly(file, 0, identification, EI_NIDENT,
"Failed to read ELF identification.");
// check version
if (identification[EI_VERSION] != EV_CURRENT)
throw Exception(B_UNSUPPORTED, "Unsupported ELF version.");
// check data encoding (endianess) // check data encoding (endianess)
switch (fileHeader.e_ident[EI_DATA]) { switch (identification[EI_DATA]) {
case ELFDATA2LSB: case ELFDATA2LSB:
fHostEndianess = B_HOST_IS_LENDIAN; fHostEndianess = B_HOST_IS_LENDIAN;
break; break;
@@ -485,57 +473,84 @@ ResourceFile::_InitELFFile(BFile &file)
break; break;
default: default:
case ELFDATANONE: case ELFDATANONE:
throw Exception(B_IO_ERROR, "Unsupported ELF data encoding."); throw Exception(B_UNSUPPORTED, "Unsupported ELF data encoding.");
break;
} }
// check class (32/64 bit) and call the respective method handling it
switch (identification[EI_CLASS]) {
case ELFCLASS32:
_InitELFXFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(file, fileSize);
break;
case ELFCLASS64:
_InitELFXFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(file, fileSize);
break;
default:
throw Exception(B_UNSUPPORTED, "Unsupported ELF class.");
}
}
template<typename ElfHeader, typename ElfProgramHeader,
typename ElfSectionHeader>
void
ResourceFile::_InitELFXFile(BFile& file, uint64 fileSize)
{
// read ELF header
ElfHeader fileHeader;
read_exactly(file, 0, &fileHeader, sizeof(ElfHeader),
"Failed to read ELF header.");
// get the header values // get the header values
uint32 headerSize = _GetUInt16(fileHeader.e_ehsize); uint32 headerSize = _GetInt(fileHeader.e_ehsize);
uint32 programHeaderTableOffset = _GetUInt32(fileHeader.e_phoff); uint64 programHeaderTableOffset = _GetInt(fileHeader.e_phoff);
uint32 programHeaderSize = _GetUInt16(fileHeader.e_phentsize); uint32 programHeaderSize = _GetInt(fileHeader.e_phentsize);
uint32 programHeaderCount = _GetUInt16(fileHeader.e_phnum); uint32 programHeaderCount = _GetInt(fileHeader.e_phnum);
uint32 sectionHeaderTableOffset = _GetUInt32(fileHeader.e_shoff); uint64 sectionHeaderTableOffset = _GetInt(fileHeader.e_shoff);
uint32 sectionHeaderSize = _GetUInt16(fileHeader.e_shentsize); uint32 sectionHeaderSize = _GetInt(fileHeader.e_shentsize);
uint32 sectionHeaderCount = _GetUInt16(fileHeader.e_shnum); uint32 sectionHeaderCount = _GetInt(fileHeader.e_shnum);
bool hasProgramHeaderTable = (programHeaderTableOffset != 0); bool hasProgramHeaderTable = (programHeaderTableOffset != 0);
bool hasSectionHeaderTable = (sectionHeaderTableOffset != 0); bool hasSectionHeaderTable = (sectionHeaderTableOffset != 0);
// check the sanity of the header values // check the sanity of the header values
// ELF header size // ELF header size
if (headerSize < sizeof(Elf32_Ehdr) || headerSize > kMaxELFHeaderSize) { if (headerSize < sizeof(ElfHeader) || headerSize > kMaxELFHeaderSize) {
throw Exception(B_IO_ERROR, throw Exception(B_IO_ERROR,
"Invalid ELF header: invalid ELF header size: %lu.", "Invalid ELF header: invalid ELF header size: %lu.", headerSize);
headerSize);
} }
uint32 resourceOffset = headerSize; uint64 resourceOffset = headerSize;
uint32 resourceAlignment = 0; uint64 resourceAlignment = 0;
// program header table offset and entry count/size // program header table offset and entry count/size
uint32 programHeaderTableSize = 0; uint64 programHeaderTableSize = 0;
if (hasProgramHeaderTable) { if (hasProgramHeaderTable) {
if (programHeaderTableOffset < headerSize if (programHeaderTableOffset < headerSize
|| programHeaderTableOffset > fileSize) { || programHeaderTableOffset > fileSize) {
throw Exception(B_IO_ERROR, "Invalid ELF header: invalid program " throw Exception(B_IO_ERROR, "Invalid ELF header: invalid program "
"header table offset: %lu.", "header table offset: %lu.", programHeaderTableOffset);
programHeaderTableOffset);
} }
programHeaderTableSize = programHeaderSize * programHeaderCount; programHeaderTableSize = (uint64)programHeaderSize * programHeaderCount;
if (programHeaderSize < sizeof(Elf32_Phdr) if (programHeaderSize < sizeof(ElfProgramHeader)
|| programHeaderTableOffset + programHeaderTableSize > fileSize) { || programHeaderTableOffset + programHeaderTableSize > fileSize) {
throw Exception(B_IO_ERROR, "Invalid ELF header: program header " throw Exception(B_IO_ERROR, "Invalid ELF header: program header "
"table exceeds file: %lu.", "table exceeds file: %lu.",
programHeaderTableOffset + programHeaderTableSize); programHeaderTableOffset + programHeaderTableSize);
} }
resourceOffset = max_c(resourceOffset, programHeaderTableOffset resourceOffset = std::max(resourceOffset,
+ programHeaderTableSize); programHeaderTableOffset + programHeaderTableSize);
// iterate through the program headers // iterate through the program headers
for (int32 i = 0; i < (int32)programHeaderCount; i++) { for (uint32 i = 0; i < programHeaderCount; i++) {
uint32 shOffset = programHeaderTableOffset + i * programHeaderSize; uint64 shOffset = programHeaderTableOffset + i * programHeaderSize;
Elf32_Phdr programHeader; ElfProgramHeader programHeader;
read_exactly(file, shOffset, &programHeader, sizeof(Elf32_Shdr), read_exactly(file, shOffset, &programHeader,
"Failed to read ELF program header."); sizeof(ElfProgramHeader), "Failed to read ELF program header.");
// get the header values // get the header values
uint32 type = _GetUInt32(programHeader.p_type); uint32 type = _GetInt(programHeader.p_type);
uint32 offset = _GetUInt32(programHeader.p_offset); uint64 offset = _GetInt(programHeader.p_offset);
uint32 size = _GetUInt32(programHeader.p_filesz); uint64 size = _GetInt(programHeader.p_filesz);
uint32 alignment = _GetUInt32(programHeader.p_align); uint64 alignment = _GetInt(programHeader.p_align);
// check the values // check the values
// PT_NULL marks the header unused, // PT_NULL marks the header unused,
if (type != PT_NULL) { if (type != PT_NULL) {
@@ -543,44 +558,47 @@ ResourceFile::_InitELFFile(BFile &file)
throw Exception(B_IO_ERROR, "Invalid ELF program header: " throw Exception(B_IO_ERROR, "Invalid ELF program header: "
"invalid program offset: %lu.", offset); "invalid program offset: %lu.", offset);
} }
uint32 segmentEnd = offset + size; uint64 segmentEnd = offset + size;
if (segmentEnd > fileSize) { if (segmentEnd > fileSize) {
throw Exception(B_IO_ERROR, "Invalid ELF section header: " throw Exception(B_IO_ERROR, "Invalid ELF section header: "
"segment exceeds file: %lu.", segmentEnd); "segment exceeds file: %lu.", segmentEnd);
} }
resourceOffset = max_c(resourceOffset, segmentEnd); resourceOffset = std::max(resourceOffset, segmentEnd);
resourceAlignment = max_c(resourceAlignment, alignment); resourceAlignment = std::max(resourceAlignment, alignment);
} }
} }
} }
// section header table offset and entry count/size // section header table offset and entry count/size
uint32 sectionHeaderTableSize = 0; uint64 sectionHeaderTableSize = 0;
if (hasSectionHeaderTable) { if (hasSectionHeaderTable) {
if (sectionHeaderTableOffset < headerSize if (sectionHeaderTableOffset < headerSize
|| sectionHeaderTableOffset > fileSize) { || sectionHeaderTableOffset > fileSize) {
throw Exception(B_IO_ERROR, "Invalid ELF header: invalid section " throw Exception(B_IO_ERROR, "Invalid ELF header: invalid section "
"header table offset: %lu.", "header table offset: %lu.", sectionHeaderTableOffset);
sectionHeaderTableOffset);
} }
sectionHeaderTableSize = sectionHeaderSize * sectionHeaderCount; sectionHeaderTableSize = (uint64)sectionHeaderSize * sectionHeaderCount;
if (sectionHeaderSize < sizeof(Elf32_Shdr) if (sectionHeaderSize < sizeof(ElfSectionHeader)
|| sectionHeaderTableOffset + sectionHeaderTableSize > fileSize) { || sectionHeaderTableOffset + sectionHeaderTableSize > fileSize) {
throw Exception(B_IO_ERROR, "Invalid ELF header: section header " throw Exception(B_IO_ERROR, "Invalid ELF header: section header "
"table exceeds file: %lu.", "table exceeds file: %lu.",
sectionHeaderTableOffset + sectionHeaderTableSize); sectionHeaderTableOffset + sectionHeaderTableSize);
} }
resourceOffset = max_c(resourceOffset, sectionHeaderTableOffset resourceOffset = std::max(resourceOffset,
+ sectionHeaderTableSize); sectionHeaderTableOffset + sectionHeaderTableSize);
// iterate through the section headers // iterate through the section headers
for (int32 i = 0; i < (int32)sectionHeaderCount; i++) { for (uint32 i = 0; i < sectionHeaderCount; i++) {
uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize; uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize;
Elf32_Shdr sectionHeader; ElfSectionHeader sectionHeader;
read_exactly(file, shOffset, &sectionHeader, sizeof(Elf32_Shdr), read_exactly(file, shOffset, &sectionHeader,
"Failed to read ELF section header."); sizeof(ElfSectionHeader), "Failed to read ELF section header.");
// get the header values // get the header values
uint32 type = _GetUInt32(sectionHeader.sh_type); uint32 type = _GetInt(sectionHeader.sh_type);
uint32 offset = _GetUInt32(sectionHeader.sh_offset); uint64 offset = _GetInt(sectionHeader.sh_offset);
uint32 size = _GetUInt32(sectionHeader.sh_size); uint64 size = _GetInt(sectionHeader.sh_size);
// check the values // check the values
// SHT_NULL marks the header unused, // SHT_NULL marks the header unused,
// SHT_NOBITS sections take no space in the file // SHT_NOBITS sections take no space in the file
@@ -589,15 +607,16 @@ ResourceFile::_InitELFFile(BFile &file)
throw Exception(B_IO_ERROR, "Invalid ELF section header: " throw Exception(B_IO_ERROR, "Invalid ELF section header: "
"invalid section offset: %lu.", offset); "invalid section offset: %lu.", offset);
} }
uint32 sectionEnd = offset + size; uint64 sectionEnd = offset + size;
if (sectionEnd > fileSize) { if (sectionEnd > fileSize) {
throw Exception(B_IO_ERROR, "Invalid ELF section header: " throw Exception(B_IO_ERROR, "Invalid ELF section header: "
"section exceeds file: %lu.", sectionEnd); "section exceeds file: %lu.", sectionEnd);
} }
resourceOffset = max_c(resourceOffset, sectionEnd); resourceOffset = std::max(resourceOffset, sectionEnd);
} }
} }
} }
// align the offset // align the offset
if (resourceAlignment < kELFMinResourceAlignment) if (resourceAlignment < kELFMinResourceAlignment)
resourceAlignment = kELFMinResourceAlignment; resourceAlignment = kELFMinResourceAlignment;
@@ -611,11 +630,12 @@ ResourceFile::_InitELFFile(BFile &file)
fEmptyResources = true; fEmptyResources = true;
} else } else
fEmptyResources = false; fEmptyResources = false;
// fine, init the offset file // fine, init the offset file
fFile.SetTo(&file, resourceOffset); fFile.SetTo(&file, resourceOffset);
} }
// _InitPEFFile
void void
ResourceFile::_InitPEFFile(BFile& file, const PEFContainerHeader& pefHeader) ResourceFile::_InitPEFFile(BFile& file, const PEFContainerHeader& pefHeader)
{ {
@@ -630,7 +650,7 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
throw Exception(B_IO_ERROR, "PEF file architecture is not PPC."); throw Exception(B_IO_ERROR, "PEF file architecture is not PPC.");
fHostEndianess = B_HOST_IS_BENDIAN; fHostEndianess = B_HOST_IS_BENDIAN;
// get the section count // get the section count
uint16 sectionCount = _GetUInt16(pefHeader.sectionCount); uint16 sectionCount = _GetInt(pefHeader.sectionCount);
// iterate through the PEF sections headers // iterate through the PEF sections headers
uint32 sectionHeaderTableOffset = kPEFContainerHeaderSize; uint32 sectionHeaderTableOffset = kPEFContainerHeaderSize;
uint32 sectionHeaderTableEnd uint32 sectionHeaderTableEnd
@@ -642,8 +662,8 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
read_exactly(file, shOffset, &sectionHeader, kPEFSectionHeaderSize, read_exactly(file, shOffset, &sectionHeader, kPEFSectionHeaderSize,
"Failed to read PEF section header."); "Failed to read PEF section header.");
// get the header values // get the header values
uint32 offset = _GetUInt32(sectionHeader.containerOffset); uint32 offset = _GetInt(sectionHeader.containerOffset);
uint32 size = _GetUInt32(sectionHeader.packedSize); uint32 size = _GetInt(sectionHeader.packedSize);
// check the values // check the values
if (offset < sectionHeaderTableEnd || offset > fileSize) { if (offset < sectionHeaderTableEnd || offset > fileSize) {
throw Exception(B_IO_ERROR, "Invalid PEF section header: invalid " throw Exception(B_IO_ERROR, "Invalid PEF section header: invalid "
@@ -654,7 +674,7 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
throw Exception(B_IO_ERROR, "Invalid PEF section header: section " throw Exception(B_IO_ERROR, "Invalid PEF section header: section "
"exceeds file: %lu.", sectionEnd); "exceeds file: %lu.", sectionEnd);
} }
resourceOffset = max_c(resourceOffset, sectionEnd); resourceOffset = std::max(resourceOffset, sectionEnd);
} }
if (resourceOffset >= fileSize) { if (resourceOffset >= fileSize) {
// throw Exception("The PEF object file does not contain resources."); // throw Exception("The PEF object file does not contain resources.");
@@ -665,7 +685,7 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
fFile.SetTo(&file, resourceOffset); fFile.SetTo(&file, resourceOffset);
} }
// _ReadHeader
void void
ResourceFile::_ReadHeader(resource_parse_info& parseInfo) ResourceFile::_ReadHeader(resource_parse_info& parseInfo)
{ {
@@ -675,7 +695,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
"Failed to read the header."); "Failed to read the header.");
// check the header // check the header
// magic // magic
uint32 magic = _GetUInt32(header.rh_resources_magic); uint32 magic = _GetInt(header.rh_resources_magic);
if (magic == kResourcesHeaderMagic) { if (magic == kResourcesHeaderMagic) {
// everything is fine // everything is fine
} else if (B_SWAP_INT32(magic) == kResourcesHeaderMagic) { } else if (B_SWAP_INT32(magic) == kResourcesHeaderMagic) {
@@ -690,11 +710,11 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
} else } else
throw Exception(B_IO_ERROR, "Invalid resources header magic."); throw Exception(B_IO_ERROR, "Invalid resources header magic.");
// resource count // resource count
uint32 resourceCount = _GetUInt32(header.rh_resource_count); uint32 resourceCount = _GetInt(header.rh_resource_count);
if (resourceCount > kMaxResourceCount) if (resourceCount > kMaxResourceCount)
throw Exception(B_IO_ERROR, "Bad number of resources."); throw Exception(B_IO_ERROR, "Bad number of resources.");
// index section offset // index section offset
uint32 indexSectionOffset = _GetUInt32(header.rh_index_section_offset); uint32 indexSectionOffset = _GetInt(header.rh_index_section_offset);
if (indexSectionOffset != kResourceIndexSectionOffset) { if (indexSectionOffset != kResourceIndexSectionOffset) {
throw Exception(B_IO_ERROR, "Unexpected resource index section " throw Exception(B_IO_ERROR, "Unexpected resource index section "
"offset. Is: %lu, should be: %lu.", indexSectionOffset, "offset. Is: %lu, should be: %lu.", indexSectionOffset,
@@ -705,7 +725,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
+ kResourceIndexEntrySize * resourceCount; + kResourceIndexEntrySize * resourceCount;
indexSectionSize = align_value(indexSectionSize, indexSectionSize = align_value(indexSectionSize,
kResourceIndexSectionAlignment); kResourceIndexSectionAlignment);
uint32 adminSectionSize = _GetUInt32(header.rh_admin_section_size); uint32 adminSectionSize = _GetInt(header.rh_admin_section_size);
if (adminSectionSize != indexSectionOffset + indexSectionSize) { if (adminSectionSize != indexSectionOffset + indexSectionSize) {
throw Exception(B_IO_ERROR, "Unexpected resource admin section size. " throw Exception(B_IO_ERROR, "Unexpected resource admin section size. "
"Is: %lu, should be: %lu.", adminSectionSize, "Is: %lu, should be: %lu.", adminSectionSize,
@@ -715,7 +735,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
parseInfo.resource_count = resourceCount; parseInfo.resource_count = resourceCount;
} }
// _ReadIndex
void void
ResourceFile::_ReadIndex(resource_parse_info& parseInfo) ResourceFile::_ReadIndex(resource_parse_info& parseInfo)
{ {
@@ -728,7 +748,7 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
"Failed to read the resource index section header."); "Failed to read the resource index section header.");
// check the header // check the header
// index section offset // index section offset
uint32 indexSectionOffset = _GetUInt32(header.rish_index_section_offset); uint32 indexSectionOffset = _GetInt(header.rish_index_section_offset);
if (indexSectionOffset != kResourceIndexSectionOffset) { if (indexSectionOffset != kResourceIndexSectionOffset) {
throw Exception(B_IO_ERROR, "Unexpected resource index section " throw Exception(B_IO_ERROR, "Unexpected resource index section "
"offset. Is: %lu, should be: %lu.", indexSectionOffset, "offset. Is: %lu, should be: %lu.", indexSectionOffset,
@@ -739,7 +759,7 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
+ kResourceIndexEntrySize * resourceCount; + kResourceIndexEntrySize * resourceCount;
expectedIndexSectionSize = align_value(expectedIndexSectionSize, expectedIndexSectionSize = align_value(expectedIndexSectionSize,
kResourceIndexSectionAlignment); kResourceIndexSectionAlignment);
uint32 indexSectionSize = _GetUInt32(header.rish_index_section_size); uint32 indexSectionSize = _GetInt(header.rish_index_section_size);
if (indexSectionSize != expectedIndexSectionSize) { if (indexSectionSize != expectedIndexSectionSize) {
throw Exception(B_IO_ERROR, "Unexpected resource index section size. " throw Exception(B_IO_ERROR, "Unexpected resource index section size. "
"Is: %lu, should be: %lu.", indexSectionSize, "Is: %lu, should be: %lu.", indexSectionSize,
@@ -747,22 +767,22 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
} }
// unknown section offset // unknown section offset
uint32 unknownSectionOffset uint32 unknownSectionOffset
= _GetUInt32(header.rish_unknown_section_offset); = _GetInt(header.rish_unknown_section_offset);
if (unknownSectionOffset != indexSectionOffset + indexSectionSize) { if (unknownSectionOffset != indexSectionOffset + indexSectionSize) {
throw Exception(B_IO_ERROR, "Unexpected resource index section size. " throw Exception(B_IO_ERROR, "Unexpected resource index section size. "
"Is: %lu, should be: %lu.", unknownSectionOffset, "Is: %lu, should be: %lu.", unknownSectionOffset,
indexSectionOffset + indexSectionSize); indexSectionOffset + indexSectionSize);
} }
// unknown section size // unknown section size
uint32 unknownSectionSize = _GetUInt32(header.rish_unknown_section_size); uint32 unknownSectionSize = _GetInt(header.rish_unknown_section_size);
if (unknownSectionSize != kUnknownResourceSectionSize) { if (unknownSectionSize != kUnknownResourceSectionSize) {
throw Exception(B_IO_ERROR, "Unexpected resource index section " throw Exception(B_IO_ERROR, "Unexpected resource index section "
"offset. Is: %lu, should be: %lu.", "offset. Is: %lu, should be: %lu.",
unknownSectionOffset, kUnknownResourceSectionSize); unknownSectionOffset, kUnknownResourceSectionSize);
} }
// info table offset and size // info table offset and size
uint32 infoTableOffset = _GetUInt32(header.rish_info_table_offset); uint32 infoTableOffset = _GetInt(header.rish_info_table_offset);
uint32 infoTableSize = _GetUInt32(header.rish_info_table_size); uint32 infoTableSize = _GetInt(header.rish_info_table_size);
if (infoTableOffset + infoTableSize > fileSize) if (infoTableOffset + infoTableSize > fileSize)
throw Exception(B_IO_ERROR, "Invalid info table location."); throw Exception(B_IO_ERROR, "Invalid info table location.");
parseInfo.info_table_offset = infoTableOffset; parseInfo.info_table_offset = infoTableOffset;
@@ -793,7 +813,7 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
} }
} }
// _ReadIndexEntry
bool bool
ResourceFile::_ReadIndexEntry(resource_parse_info& parseInfo, int32 index, ResourceFile::_ReadIndexEntry(resource_parse_info& parseInfo, int32 index,
uint32 tableOffset, bool peekAhead) uint32 tableOffset, bool peekAhead)
@@ -816,8 +836,8 @@ ResourceFile::_ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
} }
result = false; result = false;
} }
uint32 offset = _GetUInt32(entry.rie_offset); uint32 offset = _GetInt(entry.rie_offset);
uint32 size = _GetUInt32(entry.rie_size); uint32 size = _GetInt(entry.rie_size);
// check the location // check the location
if (result && offset + size > fileSize) { if (result && offset + size > fileSize) {
if (peekAhead) { if (peekAhead) {
@@ -825,8 +845,8 @@ ResourceFile::_ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
// "table."); // "table.");
} else { } else {
throw Exception(B_IO_ERROR, "Invalid resource index entry: index: " throw Exception(B_IO_ERROR, "Invalid resource index entry: index: "
"%ld, offset: %lu (%lx), size: %lu (%lx).", "%ld, offset: %lu (%lx), size: %lu (%lx).", index + 1, offset,
index + 1, offset, offset, size, size); offset, size, size);
} }
result = false; result = false;
} }
@@ -844,7 +864,7 @@ ResourceFile::_ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
return result; return result;
} }
// _ReadInfoTable
void void
ResourceFile::_ReadInfoTable(resource_parse_info& parseInfo) ResourceFile::_ReadInfoTable(resource_parse_info& parseInfo)
{ {
@@ -863,7 +883,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
// + 1 => always > 0 // + 1 => always > 0
if (!readIndices) if (!readIndices)
throw Exception(B_NO_MEMORY); throw Exception(B_NO_MEMORY);
AutoDeleter<bool> readIndicesDeleter(readIndices, true); ArrayDeleter<bool> readIndicesDeleter(readIndices);
for (int32 i = 0; i < resourceCount; i++) for (int32 i = 0; i < resourceCount; i++)
readIndices[i] = false; readIndices[i] = false;
MemArea area(tableData, dataSize); MemArea area(tableData, dataSize);
@@ -883,7 +903,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
} }
const resource_info_block* infoBlock const resource_info_block* infoBlock
= (const resource_info_block*)data; = (const resource_info_block*)data;
type_code type = _GetUInt32(infoBlock->rib_type); type_code type = _GetInt(infoBlock->rib_type);
// read the infos of this block // read the infos of this block
const resource_info* info = infoBlock->rib_info; const resource_info* info = infoBlock->rib_info;
while (info) { while (info) {
@@ -895,8 +915,8 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
} }
const resource_info_separator* separator const resource_info_separator* separator
= (const resource_info_separator*)data; = (const resource_info_separator*)data;
if (_GetUInt32(separator->ris_value1) == 0xffffffff if (_GetInt(separator->ris_value1) == 0xffffffff
&& _GetUInt32(separator->ris_value2) == 0xffffffff) { && _GetInt(separator->ris_value2) == 0xffffffff) {
// info block ends // info block ends
info = NULL; info = NULL;
data = skip_bytes(data, kResourceInfoSeparatorSize); data = skip_bytes(data, kResourceInfoSeparatorSize);
@@ -916,8 +936,8 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
} }
const resource_info_separator* tableTerminator const resource_info_separator* tableTerminator
= (const resource_info_separator*)data; = (const resource_info_separator*)data;
if (_GetUInt32(tableTerminator->ris_value1) != 0xffffffff if (_GetInt(tableTerminator->ris_value1) != 0xffffffff
|| _GetUInt32(tableTerminator->ris_value2) != 0xffffffff) { || _GetInt(tableTerminator->ris_value2) != 0xffffffff) {
throw Exception(B_IO_ERROR, "The resource info table ought to be " throw Exception(B_IO_ERROR, "The resource info table ought to be "
"empty, but is not properly terminated."); "empty, but is not properly terminated.");
} }
@@ -941,7 +961,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
} }
} }
// _ReadInfoTableEnd
bool bool
ResourceFile::_ReadInfoTableEnd(const void* data, int32 dataSize) ResourceFile::_ReadInfoTableEnd(const void* data, int32 dataSize)
{ {
@@ -954,17 +974,17 @@ ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
const resource_info_table_end* tableEnd const resource_info_table_end* tableEnd
= (const resource_info_table_end*) = (const resource_info_table_end*)
skip_bytes(data, dataSize - kResourceInfoTableEndSize); skip_bytes(data, dataSize - kResourceInfoTableEndSize);
if (_GetInt32(tableEnd->rite_terminator) != 0) if (_GetInt(tableEnd->rite_terminator) != 0)
hasTableEnd = false; hasTableEnd = false;
if (hasTableEnd) { if (hasTableEnd) {
dataSize -= kResourceInfoTableEndSize; dataSize -= kResourceInfoTableEndSize;
// checksum // checksum
uint32 checkSum = calculate_checksum(data, dataSize); uint32 checkSum = calculate_checksum(data, dataSize);
uint32 fileCheckSum = _GetUInt32(tableEnd->rite_check_sum); uint32 fileCheckSum = _GetInt(tableEnd->rite_check_sum);
if (checkSum != fileCheckSum) { if (checkSum != fileCheckSum) {
throw Exception(B_IO_ERROR, "Invalid resource info table check" throw Exception(B_IO_ERROR, "Invalid resource info table check"
" sum: In file: %lx, calculated: %lx.", " sum: In file: %lx, calculated: %lx.", fileCheckSum,
fileCheckSum, checkSum); checkSum);
} }
} }
} }
@@ -973,17 +993,16 @@ ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
return hasTableEnd; return hasTableEnd;
} }
// _ReadResourceInfo
const void* const void*
ResourceFile::_ReadResourceInfo(resource_parse_info& parseInfo, ResourceFile::_ReadResourceInfo(resource_parse_info& parseInfo,
const MemArea &area, const resource_info *info, const MemArea& area, const resource_info* info, type_code type,
type_code type, bool *readIndices) bool* readIndices)
{ {
int32& resourceCount = parseInfo.resource_count; int32& resourceCount = parseInfo.resource_count;
// int32 id = _GetInt(info->ri_id);
int32 id = _GetInt32(info->ri_id); int32 index = _GetInt(info->ri_index);
int32 index = _GetInt32(info->ri_index); uint16 nameSize = _GetInt(info->ri_name_size);
uint16 nameSize = _GetUInt16(info->ri_name_size);
const char* name = info->ri_name; const char* name = info->ri_name;
// check the values // check the values
bool ignore = false; bool ignore = false;
@@ -1024,7 +1043,7 @@ ResourceFile::_ReadResourceInfo(resource_parse_info &parseInfo,
return skip_bytes(name, nameSize); return skip_bytes(name, nameSize);
} }
// _WriteResources
status_t status_t
ResourceFile::_WriteResources(ResourcesContainer& container) ResourceFile::_WriteResources(ResourcesContainer& container)
{ {
@@ -1043,12 +1062,12 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
indexSectionSize = align_value(indexSectionSize, indexSectionSize = align_value(indexSectionSize,
kResourceIndexSectionAlignment); kResourceIndexSectionAlignment);
size += indexSectionSize; size += indexSectionSize;
bufferSize = max_c((uint32)bufferSize, indexSectionSize); bufferSize = std::max((uint32)bufferSize, indexSectionSize);
// unknown section // unknown section
uint32 unknownSectionOffset = size; uint32 unknownSectionOffset = size;
uint32 unknownSectionSize = kUnknownResourceSectionSize; uint32 unknownSectionSize = kUnknownResourceSectionSize;
size += unknownSectionSize; size += unknownSectionSize;
bufferSize = max_c((uint32)bufferSize, unknownSectionSize); bufferSize = std::max((uint32)bufferSize, unknownSectionSize);
// data // data
uint32 dataOffset = size; uint32 dataOffset = size;
uint32 dataSize = 0; uint32 dataSize = 0;
@@ -1057,7 +1076,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
if (!item->IsLoaded()) if (!item->IsLoaded())
throw Exception(B_IO_ERROR, "Resource is not loaded."); throw Exception(B_IO_ERROR, "Resource is not loaded.");
dataSize += item->DataSize(); dataSize += item->DataSize();
bufferSize = max_c(bufferSize, item->DataSize()); bufferSize = std::max(bufferSize, item->DataSize());
} }
size += dataSize; size += dataSize;
// info table // info table
@@ -1081,7 +1100,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
infoTableSize += kResourceInfoSeparatorSize infoTableSize += kResourceInfoSeparatorSize
+ kResourceInfoTableEndSize; + kResourceInfoTableEndSize;
size += infoTableSize; size += infoTableSize;
bufferSize = max_c((uint32)bufferSize, infoTableSize); bufferSize = std::max((uint32)bufferSize, infoTableSize);
// write... // write...
// set the file size // set the file size
@@ -1216,7 +1235,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
return error; return error;
} }
// _MakeEmptyResourceFile
status_t status_t
ResourceFile::_MakeEmptyResourceFile() ResourceFile::_MakeEmptyResourceFile()
{ {
@@ -1249,7 +1268,3 @@ ResourceFile::_MakeEmptyResourceFile()
}; // namespace Storage }; // namespace Storage
}; // namespace BPrivate }; // namespace BPrivate