Last active
July 26, 2023 16:45
-
-
Save dfrvs/d0359da6e6c03d64f9d0e8b0d261e7e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// XCActivityLogTokenyizer.swift | |
// XCActivityLogParser | |
// | |
// Created by Vorobyov Semyon on 15.07.2023. | |
// | |
import Foundation | |
// Let's take a simple tokenizer for converting the SLF0 format into tokens. | |
// | |
// https://medium.com/@vorobyov.semyon.ana/lets-parse-xcode-logs-dea4e5fb1de4 | |
// https://habr.com/ru/articles/749554/ | |
enum Token { | |
case integer(Int) | |
case double(Double) | |
case null | |
case string(String) | |
case array(Int) | |
case class_name(String) | |
case class_instance(Int) | |
} | |
guard | |
let fileHandle = FileHandle(forReadingAtPath: "test_log") | |
else { fatalError("Can't open file") } | |
// Skip SLF0 header | |
_ = try? fileHandle.read(upToCount: 4) | |
var tokens = [Token]() | |
var current_side_value = "" | |
while let data = try? fileHandle.read(upToCount: 1), let char = String(data: data, encoding: .ascii) { | |
switch char { | |
case "#": | |
guard let value = Int(current_side_value) else { break } | |
tokens.append(.integer(value)) | |
current_side_value = "" | |
case "^": | |
guard let value = UInt64(current_side_value, radix: 16) else { break } | |
let double = Double(bitPattern: value.byteSwapped) | |
tokens.append(.double(double)) | |
current_side_value = "" | |
case "-": | |
tokens.append(.null) | |
current_side_value = "" | |
case "\"": | |
guard | |
let count = Int(current_side_value), | |
let stringData = try? fileHandle.read(upToCount: count), let value = String(data: stringData, encoding: .ascii) | |
else { | |
tokens.append(.string("")) | |
current_side_value = "" | |
break | |
} | |
tokens.append(.string(value)) | |
current_side_value = "" | |
case "(": | |
guard let value = Int(current_side_value) else { break } | |
tokens.append(.array(value)) | |
current_side_value = "" | |
case "%": | |
guard | |
let count = Int(current_side_value), | |
let stringData = try? fileHandle.read(upToCount: count), let value = String(data: stringData, encoding: .ascii) | |
else { break } | |
tokens.append(.class_name(value)) | |
current_side_value = "" | |
case "@": | |
guard let value = Int(current_side_value) else { break } | |
tokens.append(.class_instance(value)) | |
current_side_value = "" | |
default: | |
current_side_value.append(char) | |
} | |
} | |
fileHandle.closeFile() | |
tokens.forEach { token in | |
print(token) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment