mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
	
	
		
			133 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
		
		
			
		
	
	
			133 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
|   | ----------------------------------------------------------------------------- | ||
|  | -- LuaSocket helper module | ||
|  | -- Author: Diego Nehab | ||
|  | -- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ | ||
|  | ----------------------------------------------------------------------------- | ||
|  | 
 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | -- Declare module and import dependencies | ||
|  | ----------------------------------------------------------------------------- | ||
|  | local base = _G | ||
|  | local string = require("string") | ||
|  | local math = require("math") | ||
|  | local socket = require("socket.core") | ||
|  | module("socket") | ||
|  | 
 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | -- Exported auxiliar functions | ||
|  | ----------------------------------------------------------------------------- | ||
|  | function connect(address, port, laddress, lport) | ||
|  |     local sock, err = socket.tcp() | ||
|  |     if not sock then return nil, err end | ||
|  |     if laddress then | ||
|  |         local res, err = sock:bind(laddress, lport, -1) | ||
|  |         if not res then return nil, err end | ||
|  |     end | ||
|  |     local res, err = sock:connect(address, port) | ||
|  |     if not res then return nil, err end | ||
|  |     return sock | ||
|  | end | ||
|  | 
 | ||
|  | function bind(host, port, backlog) | ||
|  |     local sock, err = socket.tcp() | ||
|  |     if not sock then return nil, err end | ||
|  |     sock:setoption("reuseaddr", true) | ||
|  |     local res, err = sock:bind(host, port) | ||
|  |     if not res then return nil, err end | ||
|  |     res, err = sock:listen(backlog) | ||
|  |     if not res then return nil, err end | ||
|  |     return sock | ||
|  | end | ||
|  | 
 | ||
|  | try = newtry() | ||
|  | 
 | ||
|  | function choose(table) | ||
|  |     return function(name, opt1, opt2) | ||
|  |         if base.type(name) ~= "string" then | ||
|  |             name, opt1, opt2 = "default", name, opt1 | ||
|  |         end | ||
|  |         local f = table[name or "nil"] | ||
|  |         if not f then base.error("unknown key (".. base.tostring(name) ..")", 3) | ||
|  |         else return f(opt1, opt2) end | ||
|  |     end | ||
|  | end | ||
|  | 
 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | -- Socket sources and sinks, conforming to LTN12 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | -- create namespaces inside LuaSocket namespace | ||
|  | sourcet = {} | ||
|  | sinkt = {} | ||
|  | 
 | ||
|  | BLOCKSIZE = 2048 | ||
|  | 
 | ||
|  | sinkt["close-when-done"] = function(sock) | ||
|  |     return base.setmetatable({ | ||
|  |         getfd = function() return sock:getfd() end, | ||
|  |         dirty = function() return sock:dirty() end | ||
|  |     }, { | ||
|  |         __call = function(self, chunk, err) | ||
|  |             if not chunk then | ||
|  |                 sock:close() | ||
|  |                 return 1 | ||
|  |             else return sock:send(chunk) end | ||
|  |         end | ||
|  |     }) | ||
|  | end | ||
|  | 
 | ||
|  | sinkt["keep-open"] = function(sock) | ||
|  |     return base.setmetatable({ | ||
|  |         getfd = function() return sock:getfd() end, | ||
|  |         dirty = function() return sock:dirty() end | ||
|  |     }, { | ||
|  |         __call = function(self, chunk, err) | ||
|  |             if chunk then return sock:send(chunk) | ||
|  |             else return 1 end | ||
|  |         end | ||
|  |     }) | ||
|  | end | ||
|  | 
 | ||
|  | sinkt["default"] = sinkt["keep-open"] | ||
|  | 
 | ||
|  | sink = choose(sinkt) | ||
|  | 
 | ||
|  | sourcet["by-length"] = function(sock, length) | ||
|  |     return base.setmetatable({ | ||
|  |         getfd = function() return sock:getfd() end, | ||
|  |         dirty = function() return sock:dirty() end | ||
|  |     }, { | ||
|  |         __call = function() | ||
|  |             if length <= 0 then return nil end | ||
|  |             local size = math.min(socket.BLOCKSIZE, length) | ||
|  |             local chunk, err = sock:receive(size) | ||
|  |             if err then return nil, err end | ||
|  |             length = length - string.len(chunk) | ||
|  |             return chunk | ||
|  |         end | ||
|  |     }) | ||
|  | end | ||
|  | 
 | ||
|  | sourcet["until-closed"] = function(sock) | ||
|  |     local done | ||
|  |     return base.setmetatable({ | ||
|  |         getfd = function() return sock:getfd() end, | ||
|  |         dirty = function() return sock:dirty() end | ||
|  |     }, { | ||
|  |         __call = function() | ||
|  |             if done then return nil end | ||
|  |             local chunk, err, partial = sock:receive(socket.BLOCKSIZE) | ||
|  |             if not err then return chunk | ||
|  |             elseif err == "closed" then | ||
|  |                 sock:close() | ||
|  |                 done = 1 | ||
|  |                 return partial | ||
|  |             else return nil, err end | ||
|  |         end | ||
|  |     }) | ||
|  | end | ||
|  | 
 | ||
|  | 
 | ||
|  | sourcet["default"] = sourcet["until-closed"] | ||
|  | 
 | ||
|  | source = choose(sourcet) |