TMessage.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. //
  2. // TMessage.swift
  3. // Runner
  4. //
  5. // Created by Yayan Dwi on 15/04/20.
  6. // Copyright © 2020 The Chromium Authors. All rights reserved.
  7. //
  8. import Foundation
  9. public class TMessage {
  10. public var mType: String = ""
  11. public var mVersion: String = ""
  12. public var mCode: String = ""
  13. public var mStatus: String = ""
  14. public var mPIN: String = ""
  15. public var mL_PIN: String = ""
  16. public var mBodies: [String: String] = [String: String]()
  17. private var mMedia:[UInt8] = [UInt8]()
  18. let C_HEADER:UnicodeScalar = UnicodeScalar(0x01)
  19. let C_ENTRY:UnicodeScalar = UnicodeScalar(0x02)
  20. let C_KEYVAL:UnicodeScalar = UnicodeScalar(0x03)
  21. let C_ARRAY:UnicodeScalar = UnicodeScalar(0x04)
  22. var S_HEADER: String = ""
  23. var S_ENTRY: String = ""
  24. var S_KEYVAL: String = ""
  25. var S_ARRAY: String = ""
  26. public static let TYPE_SQLITE_ONLY = "1"
  27. public static let TYPE_ALL = "2"
  28. public static let TYPE_NEED_ACK = "3"
  29. public init() {
  30. mBodies[CoreMessage_TMessageKey.IMEI] = Nexilis.getCLMUserId()
  31. // mBodies[CoreMessage_TMessageKey.VERCOD] = UIApplication.appVersion
  32. mBodies[CoreMessage_TMessageKey.VERCOD] = "1.8.5.10"
  33. }
  34. public init(data : String) {
  35. _ = unpack(data: data)
  36. }
  37. init(type: String, version: String, code: String,status: String, pin: String, l_pin: String, bodies:[String: String], media: [UInt8]) {
  38. mType = type
  39. mVersion = version
  40. mCode = code
  41. mStatus = status
  42. mPIN = pin
  43. mL_PIN = l_pin
  44. mBodies = bodies
  45. mMedia = media
  46. mBodies[CoreMessage_TMessageKey.IMEI] = Nexilis.getCLMUserId()
  47. // mBodies[CoreMessage_TMessageKey.VERCOD] = UIApplication.appVersion
  48. mBodies[CoreMessage_TMessageKey.VERCOD] = "1.8.5.10"
  49. }
  50. public func clone(p_tmessage:TMessage) -> TMessage {
  51. return TMessage(
  52. type: p_tmessage.mType,
  53. version: p_tmessage.mVersion,
  54. code: p_tmessage.mCode,
  55. status: p_tmessage.mStatus,
  56. pin: p_tmessage.mPIN,
  57. l_pin: p_tmessage.mL_PIN,
  58. bodies: p_tmessage.mBodies,
  59. media: p_tmessage.mMedia
  60. )
  61. }
  62. public func setMedia(media: [UInt8]) {
  63. mMedia = media
  64. mBodies[CoreMessage_TMessageKey.MEDIA_LENGTH] = String(media.count)
  65. }
  66. public func getCode() -> String {
  67. return mCode
  68. }
  69. public func getStatus() -> String {
  70. return mStatus
  71. }
  72. public func getPIN() -> String {
  73. return mPIN
  74. }
  75. public func getType() -> String {
  76. return mType
  77. }
  78. public func getL_PIN() -> String {
  79. return mL_PIN
  80. }
  81. public func getMedia() -> [UInt8] {
  82. return mMedia
  83. }
  84. public func getBody(key : String) -> String {
  85. if let data = mBodies[key] {
  86. return data
  87. }
  88. else {
  89. return ""
  90. }
  91. }
  92. public func getBody(key : String, default_value: String) -> String {
  93. if ((mBodies[key] == nil)) {
  94. return default_value
  95. } else if mBodies[key] == "null" {
  96. return default_value
  97. } else {
  98. return mBodies[key]!
  99. }
  100. }
  101. public func getBodyAsInteger(key : String, default_value: Int) -> Int {
  102. if ((mBodies[key] == nil)) {
  103. return default_value
  104. } else if mBodies[key] == "null" {
  105. return default_value
  106. } else {
  107. return Int(mBodies[key]!)!
  108. }
  109. }
  110. public func getBodyAsLong(key : String, default_value: CLong) -> CLong {
  111. if let body = mBodies[key] {
  112. if (body == "null") {
  113. return default_value
  114. }
  115. if (body == "nil") {
  116. return default_value
  117. }
  118. return (body as NSString).integerValue
  119. }
  120. else {
  121. return default_value
  122. }
  123. }
  124. public func pack() -> String {
  125. if (S_HEADER.isEmpty) { S_HEADER.append(Character(C_HEADER)) }
  126. var data = ""
  127. data.append(mType)
  128. data.append(Character(C_HEADER))
  129. data.append(mVersion)
  130. data.append(Character(C_HEADER))
  131. data.append(mCode)
  132. data.append(Character(C_HEADER))
  133. data.append(mStatus)
  134. data.append(Character(C_HEADER))
  135. data.append(mPIN)
  136. data.append(Character(C_HEADER))
  137. data.append(mL_PIN)
  138. data.append(Character(C_HEADER))
  139. data.append(toString(body: mBodies))
  140. data.append(Character(C_HEADER))
  141. if let media = String(data: Data(getMedia()), encoding: .windowsCP1250) {
  142. data.append(media)
  143. }
  144. return data
  145. }
  146. public func toBytes() -> [UInt8] {
  147. let data:String = pack()
  148. var result: [UInt8] = Array(data.utf8)
  149. print("[bytes_processing] build bytes data:" + String(result.count) + ", media:" + String(getMedia().count))
  150. if (!getMedia().isEmpty) {
  151. for index in 0...getMedia().count - 1 {
  152. result.append(getMedia()[index])
  153. }
  154. }
  155. return result
  156. }
  157. private func toString(body : [String: String]) -> String {
  158. if (S_ENTRY.isEmpty) { S_ENTRY.append(Character(C_ENTRY)) }
  159. if (S_KEYVAL.isEmpty) { S_KEYVAL.append(Character(C_KEYVAL)) }
  160. var result = ""
  161. for (key, value) in body {
  162. result += key + S_KEYVAL + value + S_ENTRY
  163. }
  164. if (!result.isEmpty) {
  165. result = String(result.prefix(result.count - 1))
  166. }
  167. return result
  168. }
  169. private func toMediaBytes(image: String) -> [UInt8] {
  170. if (image == "null") {
  171. return [UInt8]()
  172. }
  173. if let data = NSData(base64Encoded: image, options: .ignoreUnknownCharacters) {
  174. var buffer = [UInt8](repeating: 0, count: data.length)
  175. data.getBytes(&buffer, length: data.length)
  176. return buffer
  177. }
  178. return [UInt8]()
  179. }
  180. public func unpack(data: String) -> Bool {
  181. var result = false
  182. if (S_HEADER.isEmpty) { S_HEADER.append(Character(C_HEADER)) }
  183. let headers = data.split(separator: Character(C_HEADER), maxSplits: 8, omittingEmptySubsequences: false)
  184. if (headers.count == 8) {
  185. mType = String(headers[0])
  186. mVersion = String(headers[1])
  187. mCode = String(headers[2])
  188. mStatus = String(headers[3])
  189. mPIN = String(headers[4])
  190. mL_PIN = String(headers[5])
  191. mBodies = toBodies(data: String(headers[6]))
  192. mMedia = toMediaBytes(image: String(headers[7]))
  193. result = true
  194. }
  195. return result
  196. }
  197. public func unpack(bytes_data: [UInt8]) -> Bool {
  198. var result = false
  199. let data = getData(bytes_data: bytes_data)
  200. let headers = data.split(separator: Character(C_HEADER), maxSplits: 8, omittingEmptySubsequences: false)
  201. if (headers.count >= 8) {
  202. mType = String(headers[0])
  203. mVersion = String(headers[1])
  204. mCode = String(headers[2])
  205. mStatus = String(headers[3])
  206. mPIN = String(headers[4])
  207. mL_PIN = String(headers[5])
  208. mBodies = toBodies(data: String(headers[6]))
  209. mMedia = getMedia(bytes_data: bytes_data)
  210. result = true
  211. }
  212. else {
  213. print("[bytes_processing] Invalid header length: " + String(headers.count))
  214. }
  215. return result
  216. }
  217. private func toBodies(data: String) -> [String: String] {
  218. var cvalues = [String: String]()
  219. if (data.isEmpty || data == "") {
  220. return cvalues
  221. }
  222. if (S_ENTRY.isEmpty) { S_ENTRY.append(Character(C_ENTRY)) }
  223. if (S_KEYVAL.isEmpty) { S_KEYVAL.append(Character(C_KEYVAL)) }
  224. let elements = data.split(separator: Character(C_ENTRY), omittingEmptySubsequences: false)
  225. for element in elements {
  226. let keyval = element.split(separator: Character(C_KEYVAL), omittingEmptySubsequences: false)
  227. cvalues[String(keyval[0])] = String(keyval[1])
  228. }
  229. return cvalues
  230. }
  231. private func getData(bytes_data : [UInt8]) -> String {
  232. var result = ""
  233. if (S_HEADER.isEmpty) { S_HEADER.append(Character(C_HEADER)) }
  234. var iLength = 0
  235. for bData in bytes_data {
  236. let chr = Character(UnicodeScalar(bData))
  237. if (chr == Character(C_HEADER)) {
  238. iLength = iLength + 1
  239. if (iLength == 8) {
  240. break
  241. }
  242. }
  243. result.append(chr)
  244. }
  245. return result
  246. }
  247. private func getMedia(bytes_data: [UInt8]) -> [UInt8] {
  248. var result:[UInt8] = [UInt8]()
  249. if bytes_data.count > 0 {
  250. var ml = getBodyAsInteger(key: CoreMessage_TMessageKey.MEDIA_LENGTH, default_value: 0)
  251. if ml == 0 {
  252. ml = getBodyAsInteger(key: CoreMessage_TMessageKey.FILE_SIZE, default_value: 0)
  253. }
  254. if ml > 0 {
  255. let start = bytes_data.count - ml
  256. for index in start...bytes_data.count - 1 {
  257. result.append(bytes_data[index])
  258. }
  259. }
  260. }
  261. return result
  262. }
  263. public func toLogString() -> String {
  264. var result = ""
  265. result += ("[" + mType + "]")
  266. result += ("[" + mVersion + "]")
  267. result += ("[" + mCode + "]")
  268. result += ("[" + mStatus + "]")
  269. result += ("[" + mPIN + "]")
  270. result += ("[" + mL_PIN + "]")
  271. result += ("[" + toBodyLogString() + "]")
  272. result += ("[" + String(mMedia.count) + "]")
  273. return result
  274. }
  275. private func toBodyLogString() -> String {
  276. if (S_ENTRY.isEmpty) { S_ENTRY.append(Character(C_ENTRY)) }
  277. if (S_KEYVAL.isEmpty) { S_KEYVAL.append(Character(C_KEYVAL)) }
  278. var result = ""
  279. for (key, value) in mBodies {
  280. result += "{" + key + "=" + value + "}"
  281. }
  282. return result
  283. }
  284. public func isOk() -> Bool {
  285. return getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "00"
  286. }
  287. }