moonbridge

changeset 140:9ca22af4d4b1

Added methods "read_call" and "read_yield"
author jbe
date Fri May 01 01:46:07 2015 +0200 (2015-05-01)
parents f148bd2b3d05
children 845e3dce3774
files moonbridge_io.c reference.txt
line diff
     1.1 --- a/moonbridge_io.c	Sat Apr 18 01:33:38 2015 +0200
     1.2 +++ b/moonbridge_io.c	Fri May 01 01:46:07 2015 +0200
     1.3 @@ -71,6 +71,18 @@
     1.4    int nonblocking;
     1.5  } moonbr_io_listener_t;
     1.6  
     1.7 +static int moonbr_io_yield(lua_State *L) {
     1.8 +  return lua_yield(L, 0);
     1.9 +}
    1.10 +
    1.11 +#if LUA_VERSION_NUM >= 503
    1.12 +static int moonbr_io_cont_returnall(lua_State *L, int status, lua_KContext ctx) {
    1.13 +#else
    1.14 +static int moonbr_io_cont_returnall(lua_State *L) {
    1.15 +#endif
    1.16 +  return lua_gettop(L);
    1.17 +}
    1.18 +
    1.19  static void moonbr_io_handle_set_nonblocking(lua_State *L, moonbr_io_handle_t *handle, int nonblocking) {
    1.20    int flags;
    1.21    if (handle->nonblocking == nonblocking) return;
    1.22 @@ -265,6 +277,109 @@
    1.23    return moonbr_io_read_impl(L, 1, 1);
    1.24  }
    1.25  
    1.26 +#if LUA_VERSION_NUM >= 503
    1.27 +static int moonbr_io_read_cont(lua_State *L, int status, lua_KContext ctx) {
    1.28 +#else
    1.29 +static int moonbr_io_read_cont(lua_State *L) {
    1.30 +#endif
    1.31 +  size_t len, remaining;
    1.32 +  const char *terminatorstr = NULL;
    1.33 +  size_t terminatorlen = 0;
    1.34 +  const char *chunk;
    1.35 +  size_t chunklen;
    1.36 +#if !(LUA_VERSION_NUM >= 503)
    1.37 +  int ctx = 0;
    1.38 +  lua_getctx(L, &ctx);
    1.39 +#endif
    1.40 +  remaining = lua_tointeger(L, 3);
    1.41 +  while (1) {
    1.42 +    lua_pushcfunction(L, moonbr_io_read_nb);
    1.43 +    lua_pushvalue(L, 1);
    1.44 +    lua_pushvalue(L, 3);
    1.45 +    lua_pushvalue(L, 4);
    1.46 +    lua_call(L, 3, 2);
    1.47 +    if (lua_isnil(L, -2)) {
    1.48 +      return 2;
    1.49 +    } else if (!lua_toboolean(L, -2)) {
    1.50 +      if (ctx) {
    1.51 +        lua_pushnil(L);
    1.52 +        lua_pushliteral(L, "Unexpected EOF");
    1.53 +      }
    1.54 +      return 2;
    1.55 +    }
    1.56 +    len = lua_rawlen(L, -2);
    1.57 +    if (!len) {
    1.58 +      lua_pop(L, 2);
    1.59 +    } else {
    1.60 +      lua_pop(L, 1);
    1.61 +      if (!terminatorstr) {
    1.62 +        terminatorstr = lua_tolstring(L, 4, &terminatorlen);
    1.63 +        if (!terminatorstr) terminatorstr = "";
    1.64 +      }
    1.65 +      if (terminatorlen) chunk = lua_tolstring(L, -1, &chunklen);
    1.66 +      if (ctx == 0) {
    1.67 +        lua_replace(L, 5);
    1.68 +        ctx = 1;
    1.69 +      } else if (ctx == 1) {
    1.70 +        lua_pushvalue(L, 5);
    1.71 +        lua_newtable(L);
    1.72 +        lua_replace(L, 5);
    1.73 +        lua_rawseti(L, 5, 2);
    1.74 +        lua_rawseti(L, 5, 1);
    1.75 +        ctx = 2;
    1.76 +      } else {
    1.77 +        lua_rawseti(L, 5, lua_rawlen(L, 5) + 1);
    1.78 +      }
    1.79 +      if (remaining) {
    1.80 +        if (len >= remaining) break;
    1.81 +        remaining -= len;
    1.82 +        lua_pushinteger(L, remaining);
    1.83 +        lua_replace(L, 3);
    1.84 +      }
    1.85 +      if (terminatorlen && chunk[chunklen-1] == terminatorstr[0]) break;
    1.86 +    }
    1.87 +    lua_pushvalue(L, 2);
    1.88 +    lua_pushvalue(L, 1);
    1.89 +    lua_pushliteral(L, "r");
    1.90 +    lua_callk(L, 2, 0, ctx, moonbr_io_read_cont);
    1.91 +  }
    1.92 +  if (ctx == 1) {
    1.93 +    lua_pushvalue(L, 5);
    1.94 +  } else {
    1.95 +    luaL_Buffer buf;
    1.96 +    lua_Integer i, chunkcount;
    1.97 +    chunkcount = lua_rawlen(L, 5);
    1.98 +    luaL_buffinit(L, &buf);
    1.99 +    for (i=1; i<=chunkcount && i>0; i++) {
   1.100 +      lua_rawgeti(L, 5, i);
   1.101 +      luaL_addvalue(&buf);
   1.102 +    }
   1.103 +    luaL_pushresult(&buf);
   1.104 +  }
   1.105 +  return 1;
   1.106 +}
   1.107 +
   1.108 +static int moonbr_io_read_call(lua_State *L) {
   1.109 +  lua_settop(L, 4);
   1.110 +  lua_pushnil(L);
   1.111 +#if LUA_VERSION_NUM >= 503
   1.112 +  return moonbr_io_read_cont(L, 0, 0);
   1.113 +#else
   1.114 +  return moonbr_io_read_cont(L);
   1.115 +#endif
   1.116 +}
   1.117 +
   1.118 +static int moonbr_io_read_yield(lua_State *L) {
   1.119 +  int args;
   1.120 +  lua_pushcfunction(L, moonbr_io_read_call);
   1.121 +  lua_insert(L, 1);
   1.122 +  args = lua_gettop(L);
   1.123 +  lua_pushcfunction(L, moonbr_io_yield);
   1.124 +  lua_insert(L, 3);
   1.125 +  lua_callk(L, args, LUA_MULTRET, 0, moonbr_io_cont_returnall);
   1.126 +  return lua_gettop(L);
   1.127 +}
   1.128 +
   1.129  static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) {
   1.130    moonbr_io_handle_t *handle;
   1.131    int i, top;
   1.132 @@ -1116,6 +1231,8 @@
   1.133  static const struct luaL_Reg moonbr_io_handle_methods[] = {
   1.134    {"read", moonbr_io_read},
   1.135    {"read_nb", moonbr_io_read_nb},
   1.136 +  {"read_call", moonbr_io_read_call},
   1.137 +  {"read_yield", moonbr_io_read_yield},
   1.138    {"drain", moonbr_io_drain},
   1.139    {"drain_nb", moonbr_io_drain_nb},
   1.140    {"write", moonbr_io_write},
     2.1 --- a/reference.txt	Sat Apr 18 01:33:38 2015 +0200
     2.2 +++ b/reference.txt	Fri May 01 01:46:07 2015 +0200
     2.3 @@ -155,6 +155,12 @@
     2.4  second return value) are returned.
     2.5  
     2.6  
     2.7 +### socket:read_call(waitfunc, maxlen, terminator)
     2.8 +
     2.9 +Same as socket:read(maxlen, terminator), but calls waitfunc(socket, "r") (in an
    2.10 +infinite loop) as long as the reading is blocked.
    2.11 +
    2.12 +
    2.13  ### socket:read_nb(maxlen, terminator)
    2.14  
    2.15  Read up to maxlen bytes, until an optional termination character is encountered
    2.16 @@ -172,6 +178,11 @@
    2.17  second return value) are returned.
    2.18  
    2.19  
    2.20 +### socket:read_yield(maxlen, terminator)
    2.21 +
    2.22 +Alias for socket:read_call(coroutine.yield, maxlen, terminator)
    2.23 +
    2.24 +
    2.25  ### socket.remote_ip4
    2.26  
    2.27  Remote IPv4 address used for the connection. Encoded as 4 raw bytes in form of

Impressum / About Us