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

Reply via email to