[serialize] Misc getting copy() to work

This commit is contained in:
Behdad Esfahbod 2019-05-02 16:20:18 -07:00
parent 7d497a3a92
commit 8a32c9eecb
2 changed files with 25 additions and 17 deletions

View File

@ -288,7 +288,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts &&...ds) bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts &&...ds)
{ {
*this = 0; *this = 0;
if (has_null && &src == &Null (Type)) if (has_null && &src == _hb_has_null<Type, has_null>::get_null ())
return false; return false;
auto *s = c->serializer; auto *s = c->serializer;
@ -309,14 +309,16 @@ struct OffsetTo : Offset<OffsetType, has_null>
bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts &&...ds) bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts &&...ds)
{ {
*this = 0; *this = 0;
if (has_null && &src == &Null (Type)) if (has_null && &src == _hb_has_null<Type, has_null>::get_null ())
return false; return false;
c->push (); c->push ();
c->copy (src, hb_forward<Ts> (ds)...); bool ret = c->copy (src, hb_forward<Ts> (ds)...);
c->add_link (*this, c->pop_pack (), base); c->add_link (*this, c->pop_pack (), base);
return ret;
} }
bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
@ -429,10 +431,10 @@ struct UnsizedArrayOf
return_trace (true); return_trace (true);
} }
UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) const
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
auto *out = c->start_embed (*this); auto *out = c->start_embed (this);
if (unlikely (!out->serialize (c, count))) return_trace (nullptr); if (unlikely (!out->serialize (c, count))) return_trace (nullptr);
for (unsigned i = 0; i < count; i++) for (unsigned i = 0; i < count; i++)
out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
@ -610,10 +612,10 @@ struct ArrayOf
return_trace (true); return_trace (true);
} }
ArrayOf* copy (hb_serialize_context_t *c) ArrayOf* copy (hb_serialize_context_t *c) const
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
auto *out = c->start_embed (*this); auto *out = c->start_embed (this);
unsigned count = len; unsigned count = len;
if (unlikely (!out->serialize (c, count))) return_trace (nullptr); if (unlikely (!out->serialize (c, count))) return_trace (nullptr);
for (unsigned i = 0; i < count; i++) for (unsigned i = 0; i < count; i++)

View File

@ -71,7 +71,7 @@ struct hb_serialize_context_t
{ {
bool is_wide: 1; bool is_wide: 1;
unsigned position : 31; unsigned position : 31;
int bias; unsigned bias;
objidx_t objidx; objidx_t objidx;
}; };
@ -323,6 +323,9 @@ struct hb_serialize_context_t
allocate_size<void> (alignment - l); allocate_size<void> (alignment - l);
} }
template <typename Type>
Type *start_embed (const Type &_ HB_UNUSED) const
{ return start_embed<Type> (); }
template <typename Type> template <typename Type>
Type *start_embed (const Type *_ HB_UNUSED = nullptr) const Type *start_embed (const Type *_ HB_UNUSED = nullptr) const
{ {
@ -358,33 +361,36 @@ struct hb_serialize_context_t
} }
template <typename Type> template <typename Type>
Type *embed (const Type &obj) Type *embed (const Type *obj)
{ {
unsigned int size = obj.get_size (); unsigned int size = obj->get_size ();
Type *ret = this->allocate_size<Type> (size); Type *ret = this->allocate_size<Type> (size);
if (unlikely (!ret)) return nullptr; if (unlikely (!ret)) return nullptr;
memcpy (ret, &obj, size); memcpy (ret, obj, size);
return ret; return ret;
} }
template <typename Type>
Type *embed (const Type &obj)
{ return embed (&obj); }
template <typename Type, typename ...Ts> auto template <typename Type, typename ...Ts> auto
_copy (const Type &obj, hb_priority<1>, Ts &&...ds) const HB_RETURN _copy (const Type &src, hb_priority<1>, Ts &&...ds) HB_RETURN
(Type *, obj.copy (this, hb_forward<Ts> (ds)...)) (Type *, src.copy (this, hb_forward<Ts> (ds)...))
template <typename Type> auto template <typename Type> auto
_copy (const Type &obj, hb_priority<0>) const -> decltype (&(obj = obj)) _copy (const Type &src, hb_priority<0>) -> decltype (&(src = src))
{ {
Type *ret = this->allocate_size<Type> (sizeof (Type)); Type *ret = this->allocate_size<Type> (sizeof (Type));
if (unlikely (!ret)) return nullptr; if (unlikely (!ret)) return nullptr;
*ret = obj; *ret = src;
return ret; return ret;
} }
/* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data
* instead of memcpy(). */ * instead of memcpy(). */
template <typename Type, typename ...Ts> template <typename Type, typename ...Ts>
Type *copy (const Type &obj, Ts &&...ds) Type *copy (const Type &src, Ts &&...ds)
{ return _copy (obj, hb_prioritize, hb_forward<Ts> (ds)...); } { return _copy (src, hb_prioritize, hb_forward<Ts> (ds)...); }
template <typename Type> template <typename Type>
hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; }