lua

A copy of the Lua development repository
Log | Files | Refs | README

lzio.c (1809B)


      1 /*
      2 ** $Id: lzio.c $
      3 ** Buffered streams
      4 ** See Copyright Notice in lua.h
      5 */
      6 
      7 #define lzio_c
      8 #define LUA_CORE
      9 
     10 #include "lprefix.h"
     11 
     12 
     13 #include <string.h>
     14 
     15 #include "lua.h"
     16 
     17 #include "lapi.h"
     18 #include "llimits.h"
     19 #include "lmem.h"
     20 #include "lstate.h"
     21 #include "lzio.h"
     22 
     23 
     24 int luaZ_fill (ZIO *z) {
     25   size_t size;
     26   lua_State *L = z->L;
     27   const char *buff;
     28   lua_unlock(L);
     29   buff = z->reader(L, z->data, &size);
     30   lua_lock(L);
     31   if (buff == NULL || size == 0)
     32     return EOZ;
     33   z->n = size - 1;  /* discount char being returned */
     34   z->p = buff;
     35   return cast_uchar(*(z->p++));
     36 }
     37 
     38 
     39 void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
     40   z->L = L;
     41   z->reader = reader;
     42   z->data = data;
     43   z->n = 0;
     44   z->p = NULL;
     45 }
     46 
     47 
     48 /* --------------------------------------------------------------- read --- */
     49 
     50 static int checkbuffer (ZIO *z) {
     51   if (z->n == 0) {  /* no bytes in buffer? */
     52     if (luaZ_fill(z) == EOZ)  /* try to read more */
     53       return 0;  /* no more input */
     54     else {
     55       z->n++;  /* luaZ_fill consumed first byte; put it back */
     56       z->p--;
     57     }
     58   }
     59   return 1;  /* now buffer has something */
     60 }
     61 
     62 
     63 size_t luaZ_read (ZIO *z, void *b, size_t n) {
     64   while (n) {
     65     size_t m;
     66     if (!checkbuffer(z))
     67       return n;  /* no more input; return number of missing bytes */
     68     m = (n <= z->n) ? n : z->n;  /* min. between n and z->n */
     69     memcpy(b, z->p, m);
     70     z->n -= m;
     71     z->p += m;
     72     b = (char *)b + m;
     73     n -= m;
     74   }
     75   return 0;
     76 }
     77 
     78 
     79 const void *luaZ_getaddr (ZIO* z, size_t n) {
     80   const void *res;
     81   if (!checkbuffer(z))
     82     return NULL;  /* no more input */
     83   if (z->n < n)  /* not enough bytes? */
     84     return NULL;  /* block not whole; cannot give an address */
     85   res = z->p;  /* get block address */
     86   z->n -= n;  /* consume these bytes */
     87   z->p += n;
     88   return res;
     89 }