11use crate :: error:: Result ;
22use crate :: {
33 segment_table, Page , PageHeader , CONTAINS_FIRST_PAGE_OF_BITSTREAM ,
4- CONTAINS_LAST_PAGE_OF_BITSTREAM , CONTINUED_PACKET , MAX_CONTENT_SIZE ,
4+ CONTAINS_LAST_PAGE_OF_BITSTREAM , CONTINUED_PACKET , MAX_WRITTEN_CONTENT_SIZE ,
5+ MAX_WRITTEN_SEGMENT_COUNT ,
56} ;
67
78use std:: io:: Read ;
@@ -33,13 +34,13 @@ impl PaginateContext {
3334 } ,
3435 pos : 0 ,
3536 idx : 0 ,
36- remaining_page_size : MAX_CONTENT_SIZE ,
37+ remaining_page_size : MAX_WRITTEN_CONTENT_SIZE ,
3738 current_packet_len : 0 ,
3839 }
3940 }
4041
41- fn flush ( & mut self , content : & mut Vec < u8 > , segments : & mut Vec < u8 > ) {
42- let header = PageHeader {
42+ fn flush ( & mut self , content : & mut Vec < u8 > , segment_table : & mut Vec < u8 > ) {
43+ let mut header = PageHeader {
4344 start : self . pos ,
4445 header_type_flag : {
4546 match self . flags . first_page {
@@ -60,31 +61,44 @@ impl PaginateContext {
6061 } ,
6162 stream_serial : self . stream_serial ,
6263 sequence_number : self . idx as u32 ,
64+ segments : Vec :: new ( ) ,
6365 // No need to calculate this yet
6466 checksum : 0 ,
6567 } ;
6668
6769 let content = core:: mem:: take ( content) ;
68- let segments = core:: mem:: take ( segments) ;
69-
7070 let content_len = content. len ( ) ;
7171 self . pos += content_len as u64 ;
7272
73+ // Moving on to a new packet
74+ if self . pos > self . current_packet_len as u64 {
75+ self . flags . packet_spans_multiple_pages = false ;
76+ }
77+
78+ // We need to determine how many segments our page content takes up.
79+ // If it takes up the remainder of the segment table for the entire packet,
80+ // we'll just consume it as is.
81+ let segments_occupied = if content_len >= 255 {
82+ content_len / 255
83+ } else {
84+ 1
85+ } ;
86+
87+ if self . flags . packet_spans_multiple_pages {
88+ header. segments = segment_table. drain ( ..segments_occupied) . collect ( ) ;
89+ } else {
90+ header. segments = core:: mem:: take ( segment_table) ;
91+ }
92+
7393 self . pages . push ( Page {
7494 content,
75- segments,
7695 header,
7796 end : self . pos ,
7897 } ) ;
7998
8099 self . idx += 1 ;
81100 self . flags . packet_finished_on_page = false ;
82- self . remaining_page_size = MAX_CONTENT_SIZE ;
83-
84- // Moving on to a new packet
85- if self . pos > self . current_packet_len as u64 {
86- self . flags . packet_spans_multiple_pages = false ;
87- }
101+ self . remaining_page_size = MAX_WRITTEN_CONTENT_SIZE ;
88102 }
89103}
90104
@@ -117,8 +131,6 @@ pub fn paginate<'a, I: 'a>(
117131where
118132 I : IntoIterator < Item = & ' a [ u8 ] > ,
119133{
120- const MAX_SEGMENT_COUNT : usize = 255 ;
121-
122134 let mut ctx = PaginateContext :: new ( abgp, stream_serial, flags) ;
123135
124136 let mut packets_iter = packets. into_iter ( ) ;
@@ -129,14 +141,15 @@ where
129141 } ;
130142 ctx. current_packet_len = packet. len ( ) ;
131143
132- let mut segments = Vec :: with_capacity ( 255 ) ;
144+ let mut segments = segment_table ( packet . len ( ) ) ;
133145 let mut page_content = Vec :: new ( ) ;
134146
135147 loop {
136148 if !ctx. flags . packet_spans_multiple_pages && !ctx. flags . first_page {
137149 match packets_iter. next ( ) {
138150 Some ( packet_) => {
139151 packet = packet_;
152+ segments. append ( & mut segment_table ( packet. len ( ) ) ) ;
140153 ctx. current_packet_len = packet. len ( ) ;
141154 ctx. flags . fresh_packet = true ;
142155 } ,
@@ -150,30 +163,30 @@ where
150163 . take ( ctx. remaining_page_size as u64 )
151164 . read_to_end ( & mut page_content) ?;
152165 ctx. remaining_page_size -= bytes_read;
153- packet = & packet[ bytes_read..] ;
154-
155- segments. append ( & mut segment_table ( bytes_read) ?) ;
156- let remaining_segments = MAX_SEGMENT_COUNT - segments. len ( ) ;
157-
158- // We have a maximum of 255 segments available per page, if we require more than
159- // is left in the segment table, we'll have to split the packet into multiple pages.
160- let segments_required = ( packet. len ( ) / 255 ) + 1 ;
161- ctx. flags . packet_spans_multiple_pages = segments_required > remaining_segments;
162166
167+ packet = & packet[ bytes_read..] ;
163168 // We need to indicate whether or not any packet was finished on this page.
164169 // This is used for the absolute granule position.
165170 if packet. is_empty ( ) {
166171 ctx. flags . packet_finished_on_page = true ;
167172 }
168173
169174 // The first packet of the bitstream must have its own page, unlike any other packet.
170- let first_packet_finished_on_page = ctx. flags . first_page
171- && ctx. header_flags & CONTAINS_FIRST_PAGE_OF_BITSTREAM != 0
172- && ctx. flags . packet_finished_on_page ;
175+ let first_page_of_bitstream = ctx. header_flags & CONTAINS_FIRST_PAGE_OF_BITSTREAM != 0 ;
176+ let first_packet_finished_on_page =
177+ ctx. flags . first_page && first_page_of_bitstream && ctx. flags . packet_finished_on_page ;
178+
179+ // We have a maximum of `MAX_WRITTEN_SEGMENT_COUNT` segments available per page, if we require more than
180+ // is left in the segment table, we'll have to split the packet into multiple pages.
181+ let segments_required = ( packet. len ( ) / MAX_WRITTEN_SEGMENT_COUNT ) + 1 ;
182+ let remaining_segments = MAX_WRITTEN_SEGMENT_COUNT . saturating_sub ( segments. len ( ) ) ;
183+ ctx. flags . packet_spans_multiple_pages = segments_required > remaining_segments;
173184
174185 if first_packet_finished_on_page
175186 // We've completely filled this page, we need to flush before moving on
176187 || ( ctx. remaining_page_size == 0 || remaining_segments == 0 )
188+ // We've read all this packet has to offer
189+ || packet. is_empty ( )
177190 {
178191 ctx. flush ( & mut page_content, & mut segments) ;
179192 }
0 commit comments