r406 - trunk
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Jan 13 01:49:48 EST 2008
Author: icculus
Date: 2008-01-13 01:49:48 -0500 (Sun, 13 Jan 2008)
New Revision: 406
Modified:
trunk/fileio.c
trunk/fileio.h
trunk/lua_glue.c
Log:
Added MojoInput that reads from a memory buffer, and lua glue that uses it to
dumping a string to a file. This will eventually remove the need to use the
Lua "io" package in the loki_setup bridge.
Modified: trunk/fileio.c
===================================================================
--- trunk/fileio.c 2008-01-12 12:49:47 UTC (rev 405)
+++ trunk/fileio.c 2008-01-13 06:49:48 UTC (rev 406)
@@ -281,6 +281,128 @@
} // MojoInput_newFromFile
+
+// MojoInputs from blocks of memory.
+
+typedef struct
+{
+ void *ptr; // original pointer from xmalloc()
+ uint32 *refcount; // address in xmalloc()'d block for reference count.
+ const uint8 *data; // base of actual "file" data in xmalloc()'d block.
+ uint32 len; // size, in bytes, of "file" data.
+ uint32 pos; // current read position.
+} MojoInputMemInstance;
+
+static boolean MojoInput_memory_ready(MojoInput *io)
+{
+ return true; // always ready!
+} // MojoInput_memory_ready
+
+static int64 MojoInput_memory_read(MojoInput *io, void *buf, uint32 bufsize)
+{
+ MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque;
+ const uint32 avail = inst->len - inst->pos;
+ if (bufsize > avail)
+ bufsize = avail;
+ memcpy(buf, inst->data + inst->pos, bufsize);
+ inst->pos += bufsize;
+ return bufsize;
+} // MojoInput_memory_read
+
+static boolean MojoInput_memory_seek(MojoInput *io, uint64 pos)
+{
+ MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque;
+ if (pos > (uint64) inst->len)
+ return false;
+ inst->pos = (uint32) pos;
+ return true;
+} // MojoInput_memory_seek
+
+static int64 MojoInput_memory_tell(MojoInput *io)
+{
+ MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque;
+ return (int64) inst->pos;
+} // MojoInput_memory_tell
+
+static int64 MojoInput_memory_length(MojoInput *io)
+{
+ MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque;
+ return (int64) inst->len;
+} // MojoInput_memory_length
+
+static MojoInput *MojoInput_memory_duplicate(MojoInput *io)
+{
+ MojoInputMemInstance *srcinst = (MojoInputMemInstance *) io->opaque;
+ MojoInput *retval = NULL;
+ MojoInputMemInstance *inst = NULL;
+
+ if (srcinst->refcount != NULL)
+ {
+ // we don't copy the data for each duplicate; we just bump a reference
+ // counter. We free the data when all referencers are closed.
+ (*srcinst->refcount)++; // !!! FIXME: not thread safe!
+ } // if
+
+ inst = (MojoInputMemInstance*) xmalloc(sizeof (MojoInputMemInstance));
+ memcpy(inst, srcinst, sizeof (MojoInputMemInstance));
+ inst->pos = 0;
+
+ retval = (MojoInput *) xmalloc(sizeof (MojoInput));
+ memcpy(retval, io, sizeof (MojoInput));
+ retval->opaque = inst;
+
+ return retval;
+} // MojoInput_memory_duplicate
+
+static void MojoInput_memory_close(MojoInput *io)
+{
+ MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque;
+
+ if (inst->refcount != NULL) // memory we have to free?
+ {
+ assert(*inst->refcount > 0);
+ if (--(*inst->refcount) == 0) // !!! FIXME: not thread safe!
+ free(inst->ptr);
+ } // if
+
+ free(inst);
+ free(io);
+} // MojoInput_memory_close
+
+MojoInput *MojoInput_newFromMemory(const uint8 *ptr, uint32 len, int constant)
+{
+ MojoInput *io = (MojoInput *) xmalloc(sizeof (MojoInput));
+ MojoInputMemInstance *inst = (MojoInputMemInstance*)
+ xmalloc(sizeof (MojoInputMemInstance));
+
+ if (constant)
+ inst->data = ptr;
+ else
+ {
+ inst->ptr = xmalloc(len + sizeof (uint32));
+ inst->refcount = (uint32 *) inst->ptr;
+ inst->data = ((const uint8 *) inst->ptr) + sizeof (uint32);
+ *inst->refcount = 1;
+ memcpy((void *) inst->data, ptr, len);
+ } // else
+
+ inst->len = len;
+
+ io->ready = MojoInput_memory_ready;
+ io->read = MojoInput_memory_read;
+ io->seek = MojoInput_memory_seek;
+ io->tell = MojoInput_memory_tell;
+ io->length = MojoInput_memory_length;
+ io->duplicate = MojoInput_memory_duplicate;
+ io->close = MojoInput_memory_close;
+ io->opaque = inst;
+
+ return io;
+} // MojoInput_newFromMemory
+
+
+
+
// MojoArchives from directories on the OS filesystem.
typedef struct DirStack
Modified: trunk/fileio.h
===================================================================
--- trunk/fileio.h 2008-01-12 12:49:47 UTC (rev 405)
+++ trunk/fileio.h 2008-01-13 06:49:48 UTC (rev 406)
@@ -44,8 +44,11 @@
void *opaque;
};
+// This copies the memory, so you may free (ptr) after this function returns.
+MojoInput *MojoInput_newFromMemory(const uint8 *ptr, uint32 len, int constant);
MojoInput *MojoInput_newFromFile(const char *fname);
+
typedef enum
{
MOJOARCHIVE_ENTRY_UNKNOWN = 0,
Modified: trunk/lua_glue.c
===================================================================
--- trunk/lua_glue.c 2008-01-12 12:49:47 UTC (rev 405)
+++ trunk/lua_glue.c 2008-01-13 06:49:48 UTC (rev 406)
@@ -979,6 +979,38 @@
} // luahook_movefile
+// !!! FIXME: this is a lot of duplication from luahook_writefile
+static int luahook_stringtofile(lua_State *L)
+{
+ const char *str = luaL_checkstring(L, 1);
+ const char *path = luaL_checkstring(L, 2);
+ MojoInput *in = NULL;
+ size_t len = 0;
+ int retval = 0;
+ boolean rc = false;
+ uint16 perms = 0600; // !!! FIXME
+ MojoChecksums sums;
+
+ str = lua_tolstring(L, 1, &len);
+ in = MojoInput_newFromMemory((const uint8 *) str, (uint32) len, 1);
+ assert(in != NULL); // xmalloc() would fatal(), should not return NULL.
+ if (!lua_isnil(L, 3))
+ {
+ boolean valid = false;
+ const char *permstr = luaL_checkstring(L, 3);
+ perms = MojoPlatform_makePermissions(permstr, &valid);
+ if (!valid)
+ fatal(_("BUG: '%0' is not a valid permission string"), permstr);
+ } // if
+ rc = MojoInput_toPhysicalFile(in, path, perms, &sums, writeCallback, L);
+
+ retval += retvalBoolean(L, rc);
+ if (rc)
+ retval += retvalChecksums(L, &sums);
+ return retval;
+} // luahook_stringtofile
+
+
static void prepareSplash(MojoGuiSplash *splash, const char *fname)
{
MojoInput *io = NULL;
@@ -1510,6 +1542,7 @@
set_cfunc(luaState, luahook_debugger, "debugger");
set_cfunc(luaState, luahook_findmedia, "findmedia");
set_cfunc(luaState, luahook_writefile, "writefile");
+ set_cfunc(luaState, luahook_stringtofile, "stringtofile");
set_cfunc(luaState, luahook_download, "download");
set_cfunc(luaState, luahook_movefile, "movefile");
set_cfunc(luaState, luahook_wildcardmatch, "wildcardmatch");
More information about the mojosetup-commits
mailing list