# HG changeset patch # User jbe # Date 1428514629 -7200 # Node ID 11d03470ef199b6cfcdc963e93ac012a770a6bb8 # Parent 5e8eeb5b6c848f0cf3eb927db743bb620dd8048c Refined buffer model for reading in I/O library diff -r 5e8eeb5b6c84 -r 11d03470ef19 moonbridge_io.c --- a/moonbridge_io.c Wed Apr 08 18:38:14 2015 +0200 +++ b/moonbridge_io.c Wed Apr 08 19:37:09 2015 +0200 @@ -35,7 +35,8 @@ int nonblocking; int nopush; int readerr; - int readbufcnt; + int readbufin; + int readbufout; int writeerr; size_t writeleft; #if LUA_VERSION_NUM >= 503 @@ -123,7 +124,7 @@ char terminator; luaL_Buffer luabuf; size_t luabufcnt = 0; - int endcnt; + int remaining; char *terminatorpos; ssize_t bytesread; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); @@ -140,66 +141,91 @@ lua_pushliteral(L, "Previous read error"); return 2; } + handle->readerr = 1; if (handle->fd < 0) goto moonbr_io_read_impl_eof; /* fake EOF to simulate shutdown */ - handle->readerr = 1; moonbr_io_handle_set_nonblocking(L, handle, nonblocking); if (!drain) luaL_buffinit(L, &luabuf); while (1) { - endcnt = -1; - if (maxread > 0 && handle->readbufcnt >= (size_t)maxread - luabufcnt) { - endcnt = maxread - luabufcnt; + remaining = -1; + if ( + maxread > 0 && + handle->readbufin - handle->readbufout >= (size_t)maxread - luabufcnt + ) { + remaining = maxread - luabufcnt; } else if (terminatorlen) { - terminatorpos = memchr(handle->readbuf, terminator, handle->readbufcnt); - if (terminatorpos) endcnt = 1 + (terminatorpos - handle->readbuf); + terminatorpos = memchr( + handle->readbuf + handle->readbufout, + terminator, + handle->readbufin - handle->readbufout + ); + if (terminatorpos) remaining = 1 + ( + terminatorpos - (handle->readbuf + handle->readbufout) + ); } - if (endcnt >= 0) { + if (remaining >= 0) { if (!drain) { - luaL_addlstring(&luabuf, handle->readbuf, endcnt); + luaL_addlstring( + &luabuf, + handle->readbuf + handle->readbufout, + remaining + ); luaL_pushresult(&luabuf); } else { - luabufcnt += handle->readbufcnt; - lua_pushinteger(L, luabufcnt); + luaL_pushresult(&luabuf); + lua_pop(L, 1); + lua_pushinteger(L, luabufcnt + remaining); } - handle->readbufcnt -= endcnt; - memmove(handle->readbuf, handle->readbuf + endcnt, handle->readbufcnt); + handle->readbufout += remaining; + if (handle->readbufout == handle->readbufin) { + handle->readbufin = 0; + handle->readbufout =0; + } handle->readerr = 0; return 1; } - if (!drain) luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); - luabufcnt += handle->readbufcnt; - handle->readbufcnt = 0; + if (!drain) luaL_addlstring( + &luabuf, + handle->readbuf + handle->readbufout, + handle->readbufin - handle->readbufout + ); + luabufcnt += handle->readbufin - handle->readbufout; do { bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN); } while (bytesread < 0 && (errno == EINTR)); - if (bytesread == 0 || (nonblocking && bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break; + if ( + bytesread == 0 || ( + nonblocking && + bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) + ) + ) { + handle->readbufin = 0; + handle->readbufout = 0; + if (!drain) { + luaL_pushresult(&luabuf); + if (!luabufcnt && bytesread == 0) { + lua_pop(L, 1); + moonbr_io_read_impl_eof: + lua_pushboolean(L, 0); + lua_pushliteral(L, "End of file"); + handle->readerr = 0; + return 2; + } + } else { + if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1); + else lua_pushboolean(L, luabufcnt); + } + handle->readerr = 0; + return 1; + } if (bytesread < 0) { moonbr_io_errmsg(); lua_pushnil(L); lua_pushstring(L, errmsg); return 2; } - handle->readbufcnt += bytesread; - } - if (!drain) { - luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); - luaL_pushresult(&luabuf); + handle->readbufin = bytesread; + handle->readbufout = 0; } - luabufcnt += handle->readbufcnt; - handle->readbufcnt = 0; - if (!drain) { - if (!luabufcnt && bytesread == 0) { - handle->readerr = 0; - moonbr_io_read_impl_eof: - lua_pushboolean(L, 0); - lua_pushliteral(L, "End of file"); - return 2; - } - } else { - if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1); - else lua_pushboolean(L, luabufcnt); - } - handle->readerr = 0; - return 1; } static int moonbr_io_read(lua_State *L) { @@ -454,7 +480,8 @@ handle->nonblocking = -1; handle->nopush = -1; handle->readerr = 0; - handle->readbufcnt = 0; + handle->readbufin = 0; + handle->readbufout = 0; handle->writeerr = 0; handle->writeleft = 0; handle->writeqin = 0;