1ed08f5856
The code to parse the resource table reads one entry at a time because the table size isn't known. This resulted in a lot of read syscalls, each reading just 12 bytes. Use a BBufferIO to buffer these and reduce the number of syscalls. This helps especially when there are lot of resources, for example in libbe with all the country flags. It also removes some spam from strace output for all these read calls. Change-Id: Ib165a0eacc2bc5f3d319c22c2fac4f439efbdef2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2858 Reviewed-by: Rene Gollent <rene@gollent.com>
164 lines
4.1 KiB
C++
164 lines
4.1 KiB
C++
/*
|
|
* Copyright 2002-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef _RESOURCE_FILE_H
|
|
#define _RESOURCE_FILE_H
|
|
|
|
|
|
/*!
|
|
\file ResourceFile.h
|
|
ResourceFile interface declaration.
|
|
*/
|
|
|
|
|
|
#include <ByteOrder.h>
|
|
|
|
#include "OffsetFile.h"
|
|
|
|
|
|
struct resource_info;
|
|
struct PEFContainerHeader;
|
|
|
|
|
|
namespace BPrivate {
|
|
namespace Storage {
|
|
|
|
|
|
class Exception;
|
|
struct MemArea;
|
|
class ResourceItem;
|
|
struct resource_parse_info;
|
|
class ResourcesContainer;
|
|
|
|
|
|
/*!
|
|
\class ResourceFile
|
|
\brief Represents a file capable of containing resources.
|
|
|
|
This class provides access to the resources of a file.
|
|
Basically a ResourceFile object can be set to a file, load infos for the
|
|
resources without loading their data (InitContainer()), read the data of
|
|
one (ReadResource()) or all resources (ReadResources()) and write all
|
|
resources to the file (WriteResources()).
|
|
|
|
Note, that the object does only provide the I/O functionality, it does
|
|
not store any information about the resources -- this is done via a
|
|
ResourcesContainer. We gain flexibility using this approach, since e.g.
|
|
a certain resource may be represented by more than one ResourceItem and
|
|
we can have as many ResourcesContainers for the resources as we like.
|
|
In particular it is nice, that at any time we can write an arbitrary set
|
|
of resources to the file.
|
|
|
|
\author <a href='mailto:bonefish@users.sf.net'>Ingo Weinhold</a>
|
|
|
|
\version 0.0.0
|
|
*/
|
|
class ResourceFile {
|
|
public:
|
|
ResourceFile();
|
|
virtual ~ResourceFile();
|
|
|
|
status_t SetTo(BFile* file, bool clobber = false);
|
|
void Unset();
|
|
status_t InitCheck() const;
|
|
|
|
status_t InitContainer(ResourcesContainer& container);
|
|
status_t ReadResource(ResourceItem& resource,
|
|
bool force = false);
|
|
status_t ReadResources(ResourcesContainer& container,
|
|
bool force = false);
|
|
status_t WriteResources(ResourcesContainer& container);
|
|
|
|
private:
|
|
void _InitFile(BFile& file, bool clobber);
|
|
|
|
void _InitELFFile(BFile& file);
|
|
|
|
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 _ReadIndex(resource_parse_info& parseInfo);
|
|
bool _ReadIndexEntry(BPositionIO& buffer,
|
|
resource_parse_info& parseInfo,
|
|
int32 index, uint32 tableOffset,
|
|
bool peekAhead);
|
|
void _ReadInfoTable(resource_parse_info& parseInfo);
|
|
bool _ReadInfoTableEnd(const void* data,
|
|
int32 dataSize);
|
|
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 _MakeEmptyResourceFile();
|
|
|
|
inline int16 _GetInt(int16 value) const;
|
|
inline uint16 _GetInt(uint16 value) const;
|
|
inline int32 _GetInt(int32 value) const;
|
|
inline uint32 _GetInt(uint32 value) const;
|
|
inline int64 _GetInt(int64 value) const;
|
|
inline uint64 _GetInt(uint64 value) const;
|
|
|
|
private:
|
|
OffsetFile fFile;
|
|
uint32 fFileType;
|
|
bool fHostEndianess;
|
|
bool fEmptyResources;
|
|
};
|
|
|
|
|
|
inline int16
|
|
ResourceFile::_GetInt(int16 value) const
|
|
{
|
|
return fHostEndianess ? value : (int16)B_SWAP_INT16((uint16)value);
|
|
}
|
|
|
|
|
|
inline uint16
|
|
ResourceFile::_GetInt(uint16 value) const
|
|
{
|
|
return fHostEndianess ? value : B_SWAP_INT16(value);
|
|
}
|
|
|
|
|
|
inline int32
|
|
ResourceFile::_GetInt(int32 value) const
|
|
{
|
|
return fHostEndianess ? value : (int32)B_SWAP_INT32((uint32)value);
|
|
}
|
|
|
|
|
|
inline uint32
|
|
ResourceFile::_GetInt(uint32 value) const
|
|
{
|
|
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 BPrivate
|
|
|
|
|
|
#endif // _RESOURCE_FILE_H
|