Commit: 933f0caec65fdbbfbee9ca5f4f2a0b207b619a05
Author: Jacques Lucke
Date:   Fri Aug 21 12:45:33 2020 +0200
Branches: master
https://developer.blender.org/rB933f0caec65fdbbfbee9ca5f4f2a0b207b619a05

Blenloader: move IDProperty read/write code to blenkernel

This is part of T76372.

===================================================================

M       source/blender/blenkernel/BKE_idprop.h
M       source/blender/blenkernel/intern/idprop.c
M       source/blender/blenloader/intern/readfile.c
M       source/blender/blenloader/intern/writefile.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_idprop.h 
b/source/blender/blenkernel/BKE_idprop.h
index 58629cde6ec..c71602e10b2 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -30,6 +30,10 @@ extern "C" {
 
 struct ID;
 struct IDProperty;
+struct BlendWriter;
+struct BlendDataReader;
+struct BlendLibReader;
+struct BlendExpander;
 
 typedef union IDPropertyTemplate {
   int i;
@@ -196,6 +200,14 @@ void IDP_repr_fn(const IDProperty *prop,
                  void *user_data);
 void IDP_print(const struct IDProperty *prop);
 
+void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop);
+void IDP_BlendDataRead_impl(struct BlendDataReader *reader,
+                            IDProperty **prop,
+                            const char *caller_func_id);
+#define IDP_BlendDataRead(reader, prop) IDP_BlendDataRead_impl(reader, prop, 
__func__)
+void IDP_BlendLibRead(struct BlendLibReader *reader, IDProperty *prop);
+void IDP_BlendExpand(struct BlendExpander *expander, IDProperty *prop);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/idprop.c 
b/source/blender/blenkernel/intern/idprop.c
index 529ae227df9..5469d8a4c36 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -26,11 +26,13 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "BLI_endian_switch.h"
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_global.h"
 #include "BKE_idprop.h"
 #include "BKE_lib_id.h"
 
@@ -38,6 +40,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLO_read_write.h"
+
 #include "BLI_strict_flags.h"
 
 /* IDPropertyTemplate is a union in DNA_ID.h */
@@ -1170,4 +1174,270 @@ void IDP_foreach_property(IDProperty *id_property_root,
   }
 }
 
