/* * $ProjectName$ * $ProjectRevision$ * ----------------------------------------------------------- * $Id: FileStream.java,v 1.1 2003/04/10 19:48:22 jarnbjo Exp $ * ----------------------------------------------------------- * * $Author: jarnbjo $ * * Description: * * Copyright 2002-2003 Tor-Einar Jarnbjo * ----------------------------------------------------------- * * Change History * ----------------------------------------------------------- * $Log: FileStream.java,v $ * Revision 1.1 2003/04/10 19:48:22 jarnbjo * no message * * */ package sound.jarnbjo.ogg; import java.io.*; import java.util.*; /** * Implementation of the <code>PhysicalOggStream</code> interface for accessing * normal disk files. */ public class FileStream implements PhysicalOggStream { private boolean closed=false; private RandomAccessFile source; private long[] pageOffsets; private long numberOfSamples=-1; private HashMap logicalStreams=new HashMap(); /** * Creates access to the specified file through the <code>PhysicalOggStream</code> interface. * The specified source file must have been opened for reading. * * @param source the file to read from * * @throws OggFormatException if the stream format is incorrect * @throws IOException if some other IO error occurs when reading the file */ public FileStream(RandomAccessFile source) throws OggFormatException, IOException { this.source=source; ArrayList po=new ArrayList(); int pageNumber=0; try { while(true) { po.add(new Long(this.source.getFilePointer())); // skip data if pageNumber>0 OggPage op=getNextPage(pageNumber>0); if(op==null) { break; } LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber()); if(los==null) { los=new LogicalOggStreamImpl(this, op.getStreamSerialNumber()); logicalStreams.put(new Integer(op.getStreamSerialNumber()), los); } if(pageNumber==0) { los.checkFormat(op); } los.addPageNumberMapping(pageNumber); los.addGranulePosition(op.getAbsoluteGranulePosition()); if(pageNumber>0) { this.source.seek(this.source.getFilePointer()+op.getTotalLength()); } pageNumber++; } } catch(EndOfOggStreamException e) { // ok } catch(IOException e) { throw e; } //System.out.println("pageNumber: "+pageNumber); this.source.seek(0L); pageOffsets=new long[po.size()]; int i=0; Iterator iter=po.iterator(); while(iter.hasNext()) { pageOffsets[i++]=((Long)iter.next()).longValue(); } } public Collection getLogicalStreams() { return logicalStreams.values(); } public boolean isOpen() { return !closed; } public void close() throws IOException { closed=true; source.close(); } private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException { return getNextPage(false); } private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException { return OggPage.create(source, skipData); } public OggPage getOggPage(int index) throws IOException { source.seek(pageOffsets[index]); return OggPage.create(source); } private LogicalOggStream getLogicalStream(int serialNumber) { return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber)); } public void setTime(long granulePosition) throws IOException { for(Iterator iter=logicalStreams.values().iterator(); iter.hasNext(); ) { LogicalOggStream los=(LogicalOggStream)iter.next(); los.setTime(granulePosition); } } /** * @return always <code>true</code> */ public boolean isSeekable() { return true; } }