TMessage.swift 10 KB

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