You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

644 lines
17 KiB

  1. --[[
  2. Copyright (c) 2011-2014 chukong-inc.com
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. ]]
  19. function printLog(tag, fmt, ...)
  20. local t = {
  21. "[",
  22. string.upper(tostring(tag)),
  23. "] ",
  24. string.format(tostring(fmt), ...)
  25. }
  26. print(table.concat(t))
  27. end
  28. function printError(fmt, ...)
  29. printLog("ERR", fmt, ...)
  30. print(debug.traceback("", 2))
  31. end
  32. function printInfo(fmt, ...)
  33. if type(DEBUG) ~= "number" or DEBUG < 2 then return end
  34. printLog("INFO", fmt, ...)
  35. end
  36. local function dump_value_(v)
  37. if type(v) == "string" then
  38. v = "\"" .. v .. "\""
  39. end
  40. return tostring(v)
  41. end
  42. function EapDump(value, desciption, nesting)
  43. if (not EAP_DEBUG_MODEL) then
  44. return
  45. end
  46. if type(nesting) ~= "number" then nesting = 3 end
  47. local lookupTable = {}
  48. local result = {}
  49. local traceback = string.split(debug.traceback("", 2), "\n")
  50. print("dump from: " .. string.trim(traceback[3]))
  51. local function dump_(value, desciption, indent, nest, keylen)
  52. desciption = desciption or "<var>"
  53. local spc = ""
  54. if type(keylen) == "number" then
  55. spc = string.rep(" ", keylen - string.len(dump_value_(desciption)))
  56. end
  57. if type(value) ~= "table" then
  58. result[#result +1 ] = string.format("%s%s%s = %s", indent, dump_value_(desciption), spc, dump_value_(value))
  59. elseif lookupTable[tostring(value)] then
  60. result[#result +1 ] = string.format("%s%s%s = *REF*", indent, dump_value_(desciption), spc)
  61. else
  62. lookupTable[tostring(value)] = true
  63. if nest > nesting then
  64. result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, dump_value_(desciption))
  65. else
  66. result[#result +1 ] = string.format("%s%s = {", indent, dump_value_(desciption))
  67. local indent2 = indent.." "
  68. local keys = {}
  69. local keylen = 0
  70. local values = {}
  71. for k, v in pairs(value) do
  72. keys[#keys + 1] = k
  73. local vk = dump_value_(k)
  74. local vkl = string.len(vk)
  75. if vkl > keylen then keylen = vkl end
  76. values[k] = v
  77. end
  78. table.sort(keys, function(a, b)
  79. if type(a) == "number" and type(b) == "number" then
  80. return a < b
  81. else
  82. return tostring(a) < tostring(b)
  83. end
  84. end)
  85. for i, k in ipairs(keys) do
  86. dump_(values[k], k, indent2, nest + 1, keylen)
  87. end
  88. result[#result +1] = string.format("%s}", indent)
  89. end
  90. end
  91. end
  92. dump_(value, desciption, "- ", 1)
  93. for i, line in ipairs(result) do
  94. print(line)
  95. end
  96. end
  97. function printf(fmt, ...)
  98. print(string.format(tostring(fmt), ...))
  99. end
  100. -- function print(fmt, ...)
  101. -- -- if (not DEBUG_MODEL) then
  102. -- -- return
  103. -- -- end
  104. -- release_print(fmt, ...)
  105. -- end
  106. function checknumber(value, base)
  107. return tonumber(value, base) or 0
  108. end
  109. function checkint(value)
  110. return math.round(checknumber(value))
  111. end
  112. function checkbool(value)
  113. return (value ~= nil and value ~= false)
  114. end
  115. function checktable(value)
  116. if type(value) ~= "table" then value = {} end
  117. return value
  118. end
  119. function isset(hashtable, key)
  120. local t = type(hashtable)
  121. return (t == "table" or t == "userdata") and hashtable[key] ~= nil
  122. end
  123. local setmetatableindex_
  124. setmetatableindex_ = function(t, index)
  125. if type(t) == "userdata" then
  126. local peer = tolua.getpeer(t)
  127. if not peer then
  128. peer = {}
  129. tolua.setpeer(t, peer)
  130. end
  131. setmetatableindex_(peer, index)
  132. else
  133. local mt = getmetatable(t)
  134. if not mt then mt = {} end
  135. if not mt.__index then
  136. mt.__index = index
  137. setmetatable(t, mt)
  138. elseif mt.__index ~= index then
  139. setmetatableindex_(mt, index)
  140. end
  141. end
  142. end
  143. setmetatableindex = setmetatableindex_
  144. function clone(object)
  145. local lookup_table = {}
  146. local function _copy(object)
  147. if type(object) ~= "table" then
  148. return object
  149. elseif lookup_table[object] then
  150. return lookup_table[object]
  151. end
  152. local newObject = {}
  153. lookup_table[object] = newObject
  154. for key, value in pairs(object) do
  155. newObject[_copy(key)] = _copy(value)
  156. end
  157. return setmetatable(newObject, getmetatable(object))
  158. end
  159. return _copy(object)
  160. end
  161. function EapClass(classname, ...)
  162. local cls = {__cname = classname}
  163. local supers = {...}
  164. for _, super in ipairs(supers) do
  165. local superType = type(super)
  166. assert(superType == "nil" or superType == "table" or superType == "function",
  167. string.format("EapClass() - create class \"%s\" with invalid super class type \"%s\"",
  168. classname, superType))
  169. if superType == "function" then
  170. assert(cls.__create == nil,
  171. string.format("EapClass() - create class \"%s\" with more than one creating function",
  172. classname));
  173. -- if super is function, set it to __create
  174. cls.__create = super
  175. elseif superType == "table" then
  176. if super[".isclass"] then
  177. -- super is native class
  178. assert(cls.__create == nil,
  179. string.format("EapClass() - create class \"%s\" with more than one creating function or native class",
  180. classname));
  181. cls.__create = function() return super:create() end
  182. else
  183. -- super is pure lua class
  184. cls.__supers = cls.__supers or {}
  185. cls.__supers[#cls.__supers + 1] = super
  186. if not cls.super then
  187. -- set first super pure lua class as class.super
  188. cls.super = super
  189. end
  190. end
  191. else
  192. error(string.format("EapClass() - create class \"%s\" with invalid super type",
  193. classname), 0)
  194. end
  195. end
  196. cls.__index = cls
  197. if not cls.__supers or #cls.__supers == 1 then
  198. setmetatable(cls, {__index = cls.super})
  199. else
  200. setmetatable(cls, {__index = function(_, key)
  201. local supers = cls.__supers
  202. for i = 1, #supers do
  203. local super = supers[i]
  204. if super[key] then return super[key] end
  205. end
  206. end})
  207. end
  208. if not cls.ctor then
  209. -- add default constructor
  210. cls.ctor = function() end
  211. end
  212. cls.new = function(...)
  213. local instance
  214. if cls.__create then
  215. instance = cls.__create(...)
  216. else
  217. instance = {}
  218. end
  219. setmetatableindex(instance, cls)
  220. instance.class = cls
  221. instance:ctor(...)
  222. return instance
  223. end
  224. cls.create = function(_, ...)
  225. return cls.new(...)
  226. end
  227. return cls
  228. end
  229. local iskindof_
  230. iskindof_ = function(cls, name)
  231. local __index = rawget(cls, "__index")
  232. if type(__index) == "table" and rawget(__index, "__cname") == name then return true end
  233. if rawget(cls, "__cname") == name then return true end
  234. local __supers = rawget(cls, "__supers")
  235. if not __supers then return false end
  236. for _, super in ipairs(__supers) do
  237. if iskindof_(super, name) then return true end
  238. end
  239. return false
  240. end
  241. function iskindof(obj, classname)
  242. local t = type(obj)
  243. if t ~= "table" and t ~= "userdata" then return false end
  244. local mt
  245. if t == "userdata" then
  246. if tolua.iskindof(obj, classname) then return true end
  247. mt = tolua.getpeer(obj)
  248. else
  249. mt = getmetatable(obj)
  250. end
  251. if mt then
  252. return iskindof_(mt, classname)
  253. end
  254. return false
  255. end
  256. function import(moduleName, currentModuleName)
  257. local currentModuleNameParts
  258. local moduleFullName = moduleName
  259. local offset = 1
  260. while true do
  261. if string.byte(moduleName, offset) ~= 46 then -- .
  262. moduleFullName = string.sub(moduleName, offset)
  263. if currentModuleNameParts and #currentModuleNameParts > 0 then
  264. moduleFullName = table.concat(currentModuleNameParts, ".") .. "." .. moduleFullName
  265. end
  266. break
  267. end
  268. offset = offset + 1
  269. if not currentModuleNameParts then
  270. if not currentModuleName then
  271. local n,v = debug.getlocal(3, 1)
  272. currentModuleName = v
  273. end
  274. currentModuleNameParts = string.split(currentModuleName, ".")
  275. end
  276. table.remove(currentModuleNameParts, #currentModuleNameParts)
  277. end
  278. return require(moduleFullName)
  279. end
  280. function handler(obj, method)
  281. return function(...)
  282. return method(obj, ...)
  283. end
  284. end
  285. function math.newrandomseed()
  286. local ok, socket = pcall(function()
  287. return require("socket")
  288. end)
  289. if ok then
  290. math.randomseed(socket.gettime() * 1000)
  291. else
  292. math.randomseed(os.time())
  293. end
  294. math.random()
  295. math.random()
  296. math.random()
  297. math.random()
  298. end
  299. function math.round(value)
  300. value = checknumber(value)
  301. return math.floor(value + 0.5)
  302. end
  303. local pi_div_180 = math.pi / 180
  304. function math.angle2radian(angle)
  305. return angle * pi_div_180
  306. end
  307. local pi_mul_180 = math.pi * 180
  308. function math.radian2angle(radian)
  309. return radian / pi_mul_180
  310. end
  311. function io.exists(path)
  312. local file = io.open(path, "r")
  313. if file then
  314. io.close(file)
  315. return true
  316. end
  317. return false
  318. end
  319. function io.readfile(path)
  320. local file = io.open(path, "r")
  321. if file then
  322. local content = file:read("*a")
  323. io.close(file)
  324. return content
  325. end
  326. return nil
  327. end
  328. function io.writefile(path, content, mode)
  329. mode = mode or "w+b"
  330. local file = io.open(path, mode)
  331. if file then
  332. if file:write(content) == nil then return false end
  333. io.close(file)
  334. return true
  335. else
  336. return false
  337. end
  338. end
  339. function io.pathinfo(path)
  340. local pos = string.len(path)
  341. local extpos = pos + 1
  342. while pos > 0 do
  343. local b = string.byte(path, pos)
  344. if b == 46 then -- 46 = char "."
  345. extpos = pos
  346. elseif b == 47 then -- 47 = char "/"
  347. break
  348. end
  349. pos = pos - 1
  350. end
  351. local dirname = string.sub(path, 1, pos)
  352. local filename = string.sub(path, pos + 1)
  353. extpos = extpos - pos
  354. local basename = string.sub(filename, 1, extpos - 1)
  355. local extname = string.sub(filename, extpos)
  356. return {
  357. dirname = dirname,
  358. filename = filename,
  359. basename = basename,
  360. extname = extname
  361. }
  362. end
  363. function io.filesize(path)
  364. local size = false
  365. local file = io.open(path, "r")
  366. if file then
  367. local current = file:seek()
  368. size = file:seek("end")
  369. file:seek("set", current)
  370. io.close(file)
  371. end
  372. return size
  373. end
  374. function table.nums(t)
  375. local count = 0
  376. for k, v in pairs(t) do
  377. count = count + 1
  378. end
  379. return count
  380. end
  381. function table.keys(hashtable)
  382. local keys = {}
  383. for k, v in pairs(hashtable) do
  384. keys[#keys + 1] = k
  385. end
  386. return keys
  387. end
  388. function table.values(hashtable)
  389. local values = {}
  390. for k, v in pairs(hashtable) do
  391. values[#values + 1] = v
  392. end
  393. return values
  394. end
  395. function table.merge(dest, src)
  396. for k, v in pairs(src) do
  397. dest[k] = v
  398. end
  399. end
  400. function table.insertto(dest, src, begin)
  401. begin = checkint(begin)
  402. if begin <= 0 then
  403. begin = #dest + 1
  404. end
  405. local len = #src
  406. for i = 0, len - 1 do
  407. dest[i + begin] = src[i + 1]
  408. end
  409. end
  410. function table.indexof(array, value, begin)
  411. for i = begin or 1, #array do
  412. if array[i] == value then return i end
  413. end
  414. return false
  415. end
  416. function table.keyof(hashtable, value)
  417. for k, v in pairs(hashtable) do
  418. if v == value then return k end
  419. end
  420. return nil
  421. end
  422. function table.removebyvalue(array, value, removeall)
  423. local c, i, max = 0, 1, #array
  424. while i <= max do
  425. if array[i] == value then
  426. table.remove(array, i)
  427. c = c + 1
  428. i = i - 1
  429. max = max - 1
  430. if not removeall then break end
  431. end
  432. i = i + 1
  433. end
  434. return c
  435. end
  436. function table.map(t, fn)
  437. for k, v in pairs(t) do
  438. t[k] = fn(v, k)
  439. end
  440. end
  441. function table.walk(t, fn)
  442. for k,v in pairs(t) do
  443. fn(v, k)
  444. end
  445. end
  446. function table.filter(t, fn)
  447. for k, v in pairs(t) do
  448. if not fn(v, k) then t[k] = nil end
  449. end
  450. end
  451. function table.unique(t, bArray)
  452. local check = {}
  453. local n = {}
  454. local idx = 1
  455. for k, v in pairs(t) do
  456. if not check[v] then
  457. if bArray then
  458. n[idx] = v
  459. idx = idx + 1
  460. else
  461. n[k] = v
  462. end
  463. check[v] = true
  464. end
  465. end
  466. return n
  467. end
  468. string._htmlspecialchars_set = {}
  469. string._htmlspecialchars_set["&"] = "&amp;"
  470. string._htmlspecialchars_set["\""] = "&quot;"
  471. string._htmlspecialchars_set["'"] = "&#039;"
  472. string._htmlspecialchars_set["<"] = "&lt;"
  473. string._htmlspecialchars_set[">"] = "&gt;"
  474. function string.htmlspecialchars(input)
  475. for k, v in pairs(string._htmlspecialchars_set) do
  476. input = string.gsub(input, k, v)
  477. end
  478. return input
  479. end
  480. function string.restorehtmlspecialchars(input)
  481. for k, v in pairs(string._htmlspecialchars_set) do
  482. input = string.gsub(input, v, k)
  483. end
  484. return input
  485. end
  486. function string.nl2br(input)
  487. return string.gsub(input, "\n", "<br />")
  488. end
  489. function string.text2html(input)
  490. input = string.gsub(input, "\t", " ")
  491. input = string.htmlspecialchars(input)
  492. input = string.gsub(input, " ", "&nbsp;")
  493. input = string.nl2br(input)
  494. return input
  495. end
  496. function string.split(input, delimiter)
  497. input = tostring(input)
  498. delimiter = tostring(delimiter)
  499. if (delimiter=='') then return false end
  500. local pos,arr = 0, {}
  501. -- for each divider found
  502. for st,sp in function() return string.find(input, delimiter, pos, true) end do
  503. table.insert(arr, string.sub(input, pos, st - 1))
  504. pos = sp + 1
  505. end
  506. table.insert(arr, string.sub(input, pos))
  507. return arr
  508. end
  509. function string.ltrim(input)
  510. return string.gsub(input, "^[ \t\n\r]+", "")
  511. end
  512. function string.rtrim(input)
  513. return string.gsub(input, "[ \t\n\r]+$", "")
  514. end
  515. function string.trim(input)
  516. input = string.gsub(input, "^[ \t\n\r]+", "")
  517. return string.gsub(input, "[ \t\n\r]+$", "")
  518. end
  519. function string.ucfirst(input)
  520. return string.upper(string.sub(input, 1, 1)) .. string.sub(input, 2)
  521. end
  522. local function urlencodechar(char)
  523. return "%" .. string.format("%02X", string.byte(char))
  524. end
  525. function string.urlencode(input)
  526. -- convert line endings
  527. input = string.gsub(tostring(input), "\n", "\r\n")
  528. -- escape all characters but alphanumeric, '.' and '-'
  529. input = string.gsub(input, "([^%w%.%- ])", urlencodechar)
  530. -- convert spaces to "+" symbols
  531. return string.gsub(input, " ", "+")
  532. end
  533. function string.urldecode(input)
  534. input = string.gsub (input, "+", " ")
  535. input = string.gsub (input, "%%(%x%x)", function(h) return string.char(checknumber(h,16)) end)
  536. input = string.gsub (input, "\r\n", "\n")
  537. return input
  538. end
  539. function string.utf8len(input)
  540. local len = string.len(input)
  541. local left = len
  542. local cnt = 0
  543. local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}
  544. while left ~= 0 do
  545. local tmp = string.byte(input, -left)
  546. local i = #arr
  547. while arr[i] do
  548. if tmp >= arr[i] then
  549. left = left - i
  550. break
  551. end
  552. i = i - 1
  553. end
  554. cnt = cnt + 1
  555. end
  556. return cnt
  557. end
  558. function string.formatnumberthousands(num)
  559. local formatted = tostring(checknumber(num))
  560. local k
  561. while true do
  562. formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
  563. if k == 0 then break end
  564. end
  565. return formatted
  566. end
  567. --functions_lua--functions.lua