summaryrefslogtreecommitdiff
path: root/songdbj/de/jarnbjo/ogg/CachedUrlStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/de/jarnbjo/ogg/CachedUrlStream.java')
-rw-r--r--songdbj/de/jarnbjo/ogg/CachedUrlStream.java252
1 files changed, 0 insertions, 252 deletions
diff --git a/songdbj/de/jarnbjo/ogg/CachedUrlStream.java b/songdbj/de/jarnbjo/ogg/CachedUrlStream.java
deleted file mode 100644
index 86f792e272..0000000000
--- a/songdbj/de/jarnbjo/ogg/CachedUrlStream.java
+++ /dev/null
@@ -1,252 +0,0 @@
1/*
2 * $ProjectName$
3 * $ProjectRevision$
4 * -----------------------------------------------------------
5 * $Id$
6 * -----------------------------------------------------------
7 *
8 * $Author$
9 *
10 * Description:
11 *
12 * Copyright 2002-2003 Tor-Einar Jarnbjo
13 * -----------------------------------------------------------
14 *
15 * Change History
16 * -----------------------------------------------------------
17 * $Log$
18 * Revision 1.1 2005/07/11 15:42:36 hcl
19 * Songdb java version, source. only 1.5 compatible
20 *
21 * Revision 1.1.1.1 2004/04/04 22:09:12 shred
22 * First Import
23 *
24 * Revision 1.1 2003/04/10 19:48:22 jarnbjo
25 * no message
26 *
27 *
28 */
29
30package de.jarnbjo.ogg;
31
32import java.io.*;
33import java.net.*;
34import java.util.*;
35
36/**
37 * Implementation of the <code>PhysicalOggStream</code> interface for reading
38 * and caching an Ogg stream from a URL. This class reads the data as fast as
39 * possible from the URL, caches it locally either in memory or on disk, and
40 * supports seeking within the available data.
41 */
42
43public class CachedUrlStream implements PhysicalOggStream {
44
45 private boolean closed=false;
46 private URLConnection source;
47 private InputStream sourceStream;
48 private Object drainLock=new Object();
49 private RandomAccessFile drain;
50 private byte[] memoryCache;
51 private ArrayList pageOffsets=new ArrayList();
52 private ArrayList pageLengths=new ArrayList();
53 private long numberOfSamples=-1;
54 private long cacheLength;
55
56 private HashMap logicalStreams=new HashMap();
57
58 private LoaderThread loaderThread;
59
60 /**
61 * Creates an instance of this class, using a memory cache.
62 */
63
64 public CachedUrlStream(URL source) throws OggFormatException, IOException {
65 this(source, null);
66 }
67
68 /**
69 * Creates an instance of this class, using the specified file as cache. The
70 * file is not automatically deleted when this class is disposed.
71 */
72
73 public CachedUrlStream(URL source, RandomAccessFile drain) throws OggFormatException, IOException {
74
75 this.source=source.openConnection();
76
77 if(drain==null) {
78 int contentLength=this.source.getContentLength();
79 if(contentLength==-1) {
80 throw new IOException("The URLConncetion's content length must be set when operating with a in-memory cache.");
81 }
82 memoryCache=new byte[contentLength];
83 }
84
85 this.drain=drain;
86 this.sourceStream=this.source.getInputStream();
87
88 loaderThread=new LoaderThread(sourceStream, drain, memoryCache);
89 new Thread(loaderThread).start();
90
91 while(!loaderThread.isBosDone() || pageOffsets.size()<20) {
92 System.out.print("pageOffsets.size(): "+pageOffsets.size()+"\r");
93 try {
94 Thread.sleep(200);
95 }
96 catch (InterruptedException ex) {
97 }
98 }
99 System.out.println();
100 System.out.println("caching "+pageOffsets.size()+"/20 pages\r");
101 }
102
103 public Collection getLogicalStreams() {
104 return logicalStreams.values();
105 }
106
107 public boolean isOpen() {
108 return !closed;
109 }
110
111 public void close() throws IOException {
112 closed=true;
113 sourceStream.close();
114 }
115
116 public long getCacheLength() {
117 return cacheLength;
118 }
119
120 /*
121 private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException {
122 return getNextPage(false);
123 }
124
125 private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException {
126 return OggPage.create(sourceStream, skipData);
127 }
128 */
129
130 public OggPage getOggPage(int index) throws IOException {
131 synchronized(drainLock) {
132 Long offset=(Long)pageOffsets.get(index);
133 Long length=(Long)pageLengths.get(index);
134 if(offset!=null) {
135 if(drain!=null) {
136 drain.seek(offset.longValue());
137 return OggPage.create(drain);
138 }
139 else {
140 byte[] tmpArray=new byte[length.intValue()];
141 System.arraycopy(memoryCache, offset.intValue(), tmpArray, 0, length.intValue());
142 return OggPage.create(tmpArray);
143 }
144 }
145 else {
146 return null;
147 }
148 }
149 }
150
151 private LogicalOggStream getLogicalStream(int serialNumber) {
152 return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber));
153 }
154
155 public void setTime(long granulePosition) throws IOException {
156 for(Iterator iter=logicalStreams.values().iterator(); iter.hasNext(); ) {
157 LogicalOggStream los=(LogicalOggStream)iter.next();
158 los.setTime(granulePosition);
159 }
160 }
161
162 public class LoaderThread implements Runnable {
163
164 private InputStream source;
165 private RandomAccessFile drain;
166 private byte[] memoryCache;
167
168 private boolean bosDone=false;
169
170 private int pageNumber;
171
172 public LoaderThread(InputStream source, RandomAccessFile drain, byte[] memoryCache) {
173 this.source=source;
174 this.drain=drain;
175 this.memoryCache=memoryCache;
176 }
177
178 public void run() {
179 try {
180 boolean eos=false;
181 byte[] buffer=new byte[8192];
182 while(!eos) {
183 OggPage op=OggPage.create(source);
184 synchronized (drainLock) {
185 int listSize=pageOffsets.size();
186
187 long pos=
188 listSize>0?
189 ((Long)pageOffsets.get(listSize-1)).longValue()+
190 ((Long)pageLengths.get(listSize-1)).longValue():
191 0;
192
193 byte[] arr1=op.getHeader();
194 byte[] arr2=op.getSegmentTable();
195 byte[] arr3=op.getData();
196
197 if(drain!=null) {
198 drain.seek(pos);
199 drain.write(arr1);
200 drain.write(arr2);
201 drain.write(arr3);
202 }
203 else {
204 System.arraycopy(arr1, 0, memoryCache, (int)pos, arr1.length);
205 System.arraycopy(arr2, 0, memoryCache, (int)pos+arr1.length, arr2.length);
206 System.arraycopy(arr3, 0, memoryCache, (int)pos+arr1.length+arr2.length, arr3.length);
207 }
208
209 pageOffsets.add(new Long(pos));
210 pageLengths.add(new Long(arr1.length+arr2.length+arr3.length));
211 }
212
213 if(!op.isBos()) {
214 bosDone=true;
215 //System.out.println("bosDone=true;");
216 }
217 if(op.isEos()) {
218 eos=true;
219 }
220
221 LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber());
222 if(los==null) {
223 los=new LogicalOggStreamImpl(CachedUrlStream.this, op.getStreamSerialNumber());
224 logicalStreams.put(new Integer(op.getStreamSerialNumber()), los);
225 los.checkFormat(op);
226 }
227
228 los.addPageNumberMapping(pageNumber);
229 los.addGranulePosition(op.getAbsoluteGranulePosition());
230
231 pageNumber++;
232 cacheLength=op.getAbsoluteGranulePosition();
233 //System.out.println("read page: "+pageNumber);
234 }
235 }
236 catch(EndOfOggStreamException e) {
237 // ok
238 }
239 catch(IOException e) {
240 e.printStackTrace();
241 }
242 }
243
244 public boolean isBosDone() {
245 return bosDone;
246 }
247 }
248
249 public boolean isSeekable() {
250 return true;
251 }
252} \ No newline at end of file