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