[serialize] Streamline error propagation
This commit is contained in:
parent
969ff3c7aa
commit
9aebfb4182
|
@ -137,6 +137,8 @@ struct hb_buffer_t
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
|
|
||||||
|
bool in_error () const { return !successful; }
|
||||||
|
|
||||||
void allocate_var (unsigned int start, unsigned int count)
|
void allocate_var (unsigned int start, unsigned int count)
|
||||||
{
|
{
|
||||||
#ifndef HB_NDEBUG
|
#ifndef HB_NDEBUG
|
||||||
|
|
|
@ -508,14 +508,31 @@ struct hb_serialize_context_t
|
||||||
reset ();
|
reset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool in_error () const { return !this->successful; }
|
||||||
|
|
||||||
void reset ()
|
void reset ()
|
||||||
{
|
{
|
||||||
this->ran_out_of_room = false;
|
this->successful = true;
|
||||||
this->head = this->start;
|
this->head = this->start;
|
||||||
this->debug_depth = 0;
|
this->debug_depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool err (bool e) { return this->ran_out_of_room = this->ran_out_of_room || e; }
|
bool propagate_error (bool e)
|
||||||
|
{ return this->successful = this->successful && e; }
|
||||||
|
template <typename T> bool propagate_error (const T &obj)
|
||||||
|
{ return this->successful = this->successful && !obj.in_error (); }
|
||||||
|
template <typename T> bool propagate_error (const T *obj)
|
||||||
|
{ return this->successful = this->successful && !obj->in_error (); }
|
||||||
|
template <typename T1, typename T2> bool propagate_error (T1 &o1, T2 &o2)
|
||||||
|
{ return propagate_error (o1) && propagate_error (o2); }
|
||||||
|
template <typename T1, typename T2> bool propagate_error (T1 *o1, T2 *o2)
|
||||||
|
{ return propagate_error (o1) && propagate_error (o2); }
|
||||||
|
template <typename T1, typename T2, typename T3>
|
||||||
|
bool propagate_error (T1 &o1, T2 &o2, T3 &o3)
|
||||||
|
{ return propagate_error (o1) && propagate_error (o2, o3); }
|
||||||
|
template <typename T1, typename T2, typename T3>
|
||||||
|
bool propagate_error (T1 *o1, T2 *o2, T3 *o3)
|
||||||
|
{ return propagate_error (o1) && propagate_error (o2, o3); }
|
||||||
|
|
||||||
/* To be called around main operation. */
|
/* To be called around main operation. */
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
@ -534,7 +551,7 @@ struct hb_serialize_context_t
|
||||||
"end [%p..%p] serialized %d bytes; %s",
|
"end [%p..%p] serialized %d bytes; %s",
|
||||||
this->start, this->end,
|
this->start, this->end,
|
||||||
(int) (this->head - this->start),
|
(int) (this->head - this->start),
|
||||||
this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
|
this->successful ? "successful" : "UNSUCCESSFUL");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int length () const { return this->head - this->start; }
|
unsigned int length () const { return this->head - this->start; }
|
||||||
|
@ -556,8 +573,8 @@ struct hb_serialize_context_t
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type *allocate_size (unsigned int size)
|
Type *allocate_size (unsigned int size)
|
||||||
{
|
{
|
||||||
if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
|
if (unlikely (!this->successful || this->end - this->head < ptrdiff_t (size))) {
|
||||||
this->ran_out_of_room = true;
|
this->successful = false;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
memset (this->head, 0, size);
|
memset (this->head, 0, size);
|
||||||
|
@ -602,7 +619,7 @@ struct hb_serialize_context_t
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type *copy () const
|
Type *copy () const
|
||||||
{
|
{
|
||||||
assert (!this->ran_out_of_room);
|
assert (this->successful);
|
||||||
unsigned int len = this->head - this->start;
|
unsigned int len = this->head - this->start;
|
||||||
void *p = malloc (len);
|
void *p = malloc (len);
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -611,7 +628,7 @@ struct hb_serialize_context_t
|
||||||
}
|
}
|
||||||
hb_bytes_t copy_bytes () const
|
hb_bytes_t copy_bytes () const
|
||||||
{
|
{
|
||||||
assert (!this->ran_out_of_room);
|
assert (this->successful);
|
||||||
unsigned int len = this->head - this->start;
|
unsigned int len = this->head - this->start;
|
||||||
void *p = malloc (len);
|
void *p = malloc (len);
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -622,7 +639,7 @@ struct hb_serialize_context_t
|
||||||
}
|
}
|
||||||
hb_blob_t *copy_blob () const
|
hb_blob_t *copy_blob () const
|
||||||
{
|
{
|
||||||
assert (!this->ran_out_of_room);
|
assert (this->successful);
|
||||||
return hb_blob_create (this->start,
|
return hb_blob_create (this->start,
|
||||||
this->head - this->start,
|
this->head - this->start,
|
||||||
HB_MEMORY_MODE_DUPLICATE,
|
HB_MEMORY_MODE_DUPLICATE,
|
||||||
|
@ -632,7 +649,7 @@ struct hb_serialize_context_t
|
||||||
public:
|
public:
|
||||||
unsigned int debug_depth;
|
unsigned int debug_depth;
|
||||||
char *start, *end, *head;
|
char *start, *end, *head;
|
||||||
bool ran_out_of_room;
|
bool successful;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,8 @@ struct hb_map_t
|
||||||
fini_shallow ();
|
fini_shallow ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool in_error () const { return !successful; }
|
||||||
|
|
||||||
bool resize ()
|
bool resize ()
|
||||||
{
|
{
|
||||||
if (unlikely (!successful)) return false;
|
if (unlikely (!successful)) return false;
|
||||||
|
|
|
@ -1254,7 +1254,7 @@ struct ClassDefFormat1
|
||||||
glyphs.push()->set (glyph_map[g]);
|
glyphs.push()->set (glyph_map[g]);
|
||||||
klasses.push()->set (value);
|
klasses.push()->set (value);
|
||||||
}
|
}
|
||||||
c->serializer->err (glyphs.in_error () || klasses.in_error ());
|
c->serializer->propagate_error (glyphs, klasses);
|
||||||
|
|
||||||
hb_supplier_t<GlyphID> glyphs_supplier (glyphs);
|
hb_supplier_t<GlyphID> glyphs_supplier (glyphs);
|
||||||
hb_supplier_t<HBUINT16> klasses_supplier (klasses);
|
hb_supplier_t<HBUINT16> klasses_supplier (klasses);
|
||||||
|
@ -1413,7 +1413,7 @@ struct ClassDefFormat2
|
||||||
klasses.push ()->set (value);
|
klasses.push ()->set (value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->serializer->err (glyphs.in_error () || klasses.in_error ());
|
c->serializer->propagate_error (glyphs, klasses);
|
||||||
|
|
||||||
hb_supplier_t<GlyphID> glyphs_supplier (glyphs);
|
hb_supplier_t<GlyphID> glyphs_supplier (glyphs);
|
||||||
hb_supplier_t<HBUINT16> klasses_supplier (klasses);
|
hb_supplier_t<HBUINT16> klasses_supplier (klasses);
|
||||||
|
|
|
@ -120,7 +120,7 @@ struct SingleSubstFormat1
|
||||||
from.push ()->set (glyph_map[iter.get_glyph ()]);
|
from.push ()->set (glyph_map[iter.get_glyph ()]);
|
||||||
to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]);
|
to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]);
|
||||||
}
|
}
|
||||||
c->serializer->err (from.in_error () || to.in_error ());
|
c->serializer->propagate_error (from, to);
|
||||||
|
|
||||||
hb_supplier_t<GlyphID> from_supplier (from);
|
hb_supplier_t<GlyphID> from_supplier (from);
|
||||||
hb_supplier_t<GlyphID> to_supplier (to);
|
hb_supplier_t<GlyphID> to_supplier (to);
|
||||||
|
@ -225,7 +225,7 @@ struct SingleSubstFormat2
|
||||||
from.push ()->set (glyph_map[iter.get_glyph ()]);
|
from.push ()->set (glyph_map[iter.get_glyph ()]);
|
||||||
to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]);
|
to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]);
|
||||||
}
|
}
|
||||||
c->serializer->err (from.in_error () || to.in_error ());
|
c->serializer->propagate_error (from, to);
|
||||||
|
|
||||||
hb_supplier_t<GlyphID> from_supplier (from);
|
hb_supplier_t<GlyphID> from_supplier (from);
|
||||||
hb_supplier_t<GlyphID> to_supplier (to);
|
hb_supplier_t<GlyphID> to_supplier (to);
|
||||||
|
|
|
@ -213,6 +213,8 @@ struct hb_set_t
|
||||||
fini_shallow ();
|
fini_shallow ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool in_error () const { return !successful; }
|
||||||
|
|
||||||
bool resize (unsigned int count)
|
bool resize (unsigned int count)
|
||||||
{
|
{
|
||||||
if (unlikely (!successful)) return false;
|
if (unlikely (!successful)) return false;
|
||||||
|
|
|
@ -83,7 +83,7 @@ _subset2 (hb_subset_plan_t *plan)
|
||||||
hb_serialize_context_t serializer ((void *) buf, buf_size);
|
hb_serialize_context_t serializer ((void *) buf, buf_size);
|
||||||
hb_subset_context_t c (plan, &serializer);
|
hb_subset_context_t c (plan, &serializer);
|
||||||
result = table->subset (&c);
|
result = table->subset (&c);
|
||||||
if (serializer.ran_out_of_room)
|
if (serializer.in_error ())
|
||||||
{
|
{
|
||||||
buf_size += (buf_size >> 1) + 32;
|
buf_size += (buf_size >> 1) + 32;
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
|
||||||
|
|
Loading…
Reference in New Issue