| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
| 3 * Copyright © 2012 Google, Inc. | 3 * Copyright © 2012 Google, Inc. |
| 4 * | 4 * |
| 5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
| 6 * | 6 * |
| 7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
| 8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
| 9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
| 10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 template <> \ | 147 template <> \ |
| 148 /*static*/ inline const Type& Null<Type> (void) { \ | 148 /*static*/ inline const Type& Null<Type> (void) { \ |
| 149 return *CastP<Type> (_Null##Type); \ | 149 return *CastP<Type> (_Null##Type); \ |
| 150 } /* The following line really exists such that we end in a place needing semico
lon */ \ | 150 } /* The following line really exists such that we end in a place needing semico
lon */ \ |
| 151 ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) | 151 ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) |
| 152 | 152 |
| 153 /* Accessor macro. */ | 153 /* Accessor macro. */ |
| 154 #define Null(Type) Null<Type>() | 154 #define Null(Type) Null<Type>() |
| 155 | 155 |
| 156 | 156 |
| 157 /* |
| 158 * Dispatch |
| 159 */ |
| 160 |
| 161 template <typename Context, typename Return, unsigned int MaxDebugDepth> |
| 162 struct hb_dispatch_context_t |
| 163 { |
| 164 static const unsigned int max_debug_depth = MaxDebugDepth; |
| 165 typedef Return return_t; |
| 166 template <typename T, typename F> |
| 167 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
| 168 static return_t no_dispatch_return_value (void) { return Context::default_retu
rn_value (); } |
| 169 }; |
| 170 |
| 157 | 171 |
| 158 /* | 172 /* |
| 159 * Sanitize | 173 * Sanitize |
| 160 */ | 174 */ |
| 161 | 175 |
| 162 #ifndef HB_DEBUG_SANITIZE | 176 #ifndef HB_DEBUG_SANITIZE |
| 163 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) | 177 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) |
| 164 #endif | 178 #endif |
| 165 | 179 |
| 166 | 180 |
| 167 #define TRACE_SANITIZE(this) \ | 181 #define TRACE_SANITIZE(this) \ |
| 168 hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \ | 182 hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \ |
| 169 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | 183 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
| 170 ""); | 184 ""); |
| 171 | 185 |
| 172 /* This limits sanitizing time on really broken fonts. */ | 186 /* This limits sanitizing time on really broken fonts. */ |
| 173 #ifndef HB_SANITIZE_MAX_EDITS | 187 #ifndef HB_SANITIZE_MAX_EDITS |
| 174 #define HB_SANITIZE_MAX_EDITS 100 | 188 #define HB_SANITIZE_MAX_EDITS 100 |
| 175 #endif | 189 #endif |
| 176 | 190 |
| 177 struct hb_sanitize_context_t | 191 struct hb_sanitize_context_t : |
| 192 hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> |
| 178 { | 193 { |
| 194 inline hb_sanitize_context_t (void) : |
| 195 debug_depth (0), |
| 196 start (NULL), end (NULL), |
| 197 writable (false), edit_count (0), |
| 198 blob (NULL) {} |
| 199 |
| 179 inline const char *get_name (void) { return "SANITIZE"; } | 200 inline const char *get_name (void) { return "SANITIZE"; } |
| 180 static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; | |
| 181 typedef bool return_t; | |
| 182 template <typename T, typename F> | 201 template <typename T, typename F> |
| 183 inline bool may_dispatch (const T *obj, const F *format) | 202 inline bool may_dispatch (const T *obj, const F *format) |
| 184 { return format->sanitize (this); } | 203 { return format->sanitize (this); } |
| 185 template <typename T> | 204 template <typename T> |
| 186 inline return_t dispatch (const T &obj) { return obj.sanitize (this); } | 205 inline return_t dispatch (const T &obj) { return obj.sanitize (this); } |
| 187 static return_t default_return_value (void) { return true; } | 206 static return_t default_return_value (void) { return true; } |
| 207 static return_t no_dispatch_return_value (void) { return false; } |
| 188 bool stop_sublookup_iteration (const return_t r) const { return !r; } | 208 bool stop_sublookup_iteration (const return_t r) const { return !r; } |
| 189 | 209 |
| 190 inline void init (hb_blob_t *b) | 210 inline void init (hb_blob_t *b) |
| 191 { | 211 { |
| 192 this->blob = hb_blob_reference (b); | 212 this->blob = hb_blob_reference (b); |
| 193 this->writable = false; | 213 this->writable = false; |
| 194 } | 214 } |
| 195 | 215 |
| 196 inline void start_processing (void) | 216 inline void start_processing (void) |
| 197 { | 217 { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 hb_blob_t *blob; | 308 hb_blob_t *blob; |
| 289 }; | 309 }; |
| 290 | 310 |
| 291 | 311 |
| 292 | 312 |
| 293 /* Template to sanitize an object. */ | 313 /* Template to sanitize an object. */ |
| 294 template <typename Type> | 314 template <typename Type> |
| 295 struct Sanitizer | 315 struct Sanitizer |
| 296 { | 316 { |
| 297 static hb_blob_t *sanitize (hb_blob_t *blob) { | 317 static hb_blob_t *sanitize (hb_blob_t *blob) { |
| 298 hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}}; | 318 hb_sanitize_context_t c[1]; |
| 299 bool sane; | 319 bool sane; |
| 300 | 320 |
| 301 /* TODO is_sane() stuff */ | 321 /* TODO is_sane() stuff */ |
| 302 | 322 |
| 303 c->init (blob); | 323 c->init (blob); |
| 304 | 324 |
| 305 retry: | 325 retry: |
| 306 DEBUG_MSG_FUNC (SANITIZE, c->start, "start"); | 326 DEBUG_MSG_FUNC (SANITIZE, c->start, "start"); |
| 307 | 327 |
| 308 c->start_processing (); | 328 c->start_processing (); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ | 549 * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ |
| 530 | 550 |
| 531 /* | 551 /* |
| 532 * Int types | 552 * Int types |
| 533 */ | 553 */ |
| 534 | 554 |
| 535 | 555 |
| 536 template <typename Type, int Bytes> struct BEInt; | 556 template <typename Type, int Bytes> struct BEInt; |
| 537 | 557 |
| 538 template <typename Type> | 558 template <typename Type> |
| 559 struct BEInt<Type, 1> |
| 560 { |
| 561 public: |
| 562 inline void set (Type V) |
| 563 { |
| 564 v = V; |
| 565 } |
| 566 inline operator Type (void) const |
| 567 { |
| 568 return v; |
| 569 } |
| 570 private: uint8_t v; |
| 571 }; |
| 572 template <typename Type> |
| 539 struct BEInt<Type, 2> | 573 struct BEInt<Type, 2> |
| 540 { | 574 { |
| 541 public: | 575 public: |
| 542 inline void set (Type V) | 576 inline void set (Type V) |
| 543 { | 577 { |
| 544 v[0] = (V >> 8) & 0xFF; | 578 v[0] = (V >> 8) & 0xFF; |
| 545 v[1] = (V ) & 0xFF; | 579 v[1] = (V ) & 0xFF; |
| 546 } | 580 } |
| 547 inline operator Type (void) const | 581 inline operator Type (void) const |
| 548 { | 582 { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 { | 637 { |
| 604 Type b = v; | 638 Type b = v; |
| 605 if (sizeof (Type) < sizeof (int)) | 639 if (sizeof (Type) < sizeof (int)) |
| 606 return (int) a - (int) b; | 640 return (int) a - (int) b; |
| 607 else | 641 else |
| 608 return a < b ? -1 : a == b ? 0 : +1; | 642 return a < b ? -1 : a == b ? 0 : +1; |
| 609 } | 643 } |
| 610 inline bool sanitize (hb_sanitize_context_t *c) const | 644 inline bool sanitize (hb_sanitize_context_t *c) const |
| 611 { | 645 { |
| 612 TRACE_SANITIZE (this); | 646 TRACE_SANITIZE (this); |
| 613 return TRACE_RETURN (likely (c->check_struct (this))); | 647 return_trace (likely (c->check_struct (this))); |
| 614 } | 648 } |
| 615 protected: | 649 protected: |
| 616 BEInt<Type, Size> v; | 650 BEInt<Type, Size> v; |
| 617 public: | 651 public: |
| 618 DEFINE_SIZE_STATIC (Size); | 652 DEFINE_SIZE_STATIC (Size); |
| 619 }; | 653 }; |
| 620 | 654 |
| 621 typedef»» uint8_t» BYTE;» /* 8-bit unsigned integer. */ | 655 typedef»IntType<uint8_t», 1> BYTE;» /* 8-bit unsigned integer. */ |
| 622 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ | 656 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ |
| 623 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ | 657 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ |
| 624 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ | 658 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ |
| 625 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ | 659 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ |
| 626 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ | 660 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ |
| 627 | 661 |
| 628 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ | 662 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ |
| 629 typedef SHORT FWORD; | 663 typedef SHORT FWORD; |
| 630 | 664 |
| 631 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ | 665 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ |
| 632 typedef USHORT UFWORD; | 666 typedef USHORT UFWORD; |
| 633 | 667 |
| 634 /* Date represented in number of seconds since 12:00 midnight, January 1, | 668 /* Date represented in number of seconds since 12:00 midnight, January 1, |
| 635 * 1904. The value is represented as a signed 64-bit integer. */ | 669 * 1904. The value is represented as a signed 64-bit integer. */ |
| 636 struct LONGDATETIME | 670 struct LONGDATETIME |
| 637 { | 671 { |
| 638 inline bool sanitize (hb_sanitize_context_t *c) const | 672 inline bool sanitize (hb_sanitize_context_t *c) const |
| 639 { | 673 { |
| 640 TRACE_SANITIZE (this); | 674 TRACE_SANITIZE (this); |
| 641 return TRACE_RETURN (likely (c->check_struct (this))); | 675 return_trace (likely (c->check_struct (this))); |
| 642 } | 676 } |
| 643 protected: | 677 protected: |
| 644 LONG major; | 678 LONG major; |
| 645 ULONG minor; | 679 ULONG minor; |
| 646 public: | 680 public: |
| 647 DEFINE_SIZE_STATIC (8); | 681 DEFINE_SIZE_STATIC (8); |
| 648 }; | 682 }; |
| 649 | 683 |
| 650 /* Array of four uint8s (length = 32 bits) used to identify a script, language | 684 /* Array of four uint8s (length = 32 bits) used to identify a script, language |
| 651 * system, feature, or baseline */ | 685 * system, feature, or baseline */ |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 * Version Numbers | 742 * Version Numbers |
| 709 */ | 743 */ |
| 710 | 744 |
| 711 struct FixedVersion | 745 struct FixedVersion |
| 712 { | 746 { |
| 713 inline uint32_t to_int (void) const { return (major << 16) + minor; } | 747 inline uint32_t to_int (void) const { return (major << 16) + minor; } |
| 714 | 748 |
| 715 inline bool sanitize (hb_sanitize_context_t *c) const | 749 inline bool sanitize (hb_sanitize_context_t *c) const |
| 716 { | 750 { |
| 717 TRACE_SANITIZE (this); | 751 TRACE_SANITIZE (this); |
| 718 return TRACE_RETURN (c->check_struct (this)); | 752 return_trace (c->check_struct (this)); |
| 719 } | 753 } |
| 720 | 754 |
| 721 USHORT major; | 755 USHORT major; |
| 722 USHORT minor; | 756 USHORT minor; |
| 723 public: | 757 public: |
| 724 DEFINE_SIZE_STATIC (4); | 758 DEFINE_SIZE_STATIC (4); |
| 725 }; | 759 }; |
| 726 | 760 |
| 727 | 761 |
| 728 | 762 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 744 inline Type& serialize (hb_serialize_context_t *c, const void *base) | 778 inline Type& serialize (hb_serialize_context_t *c, const void *base) |
| 745 { | 779 { |
| 746 Type *t = c->start_embed<Type> (); | 780 Type *t = c->start_embed<Type> (); |
| 747 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ | 781 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ |
| 748 return *t; | 782 return *t; |
| 749 } | 783 } |
| 750 | 784 |
| 751 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const | 785 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 752 { | 786 { |
| 753 TRACE_SANITIZE (this); | 787 TRACE_SANITIZE (this); |
| 754 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 788 if (unlikely (!c->check_struct (this))) return_trace (false); |
| 755 unsigned int offset = *this; | 789 unsigned int offset = *this; |
| 756 if (unlikely (!offset)) return TRACE_RETURN (true); | 790 if (unlikely (!offset)) return_trace (true); |
| 757 const Type &obj = StructAtOffset<Type> (base, offset); | 791 const Type &obj = StructAtOffset<Type> (base, offset); |
| 758 return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); | 792 return_trace (likely (obj.sanitize (c)) || neuter (c)); |
| 759 } | 793 } |
| 760 template <typename T> | 794 template <typename T> |
| 761 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const | 795 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const |
| 762 { | 796 { |
| 763 TRACE_SANITIZE (this); | 797 TRACE_SANITIZE (this); |
| 764 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 798 if (unlikely (!c->check_struct (this))) return_trace (false); |
| 765 unsigned int offset = *this; | 799 unsigned int offset = *this; |
| 766 if (unlikely (!offset)) return TRACE_RETURN (true); | 800 if (unlikely (!offset)) return_trace (true); |
| 767 const Type &obj = StructAtOffset<Type> (base, offset); | 801 const Type &obj = StructAtOffset<Type> (base, offset); |
| 768 return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); | 802 return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); |
| 769 } | 803 } |
| 770 | 804 |
| 771 /* Set the offset to Null */ | 805 /* Set the offset to Null */ |
| 772 inline bool neuter (hb_sanitize_context_t *c) const { | 806 inline bool neuter (hb_sanitize_context_t *c) const { |
| 773 return c->try_set (this, 0); | 807 return c->try_set (this, 0); |
| 774 } | 808 } |
| 775 DEFINE_SIZE_STATIC (sizeof(OffsetType)); | 809 DEFINE_SIZE_STATIC (sizeof(OffsetType)); |
| 776 }; | 810 }; |
| 777 template <typename Base, typename OffsetType, typename Type> | 811 template <typename Base, typename OffsetType, typename Type> |
| 778 static inline const Type& operator + (const Base &base, const OffsetTo<Type, Off
setType> &offset) { return offset (base); } | 812 static inline const Type& operator + (const Base &base, const OffsetTo<Type, Off
setType> &offset) { return offset (base); } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 809 { | 843 { |
| 810 return array[i]; | 844 return array[i]; |
| 811 } | 845 } |
| 812 inline unsigned int get_size (void) const | 846 inline unsigned int get_size (void) const |
| 813 { return len.static_size + len * Type::static_size; } | 847 { return len.static_size + len * Type::static_size; } |
| 814 | 848 |
| 815 inline bool serialize (hb_serialize_context_t *c, | 849 inline bool serialize (hb_serialize_context_t *c, |
| 816 unsigned int items_len) | 850 unsigned int items_len) |
| 817 { | 851 { |
| 818 TRACE_SERIALIZE (this); | 852 TRACE_SERIALIZE (this); |
| 819 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 853 if (unlikely (!c->extend_min (*this))) return_trace (false); |
| 820 len.set (items_len); /* TODO(serialize) Overflow? */ | 854 len.set (items_len); /* TODO(serialize) Overflow? */ |
| 821 if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); | 855 if (unlikely (!c->extend (*this))) return_trace (false); |
| 822 return TRACE_RETURN (true); | 856 return_trace (true); |
| 823 } | 857 } |
| 824 | 858 |
| 825 inline bool serialize (hb_serialize_context_t *c, | 859 inline bool serialize (hb_serialize_context_t *c, |
| 826 Supplier<Type> &items, | 860 Supplier<Type> &items, |
| 827 unsigned int items_len) | 861 unsigned int items_len) |
| 828 { | 862 { |
| 829 TRACE_SERIALIZE (this); | 863 TRACE_SERIALIZE (this); |
| 830 if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); | 864 if (unlikely (!serialize (c, items_len))) return_trace (false); |
| 831 for (unsigned int i = 0; i < items_len; i++) | 865 for (unsigned int i = 0; i < items_len; i++) |
| 832 array[i] = items[i]; | 866 array[i] = items[i]; |
| 833 items.advance (items_len); | 867 items.advance (items_len); |
| 834 return TRACE_RETURN (true); | 868 return_trace (true); |
| 835 } | 869 } |
| 836 | 870 |
| 837 inline bool sanitize (hb_sanitize_context_t *c) const | 871 inline bool sanitize (hb_sanitize_context_t *c) const |
| 838 { | 872 { |
| 839 TRACE_SANITIZE (this); | 873 TRACE_SANITIZE (this); |
| 840 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 874 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
| 841 | 875 |
| 842 /* Note: for structs that do not reference other structs, | 876 /* Note: for structs that do not reference other structs, |
| 843 * we do not need to call their sanitize() as we already did | 877 * we do not need to call their sanitize() as we already did |
| 844 * a bound check on the aggregate array size. We just include | 878 * a bound check on the aggregate array size. We just include |
| 845 * a small unreachable expression to make sure the structs | 879 * a small unreachable expression to make sure the structs |
| 846 * pointed to do have a simple sanitize(), ie. they do not | 880 * pointed to do have a simple sanitize(), ie. they do not |
| 847 * reference other structs via offsets. | 881 * reference other structs via offsets. |
| 848 */ | 882 */ |
| 849 (void) (false && array[0].sanitize (c)); | 883 (void) (false && array[0].sanitize (c)); |
| 850 | 884 |
| 851 return TRACE_RETURN (true); | 885 return_trace (true); |
| 852 } | 886 } |
| 853 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const | 887 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 854 { | 888 { |
| 855 TRACE_SANITIZE (this); | 889 TRACE_SANITIZE (this); |
| 856 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 890 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
| 857 unsigned int count = len; | 891 unsigned int count = len; |
| 858 for (unsigned int i = 0; i < count; i++) | 892 for (unsigned int i = 0; i < count; i++) |
| 859 if (unlikely (!array[i].sanitize (c, base))) | 893 if (unlikely (!array[i].sanitize (c, base))) |
| 860 return TRACE_RETURN (false); | 894 return_trace (false); |
| 861 return TRACE_RETURN (true); | 895 return_trace (true); |
| 862 } | 896 } |
| 863 template <typename T> | 897 template <typename T> |
| 864 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const | 898 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const |
| 865 { | 899 { |
| 866 TRACE_SANITIZE (this); | 900 TRACE_SANITIZE (this); |
| 867 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 901 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
| 868 unsigned int count = len; | 902 unsigned int count = len; |
| 869 for (unsigned int i = 0; i < count; i++) | 903 for (unsigned int i = 0; i < count; i++) |
| 870 if (unlikely (!array[i].sanitize (c, base, user_data))) | 904 if (unlikely (!array[i].sanitize (c, base, user_data))) |
| 871 return TRACE_RETURN (false); | 905 return_trace (false); |
| 872 return TRACE_RETURN (true); | 906 return_trace (true); |
| 873 } | 907 } |
| 874 | 908 |
| 875 template <typename SearchType> | 909 template <typename SearchType> |
| 876 inline int lsearch (const SearchType &x) const | 910 inline int lsearch (const SearchType &x) const |
| 877 { | 911 { |
| 878 unsigned int count = len; | 912 unsigned int count = len; |
| 879 for (unsigned int i = 0; i < count; i++) | 913 for (unsigned int i = 0; i < count; i++) |
| 880 if (!this->array[i].cmp (x)) | 914 if (!this->array[i].cmp (x)) |
| 881 return i; | 915 return i; |
| 882 return -1; | 916 return -1; |
| 883 } | 917 } |
| 884 | 918 |
| 885 private: | 919 private: |
| 886 inline bool sanitize_shallow (hb_sanitize_context_t *c) const | 920 inline bool sanitize_shallow (hb_sanitize_context_t *c) const |
| 887 { | 921 { |
| 888 TRACE_SANITIZE (this); | 922 TRACE_SANITIZE (this); |
| 889 return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::s
tatic_size, len)); | 923 return_trace (c->check_struct (this) && c->check_array (array, Type::static_
size, len)); |
| 890 } | 924 } |
| 891 | 925 |
| 892 public: | 926 public: |
| 893 LenType len; | 927 LenType len; |
| 894 Type array[VAR]; | 928 Type array[VAR]; |
| 895 public: | 929 public: |
| 896 DEFINE_SIZE_ARRAY (sizeof (LenType), array); | 930 DEFINE_SIZE_ARRAY (sizeof (LenType), array); |
| 897 }; | 931 }; |
| 898 | 932 |
| 899 /* Array of Offset's */ | 933 /* Array of Offset's */ |
| 900 template <typename Type> | 934 template <typename Type> |
| 901 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; | 935 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; |
| 902 | 936 |
| 903 /* Array of offsets relative to the beginning of the array itself. */ | 937 /* Array of offsets relative to the beginning of the array itself. */ |
| 904 template <typename Type> | 938 template <typename Type> |
| 905 struct OffsetListOf : OffsetArrayOf<Type> | 939 struct OffsetListOf : OffsetArrayOf<Type> |
| 906 { | 940 { |
| 907 inline const Type& operator [] (unsigned int i) const | 941 inline const Type& operator [] (unsigned int i) const |
| 908 { | 942 { |
| 909 if (unlikely (i >= this->len)) return Null(Type); | 943 if (unlikely (i >= this->len)) return Null(Type); |
| 910 return this+this->array[i]; | 944 return this+this->array[i]; |
| 911 } | 945 } |
| 912 | 946 |
| 913 inline bool sanitize (hb_sanitize_context_t *c) const | 947 inline bool sanitize (hb_sanitize_context_t *c) const |
| 914 { | 948 { |
| 915 TRACE_SANITIZE (this); | 949 TRACE_SANITIZE (this); |
| 916 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); | 950 return_trace (OffsetArrayOf<Type>::sanitize (c, this)); |
| 917 } | 951 } |
| 918 template <typename T> | 952 template <typename T> |
| 919 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const | 953 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const |
| 920 { | 954 { |
| 921 TRACE_SANITIZE (this); | 955 TRACE_SANITIZE (this); |
| 922 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); | 956 return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data)); |
| 923 } | 957 } |
| 924 }; | 958 }; |
| 925 | 959 |
| 926 | 960 |
| 927 /* An array starting at second element. */ | 961 /* An array starting at second element. */ |
| 928 template <typename Type, typename LenType=USHORT> | 962 template <typename Type, typename LenType=USHORT> |
| 929 struct HeadlessArrayOf | 963 struct HeadlessArrayOf |
| 930 { | 964 { |
| 931 inline const Type& operator [] (unsigned int i) const | 965 inline const Type& operator [] (unsigned int i) const |
| 932 { | 966 { |
| 933 if (unlikely (i >= len || !i)) return Null(Type); | 967 if (unlikely (i >= len || !i)) return Null(Type); |
| 934 return array[i-1]; | 968 return array[i-1]; |
| 935 } | 969 } |
| 936 inline unsigned int get_size (void) const | 970 inline unsigned int get_size (void) const |
| 937 { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } | 971 { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } |
| 938 | 972 |
| 939 inline bool serialize (hb_serialize_context_t *c, | 973 inline bool serialize (hb_serialize_context_t *c, |
| 940 Supplier<Type> &items, | 974 Supplier<Type> &items, |
| 941 unsigned int items_len) | 975 unsigned int items_len) |
| 942 { | 976 { |
| 943 TRACE_SERIALIZE (this); | 977 TRACE_SERIALIZE (this); |
| 944 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 978 if (unlikely (!c->extend_min (*this))) return_trace (false); |
| 945 len.set (items_len); /* TODO(serialize) Overflow? */ | 979 len.set (items_len); /* TODO(serialize) Overflow? */ |
| 946 if (unlikely (!items_len)) return TRACE_RETURN (true); | 980 if (unlikely (!items_len)) return_trace (true); |
| 947 if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); | 981 if (unlikely (!c->extend (*this))) return_trace (false); |
| 948 for (unsigned int i = 0; i < items_len - 1; i++) | 982 for (unsigned int i = 0; i < items_len - 1; i++) |
| 949 array[i] = items[i]; | 983 array[i] = items[i]; |
| 950 items.advance (items_len - 1); | 984 items.advance (items_len - 1); |
| 951 return TRACE_RETURN (true); | 985 return_trace (true); |
| 952 } | 986 } |
| 953 | 987 |
| 954 inline bool sanitize_shallow (hb_sanitize_context_t *c) const | 988 inline bool sanitize_shallow (hb_sanitize_context_t *c) const |
| 955 { | 989 { |
| 956 return c->check_struct (this) | 990 return c->check_struct (this) |
| 957 && c->check_array (this, Type::static_size, len); | 991 && c->check_array (this, Type::static_size, len); |
| 958 } | 992 } |
| 959 | 993 |
| 960 inline bool sanitize (hb_sanitize_context_t *c) const | 994 inline bool sanitize (hb_sanitize_context_t *c) const |
| 961 { | 995 { |
| 962 TRACE_SANITIZE (this); | 996 TRACE_SANITIZE (this); |
| 963 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 997 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
| 964 | 998 |
| 965 /* Note: for structs that do not reference other structs, | 999 /* Note: for structs that do not reference other structs, |
| 966 * we do not need to call their sanitize() as we already did | 1000 * we do not need to call their sanitize() as we already did |
| 967 * a bound check on the aggregate array size. We just include | 1001 * a bound check on the aggregate array size. We just include |
| 968 * a small unreachable expression to make sure the structs | 1002 * a small unreachable expression to make sure the structs |
| 969 * pointed to do have a simple sanitize(), ie. they do not | 1003 * pointed to do have a simple sanitize(), ie. they do not |
| 970 * reference other structs via offsets. | 1004 * reference other structs via offsets. |
| 971 */ | 1005 */ |
| 972 (void) (false && array[0].sanitize (c)); | 1006 (void) (false && array[0].sanitize (c)); |
| 973 | 1007 |
| 974 return TRACE_RETURN (true); | 1008 return_trace (true); |
| 975 } | 1009 } |
| 976 | 1010 |
| 977 LenType len; | 1011 LenType len; |
| 978 Type array[VAR]; | 1012 Type array[VAR]; |
| 979 public: | 1013 public: |
| 980 DEFINE_SIZE_ARRAY (sizeof (LenType), array); | 1014 DEFINE_SIZE_ARRAY (sizeof (LenType), array); |
| 981 }; | 1015 }; |
| 982 | 1016 |
| 983 | 1017 |
| 984 /* An array with sorted elements. Supports binary searching. */ | 1018 /* An array with sorted elements. Supports binary searching. */ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1003 } | 1037 } |
| 1004 return -1; | 1038 return -1; |
| 1005 } | 1039 } |
| 1006 }; | 1040 }; |
| 1007 | 1041 |
| 1008 | 1042 |
| 1009 } /* namespace OT */ | 1043 } /* namespace OT */ |
| 1010 | 1044 |
| 1011 | 1045 |
| 1012 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ | 1046 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ |
| OLD | NEW |