+void IDP_WriteProperty_OnlyData(const IDProperty *prop, BlendWriter *writer);
+
+static void IDP_WriteArray(const IDProperty *prop, BlendWriter *writer)
+{
+  /*REMEMBER to set totalen to len in the linking code!!*/
+  if (prop->data.pointer) {
+    BLO_write_raw(writer, (int)MEM_allocN_len(prop->data.pointer), 
prop->data.pointer);
+
+    if (prop->subtype == IDP_GROUP) {
+      IDProperty **array = prop->data.pointer;
+      int a;
+
+      for (a = 0; a < prop->len; a++) {
+        IDP_BlendWrite(writer, array[a]);
+      }
+    }
+  }
+}
+
+static void IDP_WriteIDPArray(const IDProperty *prop, BlendWriter *writer)
+{
+  /*REMEMBER to set totalen to len in the linking code!!*/
+  if (prop->data.pointer) {
+    const IDProperty *array = prop->data.pointer;
+    int a;
+
+    BLO_write_struct_array(writer, IDProperty, prop->len, array);
+
+    for (a = 0; a < prop->len; a++) {
+      IDP_WriteProperty_OnlyData(&array[a], writer);
+    }
+  }
+}
+
+static void IDP_WriteString(const IDProperty *prop, BlendWriter *writer)
+{
+  /*REMEMBER to set totalen to len in the linking code!!*/
+  BLO_write_raw(writer, prop->len, prop->data.pointer);
+}
+
+static void IDP_WriteGroup(const IDProperty *prop, BlendWriter *writer)
+{
+  IDProperty *loop;
+
+  for (loop = prop->data.group.first; loop; loop = loop->next) {
+    IDP_BlendWrite(writer, loop);
+  }
+}
+
+/* Functions to read/write ID Properties */
+void IDP_WriteProperty_OnlyData(const IDProperty *prop, BlendWriter *writer)
+{
+  switch (prop->type) {
+    case IDP_GROUP:
+      IDP_WriteGroup(prop, writer);
+      break;
+    case IDP_STRING:
+      IDP_WriteString(prop, writer);
+      break;
+    case IDP_ARRAY:
+      IDP_WriteArray(prop, writer);
+      break;
+    case IDP_IDPARRAY:
+      IDP_WriteIDPArray(prop, writer);
+      break;
+  }
+}
+
+void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
+{
+  BLO_write_struct(writer, IDProperty, prop);
+  IDP_WriteProperty_OnlyData(prop, writer);
+}
+
+static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader);
+
+static void IDP_DirectLinkIDPArray(IDProperty *prop, BlendDataReader *reader)
+{
+  IDProperty *array;
+  int i;
+
+  /* since we didn't save the extra buffer, set totallen to len */
+  prop->totallen = prop->len;
+  BLO_read_data_address(reader, &prop->data.pointer);
+
+  array = (IDProperty *)prop->data.pointer;
+
+  /* note!, idp-arrays didn't exist in 2.4x, so the pointer will be cleared
+   * there's not really anything we can do to correct this, at least don't 
crash */
+  if (array == NULL) {
+    prop->len = 0;
+    prop->totallen = 0;
+  }
+
+  for (i = 0; i < prop->len; i++) {
+    IDP_DirectLinkProperty(&array[i], reader);
+  }
+}
+
+static void IDP_DirectLinkArray(IDProperty *prop, BlendDataReader *reader)
+{
+  IDProperty **array;
+  int i;
+
+  /* since we didn't save the extra buffer, set totallen to len */
+  prop->totallen = prop->len;
+
+  if (prop->subtype == IDP_GROUP) {
+    BLO_read_pointer_array(reader, &prop->data.pointer);
+    array = prop->data.pointer;
+
+    for (i = 0; i < prop->len; i++) {
+      IDP_DirectLinkProperty(array[i], reader);
+    }
+  }
+  else if (prop->subtype == IDP_DOUBLE) {
+    BLO_read_double_array(reader, prop->len, (double **)&prop->data.pointer);
+  }
+  else {
+    /* also used for floats */
+    BLO_read_int32_array(reader, prop->len, (int **)&prop->data.pointer);
+  }
+}
+
+static void IDP_DirectLinkString(IDProperty *prop, BlendDataReader *reader)
+{
+  /*since we didn't save the extra string buffer, set totallen to len.*/
+  prop->totallen = prop->len;
+  BLO_read_data_address(reader, &prop->data.pointer);
+}
+
+static void IDP_DirectLinkGroup(IDProperty *prop, BlendDataReader *reader)
+{
+  ListBase *lb = &prop->data.group;
+  IDProperty *loop;
+
+  BLO_read_list(reader, lb);
+
+  /*Link child id properties now*/
+  for (loop = prop->data.group.first; loop; loop = loop->next) {
+    IDP_DirectLinkProperty(loop, reader);
+  }
+}
+
+static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader)
+{
+  switch (prop->type) {
+    case IDP_GROUP:
+      IDP_DirectLinkGroup(prop, reader);
+      break;
+    case IDP_STRING:
+      IDP_DirectLinkString(prop, reader);
+      break;
+    case IDP_ARRAY:
+      IDP_DirectLinkArray(prop, reader);
+      break;
+    case IDP_IDPARRAY:
+      IDP_DirectLinkIDPArray(prop, reader);
+      break;
+    case IDP_DOUBLE:
+      /* Workaround for doubles.
+       * They are stored in the same field as `int val, val2` in the 
IDPropertyData struct,
+       * they have to deal with endianness specifically.
+       *
+       * In theory, val and val2 would've already been swapped
+       * if switch_endian is true, so we have to first unswap
+       * them then re-swap them as a single 64-bit entity. */
+      if (BLO_read_requires_endian_switch(reader)) {
+        BLI_endian_switch_int32(&prop->data.val);
+        BLI_endian_switch_int32(&prop->data.val2);
+        BLI_endian_switch_int64((int64_t *)&prop->data.val);
+      }
+      break;
+    case IDP_INT:
+    case IDP_FLOAT:
+    case IDP_ID:
+      break; /* Nothing special to do here. */
+    default:
+      /* Unknown IDP type, nuke it (we cannot handle unknown types everywhere 
in code,
+       * IDP are way too polymorphic to do it safely. */
+      printf(
+          "%s: found unknown IDProperty type %d, reset to Integer one !\n", 
__func__, prop->type);
+      /* Note: we do not attempt to free unknown prop, we have no way to know 
how to do that! */
+      prop->type = IDP_INT;
+      prop->subtype = 0;
+      IDP_Int(prop) = 0;
+  }
+}
+
+void IDP_BlendDataRead_impl(BlendDataReader *reader, IDProperty **prop, const 
char *caller_func_id)
+{
+  if (*prop) {
+    if ((*prop)->type == IDP_GROUP) {
+      IDP_DirectLinkGroup(*prop, reader);
+    }
+    else {
+      /* corrupt file! */
+      printf("%s: found non group data, freeing type %d!\n", caller_func_id, 
(*prop)->type);
+      /* don't risk id, data's likely corrupt. */
+      // IDP_FreePropertyContent(*prop);
+      *prop = NULL;
+    }
+  }
+}
+
+void IDP_BlendLibRead(BlendLibReader *reader, IDProperty *prop)
+{
+  if (!prop) {
+    return;
+  }
+
+  switch (prop->type) {
+    case IDP_ID: /* PointerProperty */
+    {
+      void *newaddr = BLO_read_get_new_id_address(reader, NULL, IDP_Id(prop));
+      if (IDP_Id(prop) && !newaddr && G.debug) {
+        printf("Error while loading \"%s\". Data not found in file!\n", 
prop->name);
+      }
+      prop->data.pointer = newaddr;
+      break;
+    }
+    case IDP_IDPARRAY: /* CollectionProperty */
+    {
+      IDProperty *idp_array = IDP_IDPArray(prop);
+      for (int i = 0; i < prop->len; i++) {
+        IDP_BlendLibRead(reader, &(idp_array[i]));
+      }
+      break;
+    }
+    case IDP_GROUP: /* PointerProperty */
+    {
+      LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
+        IDP_BlendLibRead(reader, loop);
+      }
+      break;
+    }
+    default:
+      break; /* Nothing to do for other IDProps. */
+  }
+}
+
+void IDP_BlendExpand(struct BlendExpander *expander, IDProperty *prop)
+{
+  if (!prop) {
+    return;
+  }
+
+  switch (prop->type) {
+    case IDP_ID:
+      BLO_expand(expander, IDP_Id(prop));
+      break;
+    case IDP_IDPARRAY: {
+      IDProperty *idp_array = IDP_IDPArray(prop);
+      for (int i = 0; i < prop->len; i++) {
+        IDP_BlendExpand(expander, &idp_array[i]);
+      }
+      break;
+    }
+    case IDP_GROUP:
+      LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
+        IDP_BlendExpand(expander, loop);
+      }
+      break;
+  }
+}
+
 /** \} */
diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index 42b97550db1..8b4b526472c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2268,185 +2268,6 @@ static void link_glob_list(FileData *fd, ListBase *lb) 
/* for glob data */
 
 /** \} */
 
-/* -------------------------------------------------------------------- */
-/** \name Read ID Properties
- * \{ */
-
-static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader);
-static void IDP_LibLinkProperty(IDProperty *prop, BlendLibReader *reader);
-
-static void IDP_DirectLinkIDPArray(IDProperty *prop, BlendDataReader *reader)
-{
-  IDPrope

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to