1-----------------------------------------------------------------------------
2-- Licensed to the Apache Software Foundation (ASF) under one or more
3-- contributor license agreements.
4-- The ASF licenses this file to You under the Apache License, Version 2.0
5-- (the "License"); you may not use this file except in compliance with
6-- the License.  You may obtain a copy of the License at
7--     http://www.apache.org/licenses/LICENSE-2.0
8-- Unless required by applicable law or agreed to in writing, software
9-- distributed under the License is distributed on an "AS IS" BASIS,
10-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11-- See the License for the specific language governing permissions and
12-- limitations under the License.
13-----------------------------------------------------------------------------
14-- Buffered Class
15-- by christian liesch <liesch@gmx.ch>
16-----------------------------------------------------------------------------
17
18Buffered = {transport = nil, buffer = nil, pos = nil}
19
20-- Constructor
21-- @param t IN htt transport object
22-- @return buffered object
23function Buffered:new(t)
24  o = {transport = t, buffer = t:read(8192), pos = 1}
25  setmetatable(o, self)
26  self.__index = self
27  return o
28end
29
30-- Line iterator
31-- @return next line and self
32function Buffered:lines()
33  return self.readline, self
34end
35
36-- read line excluding \r\n
37-- @return line
38function Buffered:readline()
39  local chunks = {}
40  while (self.buffer) do
41    local s, e = string.find(self.buffer, "[^\r\n]*\r\n", self.pos)
42    if s then
43      self.pos = e + 1
44      table.insert(chunks, string.sub(self.buffer, s, e-2))
45      local line = table.concat(chunks)
46      chunks = nil
47      return line
48    else
49      table.insert(chunks, string.sub(self.buffer, self.pos))
50      self.buffer = self.transport:read(8192)
51      self.pos = 1
52    end
53  end
54  return nil
55end
56
57-- Read a number of bytes
58-- @param len IN bytes to read
59-- @return received bytes
60function Buffered:read(len)
61  local rest_len = string.len(self.buffer) - self.pos + 1
62  if (len == 0) then
63    return ""
64  end
65  if (len <= rest_len) then
66    local block = string.sub(self.buffer, self.pos, self.pos + len - 1)
67    self.pos = self.pos + len
68    return block
69  end
70  local chunks = {}
71  local real_len = len - rest_len
72  table.insert(chunks, string.sub(self.buffer, self.pos))
73  while real_len > 0 do
74    self.buffer = self.transport:read(real_len)
75    real_len = real_len - string.len(self.buffer)
76    table.insert(chunks, self.buffer)
77  end
78  local block = table.concat(chunks)
79  chunks = nil
80  return block
81end
82
83-- Read until eof
84-- @return received bytes
85function Buffered:readeof()
86  local chunks = {}
87  while (self.buffer) do
88    table.insert(chunks, string.sub(self.buffer, self.pos))
89    self.pos = 1
90    self.buffer = self.transport:read(8192)
91  end
92  local block = table.concat(chunks)
93  chunks = nil
94  return block
95end
96
97