예제 #1
0
파일: use.c 프로젝트: 8l/myrddin
static void wrucon(FILE *fd, Ucon *uc)
{
    wrint(fd, uc->loc.line);
    wrint(fd, uc->id);
    wrbool(fd, uc->synth);
    pickle(fd, uc->name);
    wrbool(fd, uc->etype != NULL);
    if (uc->etype)
      wrtype(fd, uc->etype);
}
예제 #2
0
파일: use.c 프로젝트: 8l/myrddin
/* Writes the name and type of a variable,
 * but only writes its intializer for things
 * we want to inline cross-file (currently,
 * the only cross-file inline is generics) */
static void wrsym(FILE *fd, Node *val)
{
    /* sym */
    wrint(fd, val->loc.line);
    pickle(fd, val->decl.name);
    wrtype(fd, val->decl.type);

    /* symflags */
    wrint(fd, val->decl.vis);
    wrbool(fd, val->decl.isconst);
    wrbool(fd, val->decl.isgeneric);
    wrbool(fd, val->decl.isextern);
    wrbool(fd, val->decl.ispkglocal);
    wrbool(fd, val->decl.isnoret);
    wrbool(fd, val->decl.isexportinit);
    wrbool(fd, val->decl.isinit);
    if (val->decl.isexportinit) {
        pickle(fd, val->decl.init);
    }
}
예제 #3
0
void pickle(const boost::shared_ptr<EnumerationStrategyBase> &enumerator,
            std::string &s) {
#ifdef RDK_USE_BOOST_SERIALIZATION    
  std::stringstream ss;
  pickle(enumerator, ss);
  s = ss.str();
#else
  RDUNUSED_PARAM(enumerator);
  RDUNUSED_PARAM(s);
  PRECONDITION(0, "BOOST SERIALIZATION NOT INSTALLED");
#endif  
}
예제 #4
0
파일: use.c 프로젝트: 8l/myrddin
static void traitpickle(FILE *fd, Trait *tr)
{
    size_t i;

    wrint(fd, tr->uid);
    wrbool(fd, tr->ishidden);
    pickle(fd, tr->name);
    typickle(fd, tr->param);
    wrint(fd, tr->nmemb);
    for (i = 0; i < tr->nmemb; i++)
        wrsym(fd, tr->memb[i]);
    wrint(fd, tr->nfuncs);
    for (i = 0; i < tr->nfuncs; i++)
        wrsym(fd, tr->funcs[i]);
}
예제 #5
0
void LuaSerializer::Serialize(Serializer::Writer &wr)
{
	lua_State *l = Lua::manager->GetLuaState();

	LUA_DEBUG_START(l);

	lua_newtable(l);
	int savetable = lua_gettop(l);

	lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks");
	if (lua_isnil(l, -1)) {
		lua_pop(l, 1);
		lua_newtable(l);
		lua_pushvalue(l, -1);
		lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks");
	}

	lua_pushnil(l);
	while (lua_next(l, -2) != 0) {
		lua_pushinteger(l, 1);
		lua_gettable(l, -2);
		pi_lua_protected_call(l, 0, 1);
		lua_pushvalue(l, -3);
		lua_insert(l, -2);
		lua_settable(l, savetable);
		lua_pop(l, 1);
	}

	lua_pop(l, 1);

	lua_newtable(l);
	lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");

	std::string pickled;
	pickle(l, savetable, pickled);

	wr.String(pickled);

	lua_pop(l, 1);

	lua_pushnil(l);
	lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");

	LUA_DEBUG_END(l, 0);
}
예제 #6
0
void LuaSerializer::ToJson(Json::Value &jsonObj)
{
	PROFILE_SCOPED()
	lua_State *l = Lua::manager->GetLuaState();

	LUA_DEBUG_START(l);

	lua_newtable(l);
	int savetable = lua_gettop(l);

	lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks");
	if (lua_isnil(l, -1)) {
		lua_pop(l, 1);
		lua_newtable(l);
		lua_pushvalue(l, -1);
		lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks");
	}

	lua_pushnil(l);
	while (lua_next(l, -2) != 0) {
		lua_pushinteger(l, 1); // 1, fntable, key
		lua_gettable(l, -2); // fn, fntable, key
		pi_lua_protected_call(l, 0, 1); // table, fntable, key
		lua_pushvalue(l, -3); // key, table, fntable, key
		lua_insert(l, -2); // table, key, fntable, key
		lua_settable(l, savetable); // fntable, key
		lua_pop(l, 1);
	}

	lua_pop(l, 1);

	std::string pickled;
	pickle(l, savetable, pickled);

	BinStrToJson(jsonObj, pickled, "lua_modules");

	lua_pop(l, 1);

	LUA_DEBUG_END(l, 0);
}
예제 #7
0
파일: use.c 프로젝트: 8l/myrddin
/* Outputs a symbol table to file in a way that can be
 * read back usefully. Only writes declarations, types
 * and sub-namespaces. Captured variables are ommitted. */
