moonbridge
diff moonbridge_io.c @ 105:11d03470ef19
Refined buffer model for reading in I/O library
author | jbe |
---|---|
date | Wed Apr 08 19:37:09 2015 +0200 (2015-04-08) |
parents | 5e8eeb5b6c84 |
children | 8fce76ef321f |
line diff
1.1 --- a/moonbridge_io.c Wed Apr 08 18:38:14 2015 +0200 1.2 +++ b/moonbridge_io.c Wed Apr 08 19:37:09 2015 +0200 1.3 @@ -35,7 +35,8 @@ 1.4 int nonblocking; 1.5 int nopush; 1.6 int readerr; 1.7 - int readbufcnt; 1.8 + int readbufin; 1.9 + int readbufout; 1.10 int writeerr; 1.11 size_t writeleft; 1.12 #if LUA_VERSION_NUM >= 503 1.13 @@ -123,7 +124,7 @@ 1.14 char terminator; 1.15 luaL_Buffer luabuf; 1.16 size_t luabufcnt = 0; 1.17 - int endcnt; 1.18 + int remaining; 1.19 char *terminatorpos; 1.20 ssize_t bytesread; 1.21 handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); 1.22 @@ -140,66 +141,91 @@ 1.23 lua_pushliteral(L, "Previous read error"); 1.24 return 2; 1.25 } 1.26 + handle->readerr = 1; 1.27 if (handle->fd < 0) goto moonbr_io_read_impl_eof; /* fake EOF to simulate shutdown */ 1.28 - handle->readerr = 1; 1.29 moonbr_io_handle_set_nonblocking(L, handle, nonblocking); 1.30 if (!drain) luaL_buffinit(L, &luabuf); 1.31 while (1) { 1.32 - endcnt = -1; 1.33 - if (maxread > 0 && handle->readbufcnt >= (size_t)maxread - luabufcnt) { 1.34 - endcnt = maxread - luabufcnt; 1.35 + remaining = -1; 1.36 + if ( 1.37 + maxread > 0 && 1.38 + handle->readbufin - handle->readbufout >= (size_t)maxread - luabufcnt 1.39 + ) { 1.40 + remaining = maxread - luabufcnt; 1.41 } else if (terminatorlen) { 1.42 - terminatorpos = memchr(handle->readbuf, terminator, handle->readbufcnt); 1.43 - if (terminatorpos) endcnt = 1 + (terminatorpos - handle->readbuf); 1.44 + terminatorpos = memchr( 1.45 + handle->readbuf + handle->readbufout, 1.46 + terminator, 1.47 + handle->readbufin - handle->readbufout 1.48 + ); 1.49 + if (terminatorpos) remaining = 1 + ( 1.50 + terminatorpos - (handle->readbuf + handle->readbufout) 1.51 + ); 1.52 } 1.53 - if (endcnt >= 0) { 1.54 + if (remaining >= 0) { 1.55 if (!drain) { 1.56 - luaL_addlstring(&luabuf, handle->readbuf, endcnt); 1.57 + luaL_addlstring( 1.58 + &luabuf, 1.59 + handle->readbuf + handle->readbufout, 1.60 + remaining 1.61 + ); 1.62 luaL_pushresult(&luabuf); 1.63 } else { 1.64 - luabufcnt += handle->readbufcnt; 1.65 - lua_pushinteger(L, luabufcnt); 1.66 + luaL_pushresult(&luabuf); 1.67 + lua_pop(L, 1); 1.68 + lua_pushinteger(L, luabufcnt + remaining); 1.69 } 1.70 - handle->readbufcnt -= endcnt; 1.71 - memmove(handle->readbuf, handle->readbuf + endcnt, handle->readbufcnt); 1.72 + handle->readbufout += remaining; 1.73 + if (handle->readbufout == handle->readbufin) { 1.74 + handle->readbufin = 0; 1.75 + handle->readbufout =0; 1.76 + } 1.77 handle->readerr = 0; 1.78 return 1; 1.79 } 1.80 - if (!drain) luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); 1.81 - luabufcnt += handle->readbufcnt; 1.82 - handle->readbufcnt = 0; 1.83 + if (!drain) luaL_addlstring( 1.84 + &luabuf, 1.85 + handle->readbuf + handle->readbufout, 1.86 + handle->readbufin - handle->readbufout 1.87 + ); 1.88 + luabufcnt += handle->readbufin - handle->readbufout; 1.89 do { 1.90 bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN); 1.91 } while (bytesread < 0 && (errno == EINTR)); 1.92 - if (bytesread == 0 || (nonblocking && bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))) break; 1.93 + if ( 1.94 + bytesread == 0 || ( 1.95 + nonblocking && 1.96 + bytesread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK) 1.97 + ) 1.98 + ) { 1.99 + handle->readbufin = 0; 1.100 + handle->readbufout = 0; 1.101 + if (!drain) { 1.102 + luaL_pushresult(&luabuf); 1.103 + if (!luabufcnt && bytesread == 0) { 1.104 + lua_pop(L, 1); 1.105 + moonbr_io_read_impl_eof: 1.106 + lua_pushboolean(L, 0); 1.107 + lua_pushliteral(L, "End of file"); 1.108 + handle->readerr = 0; 1.109 + return 2; 1.110 + } 1.111 + } else { 1.112 + if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1); 1.113 + else lua_pushboolean(L, luabufcnt); 1.114 + } 1.115 + handle->readerr = 0; 1.116 + return 1; 1.117 + } 1.118 if (bytesread < 0) { 1.119 moonbr_io_errmsg(); 1.120 lua_pushnil(L); 1.121 lua_pushstring(L, errmsg); 1.122 return 2; 1.123 } 1.124 - handle->readbufcnt += bytesread; 1.125 - } 1.126 - if (!drain) { 1.127 - luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); 1.128 - luaL_pushresult(&luabuf); 1.129 + handle->readbufin = bytesread; 1.130 + handle->readbufout = 0; 1.131 } 1.132 - luabufcnt += handle->readbufcnt; 1.133 - handle->readbufcnt = 0; 1.134 - if (!drain) { 1.135 - if (!luabufcnt && bytesread == 0) { 1.136 - handle->readerr = 0; 1.137 - moonbr_io_read_impl_eof: 1.138 - lua_pushboolean(L, 0); 1.139 - lua_pushliteral(L, "End of file"); 1.140 - return 2; 1.141 - } 1.142 - } else { 1.143 - if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1); 1.144 - else lua_pushboolean(L, luabufcnt); 1.145 - } 1.146 - handle->readerr = 0; 1.147 - return 1; 1.148 } 1.149 1.150 static int moonbr_io_read(lua_State *L) { 1.151 @@ -454,7 +480,8 @@ 1.152 handle->nonblocking = -1; 1.153 handle->nopush = -1; 1.154 handle->readerr = 0; 1.155 - handle->readbufcnt = 0; 1.156 + handle->readbufin = 0; 1.157 + handle->readbufout = 0; 1.158 handle->writeerr = 0; 1.159 handle->writeleft = 0; 1.160 handle->writeqin = 0;