1
1
pub mod init {
2
2
#![ allow( unused) ]
3
+
4
+ use crate :: file:: decode;
3
5
use crate :: { File , State } ;
4
6
use memmap2:: Mmap ;
5
7
use std:: path:: { Path , PathBuf } ;
6
8
7
9
mod error {
10
+ use crate :: file:: decode;
8
11
use quick_error:: quick_error;
9
12
10
13
quick_error ! {
@@ -15,6 +18,11 @@ pub mod init {
15
18
source( err)
16
19
from( )
17
20
}
21
+ DecodeHeader ( err: decode:: header:: Error ) {
22
+ display( "The header could not be understood" )
23
+ source( err)
24
+ from( )
25
+ }
18
26
}
19
27
}
20
28
}
@@ -31,6 +39,8 @@ pub mod init {
31
39
( data, filetime:: FileTime :: from_last_modification_time ( & file. metadata ( ) ?) )
32
40
} ;
33
41
42
+ let ( version, num_entries, data) = decode:: header ( & data) ?;
43
+
34
44
Ok ( File {
35
45
state : State { timestamp : mtime } ,
36
46
path,
@@ -40,25 +50,55 @@ pub mod init {
40
50
}
41
51
42
52
pub mod decode {
53
+ use crate :: Version ;
54
+
43
55
pub mod header {
44
56
mod error {
45
57
use quick_error:: quick_error;
46
58
47
59
quick_error ! {
48
60
#[ derive( Debug ) ]
49
61
pub enum Error {
50
- Io ( err: std:: io:: Error ) {
51
- display( "An IO error occurred while opening the index" )
52
- source( err)
53
- from( )
62
+ Corrupt ( message: & ' static str ) {
63
+ display( "{}" , message)
64
+ }
65
+ UnsupportedVersion ( version: u32 ) {
66
+ display( "Index version {} is not supported" , version)
54
67
}
55
68
}
56
69
}
57
70
}
58
71
pub use error:: Error ;
59
72
}
60
73
61
- fn header ( data : & [ u8 ] ) -> Result < ( crate :: Version , & [ u8 ] ) , header:: Error > {
62
- todo ! ( "header parsing" )
74
+ pub ( crate ) fn header ( data : & [ u8 ] ) -> Result < ( crate :: Version , u32 , & [ u8 ] ) , header:: Error > {
75
+ if data. len ( ) < 3 * 4 {
76
+ return Err ( header:: Error :: Corrupt ( "The header is truncated" ) ) ;
77
+ }
78
+
79
+ const SIGNATURE : & [ u8 ] = b"DIRC" ;
80
+ let ( signature, data) = data. split_at ( 4 ) ;
81
+ if signature != SIGNATURE {
82
+ return Err ( header:: Error :: Corrupt (
83
+ "Signature mismatch - this doesn't claim to be a header file" ,
84
+ ) ) ;
85
+ }
86
+
87
+ let ( version, data) = data. split_at ( 4 ) ;
88
+ let version = match read_u32 ( version) {
89
+ 2 => Version :: V2 ,
90
+ 3 => Version :: V3 ,
91
+ 4 => Version :: V4 ,
92
+ unknown => return Err ( header:: Error :: UnsupportedVersion ( unknown) ) ,
93
+ } ;
94
+ let ( entries, data) = data. split_at ( 4 ) ;
95
+ let entries = read_u32 ( entries) ;
96
+
97
+ Ok ( ( version, entries, data) )
98
+ }
99
+
100
+ #[ inline]
101
+ fn read_u32 ( b : & [ u8 ] ) -> u32 {
102
+ u32:: from_be_bytes ( b. try_into ( ) . unwrap ( ) )
63
103
}
64
104
}
0 commit comments