static void wrstab(FILE *fd, Stab *val)
{
    size_t n, i;
    void **keys;

    wrstr(fd, val->name);

    /* write decls */
    keys = htkeys(val->dcl, &n);
    wrint(fd, n);
    for (i = 0; i < n; i++)
        wrsym(fd, getdcl(val, keys[i]));
    free(keys);

    /* write types */
    keys = htkeys(val->ty, &n);
    wrint(fd, n);
    for (i = 0; i < n; i++) {
        pickle(fd, keys[i]); /* name */
        wrtype(fd, gettype(val, keys[i])); /* type */
    }
    free(keys);

}
예제 #8
0
파일: use.c 프로젝트: 8l/myrddin
/* Usefile format:
 * U<pkgname>
 * L<liblist>
 * I<initlist>
 * T<pickled-type>
 * D<picled-decl>
 * G<pickled-decl><pickled-initializer>
 * Z
 */
void writeuse(FILE *f, Node *file)
{
    Stab *st;
    void **k;
    Node *s, *u;
    size_t i, n;

    assert(file->type == Nfile);
    st = file->file.globls;

    /* usefile name */
    wrbyte(f, 'U');
    wrint(f, Abiversion);        /* use version */
    if (st->name)
        wrstr(f, st->name);
    else
        wrstr(f, NULL);

    /* library deps */
    for (i = 0; i < file->file.nuses; i++) {
        u = file->file.uses[i];
        if (!u->use.islocal) {
            wrbyte(f, 'L');
            wrstr(f, u->use.name);
        }
    }
    for (i = 0; i < file->file.nlibdeps; i++) {
        wrbyte(f, 'L');
        wrstr(f, file->file.libdeps[i]);
    }
    for (i = 0; i < file->file.nextlibs; i++) {
        wrbyte(f, 'X');
        wrstr(f, file->file.extlibs[i]);
    }

    /* source file name */
    wrbyte(f, 'F');
    wrstr(f, file->file.files[0]);

    for (i = 0; i < ntypes; i++) {
        if (types[i]->vis == Visexport || types[i]->vis == Vishidden) {
            wrbyte(f, 'T');
            wrint(f, types[i]->tid);
            typickle(f, types[i]);
        }
    }

    for (i = 0; i < ntraittab; i++) {
        if (traittab[i]->vis == Visexport || traittab[i]->vis == Vishidden) {
            wrbyte(f, 'R');
            traitpickle(f, traittab[i]);
        }
    }

    k = htkeys(st->impl, &n);
    for (i = 0; i < n; i++) {
        /* merging during inference should remove all protos */
        s = getimpl(st, k[i]);
        assert(!s->impl.isproto);
        if (s->impl.vis == Visexport || s->impl.vis == Vishidden) {
            wrbyte(f, 'I');
            pickle(f, s);
        }
    }
    free(k);

    k = htkeys(st->dcl, &n);
    for (i = 0; i < n; i++) {
        s = getdcl(st, k[i]);
        assert(s != NULL);
        if (s->decl.vis == Visintern || s->decl.vis == Visbuiltin)
            continue;
        /* trait functions get written out with their traits */
        if (s->decl.trait || s->decl.isinit)
            continue;
        else if (s->decl.isgeneric)
            wrbyte(f, 'G');
        else
            wrbyte(f, 'D');
        wrsym(f, s);
    }
    for (i = 0; i < file->file.ninit; i++) {
        wrbyte(f, 'S');
        pickle(f, file->file.init[i]);
    }
    if (file->file.localinit) {
        wrbyte(f, 'S');
        pickle(f, file->file.localinit->decl.name);
    }
    free(k);
}
예제 #9
0
파일: use.c 프로젝트: 8l/myrddin
/* Pickles a node to a file.  The format
 * is more or less equivalen to to
 * simplest serialization of the
 * in-memory representation. Minimal
 * checking is done, so a bad type can
 * crash the compiler */
