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 + -
显示快捷键?