re-implement Tail; rewrote name table with it
This commit is contained in:
parent
c1313e4be2
commit
4ca8e0d989
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue