用lua实现ByteArray和ByteArrayVarint

http://zengrong.net/post/1968.htm

用lua实现ByteArray和ByteArrayVarint

2014-01-10更新: ByteArray 和 ByteArrayVarint 已经进入 quick-cocos2d-x 的 framework.


许多 Actionscript 程序员已经从 Flash 转到 Cocos2d-x 了。那么以前的那些超级好用的类库都不见了,只好重新来过。

我利用 Lua 和 lpack 库实现了一套 lua版本的 ByteArray 。这套库用于 quick-cocos2d-x(后称quick) 中。因此依赖一些 quick 中已经包含的c库和lua库 。

主要依赖如下:

utils.ByteArray

ByteArray依赖 lpack 。

lpack 其实已经足够好用了。但是由于lpack的指针功能有限,所以使用起来还是有些麻烦。这个类模仿了 Actionscript 的 flash.utils.ByteArray ,指针在内部实现,方便读取和缓存 socket 服务器数据。

当然了,有一点点不同,但或许更好用。

下面是使用ByteArray的例子:

-- 直接使用 lpack 库生成一个字节流
local __pack = string.pack("<bihP2", 0x59, 11, 1101, "", "中文")

-- 创建一个ByteArray
local __ba = ByteArray.new()

-- ByteArray 允许直接写入 lpack 生成的字节流
__ba:writeBuf(__pack)

-- 不要忘了,lua数组是1基的。而且函数名称比 position 短
__ba:setPos(1)

-- 这个用法和AS3相同了,只是有些函数名称被我改掉了
print("ba.len:", __ba:getLen())
print("ba.readByte:", __ba:readByte())
print("ba.readInt:", __ba:readInt())
print("ba.readShort:", __ba:readShort())
print("ba.readString:", __ba:readStringUShort())
print("ba.available:", __ba:getAvailable())
-- 自带的toString方法可以以10进制、16进制、8进制打印
print("ba.toString(16):", __ba:toString(16))

-- 创建一个新的ByteArray
local __ba2 = ByteArray.new()

-- 和AS3的用法相同,还支持链式调用
__ba2:writeByte(0x59)
    :writeInt(11)
    :writeShort(1101)
-- 写入空字符串
__ba2:writeStringUShort("")
-- 写入中文(UTF8)字符串
__ba2:writeStringUShort("中文")

-- 十进制输出
print("ba2.toString(10):", __ba2:toString(10))

下面就是效果了:

luabytearray

utils.ByteArrayVarint

ByteArrayVarint 继承 ByteArray,同时依赖 BitOp。

ByteArrayVarint 实现了 google protocol buffer协议中的Varint编码

Protocol Buffer协议是何方神圣,google一下就知道。简单说就是能大幅降低 socket 协议中传递的字节流的长度。但是protocol buffer协议还包含许多东西,而我只需要 varint 编码而已。

我们的上一个游戏就在 AS3中实现了varint编码 。现在又用lua实现了一遍。

方法名称说明
ByteArrayVarint.readUVInt()read a unsigned varint int
ByteArrayVarint.writeUVInt()write a unsigned varint int
ByteArrayVarint.readVInt()read varint int
ByteArrayVarint.writeVInt()write varint int
ByteArrayVarint.readStringUVInt()read a string preceding a unsigned varint int
ByteArrayVarint.writeStringUVInt()write a string preceding a unsigned varint int

虽然lua支持64位数字,但由于 BitOp 仅支持32位有符号整数,这个 ByteArrayVarint 类能做的事情有限,甚至比AS3的都要差点(AS3好歹还支持32位无符号整数)。但如果程序中不使用变态的64位(或更高)数字的话,还是挺好的。

我会把自己在游戏中常用的 lua 功能陆续整合进入这个开源库,就像我的 as3库java库 一样。

cocos2d-xLua

文章导航

《用lua实现ByteArray和ByteArrayVarint》有12个想法

  1. 你用的哪里的版本?能给个例子么?

  2. tanti

    曾大侠,我用了一下readbytes函数发现了问题,您在求可用长度时没有+1,并且循环writerawbyte()时,多循环一次,导致结果出错

  3. 确实是可以加一个。

  4. 应该加一个clear方法
    function ByteArray:clear()
    self._buf = {}
    self._pos = 1
    end

  5. 我主要考虑到string在lua中是不可变的。这样在缓冲区扩展并进行字符串拼合的时候可能会影响性能和耗费内存。而table则没有这个问题。

  6. wills

    我看了你的代码,是将socket中的string变成一个table来进行读写操作,为什么不直接用String来操作呢?因为它本身是一个缓冲区;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值