It seems that it is impossible to extend a ByteBuffer, since its constructors are private. (It makes me wonder why it was done this way instead of using a final class ... anyway)
The problem is that I need the full functionality of the ByteBuffer, and only some minor changes in wrap(byte[], int, int), flip() and compact(). The rest I need it to stay the same, and of course I do not want to encapsulate the whole funationality of a ByteBuffer into a new object.
So I need to subclass ByteBuffer ... how can this be done, and if it cannot, how can this be done .. (it has to be done)
yes .. it is ... but it cannot be extended ... Have you ever tried to do so ?? you get constructor errors and even if you place the correct constructors in the class you still get an error since the original constructor of the class is private, and you can only access it through the package, and I'm not programming in the package java.nio
It seems that it is impossible to extend a
ByteBuffer, since its constructors are private. (It
makes me wonder why it was done this way instead of
using a final class ... anyway)
Same thing. Seems to work well enough to keep you from extending it.
The problem is that I need the full functionality of
the ByteBuffer, and only some minor changes in
wrap(byte[], int, int), flip() and compact(). The
rest I need it to stay the same, and of course I do
not want to encapsulate the whole funationality of a
ByteBuffer into a new object.
But of course that's what you'll have to do.
So I need to subclass ByteBuffer ... how can this be
done, and if it cannot, how can this be done .. (it
has to be done)
Cannot be done, as you've already learned. You'll have to write your own.
A final class cannot be extended. But a class with private constructors can ---- inside the class itself. ByteBuffer.wrap, ByteBuffer.allocateDirect return instances of subclasses of ByteBuffer. This is an important difference.
Anyway, the constructors of ByteBuffer aren't private; they are only package protected. This way MappedByteBuffer can extend ByteBuffer. There are probably good reasons for making it that way: a subclass that overrides all the major methods could easily be used to breach security.
Is there any particular reason why you have to extend ByteBuffer ? If it is only to modify the behaviour slightly for certain methods instead of creating some fundamentally new byte buffer (like what mapped byte buffer is: a memory mapped file) perhaps you should use delegation instead of inheritance. In other words: write a class that has a ByteBuffer as a member and declares some of the same methods, and these methods are implemented by forwarding the call to the underlaying ByteBuffer. How does that sound?
I want to have ByteBuffer work in a portion of a wrapped array. That is I have an array lets say a[1000] and I want the ByteBuffer to work on the portion from a[53] to a[170] only ... unfortunately, flip and compact use array.length and index 0 to set position and limit so although I can wrap with offset and length, after a flip or compact I end up using the whole array again ... (never mind reset, or rewind for now) This is what I need ... the orginal ByteBuffer with its full functionality working on a portion of an array ... It seems that the functionality id there since there is an arrayOffset to be returned, but this cannot be set with wrap (or something similar) and still limit seems to always be set to array.length instead of the length given to wrap.
I need to subclass ByteBuffer so that it gets its bytes from a remote file using HTTP.
Any tips ?
Thanks!
Hello,
It seems that it is impossible to extend a
ByteBuffer, since its constructors are private. (It
makes me wonder why it was done this way instead of
using a final class ... anyway)
The problem is that I need the full functionality of
the ByteBuffer, and only some minor changes in
wrap(byte[], int, int), flip() and compact(). The
rest I need it to stay the same, and of course I do
not want to encapsulate the whole funationality of a
ByteBuffer into a new object.
So I need to subclass ByteBuffer ... how can this be
done, and if it cannot, how can this be done .. (it
has to be done)
As you can see, I can pass ANY type of ByteBuffer to this class, so it can "mount" an Amiga fast file system (http://en.wikipedia.org/wiki/Amiga_Fast_File_System, for instance) stored on any kind of source (be it a local file, a file stored on a HTTP server, and so on).
Let's follow your suggestion to read the bytes into the buffer:
Assume there is a 2 GB file stored on an HTTP server. The user mounts this file as an Amiga Fas File System, and reads the contents of a certain file. Doing so, the user had to wait for 2 GB of data to be read into the buffer.
If I could subclass ByteBuffer, I would not have to read the whole file into the buffer.
The AmigaFileSystem class would ask for a few bytes (in method 'initializeDirectoryEntries') to learn the starting position and size of the needed file, and then it would read a few more bytes corresponding to the file contents (which could be quite small).
In order to read only the needed bytes, I would have to use the HTTP byte range header (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35)
I'd appreciate if anyone could help me on this...
Why? Whynot just read the bytes into the buffer? What
does subclassing have to do with this?
I need to subclass ByteBuffer so that it gets its
bytes from a remote file using HTTP.
As jsalonen said it's package protected therefore you can do this:
/ Copyright (c) 2008-2009, Markos Evlogimenos
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. The name of Markos Evlogimenos may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /
package java.nio;
import java.nio.ByteBuffer;
public abstract class ByteBufferExtended extends ByteBuffer
{
ByteBufferExtended(int i, int j, int k, int l, byte abyte0[], int i1) {
super(i,j,k,l,abyte0,i1);
}
/* Returns a string from the ByteBuffer. /
public String getString()
{
int stringSize = getInt();
return new String(getBytes(stringSize));
}
/* The string stored will be 4 bytes longer than the actual string size. /
public ByteBuffer putString(String str)
{
byte [] bytes = str.getBytes();
int stringSize = bytes.length;
putInt(stringSize);
put(str.getBytes());
return this;
}
/* Returns a byte [] with all the remaining bytes left in the ByteBuffer. /
public byte [] getBytes()
{
return getBytes(remaining());
}
/* Returns a byte [] with the next n bytes left in the ByteBuffer. /
public byte [] getBytes(int n)
{
byte [] bytes = new byte [n];
get(bytes);
return bytes;
}
}
Now depending on what u need this for, it might turn useful.
However if you are trying to use a framework that passes ByteBuffers it's a bit pointless...
You wont be able to use your class at runtime.
In that case you should either make service class like ByteBufferTools and send the ByteBuffer reference and do what u want to do ex:
/* The string stored will be 4 bytes longer than the actual string size. */
public static void putString(String str, ByteBuffer bb)
{
byte [] bytes = str.getBytes();
int stringSize = bytes.length;
bb.putInt(stringSize);
bb.put(str.getBytes());
}
That copyright statement is invalid and non-binding. You can't assert a copyright from a date in the future.
package java.nio;
That's a violation of the licence agreement and the Java copyright.
I can't see anything startling in this class, or in this entire thread, that can't be done with the existing ByteBuffer API. Buffer.slice() is the answer to most of it, as pointed out years ago.
I just offered a solution to the question :)
sorry about the copyright it was autogenerated by my IDE....
and i simply copy pasted the code here as an example
funny that i just found the reply to my post by googling my name for fun :D