const char bufread_lua[] =
"-- An implementation of buffered reading data from\n"
"-- an arbitrary binary file.\n"
"--\n"
"-- Major portions taken verbatim or adapted from the LuaVela.\n"
"-- Copyright (C) 2015-2019 IPONWEB Ltd.\n"
"\n"
"local assert = assert\n"
"\n"
"local ffi = require \"ffi\"\n"
"local bit = require \"bit\"\n"
"\n"
"local ffi_C = ffi.C\n"
"local band = bit.band\n"
"\n"
"local LINK_BIT = 0x80\n"
"local PAYLOAD_MASK = 0x7f\n"
"local SHIFT_STEP = 7\n"
"\n"
"-- 10 Mb.\n"
"local BUFFER_SIZE = 10 * 1024 * 1024\n"
"\n"
"local M = {}\n"
"\n"
"ffi.cdef[[\n"
"  void *memmove(void *, const void *, size_t);\n"
"\n"
"  typedef struct FILE_ FILE;\n"
"  FILE *fopen(const char *, const char *);\n"
"  size_t fread(void *, size_t, size_t, FILE *);\n"
"  int feof(FILE *);\n"
"  int fclose(FILE *);\n"
"]]\n"
"\n"
"local function _read_stream(reader, n)\n"
"  local tail_size = reader._end - reader._pos\n"
"\n"
"  assert(n <= BUFFER_SIZE, \"Internal buffer is large enough\")\n"
"\n"
"  if tail_size >= n then\n"
"    -- Enough data to satisfy the request of n bytes.\n"
"    return true\n"
"  end\n"
"\n"
"  -- Otherwise carry tail_size bytes from the end of the buffer\n"
"  -- to the start and fill up free_size bytes with fresh data.\n"
"\n"
"  local free_size = BUFFER_SIZE - tail_size\n"
"\n"
"  if tail_size ~= 0 then\n"
"    ffi_C.memmove(reader._buf, reader._buf + reader._pos, tail_size)\n"
"  end\n"
"\n"
"  local bytes_read = ffi_C.fread(\n"
"    reader._buf + tail_size, 1, free_size, reader._file\n"
"  )\n"
"\n"
"  reader._pos = 0\n"
"  reader._end = tail_size + bytes_read\n"
"\n"
"  return reader._end - reader._pos >= n\n"
"end\n"
"\n"
"function M.read_octet(reader)\n"
"  if not _read_stream(reader, 1) then\n"
"    return nil\n"
"  end\n"
"\n"
"  local oct = reader._buf[reader._pos]\n"
"  reader._pos = reader._pos + 1\n"
"  return oct\n"
"end\n"
"\n"
"function M.read_octets(reader, n)\n"
"  if not _read_stream(reader, n) then\n"
"    return nil\n"
"  end\n"
"\n"
"  local octets = ffi.string(reader._buf + reader._pos, n)\n"
"  reader._pos = reader._pos + n\n"
"  return octets\n"
"end\n"
"\n"
"function M.read_uleb128(reader)\n"
"  local value = ffi.new(\"uint64_t\", 0)\n"
"  local shift = 0\n"
"\n"
"  repeat\n"
"    local oct = M.read_octet(reader)\n"
"\n"
"    if oct == nil then\n"
"      error(string.format(\"fread, errno: %d\", ffi.errno()))\n"
"    end\n"
"\n"
"    -- Alas, bit library works only with 32-bit arguments.\n"
"    local oct_u64 = ffi.new(\"uint64_t\", band(oct, PAYLOAD_MASK))\n"
"    value = value + oct_u64 * (2 ^ shift)\n"
"    shift = shift + SHIFT_STEP\n"
"\n"
"  until band(oct, LINK_BIT) == 0\n"
"\n"
"  return tonumber(value)\n"
"end\n"
"\n"
"function M.read_string(reader)\n"
"  local len = M.read_uleb128(reader)\n"
"  return M.read_octets(reader, len)\n"
"end\n"
"\n"
"function M.eof(reader)\n"
"  local sys_feof = ffi_C.feof(reader._file)\n"
"  if sys_feof == 0 then\n"
"    return false\n"
"  end\n"
"  -- Otherwise return true only if we have reached\n"
"  -- the end of the buffer.\n"
"  return reader._pos == reader._end\n"
"end\n"
"\n"
"function M.new(fname)\n"
"  local file = ffi_C.fopen(fname, \"rb\")\n"
"  if file == nil then\n"
"    error(string.format(\"fopen, errno: %d\", ffi.errno()))\n"
"  end\n"
"\n"
"  local finalizer = function(f)\n"
"    if ffi_C.fclose(f) ~= 0 then\n"
"      error(string.format(\"fclose, errno: %d\", ffi.errno()))\n"
"    end\n"
"    ffi.gc(f, nil)\n"
"  end\n"
"\n"
"  local reader = setmetatable({\n"
"    _file = ffi.gc(file, finalizer),\n"
"    _buf = ffi.new(\"uint8_t[\?]\", BUFFER_SIZE),\n"
"    _pos = 0,\n"
"    _end = 0,\n"
"  }, {__index = M})\n"
"\n"
"  _read_stream(reader, BUFFER_SIZE)\n"
"\n"
"  return reader\n"
"end\n"
"\n"
"return M\n"
""
;
