Skip to content

Commit d1beb78

Browse files
committed
ogg_pager: Store segment table in PageHeader
1 parent 54cd6ca commit d1beb78

File tree

6 files changed

+40
-35
lines changed

6 files changed

+40
-35
lines changed

ogg_pager/src/header.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ use std::io::{Read, Seek};
44

55
use byteorder::{LittleEndian, ReadBytesExt};
66

7+
pub const PAGE_HEADER_SIZE: usize = 27;
8+
79
/// An OGG page header
8-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
10+
#[derive(Clone, PartialEq, Eq, Debug)]
911
pub struct PageHeader {
1012
/// The position in the stream the page started at
1113
pub start: u64,
@@ -16,6 +18,7 @@ pub struct PageHeader {
1618
pub stream_serial: u32,
1719
/// The page's sequence number
1820
pub sequence_number: u32,
21+
pub(crate) segments: Vec<u8>,
1922
pub(crate) checksum: u32,
2023
}
2124

@@ -34,6 +37,7 @@ impl PageHeader {
3437
abgp,
3538
stream_serial,
3639
sequence_number,
40+
segments: Vec::new(),
3741
checksum: 0,
3842
}
3943
}
@@ -46,7 +50,7 @@ impl PageHeader {
4650
/// * [`PageError::InvalidVersion`]
4751
/// * [`PageError::BadSegmentCount`]
4852
/// * Reader does not have enough data
49-
pub fn read<R>(data: &mut R) -> Result<(Self, Vec<u8>)>
53+
pub fn read<R>(data: &mut R) -> Result<Self>
5054
where
5155
R: Read + Seek,
5256
{
@@ -88,10 +92,16 @@ impl PageHeader {
8892
abgp,
8993
stream_serial,
9094
sequence_number,
95+
segments: segment_table,
9196
checksum,
9297
};
9398

94-
Ok((header, segment_table))
99+
Ok(header)
100+
}
101+
102+
/// Returns the size of the page content, excluding the header
103+
pub fn content_size(&self) -> usize {
104+
self.segments.iter().map(|&b| usize::from(b)).sum::<usize>()
95105
}
96106

97107
/// Returns the page's header type flag

ogg_pager/src/lib.rs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ mod header;
66
mod packets;
77
mod paginate;
88

9-
use std::io::{Read, Seek, SeekFrom};
9+
use std::io::{Read, Seek};
1010

1111
pub use crc::crc32;
1212
pub use error::{PageError, Result};
13-
pub use header::PageHeader;
13+
pub use header::{PageHeader, PAGE_HEADER_SIZE};
1414
pub use packets::{Packets, PacketsIter};
1515
pub use paginate::paginate;
1616

@@ -27,7 +27,6 @@ pub const CONTAINS_LAST_PAGE_OF_BITSTREAM: u8 = 0x04;
2727
#[derive(Clone, PartialEq, Eq, Debug)]
2828
pub struct Page {
2929
content: Vec<u8>,
30-
segments: Vec<u8>,
3130
header: PageHeader,
3231
/// The position in the stream the page ended
3332
pub end: u64,
@@ -49,7 +48,10 @@ impl Page {
4948
/// NOTE: This will write the checksum as is. It is likely [`Page::gen_crc`] will have
5049
/// to be used prior.
5150
pub fn as_bytes(&self) -> Vec<u8> {
52-
let mut bytes = Vec::with_capacity(27 + self.segments.len() + self.content.len());
51+
let segment_table = &self.header.segments;
52+
let num_segments = segment_table.len();
53+
let mut bytes =
54+
Vec::with_capacity(PAGE_HEADER_SIZE + num_segments + self.header.content_size());
5355

5456
bytes.extend(b"OggS");
5557
bytes.push(0); // Version
@@ -58,8 +60,8 @@ impl Page {
5860
bytes.extend(self.header.stream_serial.to_le_bytes());
5961
bytes.extend(self.header.sequence_number.to_le_bytes());
6062
bytes.extend(self.header.checksum.to_le_bytes());
61-
bytes.push(self.segments.len() as u8);
62-
bytes.extend(&self.segments);
63+
bytes.push(num_segments as u8);
64+
bytes.extend(segment_table);
6365
bytes.extend(self.content.iter());
6466

6567
bytes
@@ -73,27 +75,19 @@ impl Page {
7375
///
7476
/// * [`std::io::Error`]
7577
/// * [`PageError`]
76-
pub fn read<V>(data: &mut V, skip_content: bool) -> Result<Self>
78+
pub fn read<V>(data: &mut V) -> Result<Self>
7779
where
7880
V: Read + Seek,
7981
{
80-
let (header, segments) = PageHeader::read(data)?;
82+
let header = PageHeader::read(data)?;
8183

82-
let mut content: Vec<u8> = Vec::new();
83-
let content_len: u16 = segments.iter().map(|&b| u16::from(b)).sum();
84-
85-
if skip_content {
86-
data.seek(SeekFrom::Current(i64::from(content_len)))?;
87-
} else {
88-
content = vec![0; content_len as usize];
89-
data.read_exact(&mut content)?;
90-
}
84+
let mut content = vec![0; header.content_size()];
85+
data.read_exact(&mut content)?;
9186

9287
let end = data.stream_position()?;
9388

9489
Ok(Page {
9590
content,
96-
segments,
9791
header,
9892
end,
9993
})
@@ -131,13 +125,13 @@ impl Page {
131125

132126
let mut p = Page {
133127
content: content[remaining..].to_vec(),
134-
segments: segment_table(remaining),
135128
header: PageHeader {
136129
start: self.end,
137130
header_type_flag: 1,
138131
abgp: 0,
139132
stream_serial: self.header.stream_serial,
140133
sequence_number: self.header.sequence_number + 1,
134+
segments: segment_table(remaining),
141135
checksum: 0,
142136
},
143137
end: self.header().start + content.len() as u64,
@@ -201,21 +195,21 @@ mod tests {
201195
0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02, 0x38, 0x01, 0x80, 0xBB,
202196
0, 0, 0, 0, 0,
203197
],
204-
segments: vec![19],
205198
header: PageHeader {
206199
start: 0,
207200
header_type_flag: 2,
208201
abgp: 0,
209202
stream_serial: 1759377061,
210203
sequence_number: 0,
204+
segments: vec![19],
211205
checksum: 3579522525,
212206
},
213207
end: 47,
214208
};
215209

216210
let content = std::fs::read("test_assets/opus_ident_header.page").unwrap();
217211

218-
let page = Page::read(&mut Cursor::new(content), false).unwrap();
212+
let page = Page::read(&mut Cursor::new(content)).unwrap();
219213

220214
assert_eq!(expected, page);
221215
}

ogg_pager/src/packets.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ impl Packets {
8484
let mut packet_bytes_already_read = None;
8585
let mut current_packet_content;
8686
'outer: loop {
87-
if let Ok((_, segment_table)) = PageHeader::read(data) {
88-
for i in segment_table {
87+
if let Ok(header) = PageHeader::read(data) {
88+
for i in header.segments {
8989
packet_size += i as u64;
9090

9191
if i < 255 {

src/ogg/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ pub(crate) mod write;
1515
use crate::error::Result;
1616
use crate::macros::decode_err;
1717

18-
use std::io::{Read, Seek};
18+
use std::io::{Read, Seek, SeekFrom};
1919

20-
use ogg_pager::Page;
20+
use ogg_pager::{Page, PageHeader};
2121

2222
// Exports
2323

@@ -44,11 +44,12 @@ pub(self) fn find_last_page<R>(data: &mut R) -> Result<Page>
4444
where
4545
R: Read + Seek,
4646
{
47-
let mut last_page = Page::read(data, true)?;
47+
let mut last_page_header = PageHeader::read(data)?;
4848

49-
while let Ok(page) = Page::read(data, true) {
50-
last_page = page
49+
while let Ok(header) = PageHeader::read(data) {
50+
last_page_header = header
5151
}
5252

53-
Ok(last_page)
53+
data.seek(SeekFrom::Start(last_page_header.start))?;
54+
Ok(Page::read(data)?)
5455
}

src/ogg/read.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ where
100100

101101
// TODO: Would be nice if we didn't have to read just to seek and reread immediately
102102
let start = data.stream_position()?;
103-
let (first_page_header, _) = PageHeader::read(data)?;
103+
let first_page_header = PageHeader::read(data)?;
104104

105105
data.seek(SeekFrom::Start(start))?;
106106

src/ogg/write.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ where
9999

100100
// Read the first page header to get the stream serial number
101101
let start = file.stream_position()?;
102-
let (first_page_header, _) = PageHeader::read(file)?;
102+
let first_page_header = PageHeader::read(file)?;
103103

104104
let stream_serial = first_page_header.stream_serial;
105105

@@ -142,7 +142,7 @@ where
142142

143143
let mut pages_reader = Cursor::new(&remaining_file_content[..]);
144144
let mut idx = 0;
145-
while let Ok(mut page) = Page::read(&mut pages_reader, false) {
145+
while let Ok(mut page) = Page::read(&mut pages_reader) {
146146
let header = page.header_mut();
147147
header.sequence_number = pages_written + idx;
148148
page.gen_crc();

0 commit comments

Comments
 (0)