sparse/
format.rs

1// Copyright 2023 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 serde::{Deserialize, Serialize};
6use static_assertions::const_assert_eq;
7
8/// `SparseHeader` represents the header section of a `SparseFile`
9#[derive(Debug, Serialize, Deserialize)]
10#[repr(C)]
11pub struct SparseHeader {
12    /// Magic Number.
13    pub magic: u32,
14    /// Highest Major Version number supported.
15    pub major_version: u16,
16    /// Lowest Minor Version number supported.
17    pub minor_version: u16,
18    /// Size of the Header. (Defaults to 0)
19    pub file_hdr_sz: u16,
20    /// Size of the Header per-chunk. (Defaults to 0)
21    pub chunk_hdr_sz: u16,
22    /// Size of each block (Defaults to 4096)
23    pub blk_sz: u32,
24    /// Total number of blocks in the output image
25    pub total_blks: u32,
26    /// Total number of chunks.
27    pub total_chunks: u32,
28    /// Image Checksum... unused
29    pub image_checksum: u32,
30}
31
32pub const SPARSE_HEADER_SIZE: usize = std::mem::size_of::<SparseHeader>();
33const_assert_eq!(SPARSE_HEADER_SIZE, 28);
34
35impl SparseHeader {
36    pub fn new(blk_sz: u32, total_blks: u32, total_chunks: u32) -> SparseHeader {
37        SparseHeader {
38            magic: SPARSE_HEADER_MAGIC,
39            major_version: MAJOR_VERSION,
40            minor_version: MINOR_VERSION,
41            file_hdr_sz: std::mem::size_of::<SparseHeader>() as u16,
42            chunk_hdr_sz: std::mem::size_of::<ChunkHeader>() as u16,
43            blk_sz,
44            total_blks,
45            total_chunks,
46            image_checksum: CHECKSUM, // Checksum verification unused
47        }
48    }
49
50    pub fn valid(&self) -> bool {
51        self.magic == SPARSE_HEADER_MAGIC
52            && self.major_version == MAJOR_VERSION
53            && self.minor_version == MINOR_VERSION
54    }
55}
56
57/// `ChunkHeader` represents the header portion of a Chunk.
58#[derive(Debug, Serialize, Deserialize)]
59#[repr(C)]
60pub struct ChunkHeader {
61    pub chunk_type: u16,
62    reserved1: u16,
63    pub chunk_sz: u32,
64    pub total_sz: u32,
65}
66
67pub const CHUNK_HEADER_SIZE: usize = std::mem::size_of::<ChunkHeader>();
68const_assert_eq!(CHUNK_HEADER_SIZE, 12);
69
70pub const CHUNK_TYPE_RAW: u16 = 0xCAC1;
71pub const CHUNK_TYPE_FILL: u16 = 0xCAC2;
72pub const CHUNK_TYPE_DONT_CARE: u16 = 0xCAC3;
73pub const CHUNK_TYPE_CRC32: u16 = 0xCAC4;
74
75impl ChunkHeader {
76    pub fn new(chunk_type: u16, reserved1: u16, chunk_sz: u32, total_sz: u32) -> ChunkHeader {
77        ChunkHeader { chunk_type, reserved1, chunk_sz, total_sz }
78    }
79
80    pub fn valid(&self) -> bool {
81        self.chunk_type == CHUNK_TYPE_RAW
82            || self.chunk_type == CHUNK_TYPE_FILL
83            || self.chunk_type == CHUNK_TYPE_DONT_CARE
84            || self.chunk_type == CHUNK_TYPE_CRC32
85    }
86}
87
88// Header constants.
89pub const SPARSE_HEADER_MAGIC: u32 = 0xED26FF3A;
90/// Maximum Major Version Supported.
91const MAJOR_VERSION: u16 = 0x1;
92// Minimum Minor Version Supported.
93const MINOR_VERSION: u16 = 0x0;
94/// The Checksum... hardcoded not used.
95const CHECKSUM: u32 = 0xCAFED00D;