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