[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)
{
*this = 0;
if (has_null && &src == &Null (Type))
if (has_null && &src == _hb_has_null<Type, has_null>::get_null ())
return false;
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)
{
*this = 0;
if (has_null && &src == &Null (Type))
if (has_null && &src == _hb_has_null<Type, has_null>::get_null ())
return false;
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);
return ret;
}
bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
@ -429,10 +431,10 @@ struct UnsizedArrayOf
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);
auto *out = c->start_embed (*this);
auto *out = c->start_embed (this);
if (unlikely (!out->serialize (c, count))) return_trace (nullptr);
for (unsigned i = 0; i < count; i++)
out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
@ -610,10 +612,10 @@ struct ArrayOf
return_trace (true);
}
ArrayOf* copy (hb_serialize_context_t *c)
ArrayOf* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
auto *out = c->start_embed (*this);
auto *out = c->start_embed (this);
unsigned count = len;
if (unlikely (!out->serialize (c, count))) return_trace (nullptr);
for (unsigned i = 0; i < count; i++)

View File

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