Hey ... if you are trying to create a datasource from a stream, try this ... it worked for me. Two things you need before you can do this. First, you need to take the stream and convert it to a byte buffer (easy enough). Secondly, you need to know the content type of the stream. If this isn't what you are looking for, let me know. I may be able to help further. I do have a question for you. Assuming I have a stream of data that has no header (header info has already been parsed), BUT, I do have the info in the header (and I don;t want to rebuild it), is there some way I can use the Formats class to create a datasource instead of using a content descriptor? Thanks
Chad
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.PullDataSource;
import java.nio.ByteBuffer;
import java.io.IOException;
import javax.media.MediaLocator;
import javax.media.Duration;
import javax.media.Time;
/**
*
* @author Chad McMillan
*/
public class ByteBufferDataSource extends PullDataSource {
protected ContentDescriptor contentType;
protected SeekableStream[] sources;
protected boolean connected;
protected ByteBuffer anInput;
protected ByteBufferDataSource(){
}
/**
* Construct a <CODE>ByteBufferDataSource</CODE> from a <CODE>ByteBuffer</CODE>.
* @param source The <CODE>ByteBuffer</CODE> that is used to create the
* the <CODE>DataSource</CODE>.
*/
public ByteBufferDataSource(ByteBuffer input, String contentType) throws IOException {
anInput = input;
this.contentType = new ContentDescriptor(contentType);
connected = false;
}
/**
* Open a connection to the source described by
* the <CODE>ByteBuffer/CODE>.
* <p>
*
* The <CODE>connect</CODE> method initiates communication with the source.
*
* @exception IOException Thrown if there are IO problems
* when <CODE>connect</CODE> is called.
*/
public void connect() throws java.io.IOException {
connected = true;
sources = new SeekableStream [1];
sources[0] = new SeekableStream(anInput);
}
/**
* Close the connection to the source described by the locator.
* <p>
* The <CODE>disconnect</CODE> method frees resources used to maintain a
* connection to the source.
* If no resources are in use, <CODE>disconnect</CODE> is ignored.
* If <CODE>stop</CODE> hasn't already been called,
* calling <CODE>disconnect</CODE> implies a stop.
*
*/
public void disconnect() {
if(connected) {
sources[0].close();
connected = false;
}
}
/**
* Get a string that describes the content-type of the media
* that the source is providing.
* <p>
* It is an error to call <CODE>getContentType</CODE> if the source is
* not connected.
*
* @return The name that describes the media content.
*/
public String getContentType() {
if( !connected) {
throw new java.lang.Error("Source is unconnected."

;
}
return contentType.getContentType();
}
public Object getControl(String str) {
return null;
}
public Object[] getControls() {
return new Object[0];
}
public javax.media.Time getDuration() {
return Duration.DURATION_UNKNOWN;
}
/**
* Get the collection of streams that this source
* manages. The collection of streams is entirely
* content dependent. The MIME type of this
* <CODE>DataSource</CODE> provides the only indication of
* what streams can be available on this connection.
*
* @return The collection of streams for this source.
*/
public javax.media.protocol.PullSourceStream[] getStreams() {
if( !connected) {
throw new java.lang.Error("Source is unconnected."

;
}
return sources;
}
/**
* Initiate data-transfer. The <CODE>start</CODE> method must be
* called before data is available.
*(You must call <CODE>connect</CODE> before calling <CODE>start</CODE>.)
*
* @exception IOException Thrown if there are IO problems with the source
* when <CODE>start</CODE> is called.
*/
public void start() throws IOException {
}
/**
* Stop the data-transfer.
* If the source has not been connected and started,
* <CODE>stop</CODE> does nothing.
*/
public void stop() throws IOException {
}
}
(and for your stream)
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import javax.media.protocol.PullSourceStream;
import javax.media.protocol.Seekable;
import javax.media.protocol.ContentDescriptor;
/**
*
* @author Chad McMillan
*/
public class SeekableStream implements PullSourceStream, Seekable {
protected ByteBuffer inputBuffer;
/**
* a flag to indicate EOF reached
*/
/** Creates a new instance of SeekableStream */
public SeekableStream(ByteBuffer byteBuffer) {
inputBuffer = byteBuffer;
this.seek((long)(0)); // set the ByteBuffer to to beginning
}
/**
* Find out if the end of the stream has been reached.
*
* @return Returns <CODE>true</CODE> if there is no more data.
*/
public boolean endOfStream() {
return (! inputBuffer.hasRemaining());
}
/**
* Get the current content type for this stream.
*
* @return The current <CODE>ContentDescriptor</CODE> for this stream.
*/
public ContentDescriptor getContentDescriptor() {
return null;
}
/**
* Get the size, in bytes, of the content on this stream.
*
* @return The content length in bytes.
*/
public long getContentLength() {
return inputBuffer.capacity();
}
/**
* Obtain the object that implements the specified
* <code>Class</code> or <code>Interface</code>
* The full class or interface name must be used.
* <p>
*
* The control is not supported.
* <code>null</code> is returned.
*
* @return <code>null</code>.
*/
public Object getControl(String controlType) {
return null;
}
/**
* Obtain the collection of objects that
* control the object that implements this interface.
* <p>
*
* No controls are supported.
* A zero length array is returned.
*
* @return A zero length array
*/
public Object[] getControls() {
Object[] objects = new Object[0];
return objects;
}
/**
* Find out if this media object can position anywhere in the
* stream. If the stream is not random access, it can only be repositioned
* to the beginning.
*
* @return Returns <CODE>true</CODE> if the stream is random access, <CODE>false</CODE> if the stream can only
* be reset to the beginning.
*/
public boolean isRandomAccess() {
return true;
}
/**
* Block and read data from the stream.
* <p>
* Reads up to <CODE>length</CODE> bytes from the input stream into
* an array of bytes.
* If the first argument is <code>null</code>, up to
* <CODE>length</CODE> bytes are read and discarded.
* Returns -1 when the end
* of the media is reached.
*
* This method only returns 0 if it was called with
* a <CODE>length</CODE> of 0.
*
* @param buffer The buffer to read bytes into.
* @param offset The offset into the buffer at which to begin writing data.
* @param length The number of bytes to read.
* @return The number of bytes read, -1 indicating
* the end of stream, or 0 indicating <CODE>read</CODE>
* was called with <CODE>length</CODE> 0.
* @throws IOException Thrown if an error occurs while reading.
*/
public int read(byte[] buffer, int offset, int length) throws IOException {
// return n (number of bytes read), -1 (eof), 0 (asked for zero bytes)
if ( length == 0 )
return 0;
try {
inputBuffer.get(buffer,offset,length);
return length;
}
catch ( BufferUnderflowException E ) {
return -1;
}
}
public void close() {
}
/**
* Seek to the specified point in the stream.
* @param where The position to seek to.
* @return The new stream position.
*/
public long seek(long where) {
try {
inputBuffer.position((int)(where));
return where;
}
catch (IllegalArgumentException E) {
return this.tell(); // staying at the current position
}
}
/**
* Obtain the current point in the stream.
*/
public long tell() {
return inputBuffer.position();
}
/**
* Find out if data is available now.
* Returns <CODE>true</CODE> if a call to <CODE>read</CODE> would block
* for data.
*
* @return Returns <CODE>true</CODE> if read would block; otherwise
* returns <CODE>false</CODE>.
*/
public boolean willReadBlock() {
return (inputBuffer.remaining() == 0);
}
}