moonbridge

changeset 143:41da87a681d6

Method "read" always returns two return values
author jbe
date Sat May 02 01:48:29 2015 +0200 (2015-05-02)
parents 8cd9acda3853
children e7fac0918f9c
files moonbridge_io.c reference.txt
line diff
     1.1 --- a/moonbridge_io.c	Fri May 01 13:56:52 2015 +0200
     1.2 +++ b/moonbridge_io.c	Sat May 02 01:48:29 2015 +0200
     1.3 @@ -174,8 +174,14 @@
     1.4      lua_pushliteral(L, "Previous read error");
     1.5      return 2;
     1.6    }
     1.7 +  if (handle->fd < 0) {
     1.8 +    /* fake EOF to simulate shutdown */
     1.9 +    if (!drain) lua_pushliteral(L, "");
    1.10 +    else lua_pushinteger(L, 0);
    1.11 +    lua_pushliteral(L, "eof");
    1.12 +    return 2;
    1.13 +  }
    1.14    handle->readerr = 1;
    1.15 -  if (handle->fd < 0) goto moonbr_io_read_impl_eof;  /* fake EOF to simulate shutdown */
    1.16    moonbr_io_handle_set_nonblocking(L, handle, nonblocking);
    1.17    if (!drain) luaL_buffinit(L, &luabuf);
    1.18    while (1) {
    1.19 @@ -183,7 +189,7 @@
    1.20      terminatorpos = NULL;
    1.21      if (
    1.22        maxread > 0 &&
    1.23 -      (size_t)maxread - luabufcnt <= handle->readbufin - handle->readbufout
    1.24 +      handle->readbufin - handle->readbufout >= (size_t)maxread - luabufcnt
    1.25      ) {
    1.26        remaining = (size_t)maxread - luabufcnt;
    1.27        terminatorpos = memchr(
    1.28 @@ -212,13 +218,15 @@
    1.29        } else {
    1.30          lua_pushinteger(L, luabufcnt + remaining);
    1.31        }
    1.32 +      if (terminatorpos) lua_pushliteral(L, "term");
    1.33 +      else lua_pushliteral(L, "maxlen");
    1.34        handle->readbufout += remaining;
    1.35        if (handle->readbufout == handle->readbufin) {
    1.36          handle->readbufin = 0;
    1.37 -        handle->readbufout =0;
    1.38 +        handle->readbufout = 0;
    1.39        }
    1.40        handle->readerr = 0;
    1.41 -      return 1;
    1.42 +      return 2;
    1.43      }
    1.44      if (!drain) luaL_addlstring(
    1.45        &luabuf,
    1.46 @@ -226,6 +234,7 @@
    1.47        handle->readbufin - handle->readbufout
    1.48      );
    1.49      luabufcnt += handle->readbufin - handle->readbufout;
    1.50 +    handle->readbufout = 0;
    1.51      do {
    1.52        bytesread = read(handle->fd, handle->readbuf, MOONBR_IO_READBUFLEN);
    1.53      } while (bytesread < 0 && (errno == EINTR));
    1.54 @@ -236,23 +245,12 @@
    1.55        )
    1.56      ) {
    1.57        handle->readbufin = 0;
    1.58 -      handle->readbufout = 0;
    1.59 -      if (!drain) {
    1.60 -        luaL_pushresult(&luabuf);
    1.61 -        if (!luabufcnt && bytesread == 0) {
    1.62 -          lua_pop(L, 1);
    1.63 -          moonbr_io_read_impl_eof:
    1.64 -          lua_pushboolean(L, 0);
    1.65 -          lua_pushliteral(L, "End of file");
    1.66 -          handle->readerr = 0;
    1.67 -          return 2;
    1.68 -        }
    1.69 -      } else {
    1.70 -        if (!luabufcnt && bytesread == 0) lua_pushboolean(L, 1);
    1.71 -        else lua_pushboolean(L, luabufcnt);
    1.72 -      }
    1.73 +      if (!drain) luaL_pushresult(&luabuf);
    1.74 +      else lua_pushinteger(L, luabufcnt);
    1.75 +      if (bytesread == 0) lua_pushliteral(L, "eof");
    1.76 +      else lua_pushliteral(L, "block");
    1.77        handle->readerr = 0;
    1.78 -      return 1;
    1.79 +      return 2;
    1.80      }
    1.81      if (bytesread < 0) {
    1.82        moonbr_io_errmsg();
    1.83 @@ -261,7 +259,6 @@
    1.84        return 2;
    1.85      }
    1.86      handle->readbufin = bytesread;
    1.87 -    handle->readbufout = 0;
    1.88    }
    1.89  }
    1.90  
    1.91 @@ -286,11 +283,8 @@
    1.92  #else
    1.93  static int moonbr_io_read_cont(lua_State *L) {
    1.94  #endif
    1.95 -  size_t len, remaining;
    1.96 -  const char *terminatorstr = NULL;
    1.97 -  size_t terminatorlen = 0;
    1.98 -  const char *chunk;
    1.99 -  size_t chunklen;
   1.100 +  lua_Integer remaining;
   1.101 +  size_t len;
   1.102  #if !(LUA_VERSION_NUM >= 503)
   1.103    int ctx = 0;
   1.104    lua_getctx(L, &ctx);
   1.105 @@ -302,46 +296,29 @@
   1.106      lua_pushvalue(L, 3);
   1.107      lua_pushvalue(L, 4);
   1.108      lua_call(L, 3, 2);
   1.109 -    if (lua_isnil(L, -2)) {
   1.110 -      return 2;
   1.111 -    } else if (!lua_toboolean(L, -2)) {
   1.112 -      if (ctx) {
   1.113 -        lua_pushnil(L);
   1.114 -        lua_pushliteral(L, "Unexpected EOF");
   1.115 -      }
   1.116 -      return 2;
   1.117 -    }
   1.118 -    len = lua_rawlen(L, -2);
   1.119 -    if (!len) {
   1.120 -      lua_pop(L, 2);
   1.121 +    if (lua_isnil(L, -2)) return 2;
   1.122 +    lua_insert(L, -2);
   1.123 +    len = lua_rawlen(L, -1);
   1.124 +    if (ctx == 0) {
   1.125 +      lua_replace(L, 5);
   1.126 +      ctx = 1;
   1.127 +    } else if (ctx == 1) {
   1.128 +      lua_pushvalue(L, 5);
   1.129 +      lua_newtable(L);
   1.130 +      lua_replace(L, 5);
   1.131 +      lua_rawseti(L, 5, 2);
   1.132 +      lua_rawseti(L, 5, 1);
   1.133 +      ctx = 2;
   1.134      } else {
   1.135 -      lua_pop(L, 1);
   1.136 -      if (!terminatorstr) {
   1.137 -        terminatorstr = lua_tolstring(L, 4, &terminatorlen);
   1.138 -        if (!terminatorstr) terminatorstr = "";
   1.139 -      }
   1.140 -      if (terminatorlen) chunk = lua_tolstring(L, -1, &chunklen);
   1.141 -      if (ctx == 0) {
   1.142 -        lua_replace(L, 5);
   1.143 -        ctx = 1;
   1.144 -      } else if (ctx == 1) {
   1.145 -        lua_pushvalue(L, 5);
   1.146 -        lua_newtable(L);
   1.147 -        lua_replace(L, 5);
   1.148 -        lua_rawseti(L, 5, 2);
   1.149 -        lua_rawseti(L, 5, 1);
   1.150 -        ctx = 2;
   1.151 -      } else {
   1.152 -        lua_rawseti(L, 5, lua_rawlen(L, 5) + 1);
   1.153 -      }
   1.154 -      if (remaining) {
   1.155 -        if (len >= remaining) break;
   1.156 -        remaining -= len;
   1.157 -        lua_pushinteger(L, remaining);
   1.158 -        lua_replace(L, 3);
   1.159 -      }
   1.160 -      if (terminatorlen && chunk[chunklen-1] == terminatorstr[0]) break;
   1.161 +      lua_rawseti(L, 5, lua_rawlen(L, 5) + 1);
   1.162      }
   1.163 +    if (remaining >= 0) {
   1.164 +      remaining -= len;
   1.165 +      lua_pushinteger(L, remaining);
   1.166 +      lua_replace(L, 3);
   1.167 +    }
   1.168 +    if (strcmp(lua_tostring(L, -1), "block") != 0) break;
   1.169 +    lua_pop(L, 1);
   1.170      lua_pushvalue(L, 2);
   1.171      lua_pushvalue(L, 1);
   1.172      lua_pushliteral(L, "r");
   1.173 @@ -360,7 +337,8 @@
   1.174      }
   1.175      luaL_pushresult(&buf);
   1.176    }
   1.177 -  return 1;
   1.178 +  lua_pushvalue(L, -2);
   1.179 +  return 2;
   1.180  }
   1.181  
   1.182  static int moonbr_io_read_call(lua_State *L) {
     2.1 --- a/reference.txt	Fri May 01 13:56:52 2015 +0200
     2.2 +++ b/reference.txt	Sat May 02 01:48:29 2015 +0200
     2.3 @@ -70,8 +70,8 @@
     2.4  ### socket:drain(maxlen, terminator)
     2.5  
     2.6  Same as socket:read(maxlen, terminator), but discards the input and returns the
     2.7 -number of discarded bytes. If no bytes could be read but EOF was encountered,
     2.8 -then true is returned.
     2.9 +number of discarded bytes (as first return value) and the status code ("term",
    2.10 +"maxlen", "eof" as second return value).
    2.11  
    2.12  In case of an I/O error, nil (as first return value) plus an error message (as
    2.13  second return value) are returned.
    2.14 @@ -79,9 +79,9 @@
    2.15  
    2.16  ### socket:drain_nb(maxlen, terminator)
    2.17  
    2.18 -Same as socket:read_nb(maxlen, terminator), but discards the input and returns
    2.19 -the number of discarded bytes. If no bytes could be read but EOF was
    2.20 -encountered, then true is returned. 
    2.21 +Same as socket:drain(maxlen, terminator), but non-blocking. The status code
    2.22 +(which is returned as second return value) may therefore be "term", "maxlen",
    2.23 +"eof", or "block".
    2.24  
    2.25  In case of an I/O error, nil (as first return value) plus an error message (as
    2.26  second return value) are returned.
    2.27 @@ -144,16 +144,24 @@
    2.28  
    2.29  ### socket:read(maxlen, terminator)
    2.30  
    2.31 -Read up to maxlen bytes or until an optional termination character is
    2.32 +Reads up to maxlen bytes or until an optional termination character is
    2.33  encountered (which is included in the result). The maxlen value may be nil, in
    2.34  which case there is no limit on the number of bytes read.
    2.35  
    2.36 -If EOF is encountered before any data could be read, then false (as first
    2.37 -return value) plus a notice string (as second return value) are returned.
    2.38 -
    2.39  In case of an I/O error, nil (as first return value) plus an error message (as
    2.40  second return value) are returned.
    2.41  
    2.42 +In all other cases (including EOF), the following two values are returned:
    2.43 +
    2.44 +- a string containing the bytes read (first return value, may be empty string)
    2.45 +- a status code equal to "term", "maxlen", or "eof" (second return value)
    2.46 +
    2.47 +If an EOF is encountered before all data could be read, then "eof" is returned
    2.48 +as second return value. If maxlen bytes have been read and no termination
    2.49 +character has been read, then "maxlen" is returned as second return value. If
    2.50 +the termination character is the last character of the read string, the second
    2.51 +return value will be "term".
    2.52 +
    2.53  
    2.54  ### socket:read_call(waitfunc, maxlen, terminator)
    2.55  
    2.56 @@ -163,20 +171,20 @@
    2.57  
    2.58  ### socket:read_nb(maxlen, terminator)
    2.59  
    2.60 -Read up to maxlen bytes, until an optional termination character is encountered
    2.61 -(which is included in the result), or until no more data is available for
    2.62 -reading. The maxlen value may be nil, in which case there is no limit on the
    2.63 -number of bytes read.
    2.64 -
    2.65 -If EOF is encountered before any data could be read, then false (as first
    2.66 -return value) plus a notice string (as second return value) are returned.
    2.67 -
    2.68 -If no data was available for reading, but no EOF was encountered, then an empty
    2.69 -string is returned.
    2.70 +Same as socket:read(maxlen, terminator), but does not block.
    2.71  
    2.72  In case of an I/O error, nil (as first return value) plus an error message (as
    2.73  second return value) are returned.
    2.74  
    2.75 +In all other cases (including EOF), the following two values are returned:
    2.76 +
    2.77 +- a string containing the bytes read (first return value, may be empty string)
    2.78 +- a status code equal to "term", "maxlen", "eof", "block" (second return value)
    2.79 +
    2.80 +The status code "block" as second return value is used if the function returned
    2.81 +prematurely because it would block otherwise. In this case, the first return
    2.82 +value is a string that contains the bytes that could be read without blocking.
    2.83 +
    2.84  
    2.85  ### socket:read_yield(maxlen, terminator)
    2.86  

Impressum / About Us