DOCSIS-Toolkit/FileOperations.swift

121 lines
5.0 KiB
Swift

//
// FileOperations.swift
// Docsis Toolkit
//
// Created by Kilian Hofmann on 19.06.17.
// Copyright © 2017 Kilian Hofmann. All rights reserved.
//
import Cocoa
class FileOperations: NSObject {
// MARK: - Timestamp related
// 15 in threshold indicates some error
static func encodeTimeStamp(stamp: String, threshold: String) -> UInt32 {
let mappingEncode: Dictionary<String, UInt32> = ["-" : 0, "62.81": 1, "58.21": 2, "57": 3, "59.81": 4, "55.21": 5, "54": 6, "56.81": 7, "52.21": 8, "51": 9]
let separated: Array<String> = stamp.components(separatedBy: ":")
let hours: UInt32 = UInt32(separated[0])! << 16
let minutes: UInt32 = UInt32(separated[1])! << 10
let seconds: UInt32 = UInt32(separated[2])! << 4
let thresholdI: UInt32 = mappingEncode[threshold] ?? 15
return hours | seconds | minutes | thresholdI
}
static func decodeTimestamp(stamp: UInt32) -> (String, String) {
let mappingDecode: Dictionary<UInt32, String> = [0: "-", 1: "62.81", 2: "58.21", 3: "57", 4: "59.81", 5: "55.21", 6: "54", 7: "56.81", 8: "52.21", 9: "51"]
let threshold: UInt32 = stamp & 0b1111
let seconds: UInt32 = (stamp >> 4) & 0b111111
let minutes: UInt32 = (stamp >> 10) & 0b111111
let hours: UInt32 = (stamp >> 16) & 0b11111
return ("\(hours):\(minutes):\(seconds)", mappingDecode[threshold] ?? "\(15)")
}
// MARK: - Loss log related
static func log(data: String, toLog path: String) {
let dataToWrite = encodeTimeStamp(stamp: data, threshold: "")
let file: UnsafeMutableRawPointer = UnsafeMutableRawPointer.allocate(bytes: 3, alignedTo: 1)
file.storeBytes(of: dataToWrite, as: UInt32.self)
do {
let fileData: NSMutableData = try NSMutableData(contentsOf: URL(fileURLWithPath: path))
fileData.append(file, length: 3)
fileData.write(to: URL(fileURLWithPath: path), atomically: true)
} catch _ {
let fileData: NSMutableData = NSMutableData()
fileData.append(file, length: 3)
fileData.write(to: URL(fileURLWithPath: path), atomically: true)
}
}
static func load(log Data: NSData) -> String? {
var returnString: String? = ""
var i: Int = 0
while i < Data.length - 3 {
let data: UnsafeMutableRawPointer = UnsafeMutableRawPointer.allocate(bytes: 3, alignedTo: 1)
Data.getBytes(data, range: NSRange(location: i, length: 3))
returnString?.append("\(decodeTimestamp(stamp: data.load(as: UInt32.self)).0)\n")
i += 3
}
if returnString != "" {
return returnString
}
return nil
}
// MARK: - Frequency logging (encoding)
static func logUpstream(data: String, toFrequencyLog path: String) {
let separated: Array<String> = data.components(separatedBy: ";")
var encodedTime: UInt32 = encodeTimeStamp(stamp: separated[0], threshold: separated[2])
// NaN Used for -
var encodedPower: Int32 = Int32.min
if (Double(separated[1]) != nil) {
encodedPower = Int32(Double(Double(separated[1])! * 100.0))
}
var stringSize: UInt8 = UInt8(separated[3].lengthOfBytes(using: .ascii))
let fileContent: NSMutableData = NSMutableData()
fileContent.append(&stringSize, length: 1)
fileContent.append(&encodedTime, length: 3)
fileContent.append(&encodedPower, length: 4)
fileContent.append(separated[3].data(using: .ascii)!)
do {
let fileData: NSMutableData = try NSMutableData(contentsOf: URL(fileURLWithPath: path))
fileData.append(fileContent as Data)
fileData.write(to: URL(fileURLWithPath: path), atomically: true)
} catch _ {
fileContent.write(to: URL(fileURLWithPath: path), atomically: true)
}
}
static func logDownstream(data: String, toFrequencyLog path: String) {
let separated: Array<String> = data.components(separatedBy: ";")
var encodedTime: UInt32 = encodeTimeStamp(stamp: separated[0], threshold: "")
// NaN Used for -
var encodedPower: Int32 = Int32.min
if (Double(separated[1]) != nil) {
encodedPower = Int32(Double(Double(separated[1])! * 100.0))
}
var encodedSNR = UInt8(separated[2]) ?? UInt8.max
let fileContent: NSMutableData = NSMutableData()
fileContent.append(&encodedTime, length: 3)
fileContent.append(&encodedPower, length: 4)
fileContent.append(&encodedSNR, length: 1)
do {
let fileData: NSMutableData = try NSMutableData(contentsOf: URL(fileURLWithPath: path))
fileData.append(fileContent as Data)
fileData.write(to: URL(fileURLWithPath: path), atomically: true)
} catch _ {
fileContent.write(to: URL(fileURLWithPath: path), atomically: true)
}
}
// MARK: - Frequency loading (decoding)
}