static void read_all (lua_State *L, FILE *f) { size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ l_seeknum old, nrlen = 0; /* for testing file size */ luaL_Buffer b; luaL_buffinit(L, &b); /* speed up loading of not too large files: */ old = l_ftell(f); if ((l_fseek(f, 0, SEEK_END) >= 0) && ((nrlen = l_ftell(f)) > 0) && nrlen < 1000 * 1000 * 100) { rlen = nrlen; } l_fseek(f, old, SEEK_SET); for (;;) { char *p = luaL_prepbuffsize(&b, rlen); size_t nr = fread(p, sizeof(char), rlen, f); luaL_addsize(&b, nr); if (nr < rlen) break; /* eof? */ else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ rlen *= 2; /* double buffer size at each iteration */ } luaL_pushresult(&b); /* close buffer */ }
static int f_seek(lua_State *L) { static const int mode[] = { SEEK_SET, SEEK_CUR, SEEK_END }; static const char *const modenames[] = { "set", "cur", "end", NULL }; FILE *f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); lua_Number p3 = luaL_optnumber(L, 3, 0); l_seeknum offset = (l_seeknum)p3; luaL_argcheck(L, (lua_Number)offset == p3, 3, "not an integer in proper range"); op = l_fseek(f, offset, mode[op]); if (op) return luaL_fileresult(L, 0, NULL); /* error */ else { lua_pushnumber(L, (lua_Number)l_ftell(f)); return 1; } }