* Style cleanup.
* Removed AutoDeleter class and use the shared one instead. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34244 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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.
|
||||||
@@ -53,31 +59,37 @@ public:
|
|||||||
ResourceFile();
|
ResourceFile();
|
||||||
virtual ~ResourceFile();
|
virtual ~ResourceFile();
|
||||||
|
|
||||||
status_t SetTo(BFile *file, bool clobber = false);
|
status_t SetTo(BFile* file, bool clobber = false);
|
||||||
void Unset();
|
void Unset();
|
||||||
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 WriteResources(ResourcesContainer &container);
|
status_t ReadResources(ResourcesContainer& container,
|
||||||
|
bool force = false);
|
||||||
|
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);
|
void _InitPEFFile(BFile& file,
|
||||||
void _ReadHeader(resource_parse_info &parseInfo);
|
const PEFContainerHeader& pefHeader);
|
||||||
void _ReadIndex(resource_parse_info &parseInfo);
|
void _ReadHeader(resource_parse_info& parseInfo);
|
||||||
bool _ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
|
void _ReadIndex(resource_parse_info& parseInfo);
|
||||||
uint32 tableOffset, bool peekAhead);
|
bool _ReadIndexEntry(resource_parse_info& parseInfo,
|
||||||
void _ReadInfoTable(resource_parse_info &parseInfo);
|
int32 index, uint32 tableOffset,
|
||||||
bool _ReadInfoTableEnd(const void *data, int32 dataSize);
|
bool peekAhead);
|
||||||
const void *_ReadResourceInfo(resource_parse_info &parseInfo,
|
void _ReadInfoTable(resource_parse_info& parseInfo);
|
||||||
const MemArea &area,
|
bool _ReadInfoTableEnd(const void* data,
|
||||||
const resource_info *info, type_code type,
|
int32 dataSize);
|
||||||
bool *readIndices);
|
const void* _ReadResourceInfo(
|
||||||
|
resource_parse_info& parseInfo,
|
||||||
|
const MemArea& area,
|
||||||
|
const resource_info* info, type_code type,
|
||||||
|
bool* readIndices);
|
||||||
|
|
||||||
status_t _WriteResources(ResourcesContainer &container);
|
status_t _WriteResources(ResourcesContainer& container);
|
||||||
status_t _MakeEmptyResourceFile();
|
status_t _MakeEmptyResourceFile();
|
||||||
|
|
||||||
inline int16 _GetInt16(int16 value);
|
inline int16 _GetInt16(int16 value);
|
||||||
@@ -92,41 +104,37 @@ private:
|
|||||||
bool fEmptyResources;
|
bool fEmptyResources;
|
||||||
};
|
};
|
||||||
|
|
||||||
// _GetInt16
|
|
||||||
inline
|
inline int16
|
||||||
int16
|
|
||||||
ResourceFile::_GetInt16(int16 value)
|
ResourceFile::_GetInt16(int16 value)
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT16(value));
|
return fHostEndianess ? value : B_SWAP_INT16(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _GetUInt16
|
|
||||||
inline
|
inline uint16
|
||||||
uint16
|
|
||||||
ResourceFile::_GetUInt16(uint16 value)
|
ResourceFile::_GetUInt16(uint16 value)
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT16(value));
|
return fHostEndianess ? value : B_SWAP_INT16(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _GetInt32
|
|
||||||
inline
|
inline int32
|
||||||
int32
|
|
||||||
ResourceFile::_GetInt32(int32 value)
|
ResourceFile::_GetInt32(int32 value)
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT32(value));
|
return fHostEndianess ? value : B_SWAP_INT32(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _GetUInt32
|
|
||||||
inline
|
inline uint32
|
||||||
uint32
|
|
||||||
ResourceFile::_GetUInt32(uint32 value)
|
ResourceFile::_GetUInt32(uint32 value)
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT32(value));
|
return fHostEndianess ? value : B_SWAP_INT32(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // namespace Storage
|
}; // namespace Storage
|
||||||
}; // namespace BPrivate
|
}; // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
#endif // _RESOURCE_FILE_H
|
#endif // _RESOURCE_FILE_H
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+171
-198
@@ -1,33 +1,36 @@
|
|||||||
//----------------------------------------------------------------------
|
/*
|
||||||
// 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.
|
||||||
//---------------------------------------------------------------------
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\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 "Warnings.h"
|
#include <ResourcesContainer.h>
|
||||||
|
#include <ResourcesDefs.h>
|
||||||
|
//#include <Warnings.h>
|
||||||
|
|
||||||
using std::max;
|
|
||||||
using std::min;
|
|
||||||
using std::nothrow;
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
|
||||||
|
|
||||||
// ELF defs
|
// ELF defs
|
||||||
static const uint32 kMaxELFHeaderSize = sizeof(Elf32_Ehdr) + 32;
|
static const uint32 kMaxELFHeaderSize = sizeof(Elf32_Ehdr) + 32;
|
||||||
static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
|
static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
|
||||||
@@ -36,6 +39,7 @@ static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
|
|||||||
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,
|
||||||
@@ -46,7 +50,8 @@ enum {
|
|||||||
FILE_TYPE_EMPTY = 5,
|
FILE_TYPE_EMPTY = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *kFileTypeNames[] = {
|
|
||||||
|
const char* kFileTypeNames[] = {
|
||||||
"unknown",
|
"unknown",
|
||||||
"x86 resource file",
|
"x86 resource file",
|
||||||
"PPC resource file",
|
"PPC resource file",
|
||||||
@@ -55,19 +60,19 @@ 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)
|
|
||||||
{
|
{
|
||||||
ssize_t read = file.ReadAt(position, buffer, size);
|
ssize_t read = file.ReadAt(position, buffer, size);
|
||||||
if (read < 0)
|
if (read < 0)
|
||||||
@@ -81,11 +86,10 @@ 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)
|
|
||||||
{
|
{
|
||||||
ssize_t written = file.WriteAt(position, buffer, size);
|
ssize_t written = file.WriteAt(position, buffer, size);
|
||||||
if (written < 0)
|
if (written < 0)
|
||||||
@@ -99,27 +103,25 @@ 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;
|
||||||
const uint8 *csData = (const uint8*)data;
|
const uint8* csData = (const uint8*)data;
|
||||||
const uint8 *dataEnd = csData + size;
|
const uint8* dataEnd = csData + 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(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;
|
||||||
@@ -127,57 +129,51 @@ 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;
|
||||||
for (uint32 i = 0; i < count; i++)
|
for (uint32 i = 0; i < count; i++)
|
||||||
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)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
uint32 *buffer = (uint32*)_buffer;
|
uint32* buffer = (uint32*)_buffer;
|
||||||
for (uint32 i = 0; result && i < count; i++) {
|
for (uint32 i = 0; result && i < count; i++) {
|
||||||
uint32 value = buffer[i];
|
uint32 value = buffer[i];
|
||||||
if (!hostEndianess)
|
if (!hostEndianess)
|
||||||
@@ -188,14 +184,17 @@ check_pattern(uint32 byteOffset, void *_buffer, uint32 count,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemArea
|
|
||||||
struct MemArea {
|
|
||||||
MemArea(const void *data, uint32 size) : data(data), size(size) {}
|
|
||||||
|
|
||||||
inline bool check(const void *_current, uint32 skip = 0) const
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
struct MemArea {
|
||||||
|
MemArea(const void* data, uint32 size) : data(data), size(size) {}
|
||||||
|
|
||||||
|
inline bool check(const void* _current, uint32 skip = 0) const
|
||||||
{
|
{
|
||||||
const char *start = (const char*)data;
|
const char* start = (const char*)data;
|
||||||
const char *current = (const char*)_current;
|
const char* current = (const char*)_current;
|
||||||
return (start <= current && start + size >= current + skip);
|
return (start <= current && start + size >= current + skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,54 +202,38 @@ 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;
|
||||||
ResourcesContainer *container;
|
ResourcesContainer* container;
|
||||||
char *info_table;
|
char* info_table;
|
||||||
uint32 info_table_offset;
|
uint32 info_table_offset;
|
||||||
uint32 info_table_size;
|
uint32 info_table_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
status_t error = (file ? B_OK : B_BAD_VALUE);
|
status_t error = (file ? B_OK : B_BAD_VALUE);
|
||||||
Unset();
|
Unset();
|
||||||
@@ -268,27 +251,26 @@ 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)
|
||||||
{
|
{
|
||||||
container.MakeEmpty();
|
container.MakeEmpty();
|
||||||
status_t error = InitCheck();
|
status_t error = InitCheck();
|
||||||
@@ -320,16 +302,16 @@ 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)
|
||||||
{
|
{
|
||||||
status_t error = InitCheck();
|
status_t error = InitCheck();
|
||||||
size_t size = resource.DataSize();
|
size_t size = resource.DataSize();
|
||||||
if (error == B_OK && (force || !resource.IsLoaded())) {
|
if (error == B_OK && (force || !resource.IsLoaded())) {
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = resource.SetSize(size);
|
error = resource.SetSize(size);
|
||||||
void *data = NULL;
|
void* data = NULL;
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
data = resource.Data();
|
data = resource.Data();
|
||||||
ssize_t bytesRead = fFile.ReadAt(resource.Offset(), data, size);
|
ssize_t bytesRead = fFile.ReadAt(resource.Offset(), data, size);
|
||||||
@@ -349,14 +331,14 @@ 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)
|
||||||
{
|
{
|
||||||
status_t error = InitCheck();
|
status_t error = InitCheck();
|
||||||
int32 count = container.CountResources();
|
int32 count = container.CountResources();
|
||||||
for (int32 i = 0; error == B_OK && i < count; i++) {
|
for (int32 i = 0; error == B_OK && i < count; i++) {
|
||||||
if (ResourceItem *resource = container.ResourceAt(i))
|
if (ResourceItem* resource = container.ResourceAt(i))
|
||||||
error = ReadResource(*resource, force);
|
error = ReadResource(*resource, force);
|
||||||
else
|
else
|
||||||
error = B_ERROR;
|
error = B_ERROR;
|
||||||
@@ -364,9 +346,9 @@ ResourceFile::ReadResources(ResourcesContainer &container, bool force)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteResources
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::WriteResources(ResourcesContainer &container)
|
ResourceFile::WriteResources(ResourcesContainer& container)
|
||||||
{
|
{
|
||||||
status_t error = InitCheck();
|
status_t error = InitCheck();
|
||||||
if (error == B_OK && !fFile.File()->IsWritable())
|
if (error == B_OK && !fFile.File()->IsWritable())
|
||||||
@@ -381,9 +363,8 @@ ResourceFile::WriteResources(ResourcesContainer &container)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _InitFile
|
|
||||||
void
|
void
|
||||||
ResourceFile::_InitFile(BFile &file, bool clobber)
|
ResourceFile::_InitFile(BFile& file, bool clobber)
|
||||||
{
|
{
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
fFile.Unset();
|
fFile.Unset();
|
||||||
@@ -460,9 +441,9 @@ 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
|
||||||
@@ -501,8 +482,7 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
// ELF header size
|
// ELF header size
|
||||||
if (headerSize < sizeof(Elf32_Ehdr) || headerSize > kMaxELFHeaderSize) {
|
if (headerSize < sizeof(Elf32_Ehdr) || 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;
|
uint32 resourceOffset = headerSize;
|
||||||
uint32 resourceAlignment = 0;
|
uint32 resourceAlignment = 0;
|
||||||
@@ -512,8 +492,7 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
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 = programHeaderSize * programHeaderCount;
|
||||||
if (programHeaderSize < sizeof(Elf32_Phdr)
|
if (programHeaderSize < sizeof(Elf32_Phdr)
|
||||||
@@ -522,8 +501,8 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
"table exceeds file: %lu.",
|
"table exceeds file: %lu.",
|
||||||
programHeaderTableOffset + programHeaderTableSize);
|
programHeaderTableOffset + programHeaderTableSize);
|
||||||
}
|
}
|
||||||
resourceOffset = max(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 (int32 i = 0; i < (int32)programHeaderCount; i++) {
|
||||||
uint32 shOffset = programHeaderTableOffset + i * programHeaderSize;
|
uint32 shOffset = programHeaderTableOffset + i * programHeaderSize;
|
||||||
@@ -547,8 +526,8 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
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(resourceOffset, segmentEnd);
|
resourceOffset = std::max(resourceOffset, segmentEnd);
|
||||||
resourceAlignment = max(resourceAlignment, alignment);
|
resourceAlignment = std::max(resourceAlignment, alignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,8 +537,7 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
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 = sectionHeaderSize * sectionHeaderCount;
|
||||||
if (sectionHeaderSize < sizeof(Elf32_Shdr)
|
if (sectionHeaderSize < sizeof(Elf32_Shdr)
|
||||||
@@ -568,8 +546,8 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
"table exceeds file: %lu.",
|
"table exceeds file: %lu.",
|
||||||
sectionHeaderTableOffset + sectionHeaderTableSize);
|
sectionHeaderTableOffset + sectionHeaderTableSize);
|
||||||
}
|
}
|
||||||
resourceOffset = max(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 (int32 i = 0; i < (int32)sectionHeaderCount; i++) {
|
||||||
uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize;
|
uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize;
|
||||||
@@ -593,7 +571,7 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
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(resourceOffset, sectionEnd);
|
resourceOffset = std::max(resourceOffset, sectionEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -614,9 +592,9 @@ ResourceFile::_InitELFFile(BFile &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)
|
||||||
{
|
{
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
// get the file size
|
// get the file size
|
||||||
@@ -653,7 +631,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(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.");
|
||||||
@@ -664,9 +642,9 @@ 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)
|
||||||
{
|
{
|
||||||
// read the header
|
// read the header
|
||||||
resources_header header;
|
resources_header header;
|
||||||
@@ -678,7 +656,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
|
|||||||
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) {
|
||||||
// const char *endianessStr[2] = { "little", "big" };
|
// const char* endianessStr[2] = { "little", "big" };
|
||||||
// int32 endianess
|
// int32 endianess
|
||||||
// = (fHostEndianess == ((bool)B_HOST_IS_LENDIAN ? 0 : 1));
|
// = (fHostEndianess == ((bool)B_HOST_IS_LENDIAN ? 0 : 1));
|
||||||
// Warnings::AddCurrentWarning("Endianess seems to be %s, although %s "
|
// Warnings::AddCurrentWarning("Endianess seems to be %s, although %s "
|
||||||
@@ -714,12 +692,12 @@ 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)
|
||||||
{
|
{
|
||||||
int32 &resourceCount = parseInfo.resource_count;
|
int32& resourceCount = parseInfo.resource_count;
|
||||||
off_t &fileSize = parseInfo.file_size;
|
off_t& fileSize = parseInfo.file_size;
|
||||||
// read the header
|
// read the header
|
||||||
resource_index_section_header header;
|
resource_index_section_header header;
|
||||||
read_exactly(fFile, kResourceIndexSectionOffset, &header,
|
read_exactly(fFile, kResourceIndexSectionOffset, &header,
|
||||||
@@ -792,12 +770,12 @@ 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)
|
||||||
{
|
{
|
||||||
off_t &fileSize = parseInfo.file_size;
|
off_t& fileSize = parseInfo.file_size;
|
||||||
//
|
//
|
||||||
bool result = true;
|
bool result = true;
|
||||||
resource_index_entry entry;
|
resource_index_entry entry;
|
||||||
@@ -824,14 +802,14 @@ 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;
|
||||||
}
|
}
|
||||||
// add the entry
|
// add the entry
|
||||||
if (result) {
|
if (result) {
|
||||||
ResourceItem *item = new(nothrow) ResourceItem;
|
ResourceItem* item = new(std::nothrow) ResourceItem;
|
||||||
if (!item)
|
if (!item)
|
||||||
throw Exception(B_NO_MEMORY);
|
throw Exception(B_NO_MEMORY);
|
||||||
item->SetLocation(offset, size);
|
item->SetLocation(offset, size);
|
||||||
@@ -843,14 +821,14 @@ 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)
|
||||||
{
|
{
|
||||||
int32 &resourceCount = parseInfo.resource_count;
|
int32& resourceCount = parseInfo.resource_count;
|
||||||
// read the info table
|
// read the info table
|
||||||
// alloc memory for the table
|
// alloc memory for the table
|
||||||
char *tableData = new(nothrow) char[parseInfo.info_table_size];
|
char* tableData = new(std::nothrow) char[parseInfo.info_table_size];
|
||||||
if (!tableData)
|
if (!tableData)
|
||||||
throw Exception(B_NO_MEMORY);
|
throw Exception(B_NO_MEMORY);
|
||||||
int32 dataSize = parseInfo.info_table_size;
|
int32 dataSize = parseInfo.info_table_size;
|
||||||
@@ -858,15 +836,15 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
read_exactly(fFile, parseInfo.info_table_offset, tableData, dataSize,
|
read_exactly(fFile, parseInfo.info_table_offset, tableData, dataSize,
|
||||||
"Failed to read resource info table.");
|
"Failed to read resource info table.");
|
||||||
//
|
//
|
||||||
bool *readIndices = new(nothrow) bool[resourceCount + 1];
|
bool* readIndices = new(std::nothrow) bool[resourceCount + 1];
|
||||||
// + 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);
|
||||||
const void *data = tableData;
|
const void* data = tableData;
|
||||||
// check the table end/check sum
|
// check the table end/check sum
|
||||||
if (_ReadInfoTableEnd(data, dataSize))
|
if (_ReadInfoTableEnd(data, dataSize))
|
||||||
dataSize -= kResourceInfoTableEndSize;
|
dataSize -= kResourceInfoTableEndSize;
|
||||||
@@ -880,11 +858,11 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
throw Exception(B_IO_ERROR, "Unexpected end of resource info "
|
throw Exception(B_IO_ERROR, "Unexpected end of resource info "
|
||||||
"table at index %ld.", resourceIndex);
|
"table at index %ld.", resourceIndex);
|
||||||
}
|
}
|
||||||
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 = _GetUInt32(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) {
|
||||||
data = _ReadResourceInfo(parseInfo, area, info, type, readIndices);
|
data = _ReadResourceInfo(parseInfo, area, info, type, readIndices);
|
||||||
// prepare for next iteration, if there is another info
|
// prepare for next iteration, if there is another info
|
||||||
@@ -892,7 +870,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
throw Exception(B_IO_ERROR, "Unexpected end of resource info "
|
throw Exception(B_IO_ERROR, "Unexpected end of resource info "
|
||||||
"table after index %ld.", resourceIndex);
|
"table after index %ld.", resourceIndex);
|
||||||
}
|
}
|
||||||
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 (_GetUInt32(separator->ris_value1) == 0xffffffff
|
||||||
&& _GetUInt32(separator->ris_value2) == 0xffffffff) {
|
&& _GetUInt32(separator->ris_value2) == 0xffffffff) {
|
||||||
@@ -913,7 +891,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
throw Exception(B_IO_ERROR, "Unexpected end of resource info "
|
throw Exception(B_IO_ERROR, "Unexpected end of resource info "
|
||||||
"table.");
|
"table.");
|
||||||
}
|
}
|
||||||
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 (_GetUInt32(tableTerminator->ris_value1) != 0xffffffff
|
||||||
|| _GetUInt32(tableTerminator->ris_value2) != 0xffffffff) {
|
|| _GetUInt32(tableTerminator->ris_value2) != 0xffffffff) {
|
||||||
@@ -933,16 +911,16 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
if (!readIndices[i]) {
|
if (!readIndices[i]) {
|
||||||
// Warnings::AddCurrentWarning("Resource item at index %ld "
|
// Warnings::AddCurrentWarning("Resource item at index %ld "
|
||||||
// "has no info. Item removed.", i + 1);
|
// "has no info. Item removed.", i + 1);
|
||||||
if (ResourceItem *item = parseInfo.container->RemoveResource(i))
|
if (ResourceItem* item = parseInfo.container->RemoveResource(i))
|
||||||
delete item;
|
delete item;
|
||||||
resourceCount--;
|
resourceCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadInfoTableEnd
|
|
||||||
bool
|
bool
|
||||||
ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
|
ResourceFile::_ReadInfoTableEnd(const void* data, int32 dataSize)
|
||||||
{
|
{
|
||||||
bool hasTableEnd = true;
|
bool hasTableEnd = true;
|
||||||
if ((uint32)dataSize < kResourceInfoSeparatorSize)
|
if ((uint32)dataSize < kResourceInfoSeparatorSize)
|
||||||
@@ -950,7 +928,7 @@ ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
|
|||||||
if ((uint32)dataSize < kResourceInfoTableEndSize)
|
if ((uint32)dataSize < kResourceInfoTableEndSize)
|
||||||
hasTableEnd = false;
|
hasTableEnd = false;
|
||||||
if (hasTableEnd) {
|
if (hasTableEnd) {
|
||||||
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 (_GetInt32(tableEnd->rite_terminator) != 0)
|
||||||
@@ -962,8 +940,8 @@ ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
|
|||||||
uint32 fileCheckSum = _GetUInt32(tableEnd->rite_check_sum);
|
uint32 fileCheckSum = _GetUInt32(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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -972,18 +950,17 @@ 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 = _GetInt32(info->ri_id);
|
int32 id = _GetInt32(info->ri_id);
|
||||||
int32 index = _GetInt32(info->ri_index);
|
int32 index = _GetInt32(info->ri_index);
|
||||||
uint16 nameSize = _GetUInt16(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;
|
||||||
// index
|
// index
|
||||||
@@ -1013,7 +990,7 @@ ResourceFile::_ReadResourceInfo(resource_parse_info &parseInfo,
|
|||||||
// set the values
|
// set the values
|
||||||
if (!ignore) {
|
if (!ignore) {
|
||||||
BString resourceName(name, nameSize);
|
BString resourceName(name, nameSize);
|
||||||
if (ResourceItem *item = parseInfo.container->ResourceAt(index - 1))
|
if (ResourceItem* item = parseInfo.container->ResourceAt(index - 1))
|
||||||
item->SetIdentity(type, id, resourceName.String());
|
item->SetIdentity(type, id, resourceName.String());
|
||||||
else {
|
else {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected error: No resource item "
|
throw Exception(B_IO_ERROR, "Unexpected error: No resource item "
|
||||||
@@ -1023,13 +1000,13 @@ 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)
|
||||||
{
|
{
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
int32 resourceCount = container.CountResources();
|
int32 resourceCount = container.CountResources();
|
||||||
char *buffer = NULL;
|
char* buffer = NULL;
|
||||||
try {
|
try {
|
||||||
// calculate sizes and offsets
|
// calculate sizes and offsets
|
||||||
// header
|
// header
|
||||||
@@ -1042,21 +1019,21 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
indexSectionSize = align_value(indexSectionSize,
|
indexSectionSize = align_value(indexSectionSize,
|
||||||
kResourceIndexSectionAlignment);
|
kResourceIndexSectionAlignment);
|
||||||
size += indexSectionSize;
|
size += indexSectionSize;
|
||||||
bufferSize = max((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((uint32)bufferSize, unknownSectionSize);
|
bufferSize = std::max((uint32)bufferSize, unknownSectionSize);
|
||||||
// data
|
// data
|
||||||
uint32 dataOffset = size;
|
uint32 dataOffset = size;
|
||||||
uint32 dataSize = 0;
|
uint32 dataSize = 0;
|
||||||
for (int32 i = 0; i < resourceCount; i++) {
|
for (int32 i = 0; i < resourceCount; i++) {
|
||||||
ResourceItem *item = container.ResourceAt(i);
|
ResourceItem* item = container.ResourceAt(i);
|
||||||
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(bufferSize, item->DataSize());
|
bufferSize = std::max(bufferSize, item->DataSize());
|
||||||
}
|
}
|
||||||
size += dataSize;
|
size += dataSize;
|
||||||
// info table
|
// info table
|
||||||
@@ -1064,7 +1041,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
uint32 infoTableSize = 0;
|
uint32 infoTableSize = 0;
|
||||||
type_code type = 0;
|
type_code type = 0;
|
||||||
for (int32 i = 0; i < resourceCount; i++) {
|
for (int32 i = 0; i < resourceCount; i++) {
|
||||||
ResourceItem *item = container.ResourceAt(i);
|
ResourceItem* item = container.ResourceAt(i);
|
||||||
if (i == 0 || type != item->Type()) {
|
if (i == 0 || type != item->Type()) {
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
infoTableSize += kResourceInfoSeparatorSize;
|
infoTableSize += kResourceInfoSeparatorSize;
|
||||||
@@ -1073,24 +1050,24 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
} else
|
} else
|
||||||
infoTableSize += kMinResourceInfoSize;
|
infoTableSize += kMinResourceInfoSize;
|
||||||
|
|
||||||
const char *name = item->Name();
|
const char* name = item->Name();
|
||||||
if (name && name[0] != '\0')
|
if (name && name[0] != '\0')
|
||||||
infoTableSize += strlen(name) + 1;
|
infoTableSize += strlen(name) + 1;
|
||||||
}
|
}
|
||||||
infoTableSize += kResourceInfoSeparatorSize
|
infoTableSize += kResourceInfoSeparatorSize
|
||||||
+ kResourceInfoTableEndSize;
|
+ kResourceInfoTableEndSize;
|
||||||
size += infoTableSize;
|
size += infoTableSize;
|
||||||
bufferSize = max((uint32)bufferSize, infoTableSize);
|
bufferSize = std::max((uint32)bufferSize, infoTableSize);
|
||||||
|
|
||||||
// write...
|
// write...
|
||||||
// set the file size
|
// set the file size
|
||||||
fFile.SetSize(size);
|
fFile.SetSize(size);
|
||||||
buffer = new(nothrow) char[bufferSize];
|
buffer = new(std::nothrow) char[bufferSize];
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
throw Exception(B_NO_MEMORY);
|
throw Exception(B_NO_MEMORY);
|
||||||
void *data = buffer;
|
void* data = buffer;
|
||||||
// header
|
// header
|
||||||
resources_header *resourcesHeader = (resources_header*)data;
|
resources_header* resourcesHeader = (resources_header*)data;
|
||||||
resourcesHeader->rh_resources_magic = kResourcesHeaderMagic;
|
resourcesHeader->rh_resources_magic = kResourcesHeaderMagic;
|
||||||
resourcesHeader->rh_resource_count = resourceCount;
|
resourcesHeader->rh_resource_count = resourceCount;
|
||||||
resourcesHeader->rh_index_section_offset = indexSectionOffset;
|
resourcesHeader->rh_index_section_offset = indexSectionOffset;
|
||||||
@@ -1103,7 +1080,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
// index section
|
// index section
|
||||||
data = buffer;
|
data = buffer;
|
||||||
// header
|
// header
|
||||||
resource_index_section_header *indexHeader
|
resource_index_section_header* indexHeader
|
||||||
= (resource_index_section_header*)data;
|
= (resource_index_section_header*)data;
|
||||||
indexHeader->rish_index_section_offset = indexSectionOffset;
|
indexHeader->rish_index_section_offset = indexSectionOffset;
|
||||||
indexHeader->rish_index_section_size = indexSectionSize;
|
indexHeader->rish_index_section_size = indexSectionSize;
|
||||||
@@ -1119,10 +1096,10 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
&indexHeader->rish_unused_data3, 1);
|
&indexHeader->rish_unused_data3, 1);
|
||||||
// index table
|
// index table
|
||||||
data = skip_bytes(data, kResourceIndexSectionHeaderSize);
|
data = skip_bytes(data, kResourceIndexSectionHeaderSize);
|
||||||
resource_index_entry *entry = (resource_index_entry*)data;
|
resource_index_entry* entry = (resource_index_entry*)data;
|
||||||
uint32 entryOffset = dataOffset;
|
uint32 entryOffset = dataOffset;
|
||||||
for (int32 i = 0; i < resourceCount; i++, entry++) {
|
for (int32 i = 0; i < resourceCount; i++, entry++) {
|
||||||
ResourceItem *item = container.ResourceAt(i);
|
ResourceItem* item = container.ResourceAt(i);
|
||||||
uint32 entrySize = item->DataSize();
|
uint32 entrySize = item->DataSize();
|
||||||
entry->rie_offset = entryOffset;
|
entry->rie_offset = entryOffset;
|
||||||
entry->rie_size = entrySize;
|
entry->rie_size = entrySize;
|
||||||
@@ -1141,8 +1118,8 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
uint32 itemOffset = dataOffset;
|
uint32 itemOffset = dataOffset;
|
||||||
for (int32 i = 0; i < resourceCount; i++) {
|
for (int32 i = 0; i < resourceCount; i++) {
|
||||||
data = buffer;
|
data = buffer;
|
||||||
ResourceItem *item = container.ResourceAt(i);
|
ResourceItem* item = container.ResourceAt(i);
|
||||||
const void *itemData = item->Data();
|
const void* itemData = item->Data();
|
||||||
uint32 itemSize = item->DataSize();
|
uint32 itemSize = item->DataSize();
|
||||||
if (!itemData && itemSize > 0)
|
if (!itemData && itemSize > 0)
|
||||||
throw Exception(error, "Invalid resource item data.");
|
throw Exception(error, "Invalid resource item data.");
|
||||||
@@ -1163,18 +1140,18 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
data = buffer;
|
data = buffer;
|
||||||
type = 0;
|
type = 0;
|
||||||
for (int32 i = 0; i < resourceCount; i++) {
|
for (int32 i = 0; i < resourceCount; i++) {
|
||||||
ResourceItem *item = container.ResourceAt(i);
|
ResourceItem* item = container.ResourceAt(i);
|
||||||
resource_info *info = NULL;
|
resource_info* info = NULL;
|
||||||
if (i == 0 || type != item->Type()) {
|
if (i == 0 || type != item->Type()) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
resource_info_separator *separator
|
resource_info_separator* separator
|
||||||
= (resource_info_separator*)data;
|
= (resource_info_separator*)data;
|
||||||
separator->ris_value1 = 0xffffffff;
|
separator->ris_value1 = 0xffffffff;
|
||||||
separator->ris_value2 = 0xffffffff;
|
separator->ris_value2 = 0xffffffff;
|
||||||
data = skip_bytes(data, kResourceInfoSeparatorSize);
|
data = skip_bytes(data, kResourceInfoSeparatorSize);
|
||||||
}
|
}
|
||||||
type = item->Type();
|
type = item->Type();
|
||||||
resource_info_block *infoBlock = (resource_info_block*)data;
|
resource_info_block* infoBlock = (resource_info_block*)data;
|
||||||
infoBlock->rib_type = type;
|
infoBlock->rib_type = type;
|
||||||
info = infoBlock->rib_info;
|
info = infoBlock->rib_info;
|
||||||
} else
|
} else
|
||||||
@@ -1185,7 +1162,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
info->ri_name_size = 0;
|
info->ri_name_size = 0;
|
||||||
data = info->ri_name;
|
data = info->ri_name;
|
||||||
|
|
||||||
const char *name = item->Name();
|
const char* name = item->Name();
|
||||||
if (name && name[0] != '\0') {
|
if (name && name[0] != '\0') {
|
||||||
uint32 nameLen = strlen(name);
|
uint32 nameLen = strlen(name);
|
||||||
memcpy(info->ri_name, name, nameLen + 1);
|
memcpy(info->ri_name, name, nameLen + 1);
|
||||||
@@ -1194,12 +1171,12 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// separator
|
// separator
|
||||||
resource_info_separator *separator = (resource_info_separator*)data;
|
resource_info_separator* separator = (resource_info_separator*)data;
|
||||||
separator->ris_value1 = 0xffffffff;
|
separator->ris_value1 = 0xffffffff;
|
||||||
separator->ris_value2 = 0xffffffff;
|
separator->ris_value2 = 0xffffffff;
|
||||||
// table end
|
// table end
|
||||||
data = skip_bytes(data, kResourceInfoSeparatorSize);
|
data = skip_bytes(data, kResourceInfoSeparatorSize);
|
||||||
resource_info_table_end *tableEnd = (resource_info_table_end*)data;
|
resource_info_table_end* tableEnd = (resource_info_table_end*)data;
|
||||||
tableEnd->rite_check_sum = calculate_checksum(buffer,
|
tableEnd->rite_check_sum = calculate_checksum(buffer,
|
||||||
infoTableSize - kResourceInfoTableEndSize);
|
infoTableSize - kResourceInfoTableEndSize);
|
||||||
tableEnd->rite_terminator = 0;
|
tableEnd->rite_terminator = 0;
|
||||||
@@ -1215,7 +1192,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _MakeEmptyResourceFile
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::_MakeEmptyResourceFile()
|
ResourceFile::_MakeEmptyResourceFile()
|
||||||
{
|
{
|
||||||
@@ -1224,7 +1201,7 @@ ResourceFile::_MakeEmptyResourceFile()
|
|||||||
error = B_NOT_ALLOWED;
|
error = B_NOT_ALLOWED;
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
try {
|
try {
|
||||||
BFile *file = fFile.File();
|
BFile* file = fFile.File();
|
||||||
// make it an x86 resource file
|
// make it an x86 resource file
|
||||||
error = file->SetSize(4);
|
error = file->SetSize(4);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
@@ -1248,7 +1225,3 @@ ResourceFile::_MakeEmptyResourceFile()
|
|||||||
|
|
||||||
}; // namespace Storage
|
}; // namespace Storage
|
||||||
}; // namespace BPrivate
|
}; // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user