Logo Search packages:      
Sourcecode: f-spot version File versions  Download package

Page [] TagLib::Ogg::Paginator::Paginate ( out int  change ) [inline]

Repaginates the pages passed into the current instance to handle changes made to the Xiph comment.

Parameters:
changeA int value reference containing the the difference between the number of pages returned and the number of pages that were added to the class.
Returns:
A Page[] containing the new page collection.

Definition at line 157 of file Paginator.cs.

References TagLib::ListBase< T >::Add(), TagLib::ListBase< T >::Count, TagLib::Ogg::PageHeader::PageSequenceNumber, TagLib::ListBase< T >::RemoveAt(), and TagLib::Ogg::PageHeader::StreamSerialNumber.

            {
                  // Ogg Pagination: Welcome to sucksville!
                  // If you don't understand this, you're not alone.
                  // It is confusing as Hell.
                  
                  // TODO: Document this method, in the mean time, there
                  // is always http://xiph.org/ogg/doc/framing.html
                  
                  if (pages_read == 0) {
                        change = 0;
                        return new Page [0];
                  }
                  
                  int count = pages_read;
                  ByteVectorCollection packets = new ByteVectorCollection (
                        this.packets);
                  PageHeader first_header = (PageHeader) first_page_header;
                  List<Page> pages = new List<Page> ();
                  uint index = 0;
                  bool bos = first_header.PageSequenceNumber == 0;
                  
                  if (bos) {
                        pages.Add (new Page (new ByteVectorCollection (packets [0]), first_header));
                        index ++;
                        packets.RemoveAt (0);
                        count --;
                  }
                  
                  int lacing_per_page = 0xfc;
                  if (count > 0) {
                        int total_lacing_bytes = 0;
                        
                        for (int i = 0; i < packets.Count; i ++)
                              total_lacing_bytes += GetLacingValueLength (
                                    packets, i);
                        
                        lacing_per_page = Math.Min (total_lacing_bytes / count + 1, lacing_per_page);
                  }
                  
                  int lacing_bytes_used = 0;
                  ByteVectorCollection page_packets = new ByteVectorCollection ();
                  bool first_packet_continued = false;
                  
                  while (packets.Count > 0) {
                        int packet_bytes = GetLacingValueLength (packets, 0);
                        int remaining = lacing_per_page - lacing_bytes_used;
                        bool whole_packet = packet_bytes <= remaining;
                        if (whole_packet) {
                              page_packets.Add (packets [0]);
                              lacing_bytes_used += packet_bytes;
                              packets.RemoveAt (0);
                        } else {
                              page_packets.Add (packets [0].Mid (0, remaining * 0xff));
                              packets [0] = packets [0].Mid (remaining * 0xff);
                              lacing_bytes_used += remaining;
                        }
                        
                        if (lacing_bytes_used == lacing_per_page) {
                              pages.Add (new Page (page_packets,
                                    new PageHeader (first_header,
                                          index, first_packet_continued ?
                                          PageFlags.FirstPacketContinued :
                                          PageFlags.None)));
                              page_packets = new ByteVectorCollection ();
                              lacing_bytes_used = 0;
                              index ++;
                              count --;
                              first_packet_continued = !whole_packet;
                        }
                  }
                  
                  if (page_packets.Count > 0) {
                        pages.Add (new Page (page_packets,
                              new PageHeader (
                                    first_header.StreamSerialNumber,
                                    index, first_packet_continued ?
                                    PageFlags.FirstPacketContinued :
                                    PageFlags.None)));
                        index ++;
                        count --;
                  }
                  change = -count;
                  return pages.ToArray ();
            }

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index