otlcommn.c
来自「一个类似windows」· C语言 代码 · 共 941 行 · 第 1/2 页
C
941 行
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 + =
减小字号Ctrl + -
显示快捷键?