Ir para conteúdo
Entre para seguir isso  
dalvorsn

NetworkMessage

Recommended Posts

dalvorsn    46
dalvorsn

NetworkMessage

 
Autor: Dalvo
Descrição: Biblioteca para manipulação de dados(strings) byte a byte, muito usado em protocolos de rede, inteiramente em lua sem necessidade de adição de nenhum módulo.

 

NetworkMessage = {}


function NetworkMessage.create(pdata)
	-- NetworkMessage.create([pdata])
	-- @params
	--	'pdata': string
	-- Instancia a classe NetworkMessage, se pdata é fornecido é definido o atributo data igual a pdata e size igual a #pdata
	return setmetatable({ data = pdata or "", size = pdata and #pdata or 0, pos = 1}, { __index = NetworkMessage })
end

function NetworkMessage:reset()
	-- NetworkMessage.reset(self)
	-- self:reset()
	-- @params
	--   'self': table
	-- Reinicia os atributos do objeto
	self.data = ""
	self.size = 0
	self.pos  = 1
end

function NetworkMessage:setBuffer(buffer)
	-- NetworkMessage.setBuffer(self, buffer)
	-- self:setBuffer(buffer)
	-- @params
	--  'self': table
	--  'buffer': string
	-- Define 'buffer' como atributo data
	if not type(buffer) == "string" then
		return false
	end

	self.data = buffer
	self.size = #buffer
	self.pos = 1
end

function NetworkMessage:getBuffer()
	-- NetworkMessage.getBuffer(self)
	-- self:getBuffer()
	-- @params
	--  'self': table
	-- Retorna o atributo 'data'
	return self.data
end

function NetworkMessage:getSize()
	-- NetworkMessage.getSize(self)
	-- self:getSize()
	-- @params
	--  'self': table
	-- Retorna o atributo 'size'
	return self.size
end

function NetworkMessage:getRanges(byteCount, signed)
	-- NetworkMessage.getRanges(self, byteCount, signed)
	-- self:getRanges(byteCount, signed)
	-- @params
	--  'self': table
	--  'byteCount': number
	--  'signed': boolean
	-- Função interna usada para calcular o limite do valor de 'byteCount' bytes, se signed é true reajusta seu valor para signed
	local min, max = 0, ((256^byteCount) -1)
	if(signed)then
		max = math.floor(max/2)
		min = -max-1
	end
	return -min, max
end

function NetworkMessage:canRead(size)
	-- NetworkMessage.canRead(self, size)
	-- self:canRead(size)
	-- @params
	--  'self': table
	--  'size': number
	-- Verifica se pode ser lido o numero 'size' de bytes, retorna um booleano
	return (self.pos + size) > (self.size + 1)
end

function NetworkMessage:readBytes(byteCount, signed)
	-- NetworkMessage.readBytes(self, byteCount, signed)
	-- self:readBytes(byteCount, signed)
	-- @params
	--  'self': table
	--  'byteCount': number
	--  'signed': boolean
	-- Tenta ler 'byteCount' numero de bytes, retorna o valor numerico dos bytes
	-- se possivel a leitura, e false se não. Se signed é true reajusta valor para signed
	if self:canRead(byteCount) then return false end

	local min, _ = self:getRanges(byteCount, signed)
	local value = 0

	for byte = 1, byteCount do
		value = value + ( self.data:byte(self.pos) * (256^(byte-1)) )
		self.pos = self.pos + 1
	end

	return value + min
end

function NetworkMessage:addBytes(value, count, signed)
	-- NetworkMessage.addBytes(self, value, count, signed)
	-- self:addBytes(value, count, signed)
	-- @params
	--  'self': table
	-- 	'value': number
	--  'count':number
	--  'signed':boolean
	-- Tenta escrever 'value' em 'count' bytes, se 'value' for maior que o numero de bytes
	-- suporta retorna false. Se signed é true reajusta valor para signed
	if signed then
		value = value * 2
	end

	if value >= (256^count) then
		return false
	end

	for byte = count, 1, -1 do
		local power = (256 ^ (byte-1))
		self.data = self.data .. string.char( math.floor(value/power) )
		value = value % power
	end

	self.size = self.size + count
	self.pos = self.pos + count
	return true
end

-- Metodos para pegar valores
function NetworkMessage:getU8()
	return self:readBytes(1, false)
end

function NetworkMessage:getU16()
	return self:readBytes(2, false)
end

function NetworkMessage:getU32()
	return self:readBytes(4, false)
end

function NetworkMessage:getU64()
	return self:readBytes(8, false)
end

function NetworkMessage:getI8()
	return self:readBytes(1, true)
end

function NetworkMessage:getI16()
	return self:readBytes(2, true)
end

function NetworkMessage:getI32()
	return self:readBytes(4, true)
end

function NetworkMessage:getI64()
	return self:readBytes(8, true)
end

function NetworkMessage:getString()
	-- NetworkMessage.getString(self)
	-- self:getString()
	-- @params
	--  'self': table
	-- Tenta ler a string e retorna-la em caso de sucesso, se falho retorna false
	local size = self:getU16()
	if not (size and self:canRead(size)) then return false end

	local str = ""
	for byte=0, size-1 do
		str = str .. string.char(self.data:byte(self.pos + byte))
	end
	self.pos = self.pos + size
	return str
end

-- Metodos para adição de valores
function NetworkMessage:addU8(value)
	return self:addBytes(value, 1, false)
end

function NetworkMessage:addU16(value)
	return self:addBytes(value, 2, false)
end

function NetworkMessage:addU32(value)
	return self:addBytes(value, 4, false)
end

function NetworkMessage:addU64(value)
	return self:addBytes(value, 8, false)
end

function NetworkMessage:addI8(value)
	return self:addBytes(value, 1, true)
end

function NetworkMessage:addI16(value)
	return self:addBytes(value, 2, true)
end

function NetworkMessage:addI32(value)
	return self:addBytes(value, 4, true)
end

function NetworkMessage:addI64(value)
	return self:addBytes(value, 8, true)
end

function NetworkMessage:addString(str)
	-- NetworkMessage.addString(self, str)
	-- self:addString(str)
	-- @params
	--  'self': table
	--  'str': string
	-- Tenta adicionar 'str', se o tamanho supera dois bytes, retorna false
	if not self:addU16(#str) then
		return false
	end

	self.data = self.data .. str

	self.size = self.size + #str
	self.pos = self.pos + #str
	return true
end


Obs.: Não use sequencialmente metodos get e add, caso queira usar o mesmo objeto para add e get, use reset primeiro

Editado por dalvorsn

Compartilhar este post


Link para o post
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  
  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×