Merge "Fix computation of 'entry_length' in AAPT2 container format"
am: 6e914e8baf
Change-Id: I4dba5b88e41745a04146f98d874f9988538002a9
This commit is contained in:
@@ -30,6 +30,7 @@ namespace aapt {
|
|||||||
|
|
||||||
constexpr const static uint32_t kContainerFormatMagic = 0x54504141u;
|
constexpr const static uint32_t kContainerFormatMagic = 0x54504141u;
|
||||||
constexpr const static uint32_t kContainerFormatVersion = 1u;
|
constexpr const static uint32_t kContainerFormatVersion = 1u;
|
||||||
|
constexpr const static size_t kPaddingAlignment = 4u;
|
||||||
|
|
||||||
ContainerWriter::ContainerWriter(ZeroCopyOutputStream* out, size_t entry_count)
|
ContainerWriter::ContainerWriter(ZeroCopyOutputStream* out, size_t entry_count)
|
||||||
: out_(out), total_entry_count_(entry_count), current_entry_count_(0u) {
|
: out_(out), total_entry_count_(entry_count), current_entry_count_(0u) {
|
||||||
@@ -49,11 +50,17 @@ ContainerWriter::ContainerWriter(ZeroCopyOutputStream* out, size_t entry_count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void WritePadding(int padding, CodedOutputStream* out) {
|
inline static size_t CalculatePaddingForAlignment(size_t size) {
|
||||||
if (padding < 4) {
|
size_t overage = size % kPaddingAlignment;
|
||||||
const uint32_t zero = 0u;
|
return overage == 0 ? 0 : kPaddingAlignment - overage;
|
||||||
out->WriteRaw(&zero, padding);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void WritePadding(size_t padding, CodedOutputStream* out) {
|
||||||
|
CHECK(padding < kPaddingAlignment);
|
||||||
|
const uint32_t zero = 0u;
|
||||||
|
static_assert(sizeof(zero) >= kPaddingAlignment, "Not enough source bytes for padding");
|
||||||
|
|
||||||
|
out->WriteRaw(&zero, padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContainerWriter::AddResTableEntry(const pb::ResourceTable& table) {
|
bool ContainerWriter::AddResTableEntry(const pb::ResourceTable& table) {
|
||||||
@@ -70,7 +77,7 @@ bool ContainerWriter::AddResTableEntry(const pb::ResourceTable& table) {
|
|||||||
|
|
||||||
// Write the aligned size.
|
// Write the aligned size.
|
||||||
const ::google::protobuf::uint64 size = table.ByteSize();
|
const ::google::protobuf::uint64 size = table.ByteSize();
|
||||||
const int padding = 4 - (size % 4);
|
const int padding = CalculatePaddingForAlignment(size);
|
||||||
coded_out.WriteLittleEndian64(size);
|
coded_out.WriteLittleEndian64(size);
|
||||||
|
|
||||||
// Write the table.
|
// Write the table.
|
||||||
@@ -103,9 +110,9 @@ bool ContainerWriter::AddResFileEntry(const pb::internal::CompiledFile& file,
|
|||||||
|
|
||||||
// Write the aligned size.
|
// Write the aligned size.
|
||||||
const ::google::protobuf::uint32 header_size = file.ByteSize();
|
const ::google::protobuf::uint32 header_size = file.ByteSize();
|
||||||
const int header_padding = 4 - (header_size % 4);
|
const int header_padding = CalculatePaddingForAlignment(header_size);
|
||||||
const ::google::protobuf::uint64 data_size = in->TotalSize();
|
const ::google::protobuf::uint64 data_size = in->TotalSize();
|
||||||
const int data_padding = 4 - (data_size % 4);
|
const int data_padding = CalculatePaddingForAlignment(data_size);
|
||||||
coded_out.WriteLittleEndian64(kResFileEntryHeaderSize + header_size + header_padding + data_size +
|
coded_out.WriteLittleEndian64(kResFileEntryHeaderSize + header_size + header_padding + data_size +
|
||||||
data_padding);
|
data_padding);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ boundary, so if a previous entry ends unaligned, padding must be inserted.
|
|||||||
| Size (in bytes) | Field | Description |
|
| Size (in bytes) | Field | Description |
|
||||||
|:----------------|:---------------|:----------------------------------------------------------------------------------------------------------|
|
|:----------------|:---------------|:----------------------------------------------------------------------------------------------------------|
|
||||||
| `4` | `entry_type` | The type of the entry. This can be one of two types: `RES_TABLE (0x00000000)` or `RES_FILE (0x00000001)`. |
|
| `4` | `entry_type` | The type of the entry. This can be one of two types: `RES_TABLE (0x00000000)` or `RES_FILE (0x00000001)`. |
|
||||||
| `8` | `entry_length` | The length of the data that follows. |
|
| `8` | `entry_length` | The length of the data that follows. Do not use if `entry_type` is `RES_FILE`; this value may be wrong. |
|
||||||
| `entry_length` | `data` | The payload. The contents of this varies based on the `entry_type`. |
|
| `entry_length` | `data` | The payload. The contents of this varies based on the `entry_type`. |
|
||||||
|
|
||||||
If the `entry_type` is equal to `RES_TABLE (0x00000000)`, the `data` field contains a serialized
|
If the `entry_type` is equal to `RES_TABLE (0x00000000)`, the `data` field contains a serialized
|
||||||
@@ -33,12 +33,13 @@ If the `entry_type` is equal to `RES_FILE (0x00000001)`, the `data` field contai
|
|||||||
|
|
||||||
|
|
||||||
| Size (in bytes) | Field | Description |
|
| Size (in bytes) | Field | Description |
|
||||||
|:----------------|:---------------|:----------------------------------------------------------------------------------------------------------|
|
|:----------------|:-----------------|:----------------------------------------------------------------------------------------------------------|
|
||||||
| `4` | `header_size` | The size of the `header` field. |
|
| `4` | `header_size` | The size of the `header` field. |
|
||||||
| `8` | `data_size` | The size of the `data` field. |
|
| `8` | `data_size` | The size of the `data` field. |
|
||||||
| `header_size` | `header` | The serialized Protobuf message [aapt.pb.internal.CompiledFile](ResourcesInternal.proto). |
|
| `header_size` | `header` | The serialized Protobuf message [aapt.pb.internal.CompiledFile](ResourcesInternal.proto). |
|
||||||
| `x` | `padding` | Up to 4 bytes of zeros, if padding is necessary to align the `data` field on a 32-bit boundary. |
|
| `x` | `header_padding` | Up to 3 bytes of zeros, if padding is necessary to align the `data` field on a 32-bit boundary. |
|
||||||
| `data_size` | `data` | The payload, which is determined by the `type` field in the `aapt.pb.internal.CompiledFile`. This can be a PNG file, binary XML, or [aapt.pb.XmlNode](Resources.proto). |
|
| `data_size` | `data` | The payload, which is determined by the `type` field in the `aapt.pb.internal.CompiledFile`. This can be a PNG file, binary XML, or [aapt.pb.XmlNode](Resources.proto). |
|
||||||
|
| `y` | `data_padding` | Up to 3 bytes of zeros, if `data_size` is not a multiple of 4. |
|
||||||
|
|
||||||
## AAPT2 Static Library Format (extension `.sapk`)
|
## AAPT2 Static Library Format (extension `.sapk`)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user