python_packed_resources/
serialization.rs

1// Copyright 2022 Gregory Szorc.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9/*! Declares the foundational data primitives inside packed resources data. */
10
11/// Header value for version 2 of resources payload.
12pub const HEADER_V3: &[u8] = b"pyembed\x03";
13
14/// Defines interior padding mechanism between entries in blob sections.
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
16pub enum BlobInteriorPadding {
17    /// No padding.
18    ///
19    /// Entries are packed next to each other. e.g. "foo" + "bar" = "foobar".
20    None = 0x01,
21
22    /// NULL byte padding.
23    ///
24    /// There exists a NULL byte between entries. e.g. "foo" + "bar" = "foo\0bar\0".
25    Null = 0x02,
26}
27
28impl From<&BlobInteriorPadding> for u8 {
29    fn from(source: &BlobInteriorPadding) -> Self {
30        match source {
31            BlobInteriorPadding::None => 0x01,
32            BlobInteriorPadding::Null => 0x02,
33        }
34    }
35}
36
37/// Describes a blob section field type in the blob index.
38#[derive(Debug, PartialEq, Eq, PartialOrd)]
39pub enum BlobSectionField {
40    EndOfIndex = 0x00,
41    StartOfEntry = 0x01,
42    EndOfEntry = 0xff,
43    ResourceFieldType = 0x03,
44    RawPayloadLength = 0x04,
45    InteriorPadding = 0x05,
46}
47
48impl From<BlobSectionField> for u8 {
49    fn from(source: BlobSectionField) -> u8 {
50        match source {
51            BlobSectionField::EndOfIndex => 0x00,
52            BlobSectionField::StartOfEntry => 0x01,
53            BlobSectionField::ResourceFieldType => 0x02,
54            BlobSectionField::RawPayloadLength => 0x03,
55            BlobSectionField::InteriorPadding => 0x04,
56            BlobSectionField::EndOfEntry => 0xff,
57        }
58    }
59}
60
61impl TryFrom<u8> for BlobSectionField {
62    type Error = &'static str;
63
64    fn try_from(value: u8) -> Result<Self, Self::Error> {
65        match value {
66            0x00 => Ok(BlobSectionField::EndOfIndex),
67            0x01 => Ok(BlobSectionField::StartOfEntry),
68            0x02 => Ok(BlobSectionField::ResourceFieldType),
69            0x03 => Ok(BlobSectionField::RawPayloadLength),
70            0x04 => Ok(BlobSectionField::InteriorPadding),
71            0xff => Ok(BlobSectionField::EndOfEntry),
72            _ => Err("invalid blob index field type"),
73        }
74    }
75}
76
77/// Describes a resource field type in the resource index.
78#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
79pub enum ResourceField {
80    EndOfIndex = 0x00,
81    StartOfEntry = 0x01,
82    EndOfEntry = 0xff,
83    // Flavor previously occupied slot 0x02.
84    Name = 0x03,
85    IsPythonPackage = 0x04,
86    IsPythonNamespacePackage = 0x05,
87    InMemorySource = 0x06,
88    InMemoryBytecode = 0x07,
89    InMemoryBytecodeOpt1 = 0x08,
90    InMemoryBytecodeOpt2 = 0x09,
91    InMemoryExtensionModuleSharedLibrary = 0x0a,
92    InMemoryResourcesData = 0x0b,
93    InMemoryDistributionResource = 0x0c,
94    InMemorySharedLibrary = 0x0d,
95    SharedLibraryDependencyNames = 0x0e,
96    RelativeFilesystemModuleSource = 0x0f,
97    RelativeFilesystemModuleBytecode = 0x10,
98    RelativeFilesystemModuleBytecodeOpt1 = 0x11,
99    RelativeFilesystemModuleBytecodeOpt2 = 0x12,
100    RelativeFilesystemExtensionModuleSharedLibrary = 0x13,
101    RelativeFilesystemPackageResources = 0x14,
102    RelativeFilesystemDistributionResource = 0x15,
103    IsPythonModule = 0x16,
104    IsPythonBuiltinExtensionModule = 0x17,
105    IsPythonFrozenModule = 0x18,
106    IsPythonExtensionModule = 0x19,
107    IsSharedLibrary = 0x1a,
108    IsUtf8FilenameData = 0x1b,
109    FileExecutable = 0x1c,
110    FileDataEmbedded = 0x1d,
111    FileDataUtf8RelativePath = 0x1e,
112}
113
114impl From<ResourceField> for u8 {
115    fn from(field: ResourceField) -> Self {
116        match field {
117            ResourceField::EndOfIndex => 0x00,
118            ResourceField::StartOfEntry => 0x01,
119            ResourceField::Name => 0x03,
120            ResourceField::IsPythonPackage => 0x04,
121            ResourceField::IsPythonNamespacePackage => 0x05,
122            ResourceField::InMemorySource => 0x06,
123            ResourceField::InMemoryBytecode => 0x07,
124            ResourceField::InMemoryBytecodeOpt1 => 0x08,
125            ResourceField::InMemoryBytecodeOpt2 => 0x09,
126            ResourceField::InMemoryExtensionModuleSharedLibrary => 0x0a,
127            ResourceField::InMemoryResourcesData => 0x0b,
128            ResourceField::InMemoryDistributionResource => 0x0c,
129            ResourceField::InMemorySharedLibrary => 0x0d,
130            ResourceField::SharedLibraryDependencyNames => 0x0e,
131            ResourceField::RelativeFilesystemModuleSource => 0x0f,
132            ResourceField::RelativeFilesystemModuleBytecode => 0x10,
133            ResourceField::RelativeFilesystemModuleBytecodeOpt1 => 0x11,
134            ResourceField::RelativeFilesystemModuleBytecodeOpt2 => 0x12,
135            ResourceField::RelativeFilesystemExtensionModuleSharedLibrary => 0x13,
136            ResourceField::RelativeFilesystemPackageResources => 0x14,
137            ResourceField::RelativeFilesystemDistributionResource => 0x15,
138            ResourceField::IsPythonModule => 0x16,
139            ResourceField::IsPythonBuiltinExtensionModule => 0x17,
140            ResourceField::IsPythonFrozenModule => 0x18,
141            ResourceField::IsPythonExtensionModule => 0x19,
142            ResourceField::IsSharedLibrary => 0x1a,
143            ResourceField::IsUtf8FilenameData => 0x1b,
144            ResourceField::FileExecutable => 0x1c,
145            ResourceField::FileDataEmbedded => 0x1d,
146            ResourceField::FileDataUtf8RelativePath => 0x1e,
147            ResourceField::EndOfEntry => 0xff,
148        }
149    }
150}
151
152impl TryFrom<u8> for ResourceField {
153    type Error = &'static str;
154
155    fn try_from(value: u8) -> Result<Self, Self::Error> {
156        match value {
157            0x00 => Ok(ResourceField::EndOfIndex),
158            0x01 => Ok(ResourceField::StartOfEntry),
159            0x03 => Ok(ResourceField::Name),
160            0x04 => Ok(ResourceField::IsPythonPackage),
161            0x05 => Ok(ResourceField::IsPythonNamespacePackage),
162            0x06 => Ok(ResourceField::InMemorySource),
163            0x07 => Ok(ResourceField::InMemoryBytecode),
164            0x08 => Ok(ResourceField::InMemoryBytecodeOpt1),
165            0x09 => Ok(ResourceField::InMemoryBytecodeOpt2),
166            0x0a => Ok(ResourceField::InMemoryExtensionModuleSharedLibrary),
167            0x0b => Ok(ResourceField::InMemoryResourcesData),
168            0x0c => Ok(ResourceField::InMemoryDistributionResource),
169            0x0d => Ok(ResourceField::InMemorySharedLibrary),
170            0x0e => Ok(ResourceField::SharedLibraryDependencyNames),
171            0x0f => Ok(ResourceField::RelativeFilesystemModuleSource),
172            0x10 => Ok(ResourceField::RelativeFilesystemModuleBytecode),
173            0x11 => Ok(ResourceField::RelativeFilesystemModuleBytecodeOpt1),
174            0x12 => Ok(ResourceField::RelativeFilesystemModuleBytecodeOpt2),
175            0x13 => Ok(ResourceField::RelativeFilesystemExtensionModuleSharedLibrary),
176            0x14 => Ok(ResourceField::RelativeFilesystemPackageResources),
177            0x15 => Ok(ResourceField::RelativeFilesystemDistributionResource),
178            0x16 => Ok(ResourceField::IsPythonModule),
179            0x17 => Ok(ResourceField::IsPythonBuiltinExtensionModule),
180            0x18 => Ok(ResourceField::IsPythonFrozenModule),
181            0x19 => Ok(ResourceField::IsPythonExtensionModule),
182            0x1a => Ok(ResourceField::IsSharedLibrary),
183            0x1b => Ok(ResourceField::IsUtf8FilenameData),
184            0x1c => Ok(ResourceField::FileExecutable),
185            0x1d => Ok(ResourceField::FileDataEmbedded),
186            0x1e => Ok(ResourceField::FileDataUtf8RelativePath),
187            0xff => Ok(ResourceField::EndOfEntry),
188            _ => Err("invalid field type"),
189        }
190    }
191}