diff --git a/Converter/AppDelegate.swift b/Converter/AppDelegate.swift
new file mode 100644
index 0000000..c570244
--- /dev/null
+++ b/Converter/AppDelegate.swift
@@ -0,0 +1,29 @@
+//
+// AppDelegate.swift
+// Converter
+//
+// Created by Kilian Hofmann on 20.06.17.
+// Copyright © 2017 Kilian Hofmann. All rights reserved.
+//
+
+import Cocoa
+
+@NSApplicationMain
+class AppDelegate: NSObject, NSApplicationDelegate {
+
+ var isConverting: Bool = false
+
+ func applicationDidFinishLaunching(_ aNotification: Notification) {
+ // Insert code here to initialize your application
+ }
+
+ func applicationWillTerminate(_ aNotification: Notification) {
+ // Insert code here to tear down your application
+ }
+
+ func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply {
+ guard isConverting else { return NSApplicationTerminateReply.terminateNow }
+ return NSApplicationTerminateReply.terminateCancel
+ }
+}
+
diff --git a/Converter/Assets.xcassets/AppIcon.appiconset/Contents.json b/Converter/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/Converter/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Converter/Base.lproj/Main.storyboard b/Converter/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..9e5a625
--- /dev/null
+++ b/Converter/Base.lproj/Main.storyboard
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Converter/Document.swift b/Converter/Document.swift
new file mode 100644
index 0000000..78a15ae
--- /dev/null
+++ b/Converter/Document.swift
@@ -0,0 +1,71 @@
+//
+// Document.swift
+// Converter
+//
+// Created by Kilian Hofmann on 20.06.17.
+// Copyright © 2017 Kilian Hofmann. All rights reserved.
+//
+
+import Cocoa
+
+class Document: NSDocument {
+
+ var file: FileWrapper!
+
+ override class func autosavesInPlace() -> Bool {
+ return false
+ }
+
+ override func makeWindowControllers() {
+ // Returns the Storyboard that contains your Document window.
+ let storyboard = NSStoryboard(name: "Main", bundle: nil)
+ let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as! NSWindowController
+ self.addWindowController(windowController)
+ windowController.window?.delegate = self
+
+ var Files: [String : [String : FileWrapper]] = [:]
+
+ var months: Int = (file.fileWrappers?.count)!
+ if (file.fileWrappers?.contains(where: {$0.0 == ".DS_Store" }))! {
+ months -= 1
+ }
+ (windowControllers.first?.contentViewController as! ViewController).months.stringValue = "\(months)"
+ var days: Int = 0
+ var files: Int = 0
+ for months in file.fileWrappers! {
+ guard months.value.isDirectory else { continue }
+ days += (months.value.fileWrappers?.count)!
+ if (months.value.fileWrappers?.contains(where: {$0.0 == ".DS_Store" }))! {
+ days -= 1
+ }
+ for days in months.value.fileWrappers! {
+ guard days.value.isDirectory else { continue }
+ files += (days.value.fileWrappers?.count)!
+ if (days.value.fileWrappers?.contains(where: {$0.0 == ".DS_Store" }))! {
+ files -= 1
+ }
+ if (days.value.fileWrappers?.contains(where: {$0.0 == "Content.plist" }))! {
+ files -= 1
+ }
+ Files[months.key] = (months.value.fileWrappers!)
+ }
+ }
+ (windowControllers.first?.contentViewController as! ViewController).days.stringValue = "\(days)"
+ (windowControllers.first?.contentViewController as! ViewController).files.stringValue = "\(files)"
+ (windowControllers.first?.contentViewController as! ViewController).fileWrappers = Files
+ (windowControllers.first?.contentViewController as! ViewController).filesTotal = files
+}
+
+ override func read(from fileWrapper: FileWrapper, ofType typeName: String) throws {
+ file = fileWrapper
+ }
+}
+
+extension Document: NSWindowDelegate {
+
+ func windowShouldClose(_ sender: Any) -> Bool {
+ guard (NSApp.delegate as! AppDelegate).isConverting else { return true }
+ return false
+ }
+}
+
diff --git a/Converter/Info.plist b/Converter/Info.plist
new file mode 100644
index 0000000..fb40b76
--- /dev/null
+++ b/Converter/Info.plist
@@ -0,0 +1,53 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeExtensions
+
+ docsisplist2
+
+ CFBundleTypeIconFile
+
+ CFBundleTypeName
+ DocumentType
+ CFBundleTypeOSTypes
+
+ ????
+
+ CFBundleTypeRole
+ Viewer
+ NSDocumentClass
+ $(PRODUCT_MODULE_NAME).Document
+
+
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2017 Kilian Hofmann. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/Converter/ViewController.swift b/Converter/ViewController.swift
new file mode 100644
index 0000000..b8e61f6
--- /dev/null
+++ b/Converter/ViewController.swift
@@ -0,0 +1,114 @@
+//
+// ViewController.swift
+// Converter
+//
+// Created by Kilian Hofmann on 20.06.17.
+// Copyright © 2017 Kilian Hofmann. All rights reserved.
+//
+
+import Cocoa
+
+class ViewController: NSViewController {
+
+ @IBOutlet var months: NSTextField!
+ @IBOutlet var days: NSTextField!
+ @IBOutlet var files: NSTextField!
+ @IBOutlet var progress: NSTextField!
+ @IBOutlet var convert: NSButton!
+ @IBOutlet var inPath: NSTextField!
+
+ var fileWrappers: [String : [String : FileWrapper]]!
+ var filesDone: Int = 0
+ var filesTotal: Int = 0
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Do any additional setup after loading the view.
+ }
+
+ @IBAction func convert(sender: NSButton) {
+ convert.isEnabled = false
+ (NSApp.delegate as! AppDelegate).isConverting = true
+ progress.stringValue = "File \(self.filesDone) of \(self.filesTotal)"
+
+ let opQueue: OperationQueue = OperationQueue()
+ let fileQueue: OperationQueue = OperationQueue()
+ fileQueue.maxConcurrentOperationCount = 4
+
+ let myActivity = ProcessInfo.processInfo.beginActivity(options: .userInitiated, reason: "Converting")
+ opQueue.addOperation {
+ defer {
+ fileQueue.waitUntilAllOperationsAreFinished()
+ ProcessInfo.processInfo.endActivity(myActivity)
+ OperationQueue.main.addOperation {
+ self.convert.isEnabled = true
+ (NSApp.delegate as! AppDelegate).isConverting = false
+ }
+ }
+
+ let inP: String = self.inPath.stringValue
+
+ for month in 1...12 {
+ for day in 1...31 {
+ let path: String = inP + String(format: "/%02d", month) + String(format: "/%02d", day)
+ do {
+ let directory = try FileWrapper(url: URL(fileURLWithPath: path), options: .immediate)
+ for file in directory.fileWrappers! {
+ if file.key == "KDLog.txt" {
+ let pathOut = path.appending("/" + file.key.replacingOccurrences(of: ".txt", with: ".hex")).replacingOccurrences(of: ".docsisplist2", with: "C.docsisplist2")
+ //print(path.appending(file.key) + " to " + pathOut)
+ self.makeSubDir(path: pathOut.replacingOccurrences(of: file.key.replacingOccurrences(of: ".txt", with: ".hex"), with: ""))
+ FileOperations.convertLoss(log: path.appending("/" + file.key), toFile: pathOut)
+ OperationQueue.main.addOperation {
+ self.filesDone += 1
+ self.progress.stringValue = "File \(self.filesDone) of \(self.filesTotal)"
+ }
+ } else if file.key.contains("Upstream") {
+ let pathOut = path.appending("/" + file.key.replacingOccurrences(of: ".csv", with: ".hex")).replacingOccurrences(of: ".docsisplist2", with: "C.docsisplist2")
+ //print(path.appending(file.key) + " to " + pathOut)
+ self.makeSubDir(path: pathOut.replacingOccurrences(of: file.key.replacingOccurrences(of: ".csv", with: ".hex"), with: ""))
+ FileOperations.convertUpstream(log: path.appending("/" + file.key), toFile: pathOut)
+ OperationQueue.main.addOperation {
+ self.filesDone += 1
+ self.progress.stringValue = "File \(self.filesDone) of \(self.filesTotal)"
+ }
+ } else if file.key.contains("Downstream") {
+ let pathOut = path.appending("/" + file.key.replacingOccurrences(of: ".csv", with: ".hex")).replacingOccurrences(of: ".docsisplist2", with: "C.docsisplist2")
+ //print(path.appending(file.key) + " to " + pathOut)
+ self.makeSubDir(path: pathOut.replacingOccurrences(of: file.key.replacingOccurrences(of: ".csv", with: ".hex"), with: ""))
+ FileOperations.convertDownstream(log: path.appending("/" + file.key), toFile: pathOut)
+ OperationQueue.main.addOperation {
+ self.filesDone += 1
+ self.progress.stringValue = "File \(self.filesDone) of \(self.filesTotal)"
+ }
+ }
+ }
+ } catch _ { continue }
+ }
+ }
+ }
+ }
+
+ func makeSubDir(path: String) {
+ // Check if directory exists, create or exit
+ let fileManager = FileManager.default
+ var directory: ObjCBool = ObjCBool(false)
+ let exists: Bool = fileManager.fileExists(atPath: (path as NSString).expandingTildeInPath, isDirectory: &directory)
+ if exists && directory.boolValue {
+ } else if exists {
+ NSLog("FILE WITH NAME KDLog EXISTS, REMOVE IT")
+ exit(1);
+ }
+ else {
+ do {
+ try fileManager.createDirectory(atPath: (path as NSString).expandingTildeInPath, withIntermediateDirectories: true, attributes: nil)
+ }
+ catch let error as NSError {
+ NSLog("ERROR ON DIRECTORY CREATION: \(error.localizedDescription)")
+ exit(1);
+ }
+ }
+ }
+}
+
diff --git a/Docsis Toolkit.xcodeproj/project.pbxproj b/Docsis Toolkit.xcodeproj/project.pbxproj
index 9b7ca38..28a23a2 100644
--- a/Docsis Toolkit.xcodeproj/project.pbxproj
+++ b/Docsis Toolkit.xcodeproj/project.pbxproj
@@ -35,6 +35,7 @@
E2268DF91EF7095100C97726 /* PDFTitle.xib in Resources */ = {isa = PBXBuildFile; fileRef = E2268DF71EF7095100C97726 /* PDFTitle.xib */; };
E23E2C621EF7FE530009D376 /* FileOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = E23E2C611EF7FE530009D376 /* FileOperations.swift */; };
E23E2C631EF7FE530009D376 /* FileOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = E23E2C611EF7FE530009D376 /* FileOperations.swift */; };
+ E25E24941EFB186000F39C01 /* GraphLoadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25E24931EFB186000F39C01 /* GraphLoadOperation.swift */; };
E262463E1EF55BCE00EAA4A6 /* GraphWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E262463C1EF55BCE00EAA4A6 /* GraphWindow.swift */; };
E262463F1EF55BCE00EAA4A6 /* GraphWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = E262463D1EF55BCE00EAA4A6 /* GraphWindow.xib */; };
E26246441EF5E64900EAA4A6 /* PDFDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = E26246421EF5E64900EAA4A6 /* PDFDraw.swift */; };
@@ -43,6 +44,12 @@
E26246491EF6688400EAA4A6 /* PDFItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E26246481EF6688400EAA4A6 /* PDFItemViewController.swift */; };
E27A9DB51EF995C1000BC7A3 /* FrequencyGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */; };
E27A9DB91EF99C20000BC7A3 /* FlippedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */; };
+ E27A9DC11EF9B7FD000BC7A3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DC01EF9B7FD000BC7A3 /* AppDelegate.swift */; };
+ E27A9DC31EF9B7FD000BC7A3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DC21EF9B7FD000BC7A3 /* ViewController.swift */; };
+ E27A9DC51EF9B7FD000BC7A3 /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27A9DC41EF9B7FD000BC7A3 /* Document.swift */; };
+ E27A9DC71EF9B7FD000BC7A3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E27A9DC61EF9B7FD000BC7A3 /* Assets.xcassets */; };
+ E27A9DCA1EF9B7FD000BC7A3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27A9DC81EF9B7FD000BC7A3 /* Main.storyboard */; };
+ E27A9DCF1EF9D0E3000BC7A3 /* FileOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = E23E2C611EF7FE530009D376 /* FileOperations.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -99,6 +106,7 @@
E2268DF61EF7095100C97726 /* PDFTitle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFTitle.swift; sourceTree = ""; };
E2268DF71EF7095100C97726 /* PDFTitle.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PDFTitle.xib; sourceTree = ""; };
E23E2C611EF7FE530009D376 /* FileOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileOperations.swift; sourceTree = ""; };
+ E25E24931EFB186000F39C01 /* GraphLoadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphLoadOperation.swift; sourceTree = ""; };
E262463C1EF55BCE00EAA4A6 /* GraphWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphWindow.swift; sourceTree = ""; };
E262463D1EF55BCE00EAA4A6 /* GraphWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GraphWindow.xib; sourceTree = ""; };
E26246421EF5E64900EAA4A6 /* PDFDraw.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFDraw.swift; sourceTree = ""; };
@@ -107,6 +115,13 @@
E26246481EF6688400EAA4A6 /* PDFItemViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFItemViewController.swift; sourceTree = ""; };
E27A9DB41EF995C1000BC7A3 /* FrequencyGraph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrequencyGraph.swift; sourceTree = ""; };
E27A9DB81EF99C20000BC7A3 /* FlippedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlippedView.swift; sourceTree = ""; };
+ E27A9DBE1EF9B7FD000BC7A3 /* Converter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Converter.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ E27A9DC01EF9B7FD000BC7A3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ E27A9DC21EF9B7FD000BC7A3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ E27A9DC41EF9B7FD000BC7A3 /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = ""; };
+ E27A9DC61EF9B7FD000BC7A3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ E27A9DC91EF9B7FD000BC7A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ E27A9DCB1EF9B7FD000BC7A3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -125,6 +140,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ E27A9DBB1EF9B7FD000BC7A3 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -134,6 +156,7 @@
E2218CA71EF2D35B004298F6 /* Shared Resources */,
E2218C991EF2D345004298F6 /* Logger4 */,
E2218D2A1EF3271F004298F6 /* Graphic Analysis 2 */,
+ E27A9DBF1EF9B7FD000BC7A3 /* Converter */,
E2218C831EF2D2B5004298F6 /* Products */,
E2218D651EF463B4004298F6 /* Frameworks */,
);
@@ -144,6 +167,7 @@
children = (
E2218C981EF2D345004298F6 /* Logger4.app */,
E2218D291EF3271F004298F6 /* Graphic Analysis 2.app */,
+ E27A9DBE1EF9B7FD000BC7A3 /* Converter.app */,
);
name = Products;
sourceTree = "";
@@ -303,6 +327,7 @@
E2218D4F1EF329C0004298F6 /* Operations */ = {
isa = PBXGroup;
children = (
+ E25E24931EFB186000F39C01 /* GraphLoadOperation.swift */,
);
name = Operations;
sourceTree = "";
@@ -395,6 +420,19 @@
name = Swift;
sourceTree = "";
};
+ E27A9DBF1EF9B7FD000BC7A3 /* Converter */ = {
+ isa = PBXGroup;
+ children = (
+ E27A9DC01EF9B7FD000BC7A3 /* AppDelegate.swift */,
+ E27A9DC21EF9B7FD000BC7A3 /* ViewController.swift */,
+ E27A9DC41EF9B7FD000BC7A3 /* Document.swift */,
+ E27A9DC61EF9B7FD000BC7A3 /* Assets.xcassets */,
+ E27A9DC81EF9B7FD000BC7A3 /* Main.storyboard */,
+ E27A9DCB1EF9B7FD000BC7A3 /* Info.plist */,
+ );
+ path = Converter;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
@@ -465,6 +503,23 @@
productReference = E2218D291EF3271F004298F6 /* Graphic Analysis 2.app */;
productType = "com.apple.product-type.application";
};
+ E27A9DBD1EF9B7FD000BC7A3 /* Converter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E27A9DCC1EF9B7FD000BC7A3 /* Build configuration list for PBXNativeTarget "Converter" */;
+ buildPhases = (
+ E27A9DBA1EF9B7FD000BC7A3 /* Sources */,
+ E27A9DBB1EF9B7FD000BC7A3 /* Frameworks */,
+ E27A9DBC1EF9B7FD000BC7A3 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Converter;
+ productName = Converter;
+ productReference = E27A9DBE1EF9B7FD000BC7A3 /* Converter.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -496,6 +551,11 @@
DevelopmentTeam = 795KPDV76S;
ProvisioningStyle = Automatic;
};
+ E27A9DBD1EF9B7FD000BC7A3 = {
+ CreatedOnToolsVersion = 8.3.3;
+ DevelopmentTeam = 795KPDV76S;
+ ProvisioningStyle = Automatic;
+ };
};
};
buildConfigurationList = E2218C7D1EF2D2B5004298F6 /* Build configuration list for PBXProject "Docsis Toolkit" */;
@@ -515,6 +575,7 @@
E2218CE51EF2D577004298F6 /* Bump Logger4 */,
E2218D281EF3271F004298F6 /* Graphic Analysis 2 */,
E2218D3D1EF32803004298F6 /* Bump Graphic Analysis 2 */,
+ E27A9DBD1EF9B7FD000BC7A3 /* Converter */,
);
};
/* End PBXProject section */
@@ -548,6 +609,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ E27A9DBC1EF9B7FD000BC7A3 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E27A9DC71EF9B7FD000BC7A3 /* Assets.xcassets in Resources */,
+ E27A9DCA1EF9B7FD000BC7A3 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -574,6 +644,7 @@
E2218D621EF41415004298F6 /* CollectionViewMonth.swift in Sources */,
E23E2C631EF7FE530009D376 /* FileOperations.swift in Sources */,
E2218D601EF40E23004298F6 /* CollectionViewYear.swift in Sources */,
+ E25E24941EFB186000F39C01 /* GraphLoadOperation.swift in Sources */,
E262463E1EF55BCE00EAA4A6 /* GraphWindow.swift in Sources */,
E26246491EF6688400EAA4A6 /* PDFItemViewController.swift in Sources */,
E2218D641EF45F37004298F6 /* LossDistributionPie.swift in Sources */,
@@ -586,6 +657,17 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ E27A9DBA1EF9B7FD000BC7A3 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E27A9DCF1EF9D0E3000BC7A3 /* FileOperations.swift in Sources */,
+ E27A9DC31EF9B7FD000BC7A3 /* ViewController.swift in Sources */,
+ E27A9DC11EF9B7FD000BC7A3 /* AppDelegate.swift in Sources */,
+ E27A9DC51EF9B7FD000BC7A3 /* Document.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -601,6 +683,17 @@
};
/* End PBXTargetDependency section */
+/* Begin PBXVariantGroup section */
+ E27A9DC81EF9B7FD000BC7A3 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ E27A9DC91EF9B7FD000BC7A3 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
/* Begin XCBuildConfiguration section */
E2218C8F1EF2D2B5004298F6 /* Debug */ = {
isa = XCBuildConfiguration;
@@ -818,6 +911,36 @@
};
name = Release;
};
+ E27A9DCD1EF9B7FD000BC7A3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEVELOPMENT_TEAM = 795KPDV76S;
+ INFOPLIST_FILE = Converter/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ PRODUCT_BUNDLE_IDENTIFIER = com.weebly.alikja.Converter;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ E27A9DCE1EF9B7FD000BC7A3 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEVELOPMENT_TEAM = 795KPDV76S;
+ INFOPLIST_FILE = Converter/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ PRODUCT_BUNDLE_IDENTIFIER = com.weebly.alikja.Converter;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -866,6 +989,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ E27A9DCC1EF9B7FD000BC7A3 /* Build configuration list for PBXNativeTarget "Converter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E27A9DCD1EF9B7FD000BC7A3 /* Debug */,
+ E27A9DCE1EF9B7FD000BC7A3 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = E2218C7A1EF2D2B5004298F6 /* Project object */;
diff --git a/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/Converter.xcscheme b/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/Converter.xcscheme
new file mode 100644
index 0000000..99e501b
--- /dev/null
+++ b/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/Converter.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/xcschememanagement.plist b/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/xcschememanagement.plist
index 381ac45..09c08d4 100644
--- a/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -9,6 +9,11 @@
orderHint
2
+ Converter.xcscheme
+
+ orderHint
+ 3
+
Graphic Analysis 2.xcscheme
orderHint
@@ -47,6 +52,11 @@
primary
+ E27A9DBD1EF9B7FD000BC7A3
+
+ primary
+
+
diff --git a/FileOperations.swift b/FileOperations.swift
index 2e66091..b98a572 100644
--- a/FileOperations.swift
+++ b/FileOperations.swift
@@ -29,7 +29,7 @@ class FileOperations: NSObject {
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)")
+ return ("\(String(format: "%02d", hours)):\(String(format: "%02d", minutes)):\(String(format: "%02d", seconds))", mappingDecode[threshold] ?? "\(15)")
}
@@ -39,7 +39,6 @@ class FileOperations: NSObject {
let dataToWrite = encodeTimeStamp(stamp: data, threshold: "")
let file: UnsafeMutableRawPointer = UnsafeMutableRawPointer.allocate(bytes: 3, alignedTo: 1)
file.storeBytes(of: dataToWrite, as: UInt32.self)
- file.deallocate(bytes: 3, alignedTo: 1)
do {
let fileData: NSMutableData = try NSMutableData(contentsOf: URL(fileURLWithPath: path))
fileData.append(file, length: 3)
@@ -49,6 +48,17 @@ class FileOperations: NSObject {
fileData.append(file, length: 3)
fileData.write(to: URL(fileURLWithPath: path), atomically: true)
}
+ file.deallocate(bytes: 3, alignedTo: 1)
+ }
+
+ static func log(data: String, toData out: inout Data) {
+ let dataToWrite = encodeTimeStamp(stamp: data, threshold: "")
+ let file: UnsafeMutableRawPointer = UnsafeMutableRawPointer.allocate(bytes: 3, alignedTo: 1)
+ file.storeBytes(of: dataToWrite, as: UInt32.self)
+ let fileData: NSMutableData = NSMutableData()
+ fileData.append(file, length: 3)
+ out.append(fileData as Data)
+ file.deallocate(bytes: 3, alignedTo: 1)
}
static func load(log Data: NSData) -> [String]? {
@@ -94,6 +104,25 @@ class FileOperations: NSObject {
}
}
+ static func logUpstream(data: String, toData out: inout Data) {
+ let separated: Array = 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)!)
+
+ out.append(fileContent as Data)
+ }
+
static func logDownstream(data: String, toFrequencyLog path: String) {
let separated: Array = data.components(separatedBy: ";")
var encodedTime: UInt32 = encodeTimeStamp(stamp: separated[0], threshold: "")
@@ -117,6 +146,25 @@ class FileOperations: NSObject {
fileContent.write(to: URL(fileURLWithPath: path), atomically: true)
}
}
+
+ static func logDownstream(data: String, toData out: inout Data) {
+ let separated: Array = 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)
+
+ out.append(fileContent as Data)
+ }
+
// MARK: - Frequency loading (decoding)
@@ -230,4 +278,53 @@ class FileOperations: NSObject {
}
return nil
}
+
+ // MARK: - Convert
+
+ static func convertLoss(log path: String, toFile pathOut: String) {
+ do {
+ var data: [String] = NSString(data: try NSData(contentsOfFile: path) as Data, encoding: String.Encoding.ascii.rawValue)!.components(separatedBy: "\n")
+ data.removeLast()
+ var dataOut: Data = Data()
+ for entry in data {
+ log(data: entry, toData: &dataOut)
+ }
+ (dataOut as NSData).write(toFile: pathOut, atomically: true)
+ } catch {
+ return
+ }
+ }
+
+ static func convertUpstream(log path: String, toFile pathOut: String) {
+ do {
+ var data: [String] = NSString(data: try NSData(contentsOfFile: path) as Data, encoding: String.Encoding.ascii.rawValue)!.components(separatedBy: "\n")
+ data.removeLast()
+ data.removeFirst()
+ var dataOut: Data = Data()
+ for var entry in data {
+ if entry.components(separatedBy: ";").count < 4 {
+ entry.append(";-")
+ }
+ logUpstream(data: entry, toData: &dataOut)
+ }
+ (dataOut as NSData).write(toFile: pathOut, atomically: true)
+ } catch {
+ return
+ }
+ }
+
+ static func convertDownstream(log path: String, toFile pathOut: String) {
+ do {
+ var data: [String] = NSString(data: try NSData(contentsOfFile: path) as Data, encoding: String.Encoding.ascii.rawValue)!.components(separatedBy: "\n")
+ data.removeLast()
+ data.removeFirst()
+ var dataOut: Data = Data()
+ for entry in data {
+ logDownstream(data: entry, toData: &dataOut)
+ }
+ (dataOut as NSData).write(toFile: pathOut, atomically: true)
+ } catch {
+ return
+ }
+ }
}
diff --git a/Graphic Analysis 2/FrequencyGraph.swift b/Graphic Analysis 2/FrequencyGraph.swift
index d9ee05d..76e9c3d 100644
--- a/Graphic Analysis 2/FrequencyGraph.swift
+++ b/Graphic Analysis 2/FrequencyGraph.swift
@@ -92,7 +92,7 @@ class FrequencyGraph: NSView {
}
}
- func initView() {
+ func initView(operation: GraphLoadOperation) {
// Setup Indicator
// Zero line
let zero: NSBezierPath = NSBezierPath()
@@ -102,6 +102,9 @@ class FrequencyGraph: NSView {
// Add data points
var lastWasSkipped: Bool = false
for point in 0.. Bool {
+ opQueue.cancelAllOperations()
collectionViewItem?.isSelected = false
collectionViewItem?.view.layer?.borderColor = NSColor.clear.cgColor
return true
diff --git a/Graphic Analysis 2/GraphWindow.xib b/Graphic Analysis 2/GraphWindow.xib
index c5668ed..3bad7c2 100644
--- a/Graphic Analysis 2/GraphWindow.xib
+++ b/Graphic Analysis 2/GraphWindow.xib
@@ -16,33 +16,33 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -51,6 +51,7 @@
+
diff --git a/Graphic Analysis 2/Info.plist b/Graphic Analysis 2/Info.plist
index 230bfcc..c49ca82 100644
--- a/Graphic Analysis 2/Info.plist
+++ b/Graphic Analysis 2/Info.plist
@@ -44,7 +44,7 @@
CFBundleShortVersionString
2.1
CFBundleVersion
- 454
+ 461
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
diff --git a/Graphic Analysis 2/PDFItemViewController.swift b/Graphic Analysis 2/PDFItemViewController.swift
index d4466b8..a0603cf 100644
--- a/Graphic Analysis 2/PDFItemViewController.swift
+++ b/Graphic Analysis 2/PDFItemViewController.swift
@@ -46,9 +46,8 @@ class PDFItemViewController: NSViewController {
month.stringValue = monthName
guard dayFW != nil else { return }
day.textColor = NSColor.black
- guard let log = dayFW?.fileWrappers?["KDLog.txt"] else { return }
- guard var logA = String(data: log.regularFileContents!, encoding: .utf8)?.components(separatedBy: "\n") else { return }
- logA.removeLast()
+ guard let log = dayFW?.fileWrappers?["KDLog.hex"] else { return }
+ guard let logA = FileOperations.load(log: log.regularFileContents! as NSData) else { return }
loss.stringValue = "\(logA.count)"
var am: [Int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
var pm: [Int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
diff --git a/Graphic Analysis 2/buildnum.ver b/Graphic Analysis 2/buildnum.ver
index 994cac0..d88db36 100644
--- a/Graphic Analysis 2/buildnum.ver
+++ b/Graphic Analysis 2/buildnum.ver
@@ -1,2 +1,2 @@
version 2.1
-build 454
+build 461
diff --git a/Logger4/Info.plist b/Logger4/Info.plist
index b648932..28f722b 100644
--- a/Logger4/Info.plist
+++ b/Logger4/Info.plist
@@ -15,9 +15,9 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 4.1
+ 4.2
CFBundleVersion
- 48
+ 49
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
diff --git a/Logger4/buildnum.ver b/Logger4/buildnum.ver
index e45f8bd..b79a0b5 100644
--- a/Logger4/buildnum.ver
+++ b/Logger4/buildnum.ver
@@ -1,2 +1,2 @@
-version 4.1
-build 48
+version 4.2
+build 49