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