#ifndef UI_BASE_RESOURCE_DATA_PACK_H_
#define UI_BASE_RESOURCE_DATA_PACK_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <vector>
#include "base/files/file.h"
#include "base/files/memory_mapped_file.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/string_piece.h"
#include "build/chromeos_buildflags.h"
#include "ui/base/resource/data_pack_export.h"
#include "ui/base/resource/resource_handle.h"
namespace base {
class FilePath;
class RefCountedStaticMemory;
}
namespace ui {
enum ResourceScaleFactor : int;
class UI_DATA_PACK_EXPORT DataPack : public ResourceHandle {
public:
explicit DataPack(ResourceScaleFactor resource_scale_factor);
DataPack(const DataPack&) = delete;
DataPack& operator=(const DataPack&) = delete;
~DataPack() override;
#pragma pack(push, 2)
struct Entry {
static int CompareById(const void* void_key, const void* void_entry);
uint16_t resource_id;
uint32_t file_offset;
};
struct Alias {
static int CompareById(const void* void_key, const void* void_entry);
uint16_t resource_id;
uint16_t entry_index;
};
#pragma pack(pop)
struct ResourceData {
explicit ResourceData(uint16_t id, base::StringPiece data)
: id(id), data(data) {}
uint16_t id;
base::StringPiece data;
};
class Iterator {
public:
Iterator() = default;
~Iterator() = default;
Iterator(const Iterator&) = default;
Iterator& operator=(const Iterator&) = default;
const ResourceData& operator*() { return *resource_data_; }
Iterator& operator++() {
++entry_;
UpdateResourceData();
return *this;
}
bool operator==(const Iterator& other) const {
return entry_ == other.entry_;
}
bool operator!=(const Iterator& other) const {
return entry_ != other.entry_;
}
private:
friend class DataPack;
explicit Iterator(const uint8_t* data_source, const Entry* entry)
: data_source_(data_source), entry_(entry) {
UpdateResourceData();
}
void UpdateResourceData();
const uint8_t* data_source_;
raw_ptr<ResourceData> resource_data_;
raw_ptr<const Entry, AllowPtrArithmetic> entry_;
};
Iterator begin() const;
Iterator end() const;
class DataSource {
public:
virtual ~DataSource() = default;
virtual size_t GetLength() const = 0;
virtual const uint8_t* GetData() const = 0;
};
bool LoadFromPath(const base::FilePath& path);
static std::unique_ptr<DataSource> LoadFromPathInternal(
const base::FilePath& path);
#if BUILDFLAG(IS_CHROMEOS_LACROS)
bool LoadSharedResourceFromPath(const base::FilePath& path);
#endif
bool LoadFromFile(base::File file);
bool LoadFromFileRegion(base::File file,
const base::MemoryMappedFile::Region& region);
bool LoadFromBuffer(base::span<const uint8_t> buffer);
static bool WritePack(const base::FilePath& path,
const std::map<uint16_t, base::StringPiece>& resources,
TextEncodingType textEncodingType);
bool HasResource(uint16_t resource_id) const override;
bool GetStringPiece(uint16_t resource_id,
base::StringPiece* data) const override;
base::RefCountedStaticMemory* GetStaticMemory(
uint16_t resource_id) const override;
TextEncodingType GetTextEncodingType() const override;
ResourceScaleFactor GetResourceScaleFactor() const override;
#if DCHECK_IS_ON()
void CheckForDuplicateResources(
const std::vector<std::unique_ptr<ResourceHandle>>& packs) override;
#endif
const Entry* GetEntryByResourceTableIndex(size_t index) const {
return &resource_table_[index];
}
const Alias* GetAliasByAliasTableIndex(size_t index) const {
return &alias_table_[index];
}
size_t GetAliasTableSize() const { return alias_count_; }
size_t GetResourceTableSizeForTesting() const { return resource_count_; }
private:
class BufferDataSource;
class MemoryMappedDataSource;
class StringDataSource;
bool LoadImpl(std::unique_ptr<DataSource> data_source);
const Entry* LookupEntryById(uint16_t resource_id) const;
bool SanityCheckFileAndRegisterResources(size_t margin_to_skip,
const uint8_t* data,
size_t data_length);
static void GetStringPieceFromOffset(uint32_t target_offset,
uint32_t next_offset,
const uint8_t* data_source,
base::StringPiece* data);
std::unique_ptr<DataSource> data_source_;
raw_ptr<const Entry> resource_table_;
size_t resource_count_;
raw_ptr<const Alias> alias_table_;
size_t alias_count_;
TextEncodingType text_encoding_type_;
ResourceScaleFactor resource_scale_factor_;
};
}
#endif