IoBuffer.getInt(position) will do a peek read without modifying
position I believe. Just be sure to use an offset from the position
since there's no guaruntee in Mina that the buffer is at the
beginning, i.e. in.getInt(in.position() + n) rather than in.getInt(n)
On Thu, Oct 2, 2008 at 2:34 PM, Andres Quijano <[EMAIL PROTECTED]> wrote:
> Latest version, with performance improvement:
>
> private ByteBuffer xor(ByteBuffer in) {
> while (in.hasRemaining()) {
> if (in.remaining() >= 4) {
> int xor = in.getInt() ^ 0xAABBCCDD;
> in.position(in.position() - 4);
> in.putInt(xor);
> }
> else {
> byte xor = (byte) (in.get() ^ 0xEE);
> in.position(in.position() - 1);
> in.put(xor);
> }
> }
>
> return in.flip();
> }
>
> I don't like to read and then have to rewind the position like this...
> is there another way? I couldn't find a peek method or something that
> reads without modifying the position
>
> On Thu, Oct 2, 2008 at 2:53 PM, Andres Quijano <[EMAIL PROTECTED]> wrote:
>> Thanks a lot Barend, it was very useful
>>
>> I had it working before your message, it was a horrible mess, like this:
>>
>> private ByteBuffer xor(ByteBuffer in) {
>> ByteBuffer xor = ByteBuffer.allocate(in.capacity(), true);
>> xor.limit(in.limit());
>>
>> int pos = in.position();
>>
>> // xor
>> for (int i = 0; i < in.limit(); ++i) {
>> byte b = in.get();
>> byte xbx = (byte) (b ^ 101);
>>
>> xor.put(xbx);
>> }
>>
>> in.release();
>>
>> xor.position(pos);
>>
>> return xor;
>> }
>>
>> After your suggestions I tried to do it in-place, this is what I came
>> up with, it works, but it doesn't feel right... any hints?
>>
>> private ByteBuffer xor(ByteBuffer in) {
>> int i = 0;
>> while (in.hasRemaining()) {
>> in.put(i, (byte) (in.get(i) ^ 0x77));
>> in.position(++i);
>> }
>>
>> return in.flip();
>> }
>>
>> Thanks again
>>
>> Andres
>>
>> On Thu, Oct 2, 2008 at 2:16 PM, W.B. Garvelink
>> <[EMAIL PROTECTED]> wrote:
>>> The next step, of course, is to xor the bytes in place in the existing
>>> buffer instead of allocating a second buffer, making a copy, and
>>> deallocating the first. How would you do that?
>>>
>>>
>>>
>>> On Thu, Oct 2, 2008 at 7:06 PM, W.B. Garvelink
>>> <[EMAIL PROTECTED]> wrote:
>>>> The ProtocolCodecFilter uses an empty buffer internally as a sentinel
>>>> value to demarcate the end of a unit of input. If you don't return
>>>> that empty buffer, it keeps allocating additional space, which is
>>>> causing those huge buffers you're crashing on.
>>>>
>>>> Your code shows some confusion about the difference between limit and
>>>> capacity, and this is what's messing up the empty buffers. Take a look
>>>> at the javadocs for java.nio.Buffer:
>>>> http://java.sun.com/javase/6/docs/api/java/nio/Buffer.html
>>>>
>>>> ...and pay close attention to the difference between capacity and
>>>> limit. Put simply, capacity indicates how much *can be* used, limit
>>>> indicates how much *is* used. Also, note the difference between flip()
>>>> and rewind(), one of which sets the value of limit to the current
>>>> position, while the other doesn't.
>>>>
>>>> Going over the source code for your xor method (quoted with line numbers
>>>> below):
>>>>
>>>> line 2: allocate the new buffer to in.limit(), not to in.capacity()
>>>>
>>>> line 5: your for loop is always reading one byte less than available
>>>> in the input, which you can fix by using i++" instead of "++i" in the
>>>> expression clause (or by changing the test clause to use ">=", but
>>>> this loop is deviant enough as it is). That said, it's a better idea
>>>> to avoid this altogether by using "while(in.hasRemaining())" as your
>>>> loop construct, because this avoids any kind of confusion about
>>>> whether you're counting bytes or elements (e.g. there are eight bytes
>>>> but only two ints in an IntBuffer of length 2).
>>>>
>>>> lines 6-9: speaking of ints... you can xor bigger chunks at a time for
>>>> a nice speed boost (leave that for later on).
>>>> line 7: I like to use hexadecimal constants because each character
>>>> represents four bits, the underlying bit pattern is a lot easier to
>>>> see than with decimal constants.
>>>>
>>>> line 11: return xor.flip() not xor.rewind(). In this particular case
>>>> they're equivalent (after fixing line 2), but if you ever copy a
>>>> partial buffer, they're quite different.
>>>>
>>>> I suspect that if you fix lines 2, 5 and 11, your buffer data
>>>> exceptions will be history.
>>>>
>>>> HTH
>>>>
>>>> Barend
>>>>
>>>>
>>>>> 1 private ByteBuffer xor(ByteBuffer in) {
>>>>> 2 ByteBuffer xor = ByteBuffer.allocate(in.capacity());
>>>>> 3
>>>>> 4 // xor
>>>>> 5 for (int i = 0; i < in.limit(); ++i) {
>>>>> 6 byte b = in.get();
>>>>> 7 byte xbx = (byte) (b ^ 101);
>>>>> 8
>>>>> 9 xor = xor.put(xbx);
>>>>>10 }
>>>>>11
>>>>>11 return xor.rewind();
>>>>>12 }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Thu, Oct 2, 2008 at 1:10 AM, Andres Quijano <[EMAIL PROTECTED]> wrote:
>>>>> Hi!
>>>>>
>>>>> I'm implementing a simple XORFilter to XOR encrypt my messages. I
>>>>> added the XORFilter on top of the ProtocolCodecFilter and it works ok,
>>>>> but even if the messages go from and to the server ok (it's a
>>>>> multiplayer game), I keep getting this error on background
>>>>>
>>>>> org.apache.mina.common.BufferDataException: dataLength: 1694498816
>>>>> at
>>>>> org.apache.mina.common.ByteBuffer.prefixedDataAvailable(ByteBuffer.java:1631)
>>>>> at
>>>>> org.apache.mina.filter.codec.serialization.ObjectSerializationDecoder.doDecode(ObjectSerializationDecoder.java:88)
>>>>> at
>>>>> org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode(CumulativeProtocolDecoder.java:133)
>>>>> at
>>>>> org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:158)
>>>>>
>>>>> Some debugging showed that (quite possibly I'm wrong) this happens
>>>>> when the XORFilter encrypts an empty ByteBuffer that MINA sends
>>>>>
>>>>> Here is the source of the XORFilter class:
>>>>>
>>>>> public class XORFilter extends IoFilterAdapter {
>>>>> @Override
>>>>> public void messageReceived(NextFilter nextFilter, IoSession session,
>>>>> Object message) throws Exception {
>>>>>
>>>>> nextFilter.messageReceived(session, xor((ByteBuffer) message));
>>>>> }
>>>>>
>>>>> @Override
>>>>> public void filterWrite(NextFilter nextFilter, IoSession session,
>>>>> WriteRequest writeRequest) throws Exception {
>>>>>
>>>>> ByteBuffer inBuffer = (ByteBuffer) writeRequest.getMessage();
>>>>>
>>>>> nextFilter.filterWrite(session, new WriteRequest(xor(inBuffer),
>>>>> writeRequest.getFuture()));
>>>>> }
>>>>>
>>>>> private ByteBuffer xor(ByteBuffer in) {
>>>>> ByteBuffer xor = ByteBuffer.allocate(in.capacity());
>>>>>
>>>>> // xor
>>>>> for (int i = 0; i < in.limit(); ++i) {
>>>>> byte b = in.get();
>>>>> byte xbx = (byte) (b ^ 101);
>>>>>
>>>>> xor = xor.put(xbx);
>>>>> }
>>>>>
>>>>> return xor.rewind();
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>> Any ideas of what might be the cause? Also I'm new to "low level"
>>>>> byte-buffer handling, so any tips on improving the code will be most
>>>>> appreciated
>>>>>
>>>>> Thanks!
>>>>>
>>>>> Andres
>>>>>
>>>>
>>>
>>
>