nixio: +performance
[project/luci.git] / libs / nixio / lua / nixio / util.lua
1 --[[
2 nixio - Linux I/O library for lua
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13 ]]--
14
15 local table = require "table"
16 local nixio = require "nixio"
17 local setmetatable, assert = setmetatable, assert
18
19 module "nixio.util"
20
21 local BUFFERSIZE = 8096
22 local socket = nixio.socket_meta
23
24 function socket.readall(self, len)
25         local block, code, msg = self:recv(len)
26
27         if not block then
28                 return "", code, msg, len
29         end
30
31         local data, total = {block}, #block
32
33         while len > total do
34                 block, code, msg = self:recv(len - total)
35
36                 if not block then
37                         return data, code, msg, len - #data
38                 end
39
40                 data[#data+1], total = block, total + #block
41         end
42
43         return (#data > 1 and table.concat(data) or data[1]), nil, nil, 0
44 end
45
46 function socket.sendall(self, data)
47         local total, block = 0
48         local sent, code, msg = self:send(data)
49
50         if not sent then
51                 return total, code, msg, data
52         end
53
54         while sent < #data do
55                 block, total = data:sub(sent + 1), total + sent
56                 sent, code, msg = self:send(block)
57                 
58                 if not sent then
59                         return total, code, msg, block
60                 end
61         end
62         
63         return total + sent, nil, nil, ""
64 end
65
66 function socket.linesource(self, limit)
67         limit = limit or BUFFERSIZE
68         local buffer = ""
69         return function(flush)
70                 local bpos, line, endp, _ = 0
71                 
72                 if flush then
73                         line = buffer
74                         buffer = ""
75                         return line
76                 end
77
78                 while not line do
79                         _, endp, line = buffer:find("^(.-)\r?\n", bpos + 1)
80                         if line then
81                                 bpos = endp
82                                 return line
83                         elseif #buffer < limit + bpos then
84                                 local newblock, code = self:recv(limit + bpos - #buffer)
85                                 if not newblock then
86                                         return nil, code
87                                 end
88                                 buffer = buffer:sub(bpos + 1) .. newblock
89                                 bpos = 0
90                         else
91                                 return nil, 0
92                         end
93                 end
94         end
95 end