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
>>>
>>
>

Reply via email to