예제 #1
0
파일: amf_codec.c 프로젝트: zhaoyao/lua-amf
void
amf0_decode_to_lua_table(lua_State *L, amf_cursor *c, int ridx)
{
    lua_newtable(L);
    amf0_decode_remember_ref(L, -1, ridx);

    for (;;) {
        amf0_decode_string(L, c, 16);
        amf_cursor_checkerr(c);


        amf_cursor_need(c, 1);
        if (c->p[0] == AMF0_END_OF_OBJECT || lua_objlen(L, -1) == 0) {
            lua_pop(L, 1); // the empty string
            amf_cursor_consume(c, 1);
            break;
        }

        amf0_decode(L, c, ridx);
        amf_cursor_checkerr(c);

        lua_rawset(L, -3);
    }

}
예제 #2
0
void amf_decode_msg(lua_State *L, amf_cursor *c)
{
    uint16_t ver, hc, bc;

    lua_createtable(L, 3, 0);

    amf_cursor_read_u16(c, &ver);
    amf_cursor_checkerr(c);
    lua_pushinteger(L, ver);
    lua_rawseti(L, -2, 1);


    /* headers */
    amf_cursor_read_u16(c, &hc);
    if (hc > 0) lua_createtable(L, hc, 0);
    unsigned int i;
    for (i = 0; i < hc; i++) {
        decode_hdr(L, c);
        amf_cursor_checkerr(c);
        lua_rawseti(L, -2, i+1);
    }
    lua_rawseti(L, -2, 2);

    /* bodies */
    amf_cursor_read_u16(c, &bc);
    if (bc > 0) lua_createtable(L, bc, 0);
    unsigned int j;
    for (j = 0; j < hc; j++) {
        decode_body(L, c);
        amf_cursor_checkerr(c);
        lua_rawseti(L, -2, j+1);
    }
    lua_rawseti(L, -2, 3);
}
예제 #3
0
static void
decode_hdr(lua_State *L, amf_cursor *c)
{
    lua_createtable(L, 3, 0);

    const char *name;
    size_t len;
    amf_cursor_read_str(c, &name, &len);
    amf_cursor_checkerr(c);
    lua_pushlstring(L, name, len);
    lua_rawseti(L, -2, 1);

    uint8_t must_understand;
    amf_cursor_read_u8(c, &must_understand);
    amf_cursor_checkerr(c);
    lua_pushboolean(L, must_understand);
    lua_rawseti(L, -2, 2);

    /* content length*/
    amf_cursor_skip(c, 4);

    lua_newtable(L);
    amf0_decode(L, c, lua_gettop(L));
    amf_cursor_checkerr(c);
    lua_rawseti(L, -3, 3);

    /* ref table */
    lua_pop(L, 1);
}
예제 #4
0
static void
decode_body(lua_State *L, amf_cursor *c)
{
    lua_createtable(L, 3, 0);

    const char *uri;
    size_t len;

    /* target uri */
    amf_cursor_read_str(c, &uri, &len);
    amf_cursor_checkerr(c);
    lua_pushlstring(L, uri, len);
    lua_rawseti(L, -2, 1);

    /* response uri */
    amf_cursor_read_str(c, &uri, &len);
    amf_cursor_checkerr(c);
    lua_pushlstring(L, uri, len);
    lua_rawseti(L, -2, 2);

    /* content length*/
    amf_cursor_skip(c, 4);

    lua_newtable(L);
    amf0_decode(L, c, lua_gettop(L));
    amf_cursor_checkerr(c);
    lua_rawseti(L, -3, 3);

    /* ref table */
    lua_pop(L, 1);

}
예제 #5
0
파일: amf_codec.c 프로젝트: zhaoyao/lua-amf
static void
amf3_decode_str(lua_State *L, amf_cursor *c, int sidx) {
    uint32_t ref, len;
    amf3_decode_u29(c, &ref);
    amf_cursor_checkerr(c);

    if (!amf3_is_ref(ref)) {
        len = ref >> 1;
        if (len > 0) {
            amf_cursor_need(c, len);
            lua_pushlstring(L, c->p, len);
            amf_cursor_consume(c, len);

            remember_object(L, -1, sidx);
        } else {
            lua_pushliteral(L, "");
        }
    } else {
예제 #6
0
파일: amf_codec.c 프로젝트: zhaoyao/lua-amf
void
amf0_decode(lua_State *L, amf_cursor *c, int ridx)
{
    amf_cursor_need(c, 1);

    switch (c->p[0]) {
    case AMF0_BOOLEAN:
        amf_cursor_need(c, 2);
        lua_pushboolean(L, c->p[1] == 0x01 ? 1 : 0);
        amf_cursor_consume(c, 2);

        break;

    case AMF0_NULL:
    case AMF0_UNDEFINED:
        lua_pushnil(L);
        amf_cursor_consume(c, 1);

        break;

    case AMF0_NUMBER:
        amf_cursor_need(c, 9);
        assert(sizeof(double) == 8);

        double d;
        memcpy(&d, c->p + 1, 8);
        reverse_if_little_endian(&d, 8);
        lua_pushnumber(L, d);
        amf_cursor_consume(c, 9);

        break;

    case AMF0_STRING:
        amf_cursor_consume(c, 1);
        amf0_decode_string(L, c, 16);

        break;

    case AMF0_L_STRING:
        amf_cursor_consume(c, 1);
        amf0_decode_string(L, c, 32);

        break;

    case AMF0_OBJECT:
        amf_cursor_consume(c, 1);
        amf0_decode_to_lua_table(L, c, ridx);
        break;

    case AMF0_ECMA_ARRAY:
        /* the property count, basicly 0 */
        amf_cursor_skip(c, 5);
        amf0_decode_to_lua_table(L, c, ridx);
        break;

    case AMF0_STRICT_ARRAY:
        amf_cursor_need(c, 5);
        uint32_t count = c->p[1] << 24
                         | c->p[2] << 16
                         | c->p[3] << 8
                         | c->p[4];
        amf_cursor_consume(c, 5);

        assert(count <= INT_MAX);
        if (count > INT_MAX) {
            c->err = AMF_CUR_ERR_BADFMT;
            c->err_msg = "strict array elements count overflow";
            return;
        }

        lua_createtable(L, (int)count, 0);
        amf0_decode_remember_ref(L, -1, ridx);

        for (int i = 1; i <= (int)count; i++) {
            amf0_decode(L, c, ridx);
            amf_cursor_checkerr(c);
            lua_rawseti(L, -2, i);
        }
        break;

    case AMF0_TYPED_OBJECT:
        amf_cursor_consume(c, 1);

        amf0_decode_string(L, c, 16);

        amf0_decode_to_lua_table(L, c, ridx);

        /* push alias name */
        lua_pushstring(L, "__amf_alias__");
        lua_pushvalue(L, -3);
        lua_rawset(L, -3);

        /* remove alias from stack */
        lua_remove(L, -2);

        break;

    case AMF0_REFERENCE:
        amf_cursor_need(c, 3);
        uint16_t ref = c->p[1] << 8 | c->p[2];
        amf_cursor_consume(c, 3);

        lua_rawgeti(L, ridx, ref + 1);
        if (lua_isnil(L, -1)) {
            c->err = AMF_CUR_ERR_BADFMT;
            c->err_msg = "reference not found";
            return;
        }

        break;

    case AMF0_AVMPLUS: {
        lua_newtable(L);
        lua_newtable(L);
        int sidx = lua_gettop(L);
        amf3_decode(L, c, sidx, ridx, sidx - 1);
        break;
    }

    default:
        c->err = AMF_CUR_ERR_BADFMT;

    }

}