Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-10-08 19:17:12 +0300
committerJacques Lucke <jacques@blender.org>2020-10-08 19:17:12 +0300
commit51e43f27fa2ecb5529d14cdfd1c73447dd420046 (patch)
tree955b0b4ef49a54b94718eaf13128ae1a33eafe64
parentf23bf4cb109cb8f39f873c4f80acbec3f33b098c (diff)
DNA: cleanup endian switching when loading file
This patch "modernizes" `DNA_struct_switch_endian` similar to how I updated `DNA_struct_reconstruct` recently. Furthermore, some special case handling have been moved to another place. Reviewers: campbellbarton Differential Revision: https://developer.blender.org/D9089
-rw-r--r--source/blender/blenloader/intern/readfile.c30
-rw-r--r--source/blender/makesdna/DNA_genfile.h2
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c190
3 files changed, 117 insertions, 105 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index cf2181c8a27..9465819a2d8 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -766,7 +766,7 @@ static void switch_endian_bh8(BHead8 *bhead)
}
}
-static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, int do_endian_swap)
+static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, bool do_endian_swap)
{
BHead4 *bhead4 = (BHead4 *)bhead;
int64_t old;
@@ -859,7 +859,7 @@ static BHeadN *get_bhead(FileData *fd)
}
if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
- bh4_from_bh8(&bhead, &bhead8, (fd->flags & FD_FLAGS_SWITCH_ENDIAN));
+ bh4_from_bh8(&bhead, &bhead8, (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0);
}
else {
/* MIN2 is only to quiet '-Warray-bounds' compiler warning. */
@@ -2509,6 +2509,32 @@ static void direct_link_ipo(BlendDataReader *reader, Ipo *ipo)
BLO_read_data_address(reader, &icu->bezt);
BLO_read_data_address(reader, &icu->bp);
BLO_read_data_address(reader, &icu->driver);
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&icu->blocktype);
+ if (icu->driver != NULL) {
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&icu->blocktype);
+ if (icu->driver != NULL) {
+ BLI_endian_switch_int16(&icu->driver->blocktype);
+ }
+ }
+ }
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&ipo->blocktype);
+ BLI_endian_switch_int16(&icu->driver->blocktype);
+ }
+ }
+ }
+
+ /* Undo generic endian switching. */
+ if (BLO_read_requires_endian_switch(reader)) {
+ BLI_endian_switch_int16(&ipo->blocktype);
}
}
diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h
index 96766bf16b8..6fcbc53d47b 100644
--- a/source/blender/makesdna/DNA_genfile.h
+++ b/source/blender/makesdna/DNA_genfile.h
@@ -103,7 +103,7 @@ void DNA_reconstruct_info_free(struct DNA_ReconstructInfo *reconstruct_info);
int DNA_struct_find_nr_ex(const struct SDNA *sdna, const char *str, unsigned int *index_last);
int DNA_struct_find_nr(const struct SDNA *sdna, const char *str);
-void DNA_struct_switch_endian(const struct SDNA *oldsdna, int oldSDNAnr, char *data);
+void DNA_struct_switch_endian(const struct SDNA *sdna, int struct_nr, char *data);
const char *DNA_struct_get_compareflags(const struct SDNA *sdna, const struct SDNA *newsdna);
void *DNA_struct_reconstruct(const struct DNA_ReconstructInfo *reconstruct_info,
int old_struct_nr,
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index d7360c67210..1a107547450 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -980,92 +980,110 @@ static int elem_offset(const SDNA *sdna,
return -1;
}
+/* Each struct member belongs to one of the categories below. */
+typedef enum eStructMemberCategory {
+ STRUCT_MEMBER_CATEGORY_STRUCT,
+ STRUCT_MEMBER_CATEGORY_PRIMITIVE,
+ STRUCT_MEMBER_CATEGORY_POINTER,
+} eStructMemberCategory;
+
+static eStructMemberCategory get_struct_member_category(const SDNA *sdna,
+ const SDNA_StructMember *member)
+{
+ const char *member_name = sdna->names[member->name];
+ if (ispointer(member_name)) {
+ return STRUCT_MEMBER_CATEGORY_POINTER;
+ }
+ const char *member_type_name = sdna->types[member->type];
+ if (DNA_struct_find(sdna, member_type_name)) {
+ return STRUCT_MEMBER_CATEGORY_STRUCT;
+ }
+ return STRUCT_MEMBER_CATEGORY_PRIMITIVE;
+}
+
+static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
+{
+ const char *name = sdna->names[member->name];
+ const int array_length = sdna->names_array_len[member->name];
+ if (ispointer(name)) {
+ return sdna->pointer_size * array_length;
+ }
+ const int type_size = sdna->types_size[member->type];
+ return type_size * array_length;
+}
+
/**
* Does endian swapping on the fields of a struct value.
*
- * \param oldsdna: SDNA of Blender that saved file
- * \param oldSDNAnr: Index of struct info within oldsdna
- * \param data: Struct data
+ * \param sdna: SDNA of the struct_nr belongs to
+ * \param struct_nr: Index of struct info within sdna
+ * \param data: Struct data that is to be converted
*/
-void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data)
+void DNA_struct_switch_endian(const SDNA *sdna, int struct_nr, char *data)
{
- /* Recursive!
- * If element is a struct, call recursive.
- */
- if (oldSDNAnr == -1) {
+ if (struct_nr == -1) {
return;
}
- const int firststructtypenr = oldsdna->structs[0]->type;
- const SDNA_Struct *struct_info = oldsdna->structs[oldSDNAnr];
- char *cur = data;
- for (int a = 0; a < struct_info->members_len; a++) {
- const SDNA_StructMember *member = &struct_info->members[a];
- const char *type = oldsdna->types[member->type];
- const char *name = oldsdna->names[member->name];
- const int old_name_array_len = oldsdna->names_array_len[member->name];
-
- /* DNA_elem_size_nr = including arraysize */
- const int elen = DNA_elem_size_nr(oldsdna, member->type, member->name);
-
- /* test: is type a struct? */
- if (member->type >= firststructtypenr && !ispointer(name)) {
- /* struct field type */
- /* where does the old data start (is there one?) */
-
- const int data_offset = elem_offset(oldsdna, type, name, struct_info);
- if (data_offset != -1) {
- char *cpo = data + data_offset;
- unsigned int oldsdna_index_last = UINT_MAX;
- oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last);
-
- int mul = old_name_array_len;
- const int elena = elen / mul;
-
- while (mul--) {
- DNA_struct_switch_endian(oldsdna, oldSDNAnr, cpo);
- cpo += elena;
+
+ const SDNA_Struct *struct_info = sdna->structs[struct_nr];
+
+ int offset_in_bytes = 0;
+ for (int member_index = 0; member_index < struct_info->members_len; member_index++) {
+ const SDNA_StructMember *member = &struct_info->members[member_index];
+ const eStructMemberCategory member_category = get_struct_member_category(sdna, member);
+ char *member_data = data + offset_in_bytes;
+ const char *member_type_name = sdna->types[member->type];
+ const int member_array_length = sdna->names_array_len[member->name];
+
+ switch (member_category) {
+ case STRUCT_MEMBER_CATEGORY_STRUCT: {
+ const int substruct_size = sdna->types_size[member->type];
+ const int substruct_nr = DNA_struct_find_nr(sdna, member_type_name);
+ BLI_assert(substruct_nr != -1);
+ for (int a = 0; a < member_array_length; a++) {
+ DNA_struct_switch_endian(sdna, substruct_nr, member_data + a * substruct_size);
}
+ break;
}
- }
- else {
- /* non-struct field type */
- if (ispointer(name)) {
- /* See readfile.c (#bh4_from_bh8 swap endian argument),
- * this is only done when reducing the size of a pointer from 4 to 8. */
- if (sizeof(void *) < 8) {
- if (oldsdna->pointer_size == 8) {
- BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len);
+ case STRUCT_MEMBER_CATEGORY_PRIMITIVE: {
+ switch (member->type) {
+ case SDNA_TYPE_SHORT:
+ case SDNA_TYPE_USHORT: {
+ BLI_endian_switch_int16_array((int16_t *)member_data, member_array_length);
+ break;
}
- }
- }
- else {
- if (ELEM(member->type, SDNA_TYPE_SHORT, SDNA_TYPE_USHORT)) {
-
- /* exception: variable called blocktype: derived from ID_ */
- bool skip = false;
- if (name[0] == 'b' && name[1] == 'l') {
- if (STREQ(name, "blocktype")) {
- skip = true;
- }
+ case SDNA_TYPE_INT:
+ case SDNA_TYPE_FLOAT: {
+ /* Note, intentionally ignore long/ulong, because these could be 4 or 8 bytes.
+ * Fortunately, we only use these types for runtime variables and only once for a
+ * struct type that is no longer used. */
+ BLI_endian_switch_int32_array((int32_t *)member_data, member_array_length);
+ break;
}
-
- if (skip == false) {
- BLI_endian_switch_int16_array((int16_t *)cur, old_name_array_len);
+ case SDNA_TYPE_INT64:
+ case SDNA_TYPE_UINT64:
+ case SDNA_TYPE_DOUBLE: {
+ BLI_endian_switch_int64_array((int64_t *)member_data, member_array_length);
+ break;
+ }
+ default: {
+ break;
}
}
- else if (ELEM(member->type, SDNA_TYPE_INT, SDNA_TYPE_FLOAT)) {
- /* note, intentionally ignore long/ulong here these could be 4 or 8 bits,
- * but turns out we only used for runtime vars and
- * only once for a struct type that's no longer used. */
-
- BLI_endian_switch_int32_array((int32_t *)cur, old_name_array_len);
- }
- else if (ELEM(member->type, SDNA_TYPE_INT64, SDNA_TYPE_UINT64, SDNA_TYPE_DOUBLE)) {
- BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len);
+ break;
+ }
+ case STRUCT_MEMBER_CATEGORY_POINTER: {
+ /* See readfile.c (#bh4_from_bh8 swap endian argument),
+ * this is only done when reducing the size of a pointer from 4 to 8. */
+ if (sizeof(void *) < 8) {
+ if (sdna->pointer_size == 8) {
+ BLI_endian_switch_uint64_array((uint64_t *)member_data, member_array_length);
+ }
}
+ break;
}
}
- cur += elen;
+ offset_in_bytes += get_member_size_in_bytes(sdna, member);
}
}
@@ -1235,38 +1253,6 @@ void *DNA_struct_reconstruct(const DNA_ReconstructInfo *reconstruct_info,
return new_blocks;
}
-/* Each struct member belongs to one of the categories below. */
-typedef enum eStructMemberCategory {
- STRUCT_MEMBER_CATEGORY_STRUCT,
- STRUCT_MEMBER_CATEGORY_PRIMITIVE,
- STRUCT_MEMBER_CATEGORY_POINTER,
-} eStructMemberCategory;
-
-static eStructMemberCategory get_struct_member_category(const SDNA *sdna,
- const SDNA_StructMember *member)
-{
- const char *member_name = sdna->names[member->name];
- if (ispointer(member_name)) {
- return STRUCT_MEMBER_CATEGORY_POINTER;
- }
- const char *member_type_name = sdna->types[member->type];
- if (DNA_struct_find(sdna, member_type_name)) {
- return STRUCT_MEMBER_CATEGORY_STRUCT;
- }
- return STRUCT_MEMBER_CATEGORY_PRIMITIVE;
-}
-
-static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *member)
-{
- const char *name = sdna->names[member->name];
- const int array_length = sdna->names_array_len[member->name];
- if (ispointer(name)) {
- return sdna->pointer_size * array_length;
- }
- const int type_size = sdna->types_size[member->type];
- return type_size * array_length;
-}
-
/** Finds a member in the given struct with the given name. */
static const SDNA_StructMember *find_member_with_matching_name(const SDNA *sdna,
const SDNA_Struct *struct_info,