/* * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package com.sun.media.sound; import java.io.ByteArrayInputStream;import java.io.DataInputStream;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.RandomAccessFile;import java.util.Collection; /** * This class is a pointer to a binary array either in memory or on disk. * * @author Karl Helgason */public class ModelByteBuffer { private ModelByteBuffer root = this; private File file; private long fileoffset; private byte[] buffer; private long offset; private final long len; private class RandomFileInputStream extends InputStream { private RandomAccessFile raf; private long left; private long mark = 0; private long markleft = 0; public RandomFileInputStream() throws IOException { raf = new RandomAccessFile(root.file, "r"); raf.seek(root.fileoffset + arrayOffset()); left = capacity(); } public int available() throws IOException { if (left > Integer.MAX_VALUE) return Integer.MAX_VALUE; return (int)left; } public synchronized void mark(int readlimit) { try { mark = raf.getFilePointer(); markleft = left; } catch (IOException e) { //e.printStackTrace(); } } public boolean markSupported() { return true; } public synchronized void reset() throws IOException { raf.seek(mark); left = markleft; } public long skip(long n) throws IOException { if( n < 0) return 0; if (n > left) n = left; long p = raf.getFilePointer(); raf.seek(p + n); left -= n; return n; } public int read(byte b[], int off, int len) throws IOException { if (len > left) len = (int)left; if (left == 0) return -1; len = raf.read(b, off, len); if (len == -1) return -1; left -= len; return len; } public int read(byte[] b) throws IOException { int len = b.length; if (len > left) len = (int)left; if (left == 0) return -1; len = raf.read(b, 0, len); if (len == -1) return -1; left -= len; return len; } public int read() throws IOException { if (left == 0) return -1; int b = raf.read(); if (b == -1) return -1; left--; return b; } public void close() throws IOException { raf.close(); } } private ModelByteBuffer(ModelByteBuffer parent, long beginIndex, long endIndex, boolean independent) { this.root = parent.root; this.offset = 0; long parent_len = parent.len; if (beginIndex < 0) beginIndex = 0; if (beginIndex > parent_len) beginIndex = parent_len; if (endIndex < 0) endIndex = 0; if (endIndex > parent_len) endIndex = parent_len; if (beginIndex > endIndex) beginIndex = endIndex; offset = beginIndex; len = endIndex - beginIndex; if (independent) { buffer = root.buffer; if (root.file != null) { file = root.file; fileoffset = root.fileoffset + arrayOffset(); offset = 0; } else offset = arrayOffset(); root = this; } } public ModelByteBuffer(byte[] buffer) { this.buffer = buffer; this.offset = 0; this.len = buffer.length; } public ModelByteBuffer(byte[] buffer, int offset, int len) { this.buffer = buffer; this.offset = offset; this.len = len; } public ModelByteBuffer(File file) { this.file = file; this.fileoffset = 0; this.len = file.length(); } public ModelByteBuffer(File file, long offset, long len) { this.file = file; this.fileoffset = offset; this.len = len; } public void writeTo(OutputStream out) throws IOException { if (root.file != null && root.buffer == null) { InputStream is = getInputStream(); byte[] buff = new byte[1024]; int ret; while ((ret = is.read(buff)) != -1) out.write(buff, 0, ret); } else out.write(array(), (int) arrayOffset(), (int) capacity()); } public InputStream getInputStream() { if (root.file != null && root.buffer == null) { try { return new RandomFileInputStream(); } catch (IOException e) { //e.printStackTrace(); return null; } } return new ByteArrayInputStream(array(), (int)arrayOffset(), (int)capacity()); } public ModelByteBuffer subbuffer(long beginIndex) { return subbuffer(beginIndex, capacity()); } public ModelByteBuffer subbuffer(long beginIndex, long endIndex) { return subbuffer(beginIndex, endIndex, false); } public ModelByteBuffer subbuffer(long beginIndex, long endIndex, boolean independent) { return new ModelByteBuffer(this, beginIndex, endIndex, independent); } public byte[] array() { return root.buffer; } public long arrayOffset() { if (root != this) return root.arrayOffset() + offset; return offset; } public long capacity() { return len; } public ModelByteBuffer getRoot() { return root; } public File getFile() { return file; } public long getFilePointer() { return fileoffset; } public static void loadAll(Collection<ModelByteBuffer> col) throws IOException { File selfile = null; RandomAccessFile raf = null; try { for (ModelByteBuffer mbuff : col) { mbuff = mbuff.root; if (mbuff.file == null) continue; if (mbuff.buffer != null) continue; if (selfile == null || !selfile.equals(mbuff.file)) { if (raf != null) { raf.close(); raf = null; } selfile = mbuff.file; raf = new RandomAccessFile(mbuff.file, "r"); } raf.seek(mbuff.fileoffset); byte[] buffer = new byte[(int) mbuff.capacity()]; int read = 0; int avail = buffer.length; while (read != avail) { if (avail - read > 65536) { raf.readFully(buffer, read, 65536); read += 65536; } else { raf.readFully(buffer, read, avail - read); read = avail; } } mbuff.buffer = buffer; mbuff.offset = 0; } } finally { if (raf != null) raf.close(); } } public void load() throws IOException { if (root != this) { root.load(); return; } if (buffer != null) return; if (file == null) { throw new IllegalStateException( "No file associated with this ByteBuffer!"); } DataInputStream is = new DataInputStream(getInputStream()); buffer = new byte[(int) capacity()]; offset = 0; is.readFully(buffer); is.close(); } public void unload() { if (root != this) { root.unload(); return; } if (file == null) { throw new IllegalStateException( "No file associated with this ByteBuffer!"); } root.buffer = null; }}
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.media.sound;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Collection;
/**
* This class is a pointer to a binary array either in memory or on disk.
*
* @author Karl Helgason
*/
public class ModelByteBuffer {
private ModelByteBuffer root = this;
private File file;
private long fileoffset;
private byte[] buffer;
private long offset;
private final long len;
private class RandomFileInputStream extends InputStream {
private RandomAccessFile raf;
private long left;
private long mark = 0;
private long markleft = 0;
public RandomFileInputStream() throws IOException {
raf = new RandomAccessFile(root.file, "r");
raf.seek(root.fileoffset + arrayOffset());
left = capacity();
}
public int available() throws IOException {
if (left > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int)left;
}
public synchronized void mark(int readlimit) {
try {
mark = raf.getFilePointer();
markleft = left;
} catch (IOException e) {
//e.printStackTrace();
}
}
public boolean markSupported() {
return true;
}
public synchronized void reset() throws IOException {
raf.seek(mark);
left = markleft;
}
public long skip(long n) throws IOException {
if( n < 0)
return 0;
if (n > left)
n = left;
long p = raf.getFilePointer();
raf.seek(p + n);
left -= n;
return n;
}
public int read(byte b[], int off, int len) throws IOException {
if (len > left)
len = (int)left;
if (left == 0)
return -1;
len = raf.read(b, off, len);
if (len == -1)
return -1;
left -= len;
return len;
}
public int read(byte[] b) throws IOException {
int len = b.length;
if (len > left)
len = (int)left;
if (left == 0)
return -1;
len = raf.read(b, 0, len);
if (len == -1)
return -1;
left -= len;
return len;
}
public int read() throws IOException {
if (left == 0)
return -1;
int b = raf.read();
if (b == -1)
return -1;
left--;
return b;
}
public void close() throws IOException {
raf.close();
}
}
private ModelByteBuffer(ModelByteBuffer parent,
long beginIndex, long endIndex, boolean independent) {
this.root = parent.root;
this.offset = 0;
long parent_len = parent.len;
if (beginIndex < 0)
beginIndex = 0;
if (beginIndex > parent_len)
beginIndex = parent_len;
if (endIndex < 0)
endIndex = 0;
if (endIndex > parent_len)
endIndex = parent_len;
if (beginIndex > endIndex)
beginIndex = endIndex;
offset = beginIndex;
len = endIndex - beginIndex;
if (independent) {
buffer = root.buffer;
if (root.file != null) {
file = root.file;
fileoffset = root.fileoffset + arrayOffset();
offset = 0;
} else
offset = arrayOffset();
root = this;
}
}
public ModelByteBuffer(byte[] buffer) {
this.buffer = buffer;
this.offset = 0;
this.len = buffer.length;
}
public ModelByteBuffer(byte[] buffer, int offset, int len) {
this.buffer = buffer;
this.offset = offset;
this.len = len;
}
public ModelByteBuffer(File file) {
this.file = file;
this.fileoffset = 0;
this.len = file.length();
}
public ModelByteBuffer(File file, long offset, long len) {
this.file = file;
this.fileoffset = offset;
this.len = len;
}
public void writeTo(OutputStream out) throws IOException {
if (root.file != null && root.buffer == null) {
InputStream is = getInputStream();
byte[] buff = new byte[1024];
int ret;
while ((ret = is.read(buff)) != -1)
out.write(buff, 0, ret);
} else
out.write(array(), (int) arrayOffset(), (int) capacity());
}
public InputStream getInputStream() {
if (root.file != null && root.buffer == null) {
try {
return new RandomFileInputStream();
} catch (IOException e) {
//e.printStackTrace();
return null;
}
}
return new ByteArrayInputStream(array(),
(int)arrayOffset(), (int)capacity());
}
public ModelByteBuffer subbuffer(long beginIndex) {
return subbuffer(beginIndex, capacity());
}
public ModelByteBuffer subbuffer(long beginIndex, long endIndex) {
return subbuffer(beginIndex, endIndex, false);
}
public ModelByteBuffer subbuffer(long beginIndex, long endIndex,
boolean independent) {
return new ModelByteBuffer(this, beginIndex, endIndex, independent);
}
public byte[] array() {
return root.buffer;
}
public long arrayOffset() {
if (root != this)
return root.arrayOffset() + offset;
return offset;
}
public long capacity() {
return len;
}
public ModelByteBuffer getRoot() {
return root;
}
public File getFile() {
return file;
}
public long getFilePointer() {
return fileoffset;
}
public static void loadAll(Collection<ModelByteBuffer> col)
throws IOException {
File selfile = null;
RandomAccessFile raf = null;
try {
for (ModelByteBuffer mbuff : col) {
mbuff = mbuff.root;
if (mbuff.file == null)
continue;
if (mbuff.buffer != null)
continue;
if (selfile == null || !selfile.equals(mbuff.file)) {
if (raf != null) {
raf.close();
raf = null;
}
selfile = mbuff.file;
raf = new RandomAccessFile(mbuff.file, "r");
}
raf.seek(mbuff.fileoffset);
byte[] buffer = new byte[(int) mbuff.capacity()];
int read = 0;
int avail = buffer.length;
while (read != avail) {
if (avail - read > 65536) {
raf.readFully(buffer, read, 65536);
read += 65536;
} else {
raf.readFully(buffer, read, avail - read);
read = avail;
}
}
mbuff.buffer = buffer;
mbuff.offset = 0;
}
} finally {
if (raf != null)
raf.close();
}
}
public void load() throws IOException {
if (root != this) {
root.load();
return;
}
if (buffer != null)
return;
if (file == null) {
throw new IllegalStateException(
"No file associated with this ByteBuffer!");
}
DataInputStream is = new DataInputStream(getInputStream());
buffer = new byte[(int) capacity()];
offset = 0;
is.readFully(buffer);
is.close();
}
public void unload() {
if (root != this) {
root.unload();
return;
}
if (file == null) {
throw new IllegalStateException(
"No file associated with this ByteBuffer!");
}
root.buffer = null;
}
}