/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.hasor.rsf.protocol.rsf.v1;
import io.netty.buffer.ByteBuf;
import net.hasor.rsf.utils.ProtocolUtils;
/**
* 池上限为 0~4095条数据,单条数据最大约16MB。
* 下面是数据格式:<pre>
* ---------------------------------bytes =6 ~ 8192
* byte[2] attrPool-size (0~4095) 池大小 0x0FFF
* byte[4] att-length 属性1大小
* byte[4] att-length 属性2大小
* ...
* ---------------------------------bytes =n
* dataBody 数据内容
* bytes[...]
* </pre>
* @version : 2014年10月25日
* @author 赵永春(zyc@hasor.net)
*/
public class PoolBlock {
public static final int NULL_MARK = 0xFFFFFFFF; //表示NULL
public static int DataMaxSize = 0x00FFFFFF; //单条数据最大约16MB
public static short PoolMaxSize = 0x0FFF; //池上限为 0~4095条
private int[] poolMap = {};
private ByteBuf poolData = null;
//
public PoolBlock() {
this.poolData = ProtocolUtils.newByteBuf();
}
public void fillFrom(ByteBuf formData) {
if (formData == null) {
return;
}
//
short attrPoolSize = (short) (PoolMaxSize & formData.readShort());
for (int i = 0; i < attrPoolSize; i++) {
int length = formData.readInt();
this.poolMap = ArrayUtils.add(this.poolMap, length);
}
this.poolData.writeBytes(formData);
}
public void fillTo(ByteBuf toData) {
if (toData == null)
return;
//
toData.writeShort(poolMap.length);
for (int i = 0; i < poolMap.length; i++) {
toData.writeInt(poolMap[i]);
}
toData.writeBytes(this.poolData);
}
//
/**添加请求参数。*/
public short pushData(byte[] dataArray) {
if (this.poolMap.length >= PoolMaxSize) {
throw new IndexOutOfBoundsException("poolMax size is " + PoolMaxSize);
}
//
int datalength = (dataArray == null) ? NULL_MARK : dataArray.length;
this.poolMap = ArrayUtils.add(this.poolMap, datalength);
if (datalength > 0) {
this.poolData.writeBytes(dataArray);
}
return (short) (this.poolMap.length - 1);
}
//
/**池长度*/
public int getPoolLength() {
return this.poolMap.length;
}
/**池大小*/
public int getPoolSize() {
int rawSize = 0;
for (int i = 0; i < this.poolMap.length; i++) {
int atPoolData = this.poolMap[i];
if (atPoolData <= 0)
continue;
rawSize += this.poolMap[i];
}
return rawSize;
}
/**池数据*/
public int[] getPoolData() {
return this.poolMap;
}
/**内容所处起始位置*/
public byte[] readPool(short attrIndex) {
if (this.poolMap[attrIndex] == NULL_MARK) {
return null;
}
//
int rawIndex = 0;
for (int i = 0; i < this.poolMap.length; i++) {
if (i == attrIndex)
break;
if (this.poolMap[i] != NULL_MARK)
rawIndex += this.poolMap[i];
}
int readLength = this.poolMap[attrIndex];//内容长度
if (readLength == NULL_MARK)
return null;
//
byte[] data = new byte[readLength];
this.poolData.getBytes(rawIndex, data, 0, readLength);
return data;
}
}