--[[ Copyright (c) 2014-2017 Chukong Technologies Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] function checknumber(value, base) return tonumber(value, base) or 0 end function checkint(value) return math.round(checknumber(value)) end function checkbool(value) return (value ~= nil and value ~= false) end function checktable(value) if type(value) ~= "table" then value = {} end return value end function clone(object) local lookup_table = {} local function _copy(object) if type(object) ~= "table" then return object elseif lookup_table[object] then return lookup_table[object] end local newObject = {} lookup_table[object] = newObject for key, value in pairs(object) do newObject[_copy(key)] = _copy(value) end return setmetatable(newObject, getmetatable(object)) end return _copy(object) end local function emptyFunction() end function class(classname, super) local cls = {__cname = classname} if super then local superType = type(super) assert(superType == "table", string.format("class() - create class \"%s\" with invalid super class type \"%s\"", classname, superType)) cls.super = super setmetatable(cls, {__index = super}) end cls.ctor = emptyFunction cls.new = function(_, ...) local instance = {} setmetatable(instance, {__index = cls}) instance.class = cls if instance.super then local _constructor _constructor = function(c, ...) if c.super then _constructor(c.super, ...) end c.ctor(instance, ...) end _constructor(instance.super, ...) end instance:ctor(...) return instance end cls.create = cls.new return cls end function iskindof(obj, classname) local t = type(obj) if t ~= "table" then return false end local mt = getmetatable(obj) if mt then local __index = rawget(mt, "__index") if type(__index) == "table" and rawget(__index, "__cname") == classname then return true end end if rawget(obj, "__cname") == classname then return true end local super = obj.super while super do if rawget(super, "__cname") == classname then return true end super = super.super end return false end function handler(obj, method) return function(...) return method(obj, ...) end end function math.newrandomseed() local ok, socket = pcall(function() return require("socket") end) if ok then math.randomseed(socket.gettime() * 1000) else math.randomseed(os.time()) end math.random() math.random() math.random() math.random() end function math.round(value) value = checknumber(value) return math.floor(value + 0.5) end function math.clamp(value, min, max) if value < min then return min end if value > max then return max end return value end local pi_div_180 = math.pi / 180 function math.angle2radian(angle) return angle * pi_div_180 end function math.radian2angle(radian) return radian * 180 / math.pi end function io.exists(path) local file = io.open(path, "r") if file then io.close(file) return true end return false end function io.readfile(path) local file = io.open(path, "r") if file then local content = file:read("*a") io.close(file) return content end return nil end function io.writefile(path, content, mode) mode = mode or "w+b" local file = io.open(path, mode) if file then if file:write(content) == nil then return false end io.close(file) return true else return false end end function io.pathinfo(path) local pos = string.len(path) local extpos = pos + 1 while pos > 0 do local b = string.byte(path, pos) if b == 46 then -- 46 = char "." extpos = pos elseif b == 47 then -- 47 = char "/" break end pos = pos - 1 end local dirname = string.sub(path, 1, pos) local filename = string.sub(path, pos + 1) extpos = extpos - pos local basename = string.sub(filename, 1, extpos - 1) local extname = string.sub(filename, extpos) return { dirname = dirname, filename = filename, basename = basename, extname = extname } end function io.filesize(path) local size = false local file = io.open(path, "r") if file then local current = file:seek() size = file:seek("end") file:seek("set", current) io.close(file) end return size end function table.nums(t) local count = 0 for k, v in pairs(t) do count = count + 1 end return count end function table.keys(hashtable) local keys = {} for k, v in pairs(hashtable) do keys[#keys + 1] = k end return keys end function table.values(hashtable) local values = {} for k, v in pairs(hashtable) do values[#values + 1] = v end return values end function table.merge(dest, src) for k, v in pairs(src) do dest[k] = v end end function table.insertto(dest, src, begin) begin = checkint(begin) if begin <= 0 then begin = #dest + 1 end local len = #src for i = 0, len - 1 do dest[i + begin] = src[i + 1] end end function table.indexof(array, value, begin) for i = begin or 1, #array do if array[i] == value then return i end end return false end function table.keyof(hashtable, value) for k, v in pairs(hashtable) do if v == value then return k end end return nil end function table.removebyvalue(array, value, removeall) local c, i, max = 0, 1, #array while i <= max do if array[i] == value then table.remove(array, i) c = c + 1 i = i - 1 max = max - 1 if not removeall then break end end i = i + 1 end return c end function table.map(t, fn) for k, v in pairs(t) do t[k] = fn(v, k) end end function table.walk(t, fn) for k,v in pairs(t) do fn(v, k) end end function table.filter(t, fn) for k, v in pairs(t) do if not fn(v, k) then t[k] = nil end end end function table.unique(t, bArray) local check = {} local n = {} local idx = 1 for k, v in pairs(t) do if not check[v] then if bArray then n[idx] = v idx = idx + 1 else n[k] = v end check[v] = true end end return n end function table.containValue(t, value) for k, v in pairs(t) do if v == value then return true end end return false end function table.shuffle(t) if type(t)~="table" then return end local tab = {} local index = 1 while #t ~= 0 do local n = math.random(1, #t) if t[n] ~= nil then tab[index] = t[n] table.remove(t,n) index = index + 1 end end return tab end ---查找一个满足条件的元素 ---@param t table ---@param predict fun(item):boolean function table.find(t, predict) for k, v in pairs(t) do if predict(v) then return v, k end end end ---浅拷贝 ---@param t table ---@return table function table.refCopy(t) if not t then return nil end local copy = {} for i,v in pairs(t) do copy[i] = v end return copy end ---将array'from' insert到to function table.addArray(to, from) if not to or not from then return end for _, v in ipairs(from) do table.insert(to, v) end return to end ---将array'from' insert到to function table.addDic(to, from) if not to or not from then return end for _, v in pairs(from) do to[_] = v end return to end --tbl需要删除对象的表, func用于判断是否是需要删除的对象的函数, --func返回两个参数,1、是否remove 2、是否继续 ---该函数会copy一次table function table.removeEx(tbl, func) if tbl == nil or func == nil then return tbl end local newTbl = {} for k, v in pairs(tbl) do local needRemove, continue = func(k, v) if not needRemove and v then newTbl[#newTbl + 1] = v end if not continue then break end end return newTbl end --- 反转阵列 function table.revert(tableArray) local length = #tableArray local half = length / 2 local temp for i = 1, half do temp = tableArray[i] tableArray[i] = tableArray[length - i + 1] tableArray[length - i + 1] = temp end return tableArray end ---满足任意条件 function table.any(tbl, func) for _, v in pairs(tbl) do if func(v) then return true end end return false end --- 遍历 function table.foreach(tbl, func) for k, v in pairs(tbl) do func(k, v) end end --- 计算每一个val的满足条件的count function table.count(tbl, func) local result = 0 for _, v in pairs(tbl) do result = result + func(v) end return result end string._htmlspecialchars_set = {} string._htmlspecialchars_set["&"] = "&" string._htmlspecialchars_set["\""] = """ string._htmlspecialchars_set["'"] = "'" string._htmlspecialchars_set["<"] = "<" string._htmlspecialchars_set[">"] = ">" function string.htmlspecialchars(input) for k, v in pairs(string._htmlspecialchars_set) do input = string.gsub(input, k, v) end return input end function string.restorehtmlspecialchars(input) for k, v in pairs(string._htmlspecialchars_set) do input = string.gsub(input, v, k) end return input end function string.nl2br(input) return string.gsub(input, "\n", "
") end function string.text2html(input) input = string.gsub(input, "\t", " ") input = string.htmlspecialchars(input) input = string.gsub(input, " ", " ") input = string.nl2br(input) return input end function string.split(input, delimiter) input = tostring(input) delimiter = tostring(delimiter) if (delimiter=='') then return false end local pos,arr = 0, {} -- for each divider found for st,sp in function() return string.find(input, delimiter, pos, true) end do table.insert(arr, string.sub(input, pos, st - 1)) pos = sp + 1 end table.insert(arr, string.sub(input, pos)) return arr end function string.ltrim(input) return string.gsub(input, "^[ \t\n\r]+", "") end function string.rtrim(input) return string.gsub(input, "[ \t\n\r]+$", "") end function string.trim(input) input = string.gsub(input, "^[ \t\n\r]+", "") return string.gsub(input, "[ \t\n\r]+$", "") end function string.ucfirst(input) return string.upper(string.sub(input, 1, 1)) .. string.sub(input, 2) end local function urlencodechar(char) return "%" .. string.format("%02X", string.byte(char)) end function string.urlencode(input) -- convert line endings input = string.gsub(tostring(input), "\n", "\r\n") -- escape all characters but alphanumeric, '.' and '-' input = string.gsub(input, "([^%w%.%- ])", urlencodechar) -- convert spaces to "+" symbols return string.gsub(input, " ", "+") end function string.urldecode(input) input = string.gsub (input, "+", " ") input = string.gsub (input, "%%(%x%x)", function(h) return string.char(checknumber(h,16)) end) input = string.gsub (input, "\r\n", "\n") return input end function string.utf8len(input) local len = string.len(input) local left = len local cnt = 0 local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc} while left ~= 0 do local tmp = string.byte(input, -left) local i = #arr while arr[i] do if tmp >= arr[i] then left = left - i break end i = i - 1 end cnt = cnt + 1 end return cnt end function string.formatnumberthousands(num) local formatted = tostring(checknumber(num)) local k while true do formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') if k == 0 then break end end return formatted end function string.isEmptyOrNil(str) return not str or #str == 0 end