mirror of
https://github.com/darlinghq/xcbuild.git
synced 2025-02-18 15:49:22 +00:00
Add MSVC support for zero-length arrays and packed structs.
This commit is contained in:
parent
8a433f1394
commit
daa326ae9f
@ -30,6 +30,19 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
#define __BOM_PACKED_STRUCT_BEGIN __pragma(pack(push, 1))
|
||||
#define __BOM_PACKED_STRUCT_END __pragma(pack(pop))
|
||||
#else
|
||||
#define __BOM_PACKED_STRUCT_BEGIN
|
||||
#define __BOM_PACKED_STRUCT_END __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
__pragma(warning(push))
|
||||
__pragma(warning(disable: 4200))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Build of Materials format (BOM)
|
||||
*
|
||||
@ -62,7 +75,7 @@ extern "C" {
|
||||
* in the tree has indexes pointing to both key and value data for that item.
|
||||
*/
|
||||
|
||||
struct bom_header {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_header {
|
||||
char magic[8]; // = BOMStore
|
||||
uint32_t version; // = 1?
|
||||
uint32_t block_count; // = 73 = 0x49?
|
||||
@ -70,52 +83,56 @@ struct bom_header {
|
||||
uint32_t index_length; // Length of second part
|
||||
uint32_t variables_offset;
|
||||
uint32_t trailer_len; // FIXME: What does this data at the end mean?
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_index {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_index {
|
||||
uint32_t address;
|
||||
uint32_t length;
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_index_header {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_index_header {
|
||||
uint32_t count; // FIXME: What is this? It is not the length of the array...
|
||||
struct bom_index index[0];
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_variable {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_variable {
|
||||
uint32_t index;
|
||||
uint8_t length;
|
||||
char name[0]; // length
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_variables {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_variables {
|
||||
uint32_t count; // Number of entries that follow
|
||||
struct bom_variable first[0];
|
||||
} __attribute__((packed));
|
||||
// Followed by bom_variable entries
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_tree { // 21 bytes
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_tree { // 21 bytes
|
||||
char magic[4]; // = "tree"
|
||||
uint32_t version;
|
||||
uint32_t child; // FIXME: Not sure about this one...
|
||||
uint32_t node_size; // byte count of each entry in the tree (BOMPaths)
|
||||
uint32_t path_count; // total number of paths in all leaves combined
|
||||
uint8_t unknown3;
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_tree_entry_indexes {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_tree_entry_indexes {
|
||||
uint32_t value_index;
|
||||
uint32_t key_index;
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_tree_entry {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_tree_entry {
|
||||
uint16_t is_leaf; // if 0 then this entry refers to other BOMPaths entries
|
||||
uint16_t count; // for leaf, count of paths. for top level, (# of leafs - 1)
|
||||
uint32_t forward; // next leaf, when there are multiple leafs
|
||||
uint32_t backward; // previous leaf, when there are multiple leafs
|
||||
struct bom_tree_entry_indexes indexes[0];
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
|
||||
#if _MSC_VER
|
||||
__pragma(warning(pop))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <bom/bom.h>
|
||||
#include <bom/bom_format.h>
|
||||
#include <libutil/Options.h>
|
||||
|
||||
#include <memory>
|
||||
@ -260,6 +261,11 @@ Help(std::string const &error = std::string())
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#if _MSC_VER
|
||||
__pragma(warning(push))
|
||||
__pragma(warning(disable: 4200))
|
||||
#endif
|
||||
|
||||
enum bom_path_type {
|
||||
bom_path_type_file = 1, // BOMPathInfo2 is exe=88 regular=35 bytes
|
||||
bom_path_type_directory = 2, // BOMPathInfo2 is 31 bytes
|
||||
@ -267,7 +273,7 @@ extern "C" {
|
||||
bom_path_type_device = 4 // BOMPathInfo2 is 35 bytes
|
||||
};
|
||||
|
||||
struct bom_path_info_2 {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_path_info_2 {
|
||||
uint8_t type; // See types above
|
||||
uint8_t unknown0; // = 1?
|
||||
uint16_t architecture; // Not sure exactly what this means...
|
||||
@ -285,17 +291,21 @@ extern "C" {
|
||||
char linkName[0];
|
||||
|
||||
// FIXME: executable files have a buch of other crap here:
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_path_info_1 {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_path_info_1 {
|
||||
uint32_t id;
|
||||
uint32_t index; // Pointer to BOMPathInfo2
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
struct bom_file {
|
||||
__BOM_PACKED_STRUCT_BEGIN struct bom_file {
|
||||
uint32_t parent; // Parent BOMPathInfo1->id
|
||||
char name[0];
|
||||
} __attribute__((packed));
|
||||
} __BOM_PACKED_STRUCT_END;
|
||||
|
||||
#if _MSC_VER
|
||||
__pragma(warning(pop))
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -39,6 +39,19 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
#define __CAR_PACKED_STRUCT_BEGIN __pragma(pack(push, 1))
|
||||
#define __CAR_PACKED_STRUCT_END __pragma(pack(pop))
|
||||
#else
|
||||
#define __CAR_PACKED_STRUCT_BEGIN
|
||||
#define __CAR_PACKED_STRUCT_END __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
__pragma(warning(push))
|
||||
__pragma(warning(disable: 4200))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Compiled Asset Archive format (car)
|
||||
*
|
||||
@ -82,10 +95,10 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
struct car_attribute_pair {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_attribute_pair {
|
||||
uint16_t identifier;
|
||||
uint16_t value;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
enum car_attribute_identifier {
|
||||
car_attribute_identifier_element = 1,
|
||||
@ -180,7 +193,7 @@ enum car_attribute_identifier_size_class_value {
|
||||
};
|
||||
|
||||
// values seem to be little endian, unlike BOM
|
||||
struct car_header {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_header {
|
||||
char magic[4]; // RATC
|
||||
|
||||
uint32_t ui_version; // 31 01 00 00
|
||||
@ -196,64 +209,64 @@ struct car_header {
|
||||
uint32_t schema_version; // 04 00 00 00
|
||||
uint32_t color_space_id; // 01 00 00 00
|
||||
uint32_t key_semantics; // 01 00 00 00
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_extended_metadata {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_extended_metadata {
|
||||
char magic[4]; // 'META'
|
||||
char contents[1024]; // string
|
||||
};
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_key_format {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_key_format {
|
||||
char magic[4]; // 'tmfk'
|
||||
uint32_t reserved;
|
||||
uint32_t num_identifiers;
|
||||
uint32_t identifier_list[0];
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
// length is key length
|
||||
typedef char car_facet_key;
|
||||
|
||||
struct car_facet_value {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_facet_value {
|
||||
// ????
|
||||
struct {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} hot_spot;
|
||||
} hot_spot __CAR_PACKED_STRUCT_END;
|
||||
|
||||
uint16_t attributes_count;
|
||||
struct car_attribute_pair attributes[0];
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_part_element_key {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_part_element_key {
|
||||
uint32_t part_element_id; // maybe id? increments
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_part_element_value {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_part_element_value {
|
||||
uint32_t unknown1;
|
||||
uint32_t unknown2;
|
||||
char name[0]; // length - 8
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
// flat list of short values in the order of the attributes from the keyformat plus a trailing null
|
||||
typedef uint16_t car_rendition_key;
|
||||
|
||||
struct car_rendition_info_header {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_header {
|
||||
uint32_t magic;
|
||||
uint32_t length;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_value {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_value {
|
||||
char magic[4]; // CTSI is Core Theme Structured Image
|
||||
uint32_t version; // current known version is 1
|
||||
|
||||
struct {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct {
|
||||
unsigned int is_header_flagged_fpo : 1;
|
||||
unsigned int is_excluded_from_contrast_filter : 1;
|
||||
unsigned int is_vector : 1;
|
||||
unsigned int is_opaque : 1;
|
||||
unsigned int bitmap_encoding : 4;
|
||||
unsigned int reserved : 24;
|
||||
} flags;
|
||||
} flags __CAR_PACKED_STRUCT_END;
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
@ -262,23 +275,23 @@ struct car_rendition_value {
|
||||
uint32_t color_space_id : 4; // colorspace ID. 0 for sRGB, all else for generic rgb, used only if pixelFormat 'ARGB'
|
||||
uint32_t reserved : 28;
|
||||
|
||||
struct {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct {
|
||||
uint32_t modification_date; // modification date in seconds since 1970?
|
||||
uint16_t layout; // layout/type of the rendition
|
||||
uint16_t reserved; // always zero
|
||||
char name[128];
|
||||
} metadata;
|
||||
} metadata __CAR_PACKED_STRUCT_END;
|
||||
|
||||
uint32_t info_len; // size of the list of information after header but before bitmap
|
||||
|
||||
struct {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct {
|
||||
uint32_t bitmap_count;
|
||||
uint32_t reserved;
|
||||
uint32_t payload_size; // size of all the proceeding information info_len + data
|
||||
} bitmaps;
|
||||
} bitmaps __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_header info[0];
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
enum car_rendition_value_pixel_format {
|
||||
car_rendition_value_pixel_format_argb = 'ARGB', // color + alpha
|
||||
@ -316,55 +329,55 @@ enum car_rendition_value_layout {
|
||||
car_rendition_value_layout_asset_pack = 1004,
|
||||
};
|
||||
|
||||
struct car_rendition_info_slice {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_slice {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_slices {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_slices {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t nslices;
|
||||
struct car_rendition_info_slice slices[0];
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_metrics_metric {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_metrics_metric {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_metrics {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_metrics {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t nmetrics; // todo should the below be an array?
|
||||
struct car_rendition_info_metrics_metric top_right_inset;
|
||||
struct car_rendition_info_metrics_metric bottom_left_inset;
|
||||
struct car_rendition_info_metrics_metric image_size;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_composition {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_composition {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t blend_mode;
|
||||
float opacity;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_uti {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_uti {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t uti_length;
|
||||
char uti[0];
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_bitmap_info {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_bitmap_info {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t exif_orientation;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_bytes_per_row {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_bytes_per_row {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t bytes_per_row;
|
||||
} __attribute__((packed));
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_info_reference {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_info_reference {
|
||||
struct car_rendition_info_header header;
|
||||
uint32_t magic; // INLK
|
||||
uint32_t padding; // always 0?
|
||||
@ -375,7 +388,7 @@ struct car_rendition_info_reference {
|
||||
uint16_t layout; // since rendition header says internal link
|
||||
uint16_t key_length;
|
||||
car_rendition_key key[0]; // rendition containing data
|
||||
};
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
enum car_rendition_info_magic {
|
||||
car_rendition_info_magic_slices = 1001,
|
||||
@ -388,33 +401,33 @@ enum car_rendition_info_magic {
|
||||
car_rendition_info_magic_alpha_cropped_frame = 1011,
|
||||
};
|
||||
|
||||
struct car_rendition_data_header1 {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_data_header1 {
|
||||
char magic[4]; // CELM
|
||||
struct {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct {
|
||||
unsigned int unknown1 : 1;
|
||||
unsigned int unknown2 : 1;
|
||||
unsigned int reserved : 30;
|
||||
} flags;
|
||||
} flags __CAR_PACKED_STRUCT_END;
|
||||
uint32_t compression; // see magic below
|
||||
uint32_t length; // length of data
|
||||
uint8_t data[0]; // length
|
||||
};
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_data_header2 {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_data_header2 {
|
||||
char magic[4]; // KCBC
|
||||
uint32_t unknown1;
|
||||
uint32_t unknown2;
|
||||
uint32_t unknown3;
|
||||
uint32_t length;
|
||||
uint8_t data[0];
|
||||
};
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
struct car_rendition_data_header_raw {
|
||||
__CAR_PACKED_STRUCT_BEGIN struct car_rendition_data_header_raw {
|
||||
char magic[4]; // DWAR
|
||||
uint32_t unknown1;
|
||||
uint32_t length; // length of data
|
||||
uint8_t data[0];
|
||||
};
|
||||
} __CAR_PACKED_STRUCT_END;
|
||||
|
||||
enum car_rendition_data_compression_magic {
|
||||
car_rendition_data_compression_magic_rle = 0,
|
||||
@ -445,6 +458,10 @@ extern const char *const car_bezels_variable;
|
||||
|
||||
extern const char *const car_attribute_identifier_names[_car_attribute_identifier_count];
|
||||
|
||||
#if _MSC_VER
|
||||
__pragma(warning(pop))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -12,28 +12,34 @@
|
||||
#include <car/AttributeList.h>
|
||||
#include <car/car_format.h>
|
||||
|
||||
struct test_car_facet_value {
|
||||
struct car_facet_value header;
|
||||
struct car_attribute_pair attributes[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
static struct test_car_facet_value test_facet_value_s = {
|
||||
{
|
||||
{ 0, 0 },
|
||||
3,
|
||||
},
|
||||
{
|
||||
static struct car_facet_value *
|
||||
TestFacetValue(size_t *size)
|
||||
{
|
||||
static struct car_attribute_pair const attributes[] = {
|
||||
{ car_attribute_identifier_element, 85 },
|
||||
{ car_attribute_identifier_part, 181 },
|
||||
{ car_attribute_identifier_identifier, 4258 },
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
static struct car_facet_value *test_facet_value = &(test_facet_value_s.header);
|
||||
static struct car_facet_value *facet_value = nullptr;
|
||||
static size_t const facet_value_size = sizeof(*facet_value) + sizeof(attributes);
|
||||
|
||||
if (facet_value == nullptr) {
|
||||
facet_value = static_cast<car_facet_value *>(malloc(facet_value_size));
|
||||
facet_value->hot_spot = { 0, 0 };
|
||||
facet_value->attributes_count = sizeof(attributes) / sizeof(*attributes);
|
||||
memcpy(&facet_value->attributes, &attributes, sizeof(attributes));
|
||||
}
|
||||
|
||||
if (size != nullptr) {
|
||||
*size = facet_value_size;
|
||||
}
|
||||
return facet_value;
|
||||
}
|
||||
|
||||
TEST(Facet, Deserialize)
|
||||
{
|
||||
auto facet = car::Facet::Load("name", test_facet_value);
|
||||
auto facet = car::Facet::Load("name", TestFacetValue(nullptr));
|
||||
EXPECT_EQ(facet.name(), "name");
|
||||
EXPECT_EQ(*facet.attributes().get(car_attribute_identifier_element), 85);
|
||||
EXPECT_EQ(*facet.attributes().get(car_attribute_identifier_part), 181);
|
||||
@ -42,8 +48,9 @@ TEST(Facet, Deserialize)
|
||||
|
||||
TEST(Facet, Serialize)
|
||||
{
|
||||
std::vector<uint8_t> test_facet_value_vector(reinterpret_cast<uint8_t *>(test_facet_value),
|
||||
reinterpret_cast<uint8_t *>(test_facet_value) + sizeof(test_facet_value_s));
|
||||
size_t test_facet_value_size = 0;
|
||||
uint8_t *test_facet_value = reinterpret_cast<uint8_t *>(TestFacetValue(&test_facet_value_size));
|
||||
std::vector<uint8_t> test_facet_value_vector(test_facet_value, test_facet_value + test_facet_value_size);
|
||||
|
||||
car::AttributeList attributes = car::AttributeList({
|
||||
{ car_attribute_identifier_element, 85 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user