2
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
5
- use crate :: types:: { Error , FileSystemError , PtrMut , Result } ;
5
+ use crate :: types:: { Context , Error , FileSystemError , PtrMut , Result } ;
6
6
7
7
use crate :: entry:: EntryItemBody ;
8
8
use crate :: group:: { GroupItem , GroupMutItem } ;
@@ -50,29 +50,41 @@ use std::borrow::Cow;
50
50
#[ derive( Clone ) ]
51
51
pub struct ApcbIoOptions {
52
52
pub check_checksum : bool ,
53
+ pub context : Context ,
53
54
}
54
55
55
56
impl Default for ApcbIoOptions {
56
57
fn default ( ) -> Self {
57
- Self { check_checksum : true }
58
+ Self { check_checksum : true , context : Context :: default ( ) }
58
59
}
59
60
}
60
61
61
62
impl ApcbIoOptions {
62
63
pub fn builder ( ) -> Self {
63
64
Self :: default ( )
64
65
}
66
+ pub fn check_checksum ( & self ) -> bool {
67
+ self . check_checksum
68
+ }
69
+ pub fn context ( & self ) -> Context {
70
+ self . context
71
+ }
65
72
pub fn with_check_checksum ( & mut self , value : bool ) -> & mut Self {
66
73
self . check_checksum = value;
67
74
self
68
75
}
76
+ pub fn with_context ( & mut self , value : Context ) -> & mut Self {
77
+ self . context = value;
78
+ self
79
+ }
69
80
pub fn build ( & self ) -> Self {
70
81
self . clone ( )
71
82
}
72
83
}
73
84
74
85
#[ cfg_attr( feature = "std" , derive( Clone ) ) ]
75
86
pub struct Apcb < ' a > {
87
+ context : Context ,
76
88
used_size : usize ,
77
89
pub backing_store : PtrMut < ' a , [ u8 ] > ,
78
90
}
@@ -83,6 +95,10 @@ pub struct Apcb<'a> {
83
95
#[ cfg_attr( feature = "serde" , serde( deny_unknown_fields) ) ]
84
96
#[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
85
97
pub struct SerdeApcb {
98
+ /// This field is out-of-band information. At the cost of slight redundancy
99
+ /// in user config and another extra field that isn't actually in the blob,
100
+ /// we can actually handle the out-of-band information quite natually.
101
+ pub context : Context ,
86
102
pub version : String ,
87
103
pub header : V2_HEADER ,
88
104
pub v3_header_ext : Option < V3_HEADER_EXT > ,
@@ -110,11 +126,15 @@ impl<'a> schemars::JsonSchema for Apcb<'a> {
110
126
use core:: convert:: TryFrom ;
111
127
112
128
#[ cfg( feature = "serde" ) ]
113
- impl < ' a > TryFrom < SerdeApcb > for Apcb < ' a > {
114
- type Error = Error ;
129
+ impl < ' a > Apcb < ' a > {
130
+ // type Error = Error;
115
131
fn try_from ( serde_apcb : SerdeApcb ) -> Result < Self > {
116
132
let buf = Cow :: from ( vec ! [ 0xFFu8 ; Self :: MAX_SIZE ] ) ;
117
- let mut apcb = Apcb :: create ( buf, 42 , & ApcbIoOptions :: default ( ) ) ?;
133
+ let mut apcb = Apcb :: create (
134
+ buf,
135
+ 42 ,
136
+ & ApcbIoOptions :: default ( ) . with_context ( serde_apcb. context ) . build ( ) ,
137
+ ) ?;
118
138
* apcb. header_mut ( ) ? = serde_apcb. header ;
119
139
match serde_apcb. v3_header_ext {
120
140
Some ( v3) => {
@@ -217,11 +237,13 @@ impl<'de> Deserialize<'de> for Apcb<'_> {
217
237
}
218
238
219
239
pub struct ApcbIterMut < ' a > {
240
+ context : Context ,
220
241
buf : & ' a mut [ u8 ] ,
221
242
remaining_used_size : usize ,
222
243
}
223
244
224
245
pub struct ApcbIter < ' a > {
246
+ context : Context ,
225
247
buf : & ' a [ u8 ] ,
226
248
remaining_used_size : usize ,
227
249
}
@@ -230,7 +252,10 @@ impl<'a> ApcbIterMut<'a> {
230
252
/// It's useful to have some way of NOT mutating self.buf. This is what
231
253
/// this function does. Note: The caller needs to manually decrease
232
254
/// remaining_used_size for each call if desired.
233
- fn next_item < ' b > ( buf : & mut & ' b mut [ u8 ] ) -> Result < GroupMutItem < ' b > > {
255
+ fn next_item < ' b > (
256
+ context : Context ,
257
+ buf : & mut & ' b mut [ u8 ] ,
258
+ ) -> Result < GroupMutItem < ' b > > {
234
259
if buf. is_empty ( ) {
235
260
return Err ( Error :: FileSystem (
236
261
FileSystemError :: InconsistentHeader ,
@@ -256,7 +281,7 @@ impl<'a> ApcbIterMut<'a> {
256
281
) ) ?;
257
282
let body_len = body. len ( ) ;
258
283
259
- Ok ( GroupMutItem { header, buf : body, used_size : body_len } )
284
+ Ok ( GroupMutItem { context , header, buf : body, used_size : body_len } )
260
285
}
261
286
262
287
/// Moves the point to the group with the given GROUP_ID. Returns (offset,
@@ -273,12 +298,12 @@ impl<'a> ApcbIterMut<'a> {
273
298
if buf. is_empty ( ) {
274
299
break ;
275
300
}
276
- let group = ApcbIterMut :: next_item ( & mut buf) ?;
301
+ let group = ApcbIterMut :: next_item ( self . context , & mut buf) ?;
277
302
let group_size = group. header . group_size . get ( ) ;
278
303
if group. header . group_id . get ( ) == group_id {
279
304
return Ok ( ( offset, group_size as usize ) ) ;
280
305
}
281
- let group = ApcbIterMut :: next_item ( & mut self . buf ) ?;
306
+ let group = ApcbIterMut :: next_item ( self . context , & mut self . buf ) ?;
282
307
let group_size = group. header . group_size . get ( ) as usize ;
283
308
offset = offset
284
309
. checked_add ( group_size)
@@ -295,7 +320,7 @@ impl<'a> ApcbIterMut<'a> {
295
320
296
321
pub ( crate ) fn next1 ( & mut self ) -> Result < GroupMutItem < ' a > > {
297
322
assert ! ( self . remaining_used_size != 0 , "Internal error" ) ;
298
- let item = Self :: next_item ( & mut self . buf ) ?;
323
+ let item = Self :: next_item ( self . context , & mut self . buf ) ?;
299
324
let group_size = item. header . group_size . get ( ) as usize ;
300
325
if group_size <= self . remaining_used_size {
301
326
self . remaining_used_size -= group_size;
@@ -324,7 +349,10 @@ impl<'a> ApcbIter<'a> {
324
349
/// It's useful to have some way of NOT mutating self.buf. This is what
325
350
/// this function does. Note: The caller needs to manually decrease
326
351
/// remaining_used_size for each call if desired.
327
- fn next_item < ' b > ( buf : & mut & ' b [ u8 ] ) -> Result < GroupItem < ' b > > {
352
+ fn next_item < ' b > (
353
+ context : Context ,
354
+ buf : & mut & ' b [ u8 ] ,
355
+ ) -> Result < GroupItem < ' b > > {
328
356
if buf. is_empty ( ) {
329
357
return Err ( Error :: FileSystem (
330
358
FileSystemError :: InconsistentHeader ,
@@ -351,12 +379,12 @@ impl<'a> ApcbIter<'a> {
351
379
352
380
let body_len = body. len ( ) ;
353
381
354
- Ok ( GroupItem { header, buf : body, used_size : body_len } )
382
+ Ok ( GroupItem { context , header, buf : body, used_size : body_len } )
355
383
}
356
384
357
385
pub ( crate ) fn next1 ( & mut self ) -> Result < GroupItem < ' a > > {
358
386
assert ! ( self . remaining_used_size != 0 , "Internal error" ) ;
359
- let item = Self :: next_item ( & mut self . buf ) ?;
387
+ let item = Self :: next_item ( self . context , & mut self . buf ) ?;
360
388
let group_size = item. header . group_size . get ( ) as usize ;
361
389
if group_size <= self . remaining_used_size {
362
390
self . remaining_used_size -= group_size;
@@ -369,7 +397,7 @@ impl<'a> ApcbIter<'a> {
369
397
}
370
398
}
371
399
/// Validates the entries (recursively). Also consumes iterator.
372
- pub ( crate ) fn validate ( mut self ) -> Result < ( ) > {
400
+ pub ( crate ) fn validate ( mut self , context : Context ) -> Result < ( ) > {
373
401
while self . remaining_used_size > 0 {
374
402
let item = self . next1 ( ) ?;
375
403
GroupId :: from_u16 ( item. header . group_id . get ( ) ) . ok_or (
@@ -509,6 +537,7 @@ impl<'a> Apcb<'a> {
509
537
510
538
pub fn groups ( & self ) -> Result < ApcbIter < ' _ > > {
511
539
Ok ( ApcbIter {
540
+ context : self . context ,
512
541
buf : self . beginning_of_groups ( ) ?,
513
542
remaining_used_size : self . used_size ,
514
543
} )
@@ -522,13 +551,14 @@ impl<'a> Apcb<'a> {
522
551
/// If ABL0_VERSION is Some, also validates against that AGESA
523
552
/// bootloader version.
524
553
pub fn validate ( & self , abl0_version : Option < u32 > ) -> Result < ( ) > {
525
- self . groups ( ) ?. validate ( ) ?;
554
+ self . groups ( ) ?. validate ( self . context ) ?;
526
555
self . ensure_abl0_compatibility ( abl0_version)
527
556
}
528
557
529
558
pub fn groups_mut ( & mut self ) -> Result < ApcbIterMut < ' _ > > {
530
559
let used_size = self . used_size ;
531
560
Ok ( ApcbIterMut {
561
+ context : self . context ,
532
562
buf : & mut * self . beginning_of_groups_mut ( ) ?,
533
563
remaining_used_size : used_size,
534
564
} )
@@ -1030,6 +1060,7 @@ impl<'a> Apcb<'a> {
1030
1060
signature : [ u8 ; 4 ] ,
1031
1061
) -> Result < GroupMutItem < ' _ > > {
1032
1062
// TODO: insert sorted.
1063
+ let context = self . context ;
1033
1064
1034
1065
if !match group_id {
1035
1066
GroupId :: Psp => signature == * b"PSPG" ,
@@ -1090,7 +1121,7 @@ impl<'a> Apcb<'a> {
1090
1121
) ) ?;
1091
1122
let body_len = body. len ( ) ;
1092
1123
1093
- Ok ( GroupMutItem { header, buf : body, used_size : body_len } )
1124
+ Ok ( GroupMutItem { context , header, buf : body, used_size : body_len } )
1094
1125
}
1095
1126
1096
1127
pub ( crate ) fn calculate_checksum (
@@ -1263,9 +1294,11 @@ impl<'a> Apcb<'a> {
1263
1294
) ) ;
1264
1295
}
1265
1296
}
1266
- let result = Self { backing_store : bs, used_size } ;
1297
+ let result =
1298
+ Self { context : options. context ( ) , backing_store : bs, used_size } ;
1267
1299
1268
- match result. groups ( ) ?. validate ( ) {
1300
+ let context = options. context ( ) ;
1301
+ match result. groups ( ) ?. validate ( context) {
1269
1302
Ok ( _) => { }
1270
1303
Err ( e) => {
1271
1304
return Err ( e) ;
0 commit comments