rive_rs/
runtime_header.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::collections::HashMap;
6
7use crate::core::BinaryReader;
8
9const FINGERPRINT: &[u8] = "RIVE".as_bytes();
10
11/// Rive file runtime header. The header is fonud at the beginning of every
12/// Rive runtime file, and begins with a specific 4-byte format: "RIVE".
13/// This is followed by the major and minor version of Rive used to create
14/// the file. Finally the owner and file ids are at the end of header; these
15/// unsigned integers may be zero.
16#[derive(Debug)]
17pub struct RuntimeHeader {
18    major_version: u32,
19    // TODO(https://fxbug.dev/42165549)
20    #[allow(unused)]
21    minor_version: u32,
22    // TODO(https://fxbug.dev/42165549)
23    #[allow(unused)]
24    file_id: u32,
25    property_to_field_index: HashMap<u32, u32>,
26}
27
28impl RuntimeHeader {
29    /// Reads the header from a binary buffer.
30    pub fn read(reader: &mut BinaryReader<'_>) -> Option<Self> {
31        if reader.read_bytes(FINGERPRINT.len())? != FINGERPRINT {
32            return None;
33        }
34
35        let major_version = reader.read_var_u64()? as u32;
36        let minor_version = reader.read_var_u64()? as u32;
37        let file_id = reader.read_var_u64()? as u32;
38
39        let mut property_keys = Vec::new();
40
41        loop {
42            let property_key = reader.read_var_u64()? as u32;
43
44            if property_key == 0 {
45                break;
46            }
47
48            property_keys.push(property_key);
49        }
50
51        let mut property_to_field_index = HashMap::new();
52        let mut current_u32 = 0;
53        let mut current_bit = 8;
54
55        for property_key in property_keys {
56            if current_bit == 8 {
57                current_u32 = reader.read_u32()?;
58                current_bit = 0;
59            }
60
61            let field_index = (current_u32 >> current_bit) & 3;
62            property_to_field_index.insert(property_key, field_index);
63            current_bit += 2;
64        }
65
66        Some(Self { major_version, minor_version, file_id, property_to_field_index })
67    }
68
69    pub fn major_version(&self) -> u32 {
70        self.major_version
71    }
72
73    pub fn property_file_id(&self, property_key: u32) -> Option<u32> {
74        self.property_to_field_index.get(&property_key).cloned()
75    }
76}