Ïåðåéòè èç ôîðóìà íà ñàéò.

ÍîâîñòèÔàéëîâûå àðõèâû
ÏîèñêÀêòèâíûå òåìûÒîï ëèñò
ÏðàâèëàÊòî â on-line?
Âõîä Çàáûëè ïàðîëü? Ïåðâûé ðàç íà ýòîì ñàéòå? Ðåãèñòðàöèÿ
Êîìïüþòåðíûé ôîðóì Ru.Board » Êîìïüþòåðû » Ïðîãðàììû » Indigo Rose AutoPlay Media Studio (÷àñòü 5)

Ìîäåðèðóåò : gyra, Maz

 Âåðñèÿ äëÿ ïå÷àòè • ÏîäïèñàòüñÿÄîáàâèòü â çàêëàäêè
Íà ïåðâóþ ñòðàíèöóê ýòîìó ñîîáùåíèþê ïîñëåäíåìó ñîîáùåíèþ

Îòêðûòü íîâóþ òåìó     Íàïèñàòü îòâåò â ýòó òåìó

KerberX



Full Member
Ðåäàêòèðîâàòü | Ïðîôèëü | Ñîîáùåíèå | Öèòèðîâàòü | Ñîîáùèòü ìîäåðàòîðó

Êîä:
local function LoadDump(...)
    local _M = {}
    -- local _NAME = ... or 'test'
 
    local io = require 'io'
    local os = require 'os'
    local math = require 'math'
    local table = require 'table'
    local string = require 'string'
 
    _M.groupsize = 4096
 
    local dumptablecontent
 
    local tkeys = {
        boolean = true,
        number = true,
        string = true,
    }
    local tvalues = {
        boolean = true,
        number = true,
        string = true,
        table = true,
    }
 
    local function dumptable(table, write, level, refs)
        -- prefix and suffix
        local mt = getmetatable(table)
        local prefix = mt and mt.__dump_prefix
        local suffix = mt and mt.__dump_suffix
        if type(prefix)=='function' then
            prefix = prefix(table)
        end
        prefix = prefix or ""
        if type(suffix)=='function' then
            suffix = suffix(table)
        end
        suffix = suffix or ""
 
        -- count keys
        local nkeys = 0
        for k,v in pairs(table) do
            nkeys = nkeys + 1
            local tk,tv = type(k),type(v)
            if not tkeys[tk] then
                return nil,"unsupported key type '"..tk.."'"
            end
            if not (tvalues[tv] or getmetatable(v) and getmetatable(v).__dump) then
                return nil,"unsupported value type '"..tv.."'"
            end
        end
 
        -- if too many keys, use multiple closures
        if nkeys > _M.groupsize then
            local success,err
            success,err = write(((prefix..[[
    (function()
        local t = { function() return {
    ]]):gsub("\n", "\n"..("\t"):rep(level))))
            if not success then return nil,err end
            success,err = dumptablecontent(table, write, level+2, _M.groupsize, ("\t"):rep(level+1)..'} end, function() return {\n', refs)
            if not success then return nil,err end
            success,err = write((([[
        } end }
        local result = {}
        for _,f in ipairs(t) do
            for k,v in pairs(f()) do
                result[k] = v
            end
        end
        return result
    end)()]]..suffix):gsub("\n", "\n"..("\t"):rep(level))))
            if not success then return nil,err end
            return true
        elseif nkeys==0 then
            local success,err = write(prefix.."{ }"..suffix)
            if not success then return nil,err end
            return true
        else
            local success,err
            success,err = write(prefix.."{\n")
            if not success then return nil,err end
            success,err = dumptablecontent(table, write, level+1, nil, nil, refs)
            if not success then return nil,err end
            success,err = write(("\t"):rep(level).."}"..suffix)
            if not success then return nil,err end
            return true
        end
    end
 
    local function dumpvalue(v, write, level, refs, iskey)
        local mt = getmetatable(v)
        local dump = mt and mt.__dump
        if type(dump)=='function' then
            dump = dump(v)
        end
        if dump~=nil then
            return write(dump)
        end
        local t = type(v)
        if t=='string' then
            if not iskey and v:match('\n.*\n') and not v:match('[\000-\008\011-\031\127]') then
                local eq
                for i=0,math.huge do
                    eq = string.rep('=', i)
                    if not v:match('%]'..eq..'%]') then
                        break
                    end
                end
                return write('['..eq..'[\n'..v..']'..eq..']')
            else
                return write('"'..v:gsub('[%z\1-\31\127"\\]', function(c)
                    if c=='\\' then
                        return '\\\\'
                    elseif c=='"' then
                        return '\\"'
                    elseif c=='\t' then
                        return '\\t'
                    elseif c=='\n' then
                        return '\\n'
                    elseif c=='\r' then
                        return '\\r'
                    else
                        return string.format('\\%03d', string.byte(c))
                    end
                end)..'"')
            end
        elseif t=='number' then
            if v~=v then -- nan
                return write('0/0')
            elseif v==1/0 then -- +inf
                return write('1/0')
            elseif v==-1/0 then -- -inf
                return write('-1/0')
            elseif v==math.floor(v) then
                return write(tostring(v))
            else
                local s = string.format('%.18f', v):gsub('(%..-)0*$', '%1')
                if tonumber(s)~=v then
                    s = string.format("%a", v) -- Lua 5.3.1
                end
                if tonumber(s)~=v then
                    s = string.format("%.13a", v) -- Lua 5.3.0
                end
                return write(s)
            end
        elseif t=='boolean' then
            if v then
                return write('true')
            else
                return write('false')
            end
        elseif t=='nil' then
            return write('nil')
        elseif t=='table' then
            return dumptable(v, write, level, refs)
        else
            return nil,"unsupported value type '"..t.."'"
        end
    end
 
    local lua_keywords = {
        ['and'] = true,
        ['break'] = true,
        ['do'] = true,
        ['else'] = true,
        ['elseif'] = true,
        ['end'] = true,
        ['false'] = true,
        ['for'] = true,
        ['function'] = true,
        ['if'] = true,
        ['in'] = true,
        ['local'] = true,
        ['nil'] = true,
        ['not'] = true,
        ['or'] = true,
        ['repeat'] = true,
        ['return'] = true,
        ['then'] = true,
        ['true'] = true,
        ['until'] = true,
        ['while'] = true,
    }
 
    local function dumppair(k, v, write, level, refs)
        if refs and refs[v] then
            v = refs[v].link
        end
        local success,err
        success,err = write(("\t"):rep(level))
        if not success then return nil,err end
        local assignment = " = "
        local tk = type(k)
        if tk=='string' and k:match("^[_a-zA-Z][_a-zA-Z0-9]*$") and not lua_keywords[k] then
            success,err = write(k)
            if not success then return nil,err end
        elseif tk=='string' or tk=='number' or tk=='boolean' then
            success,err = write('[')
            if not success then return nil,err end
            success,err = dumpvalue(k, write, level, refs, true)
            if not success then return nil,err end
            success,err = write(']')
            if not success then return nil,err end
        elseif tk=='nil' then
            -- we are in the array part
            assignment = ""
        else
            error("unsupported key type '"..type(k).."'")
        end
        success,err = write(assignment)
        if not success then return nil,err end
        success,err = dumpvalue(v, write, level, refs)
        if not success then return nil,err end
        success,err = write(",\n")
        if not success then return nil,err end
        return true
    end
 
    local function keycomp(a, b)
        local ta,tb = type(a),type(b)
        if ta==tb then
            return a < b
        else
            return ta=='string'
        end
    end
 
    local tsort = table.sort
    local function dumptablesection(table, write, level, keys, state, refs)
        -- sort keys
        local skeys = {}
        for k in pairs(keys) do skeys[#skeys+1] = k end
        tsort(skeys, keycomp)
        -- dump pairs
        for _,k in pairs(skeys) do
            local v = table[k]
            if state then
                state.i = state.i + 1
                if state.i % state.size == 0 then
                    local success,err = write(state.sep)
                    if not success then return nil,err end
                end
            end
            local success,err = dumppair(k, v, write, level, refs)
            if not success then return nil,err end
        end
        return true
    end
 
    local function dumptableimplicitsection(table, write, level, state, refs)
        for k,v in ipairs(table) do
            if state then
                state.i = state.i + 1
                if state.i % state.size == 0 then
                    local success,err = write(state.sep)
                    if not success then return nil,err end
                end
            end
            local success,err
            if state then
                success,err = dumppair(k, v, write, level, refs)
            else
                success,err = dumppair(nil, v, write, level, refs)
            end
            if not success then return nil,err end
        end
        return true
    end
 
    function dumptablecontent(table, write, level, groupsize, groupsep, refs)
        -- order of groups:
        -- - explicit keys
        --   - keys with simple values
        --   - keys with structure values (table with only explicit keys)
        --   - keys with mixed values (table with both exiplicit and implicit keys)
        --   - keys with array values (table with only implicit keys)
        -- - set part (explicit key with boolean value)
        -- - implicit keys
        -- order within a group:
        -- - string keys in lexicographic order
        -- - numbers in increasing order
        -- :TODO: handle tables as keys
        -- :TODO: handle sets
 
        -- extract implicit keys
        local implicit = {}
        for k,v in ipairs(table) do
            implicit[k] = true
        end
        -- categorize explicit keys
        local set = {}
        local simples = {}
        local structures = {}
        local mixeds = {}
        local arrays = {}
        for k,v in pairs(table) do
            if not implicit[k] then
                if type(v)=='table' then
                    if v[1]==nil then
                        structures[k] = true
                    else
                        local implicit = {}
                        for k in ipairs(v) do
                            implicit[k] = true
                        end
                        local mixed = false
                        for k in pairs(v) do
                            if not implicit[k] then
                                mixed = true
                                break
                            end
                        end
                        if mixed then
                            mixeds[k] = true
                        else
                            arrays[k] = true
                        end
                    end
                else
                    simples[k] = true
                end
            end
        end
 
        local success,err,state
        if groupsize and groupsep then
            state = {
                i = 0,
                size = groupsize,
                sep = groupsep,
            }
        end
        success,err = dumptablesection(table, write, level, simples, state, refs)
        if not success then return nil,err end
        success,err = dumptablesection(table, write, level, structures, state, refs)
        if not success then return nil,err end
        success,err = dumptablesection(table, write, level, mixeds, state, refs)
        if not success then return nil,err end
        success,err = dumptablesection(table, write, level, arrays, state, refs)
        if not success then return nil,err end
        success,err = dumptableimplicitsection(table, write, level, state, refs)
        if not success then return nil,err end
        return true
 
        --[[
        local done = {}
        for k,v in ipairs(table) do
            local success,err = dumppair(nil, v, write, level, refs)
            if not success then return nil,err end
            done[k] = true
        end
        for k,v in pairs(table) do
            if not done[k] then
                local success,err = dumppair(k, v, write, level, refs)
                if not success then return nil,err end
                done[k] = true
            end
        end
        return true
        --]]

    end
 
    local function ref_helper(processed, pending, cycles, refs, value, parent, key, path)
        if type(value)=='table' then
            local vrefs = refs[value]
            if not vrefs then
                vrefs = {
                    value = value,
                }
                refs[value] = vrefs
            end
            table.insert(vrefs, {parent=parent, key=key})
            if pending[value] then
                cycles[value] = {pending[value], {key, path}}
                return
            end
            if not processed[value] then
                local path = {key, path}
                processed[value] = true
                pending[value] = path
                for k,v in pairs(value) do
                    ref_helper(processed, pending, cycles, refs, k, value, nil, path)
                    ref_helper(processed, pending, cycles, refs, v, value, k, path)
                end
                pending[value] = nil
                -- only assign an index once the children have one
                refs.last = refs.last + 1
                vrefs.index = refs.last
            end
        end
    end
 
    local prefixes = {
        table = 't',
        ['function'] = 'f',
        thread = 'c',
        userdata = 'u',
    }
 
    local function check_refs(root)
        local processed = {}
        local pending = {}
        local cycles = {}
        local refs = {last=0}
        ref_helper(processed, pending, cycles, refs, root, nil, nil)
        refs.last = nil
        for value,vrefs in pairs(refs) do
            if #vrefs==1 then
                refs[value] = nil
            end
        end
        return cycles,refs
    end
 
    local function dumprefs(refs, file, last)
        if not last then last = {0} end
        if next(refs) then
            -- order the values from last to first discovered according to .index
            local refs2 = {}
            for value,vrefs in pairs(refs) do
                assert(vrefs.value == value)
                table.insert(refs2, vrefs)
            end
            table.sort(refs2, function(a, b) return a.index < b.index end)
            -- check all references
            for _,vrefs in ipairs(refs2) do
                for _,ref in ipairs(vrefs) do
                    assert(ref.parent, "reference has no parent") -- this should trigger a cycle error earlier
                    assert(ref.key~=nil, "not yet implemented") -- tables as keys
                end
            end
            -- generate an id and a link
            for i,vrefs in ipairs(refs2) do
                vrefs.id = prefixes[type(vrefs.value)]..tostring(i)
                vrefs.link = setmetatable({}, {__dump=vrefs.id})
            end
            -- dump shared values
            for _,vrefs in ipairs(refs2) do
                local success,err = file:write("local "..vrefs.id.." = ")
                if not success then return nil,err end
                success,err = dumpvalue(vrefs.value, function(...) return file:write(...) end, 0, refs)
                if not success then return nil,err end
                success,err = file:write("\n")
                if not success then return nil,err end
            end
        end
        return true
    end
 
    local function cycle_paths(cycles)
        local paths = {}
        for _,path_pair in pairs(cycles) do
            local top,bottom = path_pair[1],path_pair[2]
            local root = {}
            local cycle = {}
            local it = bottom
            while it~=top do
                table.insert(cycle, 1, it[1])
                it = it[2]
            end
            while it and it[1] do
                table.insert(root, 1, it[1])
                it = it[2]
            end
            table.insert(paths, {root, cycle})
        end
        return paths
    end
 
    function _M.tostring(value, ignore_refs)
        local cycles,refs = check_refs(value)
        if next(cycles) then
            return nil,"cycles in value",cycle_paths(cycles)
        end
        if next(refs) and not ignore_refs then
            return nil,"mutable values (tables) with multiple references"
        end
        local t = {}
        local success,err = dumpvalue(value, function(str) table.insert(t, str); return true end, 0, refs)
        if not success then return nil,err end
        return table.concat(t)
    end
 
    function _M.tofile(value, file)
        local cycles,refs = check_refs(value)
        if next(cycles) then
            return nil,"cycles in value",cycle_paths(cycles)
        end
        local filename
        if type(file)=='string' then
            filename = file
            file = nil
        end
        local success,err
        if filename then
            file,err = io.open(filename, 'wb')
            if not file then return nil,err end
        end
        success,err = dumprefs(refs, file)
        if not success then return nil,err end
        success,err = file:write"return "
        if not success then return nil,err end
        success,err = dumpvalue(value, function(...) return file:write(...) end, 0, refs)
        if not success then return nil,err end
        success,err = file:write("\n-- v".."i: ft=lua\n")
        if not success then return nil,err end
        if filename then
            success,err = file:close()
            if not success then return nil,err end
        end
        return true
    end
 
    function _M.toscript(value)
        local file = {}
        function file:write(str)
            self[#self+1] = str
            return true
        end
        local success,err,extra = _M.tofile(value, file)
        if not success then return nil,err,extra end
        return table.concat(file)
    end
 
    function _M.tofile_safe(value, filename, oldsuffix)
        local lfs = require 'lfs'
 
        if oldsuffix and lfs.attributes(filename, 'mode') then
            local i,suffix = 0,oldsuffix
            while io.open(filename..suffix, "rb") do
                i = i+1
                suffix = oldsuffix..i
            end
            assert(os.rename(filename, filename..suffix))
        end
        local tmpfilename = filename..'.new'
        local err,file,success
        file,err = io.open(tmpfilename, "wb")
        if not file then return nil,err end
        success,err,extra = _M.tofile(value, file)
        if not success then
            file:close()
            os.remove(tmpfilename)
            return nil,err,extra
        end
        success,err = file:close()
        if not success then
            os.remove(tmpfilename)
            return nil,err
        end
        if lfs.attributes(filename, 'mode') then
            assert(os.remove(filename))
        end
        assert(os.rename(tmpfilename, filename))
        return true
    end
    return _M
end
--
if not Table.Dump then
    Table.Dump = {};
end
local dump = LoadDump();
--
Table.Dump.ToString = dump.tostring;
Table.Dump.ToScript = dump.toscript;
Table.Dump.ToFile = dump.tofile;
--
function Table.Save(vValue, sFile)
    local hFile = io.open(sFile, "wb");
    if hFile ~= nil then
        hFile:write(dump.tostring(vValue));
        hFile:close();
    end
end
function Table.Load(sFile)
    local hFile = io.open(sFile, "rb");
    if hFile ~= nil then
        local sScript = hFile:read("*a");
        hFile:close();
        --
        return loadstring("return "..sScript)();
    else
        error();
    end
end

Âñåãî çàïèñåé: 597 | Çàðåãèñòð. 08-09-2011 | Îòïðàâëåíî: 19:08 22-06-2017 | Èñïðàâëåíî: KerberX, 00:54 23-06-2017
Îòêðûòü íîâóþ òåìó     Íàïèñàòü îòâåò â ýòó òåìó

Íà ïåðâóþ ñòðàíèöóê ýòîìó ñîîáùåíèþê ïîñëåäíåìó ñîîáùåíèþ

Êîìïüþòåðíûé ôîðóì Ru.Board » Êîìïüþòåðû » Ïðîãðàììû » Indigo Rose AutoPlay Media Studio (÷àñòü 5)


Ðåêëàìà íà ôîðóìå Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Ðåéòèíã.ru