stream.lua
Verified
Added by iNTERFACEWARE
This module performs basic stream processing, read, write, save to file, convert to text etc.
Source Code
--
-- Basic Streams: Strings, Files, Pipes and Sockets
--
-- Copyright (c) 2011-2012 iNTERFACEWARE Inc.
--
-- How much data to buffer between reads.
local buffer_size = 64*1024
-- Throw errors reported by io.open().
local function open(path, mode)
local file, err = io.open(path, mode)
if not file then
error(err, 3)
end
return file
end
-- Throw errors reported by io.popen().
local function popen(cmd, mode)
local file, err = io.popen(cmd, mode)
if not file then
error(err, 3)
end
return file
end
-- Stream from some open file (see fromFile, fromPipe).
local function fromFile(file)
return function()
local out
if file then
out = file:read(buffer_size)
if not out then
file:close()
file = nil
end
end
return out
end
end
-- Stream to some open file (see toFile, toPipe).
local function toFile(file, from, ...)
local chunk
repeat
chunk = from(...)
if chunk then
file:write(chunk)
end
until not chunk
file:close()
end
--
-- Public API
--
stream = {}
-- stream.fromString(s)
--
-- Create a stream from a string.
-- 's' - the string
--
-- e.g. stream.toFile('out.txt', stream.fromString(Data))
--
function stream.fromString(s)
return function()
local out
if #s > 0 then
out = s:sub(1,buffer_size)
s = s:sub(buffer_size+1)
end
return out
end
end
-- stream.toString(from, ...)
--
-- Write a stream to a string.
-- 'from(...)' - the stream to read from
--
-- e.g. local s = stream.toString(stream.fromFile('in.txt'))
--
function stream.toString(from, ...)
local out, chunk = {}, nil
repeat
chunk = from(...)
if chunk then
out[#out+1] = chunk
end
until not chunk
return table.concat(out)
end
-- stream.fromFile(path [,mode])
--
-- Create a stream from a file.
-- 'path' - the path of the file
-- 'mode' - the mode to use (defaults to 'rb')
--
-- e.g. local s = stream.toString(stream.fromFile('in.txt'))
--
function stream.fromFile(path, mode)
local file = open(path, mode or 'rb')
return fromFile(file)
end
-- stream.toFile(path, from, ...)
-- stream.toFile(path, mode, from, ...)
--
-- Write a stream to a file.
-- 'path' - the path of the file
-- 'mode' - the mode to use (defaults to 'wb')
-- 'from(...)' - the stream to read from
--
-- e.g. stream.toFile('out.txt', stream.fromString(Data))
--
function stream.toFile(path, mode, from, ...)
if type(mode) == 'function' then
return stream.toFile(path, 'wb', mode, from, ...)
end
local file = open(path, mode)
return toFile(file, from, ...)
end
-- stream.fromPipe(cmd)
--
-- Create a stream from an external process.
-- 'cmd' - the command to run and read from
--
-- e.g. local s = stream.toString(stream.fromPipe('ls -1'))
--
function stream.fromPipe(cmd)
local file = popen(cmd, 'r')
return fromFile(file)
end
-- stream.toPipe(cmd, from, ...)
--
-- Write a stream to an external process.
-- 'cmd' - the command to run and write to
-- 'from(...)' - the stream to read from
--
-- e.g. stream.toPipe('openssl des -out out.tmp -k '..Key,
-- stream.fromString(Data))
--
function stream.toPipe(cmd, from, ...)
local file = popen(cmd, 'w')
return toFile(file, from, ...)
end
-- stream.fromSocket(sock)
--
-- Create a stream from a TCP/IP connection.
-- 'sock' - the connection to read from
--
-- e.g. local s = net.tcp.connect{...}
-- stream.toFile('big.hl7', stream.fromSocket(s))
--
function stream.fromSocket(sock)
return function()
return sock:recv()
end
end
-- stream.toSocket(sock, from, ...)
--
-- Write a stream to a TCP/IP connection.
-- 'sock' - the connection to write to
-- 'from(...)' - the stream to read from
--
-- e.g. local s = net.tcp.connect{...}
-- stream.toSocket(s, stream.fromFile('big.hl7'))
--
function stream.toSocket(sock, from, ...)
while true do
local chunk = from(...)
if not chunk then break end
sock:send(chunk)
end
end
-- stream.filter(from, f)
--
-- Create a stream by attaching a filter to another stream.
-- 'from' - the stream to read from
-- 'f' - the filter function
--
-- The filter (f) is called with each chunk (or nil) read
-- from the stream (from) and must return chunks (or nil)
-- to be sent downstream.
--
-- e.g. local Out = stream.toString(
-- stream.filter(stream.fromString(Data),
-- function(s)
-- return s and s:upper()
-- end))
-- assert(Out == Data:upper())
--
function stream.filter(from, f)
return function(...)
local out = from(...)
return f(out, ...)
end
end
return stream
Description
This module performs basic stream processing, read, write, save to file, convert to text etc.
Usage Details
This module performs basic stream processing, read, write, save to file, convert to text etc.
How to use stream.lua:
- Add it to your shared modules in any component
- Use
local stream = require 'stream'at the top of your script - Use the various stream functions to read, write, save and convert strings
| Function | Description |
|---|---|
| stream.fromString(string) | Creates a stream from the string. |
| stream.fromFile(path [,mode]) | Creates a stream from the file located at path. |
| stream.fromPipe(cmd) | Starts cmd in a separate process and returns its output as a stream (see io.popen). |
| stream.fromSocket(sock) | Creates a stream to read from an open socket (see net.tcp.connect). |
| stream.toString(stream, …) | Reads and returns, as a string, all the data from stream. |
| stream.toFile(path, [mode], stream, …) | Writes to the file, at path, all the data from stream. |
| stream.toPipe(cmd, stream, …) | Starts cmd in a separate process with all the data from stream as its input (see io.popen). |
| stream.toSocket(sock, stream, …) | Writes to the open socket, sock, all the data from the stream (see net.tcp.connect). |
| stream.filter(stream, filter) | Advanced: Creates a new stream by applying a filter to the chunked output of stream (see the next section for details). |
More Information