hb-open-type-private.hh revision 0d77ab8a73f57c9fca4c6f9301dae394d79526e3
164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod/* 2ee58aaebd296ea8237516754fd4e825d524b11b7Behdad Esfahbod * Copyright (C) 2007,2008,2009 Red Hat, Inc. 364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * Permission is hereby granted, without written agreement and without 764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * software and its documentation for any purpose, provided that the 964aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 1064aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * all copies of this software. 1164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 1264aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * DAMAGE. 1764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 1864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1964aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2064aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2264aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 2464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 2564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod */ 2664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod 275f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#ifndef HB_OPEN_TYPES_PRIVATE_HH 285f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#define HB_OPEN_TYPES_PRIVATE_HH 2912c4568c680ea2b9b98a16a8b7402ca185c90ef6Behdad Esfahbod 302098a021a826e76ee27d5db74e32738d7d1c3d30Behdad Esfahbod#include "hb-private.h" 3112c4568c680ea2b9b98a16a8b7402ca185c90ef6Behdad Esfahbod 3270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod#include "hb-blob.h" 3370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 34a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 35706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod#define NO_INDEX ((unsigned int) 0xFFFF) 362e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod#define NO_CONTEXT ((unsigned int) 0x110000) 372e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod#define NOT_COVERED ((unsigned int) 0x110000) 382e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod#define MAX_NESTING_LEVEL 8 395a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 40706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod 41196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod/* 42196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod * Casts 43196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod */ 44196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod 452b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CONST_CHARP(X) (reinterpret_cast<const char *>(X)) 462b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define DECONST_CHARP(X) ((char *)reinterpret_cast<const char *>(X)) 472b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CHARP(X) (reinterpret_cast<char *>(X)) 482b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod 492b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CONST_CAST(T,X,Ofs) (*(reinterpret_cast<const T *>(CONST_CHARP(&(X)) + Ofs))) 502b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define DECONST_CAST(T,X,Ofs) (*(reinterpret_cast<T *>((char *)CONST_CHARP(&(X)) + Ofs))) 512b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod#define CAST(T,X,Ofs) (*(reinterpret_cast<T *>(CHARP(&(X)) + Ofs))) 52196598bbccff08415ff5192314cba044df258cadBehdad Esfahbod 5370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 5470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod/* 55b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * Array types 56b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod */ 57b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 58b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* get_len() is a method returning the number of items in an array-like object */ 59b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod#define DEFINE_LEN(Type, array, num) \ 60b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod inline unsigned int get_len(void) const { return num; } \ 61b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 62b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* An array type is one that contains a variable number of objects 63238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod * as its last item. An array object is extended with get_len() 64b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * methods, as well as overloaded [] operator. */ 65b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod#define DEFINE_ARRAY_TYPE(Type, array, num) \ 661f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod DEFINE_INDEX_OPERATOR(Type, array, num) \ 670dff25f0368c5f14ebb0a4af35f3bb6658740d57Behdad Esfahbod DEFINE_LEN(Type, array, num) 681f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod#define DEFINE_INDEX_OPERATOR(Type, array, num) \ 6960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator[] (unsigned int i) const \ 7060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 718b8358033184198ff638ee1379093717596e162dBehdad Esfahbod if (HB_UNLIKELY (i >= num)) return Null(Type); \ 72b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod return array[i]; \ 73b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod } 74b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 75b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* An offset array type is like an array type, but it contains a table 76b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * of offsets to the objects, relative to the beginning of the current 77b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * object. */ 78b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod#define DEFINE_OFFSET_ARRAY_TYPE(Type, array, num) \ 791f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \ 800dff25f0368c5f14ebb0a4af35f3bb6658740d57Behdad Esfahbod DEFINE_LEN(Offset, array, num) 811f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod#define DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \ 8260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator[] (unsigned int i) const \ 8360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 848b8358033184198ff638ee1379093717596e162dBehdad Esfahbod if (HB_UNLIKELY (i >= num)) return Null(Type); \ 858b8358033184198ff638ee1379093717596e162dBehdad Esfahbod if (HB_UNLIKELY (!array[i])) return Null(Type); \ 864497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod return *(const Type)((const char*)this + array[i]); \ 87b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod } 88b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 89fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 90fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#define DEFINE_ARRAY_INTERFACE(Type, name) \ 9160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& get_##name (unsigned int i) const { return (*this)[i]; } \ 9260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_##name##_count (void) const { return this->get_len (); } 93fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#define DEFINE_INDEX_ARRAY_INTERFACE(name) \ 9460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_##name##_index (unsigned int i) const \ 9560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 964a26ea408c87f0bb59deca9ff44008d138471aa3Behdad Esfahbod if (HB_UNLIKELY (i >= get_len ())) return NO_INDEX; \ 97fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod return (*this)[i]; \ 98fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod } \ 9960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_##name##_count (void) const { return get_len (); } 100fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 101fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod 1021f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod/* 1031f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod * List types 1041f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod */ 105b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 10640a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod#define DEFINE_LIST_INTERFACE(Type, name) \ 10760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& get_##name (unsigned int i) const { return (this+name##List)[i]; } \ 10860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_##name##_count (void) const { return (this+name##List).len; } 10940a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod 110577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 11140a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod/* 11240a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod * Tag types 11340a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod */ 11440a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod 11540a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod#define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \ 11640a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod DEFINE_ARRAY_INTERFACE (Type, name); \ 11760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Tag& get_##name##_tag (unsigned int i) const { return (*this)[i].tag; } 11840a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod#define DEFINE_TAG_LIST_INTERFACE(Type, name) \ 11940a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod DEFINE_LIST_INTERFACE (Type, name); \ 12060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Tag& get_##name##_tag (unsigned int i) const { return (this+name##List).get_tag (i); } 12140a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod 12240a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod#define DEFINE_TAG_FIND_INTERFACE(Type, name) \ 123cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod inline bool find_##name##_index (hb_tag_t tag, unsigned int *index) const { \ 124706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod const Tag t = tag; \ 12560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod for (unsigned int i = 0; i < get_##name##_count (); i++) \ 12660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 12760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod if (t == get_##name##_tag (i)) \ 12860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 129cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod if (index) *index = i; \ 130706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return true; \ 131706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod } \ 132706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod } \ 133cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod if (index) *index = NO_INDEX; \ 134706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return false; \ 13540a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod } \ 13660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& get_##name##_by_tag (hb_tag_t tag) const \ 13760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 138706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod unsigned int i; \ 139706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod if (find_##name##_index (tag, &i)) \ 140706ab25a4cb043d46e6088aa0a7184ee200276c9Behdad Esfahbod return get_##name (i); \ 14140a81314fa3eb7c701aea47b43f81bfad985f717Behdad Esfahbod else \ 1428b8358033184198ff638ee1379093717596e162dBehdad Esfahbod return Null(Type); \ 1431f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod } 144600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 145577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 146577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 147600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod/* 148600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod * Class features 149600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod */ 150600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 1518b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1528b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Null objects */ 1538b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1548b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Global nul-content Null pool. Enlarge as necessary. */ 1558b8358033184198ff638ee1379093717596e162dBehdad Esfahbodstatic const char NullPool[16] = ""; 1568b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1578b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Generic template for nul-content sizeof-sized Null objects. */ 1588b8358033184198ff638ee1379093717596e162dBehdad Esfahbodtemplate <typename Type> 15960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Null 16060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 161f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod ASSERT_STATIC (sizeof (Type) <= sizeof (NullPool)); 1624497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod static inline const Type &get () { return *(const Type*)NullPool; } 1638b8358033184198ff638ee1379093717596e162dBehdad Esfahbod}; 1648b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1658b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ 1668b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define DEFINE_NULL_DATA(Type, size, data) \ 167cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbodstatic const char _Null##Type[size] = data; \ 1688b8358033184198ff638ee1379093717596e162dBehdad Esfahbodtemplate <> \ 16960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Null <Type> \ 17060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ \ 1714497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod static inline const Type &get () { return *(const Type*)_Null##Type; } \ 1728b8358033184198ff638ee1379093717596e162dBehdad Esfahbod} 1738b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1748b8358033184198ff638ee1379093717596e162dBehdad Esfahbod/* Accessor macro. */ 1758b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define Null(Type) (Null<Type>::get()) 1768b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1778b8358033184198ff638ee1379093717596e162dBehdad Esfahbod 1788b8358033184198ff638ee1379093717596e162dBehdad Esfahbod#define ASSERT_SIZE_DATA(Type, size, data) \ 1791f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod ASSERT_SIZE (Type, size); \ 1801f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod DEFINE_NULL_DATA (Type, size, data) 1811f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod 182600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod/* get_for_data() is a static class method returning a reference to an 183600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod * instance of Type located at the input data location. It's just a 18454e5aac5e2947d4e2864c6f2987e4d275da73100Behdad Esfahbod * fancy, NULL-safe, cast! */ 185fd92a3dde32fd10df30c9eeb97641bc3c15b1e9bBehdad Esfahbod#define STATIC_DEFINE_GET_FOR_DATA(Type) \ 18660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod static inline const Type& get_for_data (const char *data) \ 18760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 1888b8358033184198ff638ee1379093717596e162dBehdad Esfahbod if (HB_UNLIKELY (data == NULL)) return Null(Type); \ 1894497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod return *(const Type*)data; \ 190212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod } 191212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod/* Like get_for_data(), but checks major version first. */ 192cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod#define STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION(Type, MajorMin, MajorMax) \ 193212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod static inline const Type& get_for_data (const char *data) \ 194212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod { \ 195212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod if (HB_UNLIKELY (data == NULL)) return Null(Type); \ 1964497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod const Type& t = *(const Type*)data; \ 197cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod if (HB_UNLIKELY (t.version.major < MajorMin || t.version.major > MajorMax)) return Null(Type); \ 198212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod return t; \ 199212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod } 200600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 201600e5eb80f553ea8eb862e6784133574c74ca513Behdad Esfahbod 202577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod/* 203577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod * Sanitize 204577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod */ 205577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 2067acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod#if HB_DEBUG >= 5 207b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_DEF , unsigned int sanitize_depth 208b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG , sanitize_depth + 1 209b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_INIT , 0 210b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG() \ 211b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod HB_STMT_START { \ 2127acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "SANITIZE(%p) %-*d-> %s\n", \ 2137acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod (CONST_CHARP (this) == NullPool) ? 0 : this, \ 2147acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod sanitize_depth+1, sanitize_depth, \ 2157acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod __PRETTY_FUNCTION__); \ 216b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod } HB_STMT_END 217b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#else 218b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_DEF 219b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG 220b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG_ARG_INIT 221b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_DEBUG() HB_STMT_START {} HB_STMT_END 222b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#endif 223b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod 224577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodtypedef struct _hb_sanitize_context_t hb_sanitize_context_t; 225577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstruct _hb_sanitize_context_t 226577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 227577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod const char *start, *end; 228577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod int edit_count; 229577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod hb_blob_t *blob; 230577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod}; 231577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 232577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstatic HB_GNUC_UNUSED void 2334e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod_hb_sanitize_init (hb_sanitize_context_t *context, 2344e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_blob_t *blob) 235577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 236577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->blob = blob; 237577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->start = hb_blob_lock (blob); 238577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->end = context->start + hb_blob_get_length (blob); 239577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod context->edit_count = 0; 2404f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 2414f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 2427acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p init [%p..%p] (%u bytes)\n", 2437acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod context->blob, context->start, context->end, context->start - context->end); 2444f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 245577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 246577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 247577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbodstatic HB_GNUC_UNUSED void 2484e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod_hb_sanitize_fini (hb_sanitize_context_t *context, 2494e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod bool unlock) 250577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 2514f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 2527acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n", 2537acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod context->blob, context->start, context->end, context->edit_count); 2544f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 2554f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 256577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod if (unlock) 257577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod hb_blob_unlock (context->blob); 258577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 259577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 2604f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbodstatic HB_GNUC_UNUSED inline bool 2614f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod_hb_sanitize_edit (hb_sanitize_context_t *context, 2624f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod const char *base HB_GNUC_UNUSED, 2634f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod unsigned int len HB_GNUC_UNUSED) 264577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod{ 2654f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod bool perm = hb_blob_try_writeable_inplace (context->blob); 266f4b58d3fc2956a9d1b6178588d809c781f7a5c0cBehdad Esfahbod context->edit_count++; 2674f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 2684f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 2697acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "sanitize %p edit %u requested for [%p..%p] (%d bytes) in [%p..%p] -> %s\n", 2707acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod context->blob, 2714f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod context->edit_count, 2724f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod base, base+len, len, 2734f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod context->start, context->end, 2744f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod perm ? "granted" : "rejected"); 2754f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 2764f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod return perm; 277577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod} 278577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 279577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_ARG_DEF \ 280b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod hb_sanitize_context_t *context SANITIZE_DEBUG_ARG_DEF 281577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_ARG \ 282b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod context SANITIZE_DEBUG_ARG 283b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod#define SANITIZE_ARG_INIT \ 284b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod &context SANITIZE_DEBUG_ARG_INIT 285577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 286577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG)) 287577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE2(X,Y) (SANITIZE (X) && SANITIZE (Y)) 288577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 289577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS(X) HB_LIKELY ((X).sanitize (SANITIZE_ARG, CONST_CHARP(this))) 290577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS2(X,Y) (SANITIZE_THIS (X) && SANITIZE_THIS (Y)) 291577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_THIS3(X,Y,Z) (SANITIZE_THIS (X) && SANITIZE_THIS (Y) && SANITIZE_THIS(Z)) 292577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 293577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_BASE(X,B) HB_LIKELY ((X).sanitize (SANITIZE_ARG, B)) 294577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_BASE2(X,Y,B) (SANITIZE_BASE (X,B) && SANITIZE_BASE (Y,B)) 295577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 296577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_SELF() SANITIZE_OBJ (*this) 297577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_OBJ(X) SANITIZE_MEM(&(X), sizeof (X)) 298577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_GET_SIZE() SANITIZE_SELF() && SANITIZE_MEM (this, this->get_size ()) 299577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 300577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod#define SANITIZE_MEM(B,L) HB_LIKELY (context->start <= CONST_CHARP(B) && CONST_CHARP(B) + (L) <= context->end) /* XXX overflow */ 301577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 3024f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#define NEUTER(Var, Val) (SANITIZE_OBJ (Var) && _hb_sanitize_edit (context, CONST_CHARP(&(Var)), sizeof (Var)) && ((Var) = (Val), true)) 303577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 304577c1116493d785d3455626612f97dabb383abf0Behdad Esfahbod 3054e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod/* Template to sanitize an object. */ 3064e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbodtemplate <typename Type> 3074e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbodstruct Sanitizer 3084e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod{ 3094e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod static hb_blob_t *sanitize (hb_blob_t *blob) { 3104e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_sanitize_context_t context; 3114e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod bool sane; 3124e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 3134e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod /* XXX is_sane() stuff */ 3144e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 3154e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod retry: 3164f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 3177acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p start %s\n", blob, __PRETTY_FUNCTION__); 3184f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 3194f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod 3204e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod _hb_sanitize_init (&context, blob); 3214e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 3228cd6fa28d1b77100491519b8dedb2e113508bf59Behdad Esfahbod Type *t = &CAST (Type, *DECONST_CHARP(context.start), 0); 3234e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 324b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod sane = t->sanitize (SANITIZE_ARG_INIT); 3254e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (sane) { 3264e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (context.edit_count) { 3270d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#if HB_DEBUG 3280d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod fprintf (stderr, "Sanitizer %p passed first round with %d edits; going a second round %s\n", 3290d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod blob, context.edit_count, __PRETTY_FUNCTION__); 3300d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#endif 3314e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod /* sanitize again to ensure not toe-stepping */ 3324e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod context.edit_count = 0; 333b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod sane = t->sanitize (SANITIZE_ARG_INIT); 3344e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (context.edit_count) { 3350d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#if HB_DEBUG 3360d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod fprintf (stderr, "Sanitizer %p requested %d edits in second round; failing %s\n", 3370d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod blob, context.edit_count, __PRETTY_FUNCTION__); 3380d77ab8a73f57c9fca4c6f9301dae394d79526e3Behdad Esfahbod#endif 3394e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod sane = false; 3404e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3414e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3424e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod _hb_sanitize_fini (&context, true); 3434e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } else { 3444f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod unsigned int edit_count = context.edit_count; 3454e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod _hb_sanitize_fini (&context, true); 3464f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod if (edit_count && !hb_blob_is_writeable (blob) && hb_blob_try_writeable (blob)) { 3474e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod /* ok, we made it writeable by relocating. try again */ 3484f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 3497acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p retry %s\n", blob, __PRETTY_FUNCTION__); 3504f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 3514e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod goto retry; 3524e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3534e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3544e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 3554f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#if HB_DEBUG 3567acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod fprintf (stderr, "Sanitizer %p %s %s\n", blob, sane ? "passed" : "failed", __PRETTY_FUNCTION__); 3574f3ad9115a4161fc23fa559c26082440196217ecBehdad Esfahbod#endif 3584e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod if (sane) 3594e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return blob; 3604e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod else { 3614e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod hb_blob_destroy (blob); 3624e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return hb_blob_create_empty (); 3634e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3644e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3654e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 366d60bb8ca2ae6edf29b2227b56c57f0d16879370bBehdad Esfahbod static const Type& lock_instance (hb_blob_t *blob) { 3674e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod return Type::get_for_data (hb_blob_lock (blob)); 3684e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod } 3694e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod}; 3704e8a0602bb0b3cbf7f26cc38790e37cdec7b0b37Behdad Esfahbod 3712d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 372b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* 373b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * 374b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * The OpenType Font File 375b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * 376b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod */ 377b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 378b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 379b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* 380b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * Data Types 381b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod */ 382b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 383b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 384b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod/* "The following data types are used in the OpenType font file. 385b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ 386b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 3875f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod/* 3885f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod * Int types 3895f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod */ 3905f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 39120cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod/* TODO On machines that do not allow unaligned access, fix the accessors. */ 39220cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN, BYTES) \ 39360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod struct NAME \ 39460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { \ 39520cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod inline NAME& operator = (TYPE i) { (TYPE&) v = BIG_ENDIAN (i); return *this; } \ 39620cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod inline operator TYPE(void) const { return BIG_ENDIAN ((TYPE&) v); } \ 39720cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod inline bool operator== (NAME o) const { return (TYPE&) v == (TYPE&) o.v; } \ 398b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { \ 399b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); \ 400b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod return SANITIZE_SELF (); \ 401b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod } \ 40220cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod private: char v[BYTES]; \ 4035f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod }; \ 40420cc86b3592db33731de671f008d7d222776be49Behdad Esfahbod ASSERT_SIZE (NAME, BYTES) 405df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod#define DEFINE_INT_TYPE0(NAME, type, b) DEFINE_INT_TYPE1 (NAME, type##_t, hb_be_##type, b) 406df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod#define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w, (w / 8)) 4075f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 408b6e62bc5db76ae342177b2b646c37f45eccad975Behdad Esfahbod 40920cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (USHORT, u, 16); /* 16-bit unsigned integer. */ 41020cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (SHORT, , 16); /* 16-bit signed integer. */ 41120cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (ULONG, u, 32); /* 32-bit unsigned integer. */ 41220cc86b3592db33731de671f008d7d222776be49Behdad EsfahbodDEFINE_INT_TYPE (LONG, , 32); /* 32-bit signed integer. */ 4136b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4146b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* Array of four uint8s (length = 32 bits) used to identify a script, language 4156b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod * system, feature, or baseline */ 41620cc86b3592db33731de671f008d7d222776be49Behdad Esfahbodstruct Tag : ULONG 41760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 4184497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline Tag (const Tag &o) { *(ULONG*)this = (ULONG&) o; } 4194497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline Tag (uint32_t i) { *(ULONG*)this = i; } 4204497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline Tag (const char *c) { *(ULONG*)this = *(ULONG*)c; } 4214497af0069a94c69fc1518b1db2c1282721b732aBehdad Esfahbod inline bool operator== (const char *c) const { return *(ULONG*)this == *(ULONG*)c; } 422befc022affd2386b3f46cd7d11e4262f6c8bce9fBehdad Esfahbod /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ 4232b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod inline operator const char* (void) const { return CONST_CHARP(this); } 4242b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod inline operator char* (void) { return CHARP(this); } 425738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod 426738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 427b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 428738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod /* Note: Only accept ASCII-visible tags (mind DEL) 429738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod * This is one of the few times (only time?) we check 430738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod * for data integrity, as opposed o just boundary checks 431738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod */ 432738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod return SANITIZE_SELF () && (((uint32_t) *this) & 0x80808080) == 0; 433738c54d9caa3affc4b434e56bfb810ff6dc9b0b3Behdad Esfahbod } 4346b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 435303fe62824d4e99df554b6bfaacba05d068522fbBehdad EsfahbodASSERT_SIZE (Tag, 4); 436da1097bc3b1995776c205707fd2b17603b804646Behdad Esfahbod#define _NULL_TAG_INIT {' ', ' ', ' ', ' '} 437da1097bc3b1995776c205707fd2b17603b804646Behdad EsfahbodDEFINE_NULL_DATA (Tag, 4, _NULL_TAG_INIT); 438da1097bc3b1995776c205707fd2b17603b804646Behdad Esfahbod#undef _NULL_TAG_INIT 4396b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4406b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* Glyph index number, same as uint16 (length = 16 bits) */ 4416ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef USHORT GlyphID; 4426b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4431f437e6f47fb6c15761021bd2078f31778f2179cBehdad Esfahbod/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */ 4446ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef USHORT Offset; 4456ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod 4466ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */ 4476ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbodtypedef ULONG LongOffset; 4486ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod 4496b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4506b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* CheckSum */ 45160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CheckSum : ULONG 45260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 45360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod static uint32_t CalcTableChecksum (ULONG *Table, uint32_t Length) 45460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 4556b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod uint32_t Sum = 0L; 45601e4fcb032be601f272e62228881e2aabfb9d925Behdad Esfahbod ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(ULONG); 4576b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4586b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod while (Table < EndPtr) 4596b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod Sum += *Table++; 4606b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod return Sum; 4616b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod } 4626b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 4638b8358033184198ff638ee1379093717596e162dBehdad EsfahbodASSERT_SIZE (CheckSum, 4); 4646b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4656b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 4666b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod/* 4676b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod * Version Numbers 4686b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod */ 4696b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 47087fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbodstruct FixedVersion 47160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 47209c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod inline operator uint32_t (void) const { return (major << 16) + minor; } 47396908b898476ca5d7da5f386b15be76f9e83d76eBehdad Esfahbod 474cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 475b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 476cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod return SANITIZE_SELF (); 477cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 478cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 4796ad8d5f3c7028147b371137ae4bca6aae66b3489Behdad Esfahbod USHORT major; 48087fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbod USHORT minor; 4816b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod}; 48287fcdcbe3644da10154688765db2d62eb9ac079aBehdad EsfahbodASSERT_SIZE (FixedVersion, 4); 4836b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 48492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 48592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 4865f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod/* 48792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Template subclasses of Offset and LongOffset that do the dereferencing. 48892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Use: (this+memberName) 4895f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod */ 4905f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 49192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename OffsetType, typename Type> 49292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct GenericOffsetTo : OffsetType 49392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod{ 49492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod inline const Type& operator() (const void *base) const 49592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod { 49692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod unsigned int offset = *this; 49792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (HB_UNLIKELY (!offset)) return Null(Type); 49895639fccc1ef18eadeb737e8b611d1d1f1315fc2Behdad Esfahbod return CONST_CAST(Type, *CONST_CHARP(base), offset); 49992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod } 50092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 50192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { 502b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 50392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (!SANITIZE_OBJ (*this)) return false; 50492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod unsigned int offset = *this; 50592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 506ac26e2a838d1266bb5f39c43245eb2a52c5e072dBehdad Esfahbod return SANITIZE (CAST(Type, *DECONST_CHARP(base), offset)) || NEUTER (DECONST_CAST(OffsetType,*this,0), 0); 50792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod } 508b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, const void *base2) { 509b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 510b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (!SANITIZE_OBJ (*this)) return false; 511b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod unsigned int offset = *this; 512b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 513b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod return SANITIZE_BASE (CAST(Type, *DECONST_CHARP(base), offset), base2) || NEUTER (DECONST_CAST(OffsetType,*this,0), 0); 514b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod } 51542b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) { 516b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 51742b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (!SANITIZE_OBJ (*this)) return false; 51842b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod unsigned int offset = *this; 51942b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (HB_UNLIKELY (!offset)) return true; 520ac26e2a838d1266bb5f39c43245eb2a52c5e072dBehdad Esfahbod return SANITIZE_BASE (CAST(Type, *DECONST_CHARP(base), offset), user_data) || NEUTER (DECONST_CAST(OffsetType,*this,0), 0); 52142b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod } 52292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod}; 52392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Base, typename OffsetType, typename Type> 52492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodinline const Type& operator + (const Base &base, GenericOffsetTo<OffsetType, Type> offset) { return offset (base); } 52592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 5265f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbodtemplate <typename Type> 52792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct OffsetTo : GenericOffsetTo<Offset, Type> {}; 52892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 52992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 53092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {}; 53192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* 53292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod * Array Types 53392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod */ 53492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 53592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename LenType, typename Type> 53692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct GenericArrayOf 53760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 53860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 53960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 5405f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod if (HB_UNLIKELY (i >= len)) return Null(Type); 5415f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod return array[i]; 5425f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod } 54360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_size () const 54479420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod { return sizeof (len) + len * sizeof (array[0]); } 545e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod 54670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 547b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 548dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 549a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod /* Note; for non-recursive types, this is not much needed 55070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod unsigned int count = len; 55170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 55270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod if (!SANITIZE (array[i])) 55370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod return false; 554a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod */ 5559bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 55670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 5572b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base) { 558b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 559dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 560e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod unsigned int count = len; 561e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 56295639fccc1ef18eadeb737e8b611d1d1f1315fc2Behdad Esfahbod if (!array[i].sanitize (SANITIZE_ARG, base)) 563e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod return false; 5649bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 565e6ab2c59ba2d37942ac5fcbfe61d38b7e359ac8cBehdad Esfahbod } 566b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, const void *base2) { 567b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 568b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 569b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod unsigned int count = len; 570b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 571b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod if (!array[i].sanitize (SANITIZE_ARG, base, base2)) 572b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod return false; 5739bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 574b508e5ccd528f3f0f49f545bd5f30a525d5abd5aBehdad Esfahbod } 57542b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF, const void *base, unsigned int user_data) { 576b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 57742b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 57842b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod unsigned int count = len; 57942b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 58042b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod if (!array[i].sanitize (SANITIZE_ARG, base, user_data)) 58142b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod return false; 5829bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 58342b778f89e0818fe06910ce04e2203485823da09Behdad Esfahbod } 58470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 58592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod LenType len; 586e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod Type array[]; 587e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod}; 588e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod 58992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* An array with a USHORT number of elements. */ 59092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 59192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct ArrayOf : GenericArrayOf<USHORT, Type> {}; 59292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 59392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* An array with a ULONG number of elements. */ 59492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 59592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongArrayOf : GenericArrayOf<ULONG, Type> {}; 59692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 59792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* Array of Offset's */ 59892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 59992b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; 60092b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 60192b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* Array of LongOffset's */ 60292b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 60392b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {}; 60492b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 60592b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod/* LongArray of LongOffset's */ 60692b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodtemplate <typename Type> 60792b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbodstruct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {}; 60892b5dd8e71e1bdeaa6e86a53f167683a3f5f4289Behdad Esfahbod 609e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod/* An array with a USHORT number of elements, 610e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod * starting at second element. */ 611e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbodtemplate <typename Type> 61260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct HeadlessArrayOf 61360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 61460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 61560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 616e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod if (HB_UNLIKELY (i >= len || !i)) return Null(Type); 617e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod return array[i-1]; 618e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod } 61960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_size () const 62079420ad9caf2d5fc94c3693e8292edfa27060b2dBehdad Esfahbod { return sizeof (len) + (len ? len - 1 : 0) * sizeof (array[0]); } 6215f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 62270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod inline bool sanitize (SANITIZE_ARG_DEF) { 623b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod SANITIZE_DEBUG (); 624dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod if (!SANITIZE_GET_SIZE()) return false; 625a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod /* Note; for non-recursive types, this is not much needed 62615164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod unsigned int count = len ? len - 1 : 0; 62770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 62870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod if (!SANITIZE (array[i])) 62970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod return false; 630a97ce570ab693190350886e4e80942851c4d5727Behdad Esfahbod */ 6319bd629ccd064e739789e504c41ad875eed93abbaBehdad Esfahbod return true; 63270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 63370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 6345f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod USHORT len; 6355f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod Type array[]; 6365f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod}; 6375f810363acc3ad3cba631a68620e3d37e54c95c4Behdad Esfahbod 6386b4ce01da121e12e1c78ad7eaedf469f35f3568dBehdad Esfahbod 6395f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OPEN_TYPES_PRIVATE_HH */ 640