aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/freetype2/src/otlayout/otlcommn.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/extras/freetype2/src/otlayout/otlcommn.c')
-rw-r--r--nx-X11/extras/freetype2/src/otlayout/otlcommn.c940
1 files changed, 940 insertions, 0 deletions
diff --git a/nx-X11/extras/freetype2/src/otlayout/otlcommn.c b/nx-X11/extras/freetype2/src/otlayout/otlcommn.c
new file mode 100644
index 000000000..742ff5b36
--- /dev/null
+++ b/nx-X11/extras/freetype2/src/otlayout/otlcommn.c
@@ -0,0 +1,940 @@
+/***************************************************************************/
+/* */
+/* otlcommn.c */
+/* */
+/* OpenType layout support, common tables (body). */
+/* */
+/* Copyright 2002 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#include "otlayout.h"
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** COVERAGE TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_coverage_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p;
+ OTL_UInt format;
+
+
+ if ( table + 4 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ format = OTL_NEXT_USHORT( p );
+ switch ( format )
+ {
+ case 1:
+ {
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+
+
+ if ( p + count * 2 >= valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ /* XXX: check glyph indices */
+ }
+ break;
+
+ case 2:
+ {
+ OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p );
+ OTL_UInt start, end, start_cover, total = 0, last = 0;
+
+
+ if ( p + num_ranges * 6 >= valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ for ( n = 0; n < num_ranges; n++ )
+ {
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+ start_cover = OTL_NEXT_USHORT( p );
+
+ if ( start > end || start_cover != total )
+ OTL_INVALID_DATA;
+
+ if ( n > 0 && start <= last )
+ OTL_INVALID_DATA;
+
+ total += end - start + 1;
+ last = end;
+ }
+ }
+ break;
+
+ default:
+ OTL_INVALID_FORMAT;
+ }
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_coverage_get_count( OTL_Bytes table )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt format = OTL_NEXT_USHORT( p );
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+ OTL_UInt result = 0;
+
+
+ switch ( format )
+ {
+ case 1:
+ return count;
+
+ case 2:
+ {
+ OTL_UInt start, end;
+
+
+ for ( ; count > 0; count-- )
+ {
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+ p += 2; /* skip start_index */
+
+ result += end - start + 1;
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ return result;
+ }
+
+
+ OTL_LOCALDEF( OTL_Int )
+ otl_coverage_get_index( OTL_Bytes table,
+ OTL_UInt glyph_index )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt format = OTL_NEXT_USHORT( p );
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+
+
+ switch ( format )
+ {
+ case 1:
+ {
+ OTL_UInt min = 0, max = count, mid, gindex;
+
+
+ table += 4;
+ while ( min < max )
+ {
+ mid = ( min + max ) >> 1;
+ p = table + 2 * mid;
+ gindex = OTL_PEEK_USHORT( p );
+
+ if ( glyph_index == gindex )
+ return (OTL_Int)mid;
+
+ if ( glyph_index < gindex )
+ max = mid;
+ else
+ min = mid + 1;
+ }
+ }
+ break;
+
+ case 2:
+ {
+ OTL_UInt min = 0, max = count, mid;
+ OTL_UInt start, end, delta, start_cover;
+
+
+ table += 4;
+ while ( min < max )
+ {
+ mid = ( min + max ) >> 1;
+ p = table + 6 * mid;
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+
+ if ( glyph_index < start )
+ max = mid;
+ else if ( glyph_index > end )
+ min = mid + 1;
+ else
+ return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start );
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ return -1;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** CLASS DEFINITION TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_class_definition_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt format;
+
+
+ if ( p + 4 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ format = OTL_NEXT_USHORT( p );
+ switch ( format )
+ {
+ case 1:
+ {
+ OTL_UInt count, start = OTL_NEXT_USHORT( p );
+
+
+ if ( p + 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ count = OTL_NEXT_USHORT( p );
+
+ if ( p + count * 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ /* XXX: check glyph indices */
+ }
+ break;
+
+ case 2:
+ {
+ OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p );
+ OTL_UInt start, end, value, last = 0;
+
+
+ if ( p + num_ranges * 6 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ for ( n = 0; n < num_ranges; n++ )
+ {
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+ value = OTL_NEXT_USHORT( p ); /* ignored */
+
+ if ( start > end || ( n > 0 && start <= last ) )
+ OTL_INVALID_DATA;
+
+ last = end;
+ }
+ }
+ break;
+
+ default:
+ OTL_INVALID_FORMAT;
+ }
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_class_definition_get_value( OTL_Bytes table,
+ OTL_UInt glyph_index )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt format = OTL_NEXT_USHORT( p );
+
+
+ switch ( format )
+ {
+ case 1:
+ {
+ OTL_UInt start = OTL_NEXT_USHORT( p );
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+ OTL_UInt idx = (OTL_UInt)( glyph_index - start );
+
+
+ if ( idx < count )
+ {
+ p += 2 * idx;
+ return OTL_PEEK_USHORT( p );
+ }
+ }
+ break;
+
+ case 2:
+ {
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+ OTL_UInt min = 0, max = count, mid, gindex;
+
+
+ table += 4;
+ while ( min < max )
+ {
+ mid = ( min + max ) >> 1;
+ p = table + 6 * mid;
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+
+ if ( glyph_index < start )
+ max = mid;
+ else if ( glyph_index > end )
+ min = mid + 1;
+ else
+ return OTL_PEEK_USHORT( p );
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ return 0;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** DEVICE TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_device_table_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt start, end, count, format, count;
+
+
+ if ( p + 8 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+ format = OTL_NEXT_USHORT( p );
+
+ if ( format < 1 || format > 3 || end < start )
+ OTL_INVALID_DATA;
+
+ count = (OTL_UInt)( end - start + 1 );
+
+ if ( p + ( ( 1 << format ) * count ) / 8 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_device_table_get_start( OTL_Bytes table )
+ {
+ OTL_Bytes p = table;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_device_table_get_end( OTL_Bytes table )
+ {
+ OTL_Bytes p = table + 2;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_Int )
+ otl_device_table_get_delta( OTL_Bytes table,
+ OTL_UInt size )
+ {
+ OTL_Bytes p = table;
+ OTL_Int result = 0;
+ OTL_UInt start, end, format, idx, value;
+
+
+ start = OTL_NEXT_USHORT( p );
+ end = OTL_NEXT_USHORT( p );
+ format = OTL_NEXT_USHORT( p );
+
+ if ( size >= start && size <= end )
+ {
+ /* we could do that with clever bit operations, but a switch is */
+ /* much simpler to understand and maintain */
+ /* */
+ switch ( format )
+ {
+ case 1:
+ idx = (OTL_UInt)( ( size - start ) * 2 );
+ p += idx / 16;
+ value = OTL_PEEK_USHORT( p );
+ shift = idx & 15;
+ result = (OTL_Short)( value << shift ) >> ( 14 - shift );
+
+ break;
+
+ case 2:
+ idx = (OTL_UInt)( ( size - start ) * 4 );
+ p += idx / 16;
+ value = OTL_PEEK_USHORT( p );
+ shift = idx & 15;
+ result = (OTL_Short)( value << shift ) >> ( 12 - shift );
+
+ break;
+
+ case 3:
+ idx = (OTL_UInt)( ( size - start ) * 8 );
+ p += idx / 16;
+ value = OTL_PEEK_USHORT( p );
+ shift = idx & 15;
+ result = (OTL_Short)( value << shift ) >> ( 8 - shift );
+
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ return result;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** LOOKUP LISTS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_lookup_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt num_tables;
+
+
+ if ( table + 6 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ p += 4;
+ num_tables = OTL_NEXT_USHORT( p );
+
+ if ( p + num_tables * 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ for ( ; num_tables > 0; num_tables-- )
+ {
+ offset = OTL_NEXT_USHORT( p );
+
+ if ( table + offset >= valid->limit )
+ OTL_INVALID_OFFSET;
+ }
+
+ /* XXX: check sub-tables? */
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_lookup_get_count( OTL_Bytes table )
+ {
+ OTL_Bytes p = table + 4;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_Bytes )
+ otl_lookup_get_table( OTL_Bytes table,
+ OTL_UInt idx )
+ {
+ OTL_Bytes p, result = NULL;
+ OTL_UInt count;
+
+
+ p = table + 4;
+ count = OTL_NEXT_USHORT( p );
+ if ( idx < count )
+ {
+ p += idx * 2;
+ result = table + OTL_PEEK_USHORT( p );
+ }
+
+ return result;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** LOOKUP LISTS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_lookup_list_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table, q;
+ OTL_UInt num_lookups, offset;
+
+
+ if ( p + 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ num_lookups = OTL_NEXT_USHORT( p );
+
+ if ( p + num_lookups * 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ for ( ; num_lookups > 0; num_lookups-- )
+ {
+ offset = OTL_NEXT_USHORT( p );
+
+ otl_lookup_validate( table + offset, valid );
+ }
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_lookup_list_get_count( OTL_Bytes table )
+ {
+ OTL_Bytes p = table;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_Bytes )
+ otl_lookup_list_get_lookup( OTL_Bytes table,
+ OTL_UInt idx )
+ {
+ OTL_Bytes p, result = 0;
+ OTL_UInt count;
+
+
+ p = table;
+ count = OTL_NEXT_USHORT( p );
+ if ( idx < count )
+ {
+ p += idx * 2;
+ result = table + OTL_PEEK_USHORT( p );
+ }
+
+ return result;
+ }
+
+
+ OTL_LOCALDEF( OTL_Bytes )
+ otl_lookup_list_get_table( OTL_Bytes table,
+ OTL_UInt lookup_index,
+ OTL_UInt table_index )
+ {
+ OTL_Bytes result = NULL;
+
+
+ result = otl_lookup_list_get_lookup( table, lookup_index );
+ if ( result )
+ result = otl_lookup_get_table( result, table_index );
+
+ return result;
+ }
+
+
+ OTL_LOCALDEF( void )
+ otl_lookup_list_foreach( OTL_Bytes table,
+ OTL_ForeachFunc func,
+ OTL_Pointer func_data )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+
+
+ for ( ; count > 0; count-- )
+ func( table + OTL_NEXT_USHORT( p ), func_data );
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** FEATURES *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_feature_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt feat_params, num_lookups;
+
+
+ if ( p + 4 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ feat_params = OTL_NEXT_USHORT( p ); /* ignored */
+ num_lookups = OTL_NEXT_USHORT( p );
+
+ if ( p + num_lookups * 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ /* XXX: check lookup indices */
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_feature_get_count( OTL_Bytes table )
+ {
+ OTL_Bytes p = table + 4;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_feature_get_lookups( OTL_Bytes table,
+ OTL_UInt start,
+ OTL_UInt count,
+ OTL_UInt *lookups )
+ {
+ OTL_Bytes p;
+ OTL_UInt num_features, result = 0;
+
+
+ p = table + 4;
+ num_features = OTL_NEXT_USHORT( p );
+
+ p += start * 2;
+
+ for ( ; count > 0 && start < num_features; count--, start++ )
+ {
+ lookups[0] = OTL_NEXT_USHORT(p);
+ lookups++;
+ result++;
+ }
+
+ return result;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** FEATURE LIST *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ OTL_LOCALDEF( void )
+ otl_feature_list_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt num_features, offset;
+
+
+ if ( table + 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ num_features = OTL_NEXT_USHORT( p );
+
+ if ( p + num_features * 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ for ( ; num_features > 0; num_features-- )
+ {
+ p += 4; /* skip tag */
+ offset = OTL_NEXT_USHORT( p );
+
+ otl_feature_table_validate( table + offset, valid );
+ }
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_feature_list_get_count( OTL_Bytes table )
+ {
+ OTL_Bytes p = table;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_Bytes )
+ otl_feature_list_get_feature( OTL_Bytes table,
+ OTL_UInt idx )
+ {
+ OTL_Bytes p, result = NULL;
+ OTL_UInt count;
+
+
+ p = table;
+ count = OTL_NEXT_USHORT( p );
+
+ if ( idx < count )
+ {
+ p += idx * 2;
+ result = table + OTL_PEEK_USHORT( p );
+ }
+
+ return result;
+ }
+
+
+ OTL_LOCALDEF( void )
+ otl_feature_list_foreach( OTL_Bytes table,
+ OTL_ForeachFunc func,
+ OTL_Pointer func_data )
+ {
+ OTL_Bytes p;
+ OTL_UInt count;
+
+
+ p = table;
+ count = OTL_NEXT_USHORT( p );
+
+ for ( ; count > 0; count-- )
+ func( table + OTL_NEXT_USHORT( p ), func_data );
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** LANGUAGE SYSTEM *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ OTL_LOCALDEF( void )
+ otl_lang_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt lookup_order;
+ OTL_UInt req_feature;
+ OTL_UInt num_features;
+
+
+ if ( table + 6 >= valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ lookup_order = OTL_NEXT_USHORT( p );
+ req_feature = OTL_NEXT_USHORT( p );
+ num_features = OTL_NEXT_USHORT( p );
+
+ /* XXX: check req_feature if not 0xFFFFU */
+
+ if ( p + 2 * num_features >= valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ /* XXX: check features indices! */
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_lang_get_count( OTL_Bytes table )
+ {
+ OTL_Bytes p = table + 4;
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_lang_get_req_feature( OTL_Bytes table )
+ {
+ OTL_Bytes p = table + 2;
+
+
+ return OTL_PEEK_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_lang_get_features( OTL_Bytes table,
+ OTL_UInt start,
+ OTL_UInt count,
+ OTL_UInt *features )
+ {
+ OTL_Bytes p = table + 4;
+ OTL_UInt num_features = OTL_NEXT_USHORT( p );
+ OTL_UInt result = 0;
+
+
+ p += start * 2;
+
+ for ( ; count > 0 && start < num_features; start++, count-- )
+ {
+ features[0] = OTL_NEXT_USHORT( p );
+ features++;
+ result++;
+ }
+
+ return result;
+ }
+
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** SCRIPTS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ OTL_LOCALDEF( void )
+ otl_script_validate( OTL_Bytes table,
+ OTL_Validator valid )
+ {
+ OTL_UInt default_lang;
+ OTL_Bytes p = table;
+
+
+ if ( table + 4 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ default_lang = OTL_NEXT_USHORT( p );
+ num_langs = OTL_NEXT_USHORT( p );
+
+ if ( default_lang != 0 )
+ {
+ if ( table + default_lang >= valid->limit )
+ OTL_INVALID_OFFSET;
+ }
+
+ if ( p + num_langs * 6 >= valid->limit )
+ OTL_INVALID_OFFSET;
+
+ for ( ; num_langs > 0; num_langs-- )
+ {
+ OTL_UInt offset;
+
+
+ p += 4; /* skip tag */
+ offset = OTL_NEXT_USHORT( p );
+
+ otl_lang_validate( table + offset, valid );
+ }
+ }
+
+
+ OTL_LOCALDEF( void )
+ otl_script_list_validate( OTL_Bytes list,
+ OTL_Validator valid )
+ {
+ OTL_UInt num_scripts;
+ OTL_Bytes p = list;
+
+
+ if ( list + 2 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ num_scripts = OTL_NEXT_USHORT( p );
+
+ if ( p + num_scripts * 6 > valid->limit )
+ OTL_INVALID_TOO_SHORT;
+
+ for ( ; num_scripts > 0; num_scripts-- )
+ {
+ OTL_UInt offset;
+
+
+ p += 4; /* skip tag */
+ offset = OTL_NEXT_USHORT( p );
+
+ otl_script_table_validate( list + offset, valid );
+ }
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** LOOKUP LISTS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ otl_lookup_table_validate( OTL_Bytes table,
+ OTL_UInt type_count,
+ OTL_ValidateFunc* type_funcs,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt lookup_type, lookup_flag, count;
+ OTL_ValidateFunc validate;
+
+ OTL_CHECK( 6 );
+ lookup_type = OTL_NEXT_USHORT( p );
+ lookup_flag = OTL_NEXT_USHORT( p );
+ count = OTL_NEXT_USHORT( p );
+
+ if ( lookup_type == 0 || lookup_type >= type_count )
+ OTL_INVALID_DATA;
+
+ validate = type_funcs[ lookup_type - 1 ];
+
+ OTL_CHECK( 2*count );
+ for ( ; count > 0; count-- )
+ validate( table + OTL_NEXT_USHORT( p ), valid );
+ }
+
+
+ OTL_LOCALDEF( void )
+ otl_lookup_list_validate( OTL_Bytes table,
+ OTL_UInt type_count,
+ OTL_ValidateFunc* type_funcs,
+ OTL_Validator valid )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt count;
+
+ OTL_CHECK( 2 );
+ count = OTL_NEXT_USHORT( p );
+
+ OTL_CHECK( 2*count );
+ for ( ; count > 0; count-- )
+ otl_lookup_table_validate( table + OTL_NEXT_USHORT( p ),
+ type_count, type_funcs, valid );
+ }
+
+/* END */