static void pickle(FILE *fd, Node *n)
{
    size_t i;

    if (!n) {
        wrbyte(fd, Nnone);
        return;
    }
    wrbyte(fd, n->type);
    wrint(fd, n->loc.line);
    switch (n->type) {
        case Nfile:
            wrstr(fd, n->file.files[0]);
            wrint(fd, n->file.nuses);
            for (i = 0; i < n->file.nuses; i++)
                pickle(fd, n->file.uses[i]);
            wrint(fd, n->file.nstmts);
            for (i = 0; i < n->file.nstmts; i++)
                pickle(fd, n->file.stmts[i]);
            wrstab(fd, n->file.globls);
            break;

        case Nexpr:
            wrbyte(fd, n->expr.op);
            wrtype(fd, n->expr.type);
            wrbool(fd, n->expr.isconst);
            pickle(fd, n->expr.idx);
            wrint(fd, n->expr.nargs);
            for (i = 0; i < n->expr.nargs; i++)
                pickle(fd, n->expr.args[i]);
            break;
        case Nname:
            wrbool(fd, n->name.ns != NULL);
            if (n->name.ns) {
                wrstr(fd, n->name.ns);
            }
            wrstr(fd, n->name.name);
            break;
        case Nuse:
            wrbool(fd, n->use.islocal);
            wrstr(fd, n->use.name);
            break;
        case Nlit:
            wrbyte(fd, n->lit.littype);
            wrtype(fd, n->lit.type);
            wrint(fd, n->lit.nelt);
            switch (n->lit.littype) {
                case Lchr:      wrint(fd, n->lit.chrval);       break;
                case Lint:      wrint(fd, n->lit.intval);       break;
                case Lflt:      wrflt(fd, n->lit.fltval);       break;
                case Lstr:      wrlenstr(fd, n->lit.strval);    break;
                case Llbl:      wrstr(fd, n->lit.lblval);       break;
                case Lbool:     wrbool(fd, n->lit.boolval);     break;
                case Lfunc:     pickle(fd, n->lit.fnval);       break;
            }
            break;
        case Nloopstmt:
            pickle(fd, n->loopstmt.init);
            pickle(fd, n->loopstmt.cond);
            pickle(fd, n->loopstmt.step);
            pickle(fd, n->loopstmt.body);
            break;
        case Niterstmt:
            pickle(fd, n->iterstmt.elt);
            pickle(fd, n->iterstmt.seq);
            pickle(fd, n->iterstmt.body);
            break;
        case Nmatchstmt:
            pickle(fd, n->matchstmt.val);
            wrint(fd, n->matchstmt.nmatches);
            for (i = 0; i < n->matchstmt.nmatches; i++)
                pickle(fd, n->matchstmt.matches[i]);
            break;
        case Nmatch:
            pickle(fd, n->match.pat);
            pickle(fd, n->match.block);
            break;
        case Nifstmt:
            pickle(fd, n->ifstmt.cond);
            pickle(fd, n->ifstmt.iftrue);
            pickle(fd, n->ifstmt.iffalse);
            break;
        case Nblock:
            wrstab(fd, n->block.scope);
            wrint(fd, n->block.nstmts);
            for (i = 0; i < n->block.nstmts; i++)
                pickle(fd, n->block.stmts[i]);
            break;
        case Ndecl:
            /* sym */
            pickle(fd, n->decl.name);
            wrtype(fd, n->decl.type);

            /* symflags */
            wrbool(fd, n->decl.isconst);
            wrbool(fd, n->decl.isgeneric);
            wrbool(fd, n->decl.isextern);
            wrbool(fd, n->decl.isnoret);
            wrbool(fd, n->decl.ispkglocal);

            /* init */
            pickle(fd, n->decl.init);
            break;
        case Nfunc:
            wrtype(fd, n->func.type);
            wrstab(fd, n->func.scope);
            wrint(fd, n->func.nargs);
            for (i = 0; i < n->func.nargs; i++)
                pickle(fd, n->func.args[i]);
            pickle(fd, n->func.body);
            break;
        case Nimpl:
            pickle(fd, n->impl.traitname);
            wrint(fd, n->impl.trait->uid);
            wrtype(fd, n->impl.type);
            wrint(fd, n->impl.ndecls);
            for (i = 0; i < n->impl.ndecls; i++)
                wrsym(fd, n->impl.decls[i]);
            break;
        case Nnone:
            die("Nnone should not be seen as node type!");
            break;
    }
}
예제 #10
0
파일: use.c 프로젝트: 8l/myrddin
/* Writes types to a file. Errors on
 * internal only types like Tyvar that
 * will not be meaningful in another file*/
