re-implement Tail; rewrote name table with it

This commit is contained in:
ariza 2020-02-19 12:52:18 -08:00
parent c1313e4be2
commit 4ca8e0d989
3 changed files with 49 additions and 49 deletions

View File

@ -338,6 +338,30 @@ struct OffsetTo : Offset<OffsetType, has_null>
}
/* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
/* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029
* Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&...
*/
template <typename ...Ts>
bool serialize_copy (hb_serialize_context_t *c,
const OffsetTo& src,
const void *src_base,
const void *dst_base,
hb_serialize_context_t::whence_t whence,
Ts&&... ds)
{
*this = 0;
if (src.is_null ())
return false;
c->push ();
bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...);
c->add_link (*this, c->pop_pack (), dst_base, whence);
return ret;
}
template <typename ...Ts>
bool serialize_copy (hb_serialize_context_t *c,
const OffsetTo& src,

View File

@ -98,13 +98,12 @@ struct NameRecord
}
NameRecord* copy (hb_serialize_context_t *c,
const void *src_base,
const void *dst_base) const
const void *src_base) const
{
TRACE_SERIALIZE (this);
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
out->offset.serialize_copy (c, offset, src_base, dst_base, length);
out->offset.serialize_copy (c, offset, src_base, nullptr, hb_serialize_context_t::Tail, length);
return_trace (out);
}
@ -216,13 +215,6 @@ struct name
this->format = 0;
this->count = it.len ();
auto snap = c->snapshot ();
this->nameRecordZ.serialize (c, this->count);
if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false);
c->revert (snap);
const void *dst_string_pool = &(this + this->stringOffset);
NameRecord *name_records = (NameRecord *) calloc (it.len (), NameRecord::static_size);
hb_array_t<NameRecord> records (name_records, it.len ());
@ -234,12 +226,12 @@ struct name
records.qsort ();
c->copy_all (records, src_string_pool, dst_string_pool);
c->copy_all (records, src_string_pool);
free (records.arrayZ);
if (unlikely (c->ran_out_of_room)) return_trace (false);
assert (this->stringOffset == c->length ());
this->stringOffset = c->length ();
return_trace (true);
}

View File

@ -50,6 +50,12 @@ struct hb_serialize_context_t
char *head, *tail;
};
enum whence_t {
Head, /* Relative to the current object head (default). */
Tail, /* Relative to the current object tail after packed. */
Absolute /* Absolute: from the start of the serialize buffer. */
};
struct object_t : range_t
{
void fini () { links.fini (); }
@ -71,7 +77,7 @@ struct hb_serialize_context_t
{
bool is_wide: 1;
bool is_signed: 1;
bool is_absolute: 1;
whence_t whence: 2;
unsigned position: 29;
unsigned bias;
objidx_t objidx;
@ -270,16 +276,10 @@ struct hb_serialize_context_t
assert (packed.tail ()->head == tail);
}
enum base_mode_t {
Head, /* Relative to the current object head (default). */
Tail, /* Relative to the current object tail. */
Absolute /* Absolute: from the start of the serialize buffer. */
};
template <typename T>
void add_link (T &ofs, objidx_t objidx,
const void *base = nullptr,
base_mode_t mode = Head)
whence_t whence = Head)
{
static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
@ -289,34 +289,19 @@ struct hb_serialize_context_t
assert (current);
assert (current->head <= (const char *) &ofs);
const char *dflt_base;
auto& link = *current->links.push ();
switch (mode)
{
case Head:
dflt_base = current->head;
link.is_absolute = false;
break;
case Tail:
dflt_base = current->tail;
link.is_absolute = false;
break;
case Absolute:
dflt_base = start;
link.is_absolute = true;
break;
default: return;
}
if (!base)
base = dflt_base;
else
assert (dflt_base <= (const char *) base);
link.is_wide = sizeof (T) == 4;
link.is_signed = hb_is_signed (hb_unwrap_type (T));
link.whence = whence;
link.position = (const char *) &ofs - current->head;
link.bias = (const char *) base - dflt_base;
if (whence == Head)
{
assert (current->head <= (const char *)base);
link.bias = (const char *) base - current->head;
}
else
link.bias = 0;
link.objidx = objidx;
}
@ -333,12 +318,11 @@ struct hb_serialize_context_t
const object_t* child = packed[link.objidx];
if (unlikely (!child)) { err_other_error(); return; }
unsigned offset;
if (link.is_absolute)
offset = (head - start) + (child->head - tail);
else
{
assert (link.bias <= (size_t) (parent->tail - parent->head));
offset = (child->head - parent->head) - link.bias;
switch (link.whence) {
case Head: offset = child->head - parent->head; break;
case Tail: offset = child->head - parent->tail; break;
case Absolute: offset = (head - start) + (child->head - tail); break;
default: assert (0);
}
if (link.is_signed)