Skip to content

Instantly share code, notes, and snippets.

@dfrvs
Last active July 26, 2023 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dfrvs/d0359da6e6c03d64f9d0e8b0d261e7e4 to your computer and use it in GitHub Desktop.
Save dfrvs/d0359da6e6c03d64f9d0e8b0d261e7e4 to your computer and use it in GitHub Desktop.
//
// 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