summaryrefslogtreecommitdiff
path: root/songdbj/org/tritonus/lowlevel/pogg/SyncState.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/org/tritonus/lowlevel/pogg/SyncState.java')
-rw-r--r--songdbj/org/tritonus/lowlevel/pogg/SyncState.java339
1 files changed, 0 insertions, 339 deletions
diff --git a/songdbj/org/tritonus/lowlevel/pogg/SyncState.java b/songdbj/org/tritonus/lowlevel/pogg/SyncState.java
deleted file mode 100644
index 4246808bd3..0000000000
--- a/songdbj/org/tritonus/lowlevel/pogg/SyncState.java
+++ /dev/null
@@ -1,339 +0,0 @@
1/*
2 * SyncState.java
3 *
4 * This file is part of Tritonus: http://www.tritonus.org/
5 */
6
7/*
8 * Copyright (c) 2000 - 2005 by Matthias Pfisterer
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25/*
26|<--- this code is formatted to fit into 80 columns --->|
27*/
28
29package org.tritonus.lowlevel.pogg;
30
31import org.tritonus.share.TDebug;
32
33
34/** Wrapper for ogg_sync_state.
35 */
36public class SyncState
37{
38 /** The stream buffer.
39 This points to a buffer that holds the incoming data from a stream
40 until the data is emitted in form of a page.
41 */
42 private byte[] m_abData;
43
44 /** The number of bytes in the stream buffer that are used. This
45 always counts from the beginning of the buffer. So
46 m_abData[m_nFill] is the first free byte in the buffer.
47 */
48 private int m_nFill;
49
50 /** Number of bytes that have been used to construct a returned
51 page. This is counted from the beginning of the
52 buffer. m_abData[m_nReturned] is the first valid byte in the
53 buffer.
54 */
55 private int m_nReturned;
56
57 /**
58 */
59 private boolean m_bUnsynced;
60
61 /**
62 */
63 private int m_nHeaderBytes;
64
65 /**
66 */
67 private int m_nBodyBytes;
68
69 /** Page object for re-calculating the checksum.
70 */
71 private Page m_tmpPage;
72
73 /** Storage for the checksum saved from the page.
74 */
75 private byte[] m_abChecksum;
76
77
78 public SyncState()
79 {
80 if (TDebug.TraceOggNative) { TDebug.out("SyncState.<init>(): begin"); }
81 m_tmpPage = new Page();
82 m_abChecksum = new byte[4];
83 if (TDebug.TraceOggNative) { TDebug.out("SyncState.<init>(): end"); }
84 }
85
86
87 // TODO: remove calls to this method
88 public void free()
89 {
90 }
91
92
93
94 /** Calls ogg_sync_init().
95 */
96 public void init()
97 {
98 m_abData = null;
99 m_nFill = 0;
100 m_nReturned = 0;
101 m_bUnsynced = false;
102 m_nHeaderBytes = 0;
103 m_nBodyBytes = 0;
104 }
105
106
107 /** Calls ogg_sync_clear().
108 */
109 public void clear()
110 {
111 init();
112 }
113
114
115 /** Calls ogg_sync_reset().
116 */
117 public void reset()
118 {
119 m_nFill = 0;
120 m_nReturned = 0;
121 m_bUnsynced = false;
122 m_nHeaderBytes = 0;
123 m_nBodyBytes = 0;
124 }
125
126
127 /** Writes to the stream buffer.
128 */
129 public int write(byte[] abBuffer, int nBytes)
130 {
131 /* Clear out space that has been previously returned. */
132 if (m_nReturned > 0)
133 {
134 m_nFill -= m_nReturned;
135 if (m_nFill > 0)
136 {
137 System.arraycopy(m_abData, m_nReturned,
138 m_abData, 0,
139 m_nFill);
140 }
141 m_nReturned = 0;
142 }
143
144 /* Check for enough space in the stream buffer and if it is
145 * allocated at all. If there isn't sufficient space, extend
146 * the buffer. */
147 if (m_abData == null || nBytes > m_abData.length - m_nFill)
148 {
149 int nNewSize = nBytes + m_nFill + 4096;
150 byte[] abOldBuffer = m_abData;
151 m_abData = new byte[nNewSize];
152 if (abOldBuffer != null)
153 {
154 System.arraycopy(abOldBuffer, 0, m_abData, 0, m_nFill);
155 }
156 }
157
158 /* Now finally fill with the new data. */
159 System.arraycopy(abBuffer, 0, m_abData, m_nFill, nBytes);
160 m_nFill += nBytes;
161 return 0;
162 }
163
164
165 /** Synchronizes the stream. This method looks if there is a
166 complete, valid page in the stream buffer. If a page is found,
167 it is returned in the passed Page object.
168
169 @param page The Page to store the result of the page search
170 in. The content is only changed if the return value is > 0.
171
172 @return if a page has been found at the current location, the
173 length of the page in bytes is returned. If not enough data
174 for a page is available in the stream buffer, 0 is
175 returned. If data in the stream buffer has been skipped
176 because there is no page at the current position, the skip
177 amount in bytes is returned as a negative number.
178 */
179 public int pageseek(Page page)
180 {
181 int nPage = m_nReturned;
182 int nBytes = m_nFill - m_nReturned;
183
184 if (m_nHeaderBytes == 0)
185 {
186 if (nBytes < 27)
187 {
188 /* Not enough data for a header. */
189 return 0;
190 }
191 /* Verify capture pattern. */
192 if (m_abData[nPage] != (byte) 'O' ||
193 m_abData[nPage + 1] != (byte) 'g' ||
194 m_abData[nPage + 2] != (byte) 'g' ||
195 m_abData[nPage + 3] != (byte) 'S')
196 {
197 TDebug.out("wrong capture pattern");
198 return syncFailure();
199 }
200 int nHeaderBytes = (m_abData[nPage + 26] & 0xFF) + 27;
201 if (nBytes < nHeaderBytes)
202 {
203 /* Not enough data for header + segment table. */
204 return 0;
205 }
206 /* Count up body length in the segment table. */
207 for (int i = 0; i < (m_abData[nPage + 26] & 0xFF); i++)
208 {
209 m_nBodyBytes += (m_abData[nPage + 27 + i] & 0xFF);
210 }
211 m_nHeaderBytes = nHeaderBytes;
212 }
213
214 if (m_nBodyBytes + m_nHeaderBytes > nBytes)
215 {
216 /* Not enough data for the whole packet. */
217 return 0;
218 }
219
220 /* Save the original checksum, set it to zero and recalculate it. */
221 System.arraycopy(m_abData, nPage + 22, m_abChecksum, 0, 4);
222 m_abData[nPage + 22] = 0;
223 m_abData[nPage + 23] = 0;
224 m_abData[nPage + 24] = 0;
225 m_abData[nPage + 25] = 0;
226
227 m_tmpPage.setData(m_abData, nPage, m_nHeaderBytes,
228 m_abData, nPage + m_nHeaderBytes, m_nBodyBytes);
229// TDebug.out("temporary page:");
230// byte[] abHeader = m_tmpPage.getHeader();
231// TDebug.out("H0:" + m_abData[nPage + 0] + " - " + abHeader[0]);
232// TDebug.out("H1:" + m_abData[nPage + 1] + " - " + abHeader[1]);
233// TDebug.out("H2:" + m_abData[nPage + 2] + " - " + abHeader[2]);
234// TDebug.out("H3:" + m_abData[nPage + 3] + " - " + abHeader[3]);
235// TDebug.out("" + m_abChecksum[0] + " - " + abHeader[22]);
236// TDebug.out("" + m_abChecksum[1] + " - " + abHeader[23]);
237// TDebug.out("" + m_abChecksum[2] + " - " + abHeader[24]);
238// TDebug.out("" + m_abChecksum[3] + " - " + abHeader[25]);
239 m_tmpPage.setChecksum();
240 byte[] abHeader = m_tmpPage.getHeader();
241 //m_tmpPage.free();
242 if (abHeader[22] != m_abChecksum[0] ||
243 abHeader[23] != m_abChecksum[1] ||
244 abHeader[24] != m_abChecksum[2] ||
245 abHeader[25] != m_abChecksum[3])
246 {
247 TDebug.out("wrong checksum");
248 TDebug.out("" + m_abChecksum[0] + " - " + abHeader[22]);
249 TDebug.out("" + m_abChecksum[1] + " - " + abHeader[23]);
250 TDebug.out("" + m_abChecksum[2] + " - " + abHeader[24]);
251 TDebug.out("" + m_abChecksum[3] + " - " + abHeader[25]);
252 /* Copy back the saved checksum. */
253 System.arraycopy(m_abChecksum, 0, m_abData, nPage + 22, 4);
254 return syncFailure();
255 }
256
257 /* Ok, we have a correct page to emit. */
258 page.setData(m_abData, nPage, m_nHeaderBytes,
259 m_abData, nPage + m_nHeaderBytes, m_nBodyBytes);
260 m_bUnsynced = false;
261 nBytes = m_nHeaderBytes + m_nBodyBytes;
262 m_nReturned += nBytes;
263 m_nHeaderBytes = 0;
264 m_nBodyBytes = 0;
265 return nBytes;
266 }
267
268
269 /** Auxiliary method for pageseek().
270 */
271 private int syncFailure()
272 {
273 int nPage = m_nReturned;
274 int nBytes = m_nFill - m_nReturned;
275 m_nHeaderBytes = 0;
276 m_nBodyBytes = 0;
277 int nNext = -1;
278 for (int i = 0; i < nBytes - 1; i++)
279 {
280 if (m_abData[nPage + 1 + i] == (byte) 'O')
281 {
282 nNext = nPage + 1 + i;
283 break;
284 }
285 }
286 if (nNext == -1)
287 {
288 nNext = m_nFill;
289 }
290 m_nReturned = nNext;
291 return -(nNext - nPage);
292 }
293
294
295
296
297 /** Returns a page from the stream buffer, if possible. This
298 method searches the current data in the stream buffer for the
299 beginning of a page. If there is one, it is returned in the
300 passed Page object. A synchronization error is signaled by a
301 return value of -1. However, only the first synchronization
302 error is reported. Consecutive sync errors are suppressed.
303
304 @param page The Page to store the result of the page search
305 in. The content is only changed if the return value is 1.
306
307 @return 1 if a page has been found, 0 if there is not enough
308 data, -1 if a synchronization error occured.
309 */
310 public int pageOut(Page page)
311 {
312 while (true)
313 {
314 int nReturn = pageseek(page);
315 if (nReturn > 0)
316 {
317 return 1;
318 }
319 else if (nReturn == 0)
320 {
321 return 0;
322 }
323 else // nReturn < 0
324 {
325 if (! m_bUnsynced)
326 {
327 m_bUnsynced = true;
328 return -1;
329 }
330 }
331 }
332 }
333}
334
335
336
337
338
339/*** SyncState.java ***/