Avifinfo

Parser::parse_iprp()privateWP 1.0

Parses an "iprp" box.

The "ipco" box contain the properties which are linked to items by the "ipma" box.

Метод класса: Parser{}

Хуков нет.

Возвращает

Status. FOUND on success or an error on failure.

Использование

// private - только в коде основоного (родительского) класса
$result = $this->parse_iprp( $num_remaining_bytes );
$num_remaining_bytes(int) (обязательный)
The number of bytes that should be available from the resource.

Код Parser::parse_iprp() WP 6.6.2

private function parse_iprp( $num_remaining_bytes ) {
  do {
    $box    = new Box();
    $status = $box->parse( $this->handle, $this->num_parsed_boxes, $num_remaining_bytes );
    if ( $status != FOUND ) {
      return $status;
    }

    if ( $box->type == 'ipco' ) {
      $status = $this->parse_ipco( $box->content_size );
      if ( $status != NOT_FOUND ) {
        return $status;
      }
    } else if ( $box->type == 'ipma' ) {
      // See ISO/IEC 23008-12:2017(E) 9.3.2
      $num_read_bytes = 4;
      if ( $box->content_size < $num_read_bytes ) {
        return INVALID;
      }
      if ( !( $data = read( $this->handle, $num_read_bytes ) ) ) {
        return TRUNCATED;
      }
      $entry_count        = read_big_endian( $data, 4 );
      $id_num_bytes       = ( $box->version < 1 ) ? 2 : 4;
      $index_num_bytes    = ( $box->flags & 1 ) ? 2 : 1;
      $essential_bit_mask = ( $box->flags & 1 ) ? 0x8000 : 0x80;

      for ( $entry = 0; $entry < $entry_count; ++$entry ) {
        if ( $entry >= MAX_PROPS ||
             count( $this->features->props ) >= MAX_PROPS ) {
          $this->data_was_skipped = true;
          break;
        }
        $num_read_bytes += $id_num_bytes + 1;
        if ( $box->content_size < $num_read_bytes ) {
          return INVALID;
        }
        if ( !( $data = read( $this->handle, $id_num_bytes + 1 ) ) ) {
          return TRUNCATED;
        }
        $item_id           = read_big_endian(
            substr( $data, 0, $id_num_bytes ), $id_num_bytes );
        $association_count = read_big_endian(
            substr( $data, $id_num_bytes, 1 ), 1 );

        for ( $property = 0; $property < $association_count; ++$property ) {
          if ( $property >= MAX_PROPS ||
               count( $this->features->props ) >= MAX_PROPS ) {
            $this->data_was_skipped = true;
            break;
          }
          $num_read_bytes += $index_num_bytes;
          if ( $box->content_size < $num_read_bytes ) {
            return INVALID;
          }
          if ( !( $data = read( $this->handle, $index_num_bytes ) ) ) {
            return TRUNCATED;
          }
          $value          = read_big_endian( $data, $index_num_bytes );
          // $essential = ($value & $essential_bit_mask);  // Unused.
          $property_index = ( $value & ~$essential_bit_mask );
          if ( $property_index <= MAX_VALUE && $item_id <= MAX_VALUE ) {
            $prop_count = count( $this->features->props );
            $this->features->props[$prop_count]                 = new Prop();
            $this->features->props[$prop_count]->property_index = $property_index;
            $this->features->props[$prop_count]->item_id        = $item_id;
          } else {
            $this->data_was_skipped = true;
          }
        }
        if ( $property < $association_count ) {
          break; // Do not read garbage.
        }
      }

      // If all features are available now, do not look further.
      $status = $this->features->get_primary_item_features();
      if ( $status != NOT_FOUND ) {
        return $status;
      }

      // Mostly if 'data_was_skipped'.
      if ( !skip( $this->handle, $box->content_size - $num_read_bytes ) ) {
        return TRUNCATED;
      }
    } else {
      if ( !skip( $this->handle, $box->content_size ) ) {
        return TRUNCATED;
      }
    }
    $num_remaining_bytes -= $box->size;
  } while ( $num_remaining_bytes > 0 );
  return NOT_FOUND;
}