📄 otlcommn.c
字号:
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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -