// Copyright (c) 2014 Tom Zhou<iwebpp@gmail.com> package com.iwebpp.wspp; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.List; import com.iwebpp.SimpleDebug; import com.iwebpp.node.Util; public final class BufferUtil extends SimpleDebug { private static final String TAG = "BufferUtil"; protected static ByteBuffer merge(/*ByteBuffer mergedBuffer,*/ List<Object> buffers) throws Exception { ///buffers.add(0, mergedBuffer); ByteBuffer mergedBuffer = Util.concatByteBuffer(buffers, 0); return mergedBuffer; } protected static ByteBuffer mask(ByteBuffer source, byte[] mask, ByteBuffer output, int offset, int length) { debug(TAG, "unmask, source:"+source+",mask:"+mask); long mask0 = mask[0], mask1 = mask[1], mask2 = mask[2], mask3 = mask[3]; long maskNum = ((mask0 << 0) & 0xffL) | ((mask1 << 8) & 0xff00L) | ((mask2 << 16) & 0xff0000L) | ((mask3 << 24) & 0xff000000L) | ((mask0 << 32) & 0xff00000000L) | ((mask1 << 40) & 0xff0000000000L) | ((mask2 << 48) & 0xff000000000000L) | ((mask3 << 56) & 0xff00000000000000L) ; int i = 0; source.order(ByteOrder.LITTLE_ENDIAN); output.order(ByteOrder.LITTLE_ENDIAN); for (; i < length - 7; i += 8) { long num = maskNum ^ source.getLong(i); ///if (num < 0) num = 4294967296 + num; output.putLong(offset + i, num); } switch (length % 8) { case 7: output.put(offset + i + 6, (byte) (source.get(i + 6) ^ mask[2])); case 6: output.put(offset + i + 5, (byte) (source.get(i + 5) ^ mask[1])); case 5: output.put(offset + i + 4, (byte) (source.get(i + 4) ^ mask[0])); case 4: output.put(offset + i + 3, (byte) (source.get(i + 3) ^ mask[3])); case 3: output.put(offset + i + 2, (byte) (source.get(i + 2) ^ mask[2])); case 2: output.put(offset + i + 1, (byte) (source.get(i + 1) ^ mask[1])); case 1: output.put(offset + i + 0, (byte) (source.get(i + 0) ^ mask[0])); case 0:; } renewBuffer(output); return output; } protected static ByteBuffer unmask(ByteBuffer data, byte[] mask) { debug(TAG, "unmask, data:"+data+",mask:"+mask); long mask0 = mask[0], mask1 = mask[1], mask2 = mask[2], mask3 = mask[3]; long maskNum = ((mask0 << 0) & 0xffL) | ((mask1 << 8) & 0xff00L) | ((mask2 << 16) & 0xff0000L) | ((mask3 << 24) & 0xff000000L) | ((mask0 << 32) & 0xff00000000L) | ((mask1 << 40) & 0xff0000000000L) | ((mask2 << 48) & 0xff000000000000L) | ((mask3 << 56) & 0xff00000000000000L) ; int length = data.capacity(); int i = 0; data.order(ByteOrder.LITTLE_ENDIAN); for (; i < length - 7; i += 8) { long num = maskNum ^ data.getLong(i); ///if (num < 0) num = 4294967296 + num; data.putLong(i, num); } switch (length % 8) { case 7: data.put(i + 6, (byte) (data.get(i + 6) ^ mask[2])); case 6: data.put(i + 5, (byte) (data.get(i + 5) ^ mask[1])); case 5: data.put(i + 4, (byte) (data.get(i + 4) ^ mask[0])); case 4: data.put(i + 3, (byte) (data.get(i + 3) ^ mask[3])); case 3: data.put(i + 2, (byte) (data.get(i + 2) ^ mask[2])); case 2: data.put(i + 1, (byte) (data.get(i + 1) ^ mask[1])); case 1: data.put(i + 0, (byte) (data.get(i + 0) ^ mask[0])); case 0:; } renewBuffer(data); return data; } protected static void fastCopy(int length, ByteBuffer srcBuffer, ByteBuffer dstBuffer, int dstOffset) { /*switch (length) { default: srcBuffer.copy(dstBuffer, dstOffset, 0, length); break; case 16: dstBuffer[dstOffset+15] = srcBuffer[15]; case 15: dstBuffer[dstOffset+14] = srcBuffer[14]; case 14: dstBuffer[dstOffset+13] = srcBuffer[13]; case 13: dstBuffer[dstOffset+12] = srcBuffer[12]; case 12: dstBuffer[dstOffset+11] = srcBuffer[11]; case 11: dstBuffer[dstOffset+10] = srcBuffer[10]; case 10: dstBuffer[dstOffset+9] = srcBuffer[9]; case 9: dstBuffer[dstOffset+8] = srcBuffer[8]; case 8: dstBuffer[dstOffset+7] = srcBuffer[7]; case 7: dstBuffer[dstOffset+6] = srcBuffer[6]; case 6: dstBuffer[dstOffset+5] = srcBuffer[5]; case 5: dstBuffer[dstOffset+4] = srcBuffer[4]; case 4: dstBuffer[dstOffset+3] = srcBuffer[3]; case 3: dstBuffer[dstOffset+2] = srcBuffer[2]; case 2: dstBuffer[dstOffset+1] = srcBuffer[1]; case 1: dstBuffer[dstOffset] = srcBuffer[0]; }*/ debug(TAG, "fastCopy, srcBuffer:"+srcBuffer+",dstBuffer:"+dstBuffer+", length:"+length+",dstOffset:"+dstOffset); if (length == 0) return; dstBuffer.position(dstOffset); dstBuffer.limit(dstBuffer.capacity()); srcBuffer.position( 0); srcBuffer.limit( length); ///dstBuffer.put(srcBuffer); switch (length) { default: dstBuffer.put(srcBuffer); break; case 16: dstBuffer.put(srcBuffer.get()); case 15: dstBuffer.put(srcBuffer.get()); case 14: dstBuffer.put(srcBuffer.get()); case 13: dstBuffer.put(srcBuffer.get()); case 12: dstBuffer.put(srcBuffer.get()); case 11: dstBuffer.put(srcBuffer.get()); case 10: dstBuffer.put(srcBuffer.get()); case 9: dstBuffer.put(srcBuffer.get()); case 8: dstBuffer.put(srcBuffer.get()); case 7: dstBuffer.put(srcBuffer.get()); case 6: dstBuffer.put(srcBuffer.get()); case 5: dstBuffer.put(srcBuffer.get()); case 4: dstBuffer.put(srcBuffer.get()); case 3: dstBuffer.put(srcBuffer.get()); case 2: dstBuffer.put(srcBuffer.get()); case 1: dstBuffer.put(srcBuffer.get()); } dstBuffer.position(0); dstBuffer.limit(dstBuffer.capacity()); srcBuffer.position(0); srcBuffer.limit(srcBuffer.capacity()); debug(TAG, "fastCopy, srcBuffer:"+srcBuffer+",dstBuffer:"+dstBuffer); } protected static ByteBuffer renewBuffer(ByteBuffer buf) { buf.position(0); buf.limit(buf.capacity()); return buf; } }