static void typickle(FILE *fd, Type *ty)
{
    size_t i;

    if (!ty) {
        die("trying to pickle null type\n");
        return;
    }
    wrbyte(fd, ty->type);
    wrbyte(fd, ty->vis);
    /* tid is generated; don't write */
    /* FIXME: since we only support hardcoded traits, we just write
     * out the set of them. we should write out the trait list as
     * well */
    if (!ty->traits) {
        wrint(fd, 0);
    } else {
        wrint(fd, bscount(ty->traits));
        for (i = 0; bsiter(ty->traits, &i); i++) {
            if (i < Ntraits)
                wrint(fd, i | Builtinmask);
            else
                wrint(fd, i);
        }
    }
    wrint(fd, ty->nsub);
    switch (ty->type) {
        case Tyunres:
            pickle(fd, ty->name);
            break;
        case Typaram:
            wrstr(fd, ty->pname);
            break;
        case Tystruct:
            wrint(fd, ty->nmemb);
            for (i = 0; i < ty->nmemb; i++)
                pickle(fd, ty->sdecls[i]);
            break;
        case Tyunion:
            wrint(fd, ty->nmemb);
            for (i = 0; i < ty->nmemb; i++)
                wrucon(fd, ty->udecls[i]);
            break;
        case Tyarray:
            wrtype(fd, ty->sub[0]);
            pickle(fd, ty->asize);
            break;
        case Tyslice:
            wrtype(fd, ty->sub[0]);
            break;
        case Tyvar:
            die("Attempting to pickle %s. This will not work.\n", tystr(ty));
            break;
        case Tyname:
            pickle(fd, ty->name);
            wrbool(fd, ty->issynth);
            wrint(fd, ty->narg);
            for (i = 0; i < ty->narg; i++)
                wrtype(fd, ty->arg[i]);
            wrtype(fd, ty->sub[0]);
            break;
        case Tygeneric:
            pickle(fd, ty->name);
            wrbool(fd, ty->issynth);
            wrint(fd, ty->ngparam);
            for (i = 0; i < ty->ngparam; i++)
                wrtype(fd, ty->gparam[i]);
            wrtype(fd, ty->sub[0]);
            break;
        default:
            for (i = 0; i < ty->nsub; i++)
                wrtype(fd, ty->sub[i]);
            break;
    }
}
예제 #11
0
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	idx = lua_absindex(l, idx);

	if (lua_getmetatable(l, idx)) {
		lua_getfield(l, -1, "class");
		if (lua_isnil(l, -1))
			lua_pop(l, 2);

		else {
			const char *cl = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "o%s\n", cl);

			lua_getglobal(l, cl);
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_getfield(l, -1, "Serialize");
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_pushvalue(l, idx);
			pi_lua_protected_call(l, 1, 1);

			lua_remove(l, idx);
			lua_insert(l, idx);

			lua_pop(l, 3);

			if (lua_isnil(l, idx)) {
				LUA_DEBUG_END(l, 0);
				return;
			}

			out += buf;
		}
	}

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			const char *str = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", strlen(str));
			out += buf;
			out += str;
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			lua_pushinteger(l, lua_Integer(lua_topointer(l, idx)));         // ptr

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");    // ptr reftable
			lua_pushvalue(l, -2);                                           // ptr reftable ptr
			lua_rawget(l, -2);                                              // ptr reftable ???

			if (!lua_isnil(l, -1)) {
				out += "r";
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]
			}

			else {
				out += "t";

				lua_pushvalue(l, -3);                                       // ptr reftable nil ptr
				lua_pushvalue(l, idx);                                      // ptr reftable nil ptr table
				lua_rawset(l, -4);                                          // ptr reftable nil
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]

				lua_pushvalue(l, idx);
				lua_pushnil(l);
				while (lua_next(l, -2)) {
					if (key) {
						pickle(l, -2, out, key);
						pickle(l, -1, out, key);
					}
					else {
						lua_pushvalue(l, -2);
						const char *k = lua_tostring(l, -1);
						pickle(l, -3, out, k);
						pickle(l, -2, out, k);
						lua_pop(l, 1);
					}
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
				out += "n";
			}

			break;
		}

		case LUA_TUSERDATA: {
			out += "u";
			lid *idp = static_cast<lid*>(lua_touserdata(l, idx));
			LuaObjectBase *lo = LuaObjectBase::Lookup(*idp);
			if (!lo)
				Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp);

			// XXX object wrappers should really have Serialize/Unserialize
			// methods to deal with this
			if (lo->Isa("SystemPath")) {
				SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object);
				snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%u\n%u\n",
					sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex);
				out += buf;
				break;
			}

			if (lo->Isa("Body")) {
				Body *b = dynamic_cast<Body*>(lo->m_object);
				snprintf(buf, sizeof(buf), "Body\n%u\n", Pi::game->GetSpace()->GetIndexForBody(b));
				out += buf;
				break;
			}

			Error("Lua serializer '%s' tried to serialize unsupported userdata value", key);
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx)));
			break;
	}

	LUA_DEBUG_END(l, 0);
}
예제 #12
0
void LuaSerializer::pickle(lua_State *l, int to_serialize, std::string &out, std::string key)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	// tables are pickled recursively, so we can run out of Lua stack space if we're not careful
	// start by ensuring we have enough (this grows the stack if necessary)
	// (20 is somewhat arbitrary)
	if (!lua_checkstack(l, 20))
		luaL_error(l, "The Lua stack couldn't be extended (out of memory?)");

	to_serialize = lua_absindex(l, to_serialize);
	int idx = to_serialize;

	if (lua_getmetatable(l, idx)) {
		lua_getfield(l, -1, "class");
		if (lua_isnil(l, -1))
			lua_pop(l, 2);

		else {
			const char *cl = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "o%s\n", cl);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses");

			lua_getfield(l, -1, cl);
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_getfield(l, -1, "Serialize");
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_pushvalue(l, idx);
			pi_lua_protected_call(l, 1, 1);

			idx = lua_gettop(l);

			if (lua_isnil(l, idx)) {
				lua_pop(l, 5);
				LUA_DEBUG_END(l, 0);
				return;
			}

			out += buf;
		}
	}

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			size_t len;
			const char *str = lua_tolstring(l, -1, &len);
			snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", len);
			out += buf;
			out.append(str, len);
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			lua_pushinteger(l, lua_Integer(lua_topointer(l, to_serialize)));         // ptr

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");    // ptr reftable
			lua_pushvalue(l, -2);                                           // ptr reftable ptr
			lua_rawget(l, -2);                                              // ptr reftable ???

			if (!lua_isnil(l, -1)) {
				out += "r";
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]
			}

			else {
				out += "t";

				lua_pushvalue(l, -3);                                       // ptr reftable nil ptr
				lua_pushvalue(l, to_serialize);                                      // ptr reftable nil ptr table
				lua_rawset(l, -4);                                          // ptr reftable nil
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]

				lua_pushvalue(l, idx);
				lua_pushnil(l);
				while (lua_next(l, -2)) {

					lua_pushvalue(l, -2);
					const char *k = lua_tostring(l, -1);
					std::string new_key = key + "." + (k? std::string(k) : "<" + std::string(lua_typename(l, lua_type(l, -1))) + ">");
					lua_pop(l, 1);

					// Copy the values to pickle, as they might be mutated by the pickling process.
					pickle(l, -2, out, new_key);
					pickle(l, -1, out, new_key);
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
				out += "n";
			}

			break;
		}

		case LUA_TUSERDATA: {
			out += "u";

			LuaObjectBase *lo = static_cast<LuaObjectBase*>(lua_touserdata(l, idx));
			void *o = lo->GetObject();
			if (!o)
				Error("Lua serializer '%s' tried to serialize an invalid '%s' object", key.c_str(), lo->GetType());

			out += lo->Serialize();
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key.c_str(), lua_typename(l, lua_type(l, idx)));
			break;
	}

	if (idx != lua_absindex(l, to_serialize)) // It means we called a transformation function on the data, so we clean it up.
		lua_pop(l, 5);

	LUA_DEBUG_END(l, 0);
}
예제 #13
0
//-------------------------------------------------------------------------------------
std::string Pickler::pickle(PyObject* pyobj)
{
	return pickle(pyobj, 2);
}
예제 #14
0
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			const char *str = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "s%lu\n", strlen(str));
			out += buf;
			out += str;
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			out += "t";
			lua_pushvalue(l, idx);
			lua_pushnil(l);
			while (lua_next(l, -2)) {
				if (key) {
					pickle(l, -2, out, key);
					pickle(l, -1, out, key);
				}
				else {
					lua_pushvalue(l, -2);
					const char *k = lua_tostring(l, -1);
					pickle(l, -3, out, k);
					pickle(l, -2, out, k);
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
			}
			lua_pop(l, 1);
			out += "n";
			break;
		}

		case LUA_TUSERDATA: {
			out += "u";
			lid *idp = static_cast<lid*>(lua_touserdata(l, idx));
			LuaObjectBase *lo = LuaObjectBase::Lookup(*idp);
			if (!lo)
				Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp);

			// XXX object wrappers should really have Serialize/Unserialize
			// methods to deal with this
			if (lo->Isa("SystemPath")) {
				SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object);
				snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%d\n%d\n",
					sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex);
				out += buf;
				break;
			}

			if (lo->Isa("Body")) {
				Body *b = dynamic_cast<Body*>(lo->m_object);
				snprintf(buf, sizeof(buf), "Body\n%d\n", Serializer::LookupBody(b));
				out += buf;
				break;
			}

			Error("Lua serializer '%s' tried to serialize unsupported userdata value", key);
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx)));
			break;
	}

	LUA_DEBUG_END(l, 0);
}