Пример #1
0
int output(lua_State* lua)
{
    void* luserdata = lua_touserdata(lua, lua_upvalueindex(1));
    if (NULL == luserdata) {
        lua_pushstring(lua, "output() invalid lightuserdata");
        lua_error(lua);
    }
    lua_sandbox* lsb = (lua_sandbox*)luserdata;

    int n = lua_gettop(lua);
    if (n == 0) {
        lua_pushstring(lua, "output() must have at least one argument");
        lua_error(lua);
    }

    int result = 0;
    void* ud = NULL;
    for (int i = 1; result == 0 && i <= n; ++i) {
        switch (lua_type(lua, i)) {
        case LUA_TNUMBER:
            if (dynamic_snprintf(&lsb->m_output, "%0.9g",
                                 lua_tonumber(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TSTRING:
            if (dynamic_snprintf(&lsb->m_output, "%s", lua_tostring(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TNIL:
            if (dynamic_snprintf(&lsb->m_output, "nil")) {
                result = 1;
            }
            break;
        case LUA_TUSERDATA:
            ud = lua_touserdata(lua, i);
            if (heka_circular_buffer == userdata_type(lua, ud, i)) {
                if (output_circular_buffer((circular_buffer*)ud,
                                           &lsb->m_output)) {
                    result = 1;
                }
            }
            break;
        }
    }
    lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT] = lsb->m_output.m_pos;
    if (lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
        > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_MAXIMUM]) {
        lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_MAXIMUM] =
          lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT];
    }
    if (result != 0
        || lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
        > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_LIMIT]) {
        lua_pushstring(lua, "output_limit exceeded");
        lua_error(lua);
    }
    return 0;
}
Пример #2
0
int inject_message(lua_State* lua)
{
    static const char* default_type = "txt";
    static const char* default_name = "";
    void* luserdata = lua_touserdata(lua, lua_upvalueindex(1));
    if (NULL == luserdata) {
        luaL_error(lua, "inject_message() invalid lightuserdata");
    }
    lua_sandbox* lsb = (lua_sandbox*)luserdata;

    void* ud = NULL;
    const char* type = default_type;
    const char* name = default_name;
    switch (lua_gettop(lua)) {
    case 0:
        break;
    case 2:
        name = luaL_checkstring(lua, 2);
        // fallthru
    case 1:
        switch (lua_type(lua, 1)) {
        case LUA_TSTRING:
            type = lua_tostring(lua, 1);
            if (strlen(type) == 0) type = default_type;
            break;
        case LUA_TTABLE:
            type = "";
            if (serialize_table_as_pb(lsb) != 0) {
                luaL_error(lua, "inject_message() cound not encode protobuf - %s",
                           lsb->m_error_message);
            }
            break;
        case LUA_TUSERDATA:
            ud = lua_touserdata(lua, 1);
            if (heka_circular_buffer == userdata_type(lua, ud, 1)) {
                circular_buffer* cb = (circular_buffer*)ud;
                type = get_output_format(cb);
                lsb->m_output.m_pos = 0;
                if (output_circular_buffer(lua, cb, &lsb->m_output)) {
                    luaL_error(lua, lsb->m_error_message);
                }
            } else {
                luaL_typerror(lua, 1, "circular_buffer");
            }
            break;
        default:
            luaL_typerror(lua, 1, "string, table, or circular_buffer");
            break;
        }
        break;
    default:
        luaL_error(lua, "inject_message() takes a maximum of 2 arguments");
        break;
    }

    if (lsb->m_output.m_pos != 0) {
        update_output_stats(lsb);
        if (lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
            > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_LIMIT]) {
            if (lsb->m_error_message[0] == 0) {
                luaL_error(lua, "output_limit exceeded");
            }
            luaL_error(lua, lsb->m_error_message);
        }
        int result = go_lua_inject_message(lsb->m_go,
                                           lsb->m_output.m_data,
                                           (int)(lsb->m_output.m_pos),
                                           (char*)type,
                                           (char*)name);
        lsb->m_output.m_pos = 0;
        if (result != 0) {
            luaL_error(lua, "inject_message() exceeded MaxMsgLoops");
        }
    }
    return 0;
}
Пример #3
0
int output(lua_State* lua)
{
    void* luserdata = lua_touserdata(lua, lua_upvalueindex(1));
    if (NULL == luserdata) {
        luaL_error(lua, "output() invalid lightuserdata");
    }
    lua_sandbox* lsb = (lua_sandbox*)luserdata;

    int n = lua_gettop(lua);
    if (n == 0) {
        luaL_error(lua, "output() must have at least one argument");
    }

    int result = 0;
    void* ud = NULL;
    for (int i = 1; result == 0 && i <= n; ++i) {
        switch (lua_type(lua, i)) {
        case LUA_TNUMBER:
            if (serialize_double(&lsb->m_output, lua_tonumber(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TSTRING:
            if (dynamic_snprintf(&lsb->m_output, "%s", lua_tostring(lua, i))) {
                result = 1;
            }
            break;
        case LUA_TNIL:
            if (dynamic_snprintf(&lsb->m_output, "nil")) {
                result = 1;
            }
            break;
        case LUA_TBOOLEAN:
            if (dynamic_snprintf(&lsb->m_output, "%s",
                                 lua_toboolean(lsb->m_lua, i)
                                 ? "true" : "false")) {
                result = 1;
            }
            break;
        case LUA_TTABLE:
            if (!dynamic_snprintf(&lsb->m_output, "{")) {
                serialization_data data;
                data.m_globals = NULL;
                data.m_tables.m_size = 64;
                data.m_tables.m_pos = 0;
                data.m_tables.m_array = malloc(data.m_tables.m_size * sizeof(table_ref));
                if (data.m_tables.m_array == NULL) {
                    snprintf(lsb->m_error_message, ERROR_SIZE,
                             "json table serialization out of memory");
                    result = 1;
                } else {
                    lua_checkstack(lsb->m_lua, 2);
                    lua_getfield(lsb->m_lua, i, "_name");
                    if (lua_type(lsb->m_lua, -1) != LUA_TSTRING) {
                        lua_pop(lsb->m_lua, 1); // remove the failed _name result
                        lua_pushstring(lsb->m_lua, "table"); // add default name
                    }
                    lua_pushvalue(lsb->m_lua, i);
                    result = serialize_kvp_as_json(lsb, &data, 1);
                    if (result == 0) {
                        result = dynamic_snprintf(&lsb->m_output, "}\n");
                    }
                    lua_pop(lsb->m_lua, 2); // remove the name and copy of the table
                    free(data.m_tables.m_array);
                }
            } else {
                result = 1;
            }
            break;
        case LUA_TUSERDATA:
            ud = lua_touserdata(lua, i);
            if (heka_circular_buffer == userdata_type(lua, ud, i)) {
                if (output_circular_buffer(lua, (circular_buffer*)ud,
                                           &lsb->m_output)) {
                    result = 1;
                }
            }
            break;
        }
    }
    update_output_stats(lsb);
    if (result != 0
        || lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_CURRENT]
        > lsb->m_usage[USAGE_TYPE_OUTPUT][USAGE_STAT_LIMIT]) {
        if (lsb->m_error_message[0] == 0) {
            luaL_error(lua, "output_limit exceeded");
        }
        luaL_error(lua, lsb->m_error_message);
    }
    return 0;
}