Skip to content

Instantly share code, notes, and snippets.

@macneko-ayu
Last active November 22, 2020 07:08
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 macneko-ayu/3d76167fceda98aa758d7b1a6369bb7d to your computer and use it in GitHub Desktop.
Save macneko-ayu/3d76167fceda98aa758d7b1a6369bb7d to your computer and use it in GitHub Desktop.
Extract the creation application version and saved version of an Illustrator file (ai, eps) ref: https://gist.github.com/monokano/8bffac0c07401627c5a1ebf020b93b0e
import Cocoa
/// ファイルを指定されたバイト数分ずつ読み込む
final class StreamReader: NSObject, StreamDelegate {
let maxLength: Int
let inputStream: InputStream?
var readedAction: (Versions) -> Void = { _ in }
var createVersion = ""
var saveVersion = ""
init(filePath: String, maxLength: Int) {
self.maxLength = maxLength
self.inputStream = InputStream(fileAtPath: filePath)
super.init()
inputStream?.delegate = self
}
func start(readedAction: @escaping (Versions) -> Void) {
self.readedAction = readedAction
inputStream?.schedule(in: RunLoop.current, forMode: .default)
inputStream?.open()
}
func stop() {
inputStream?.close()
}
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case .openCompleted:
()
case .hasBytesAvailable:
guard let inputStream = inputStream else {
self.inputStream?.close()
return
}
var buffer = [UInt8](repeating: 0, count: maxLength)
while inputStream.hasBytesAvailable {
let result = inputStream.read(&buffer, maxLength: buffer.capacity)
if result > 0 {
let save = extractString(from: Data(buffer),
prefix: "%%Creator: Adobe Illustrator(R)",
suffix: "%%AI8_CreatorVersion:")
let create = extractString(from: Data(buffer),
prefix: "AI8_CreatorVersion:",
suffix: "%%For")
if !save.isEmpty {
saveVersion = save
}
if !create.isEmpty {
saveVersion = create
}
if !save.isEmpty, !create.isEmpty {
// 作成バージョンと保存バージョンを抽出できたらクロージャを実行
readedAction(Versions(createVersion: create, saveVersion: save))
// ストリームを閉じる
self.inputStream?.close()
}
}
}
case .errorOccurred:
inputStream?.close()
case .endEncountered:
inputStream?.close()
default:
inputStream?.close()
}
}
/// 渡された2つの文字列の間の文字を取り出す
func extractString(from data: Data, prefix: String, suffix: String) -> String {
guard let prefixData = prefix.data(using: .utf8),
let suffixData = suffix.data(using: .utf8),
let prefixRange = data.range(of: prefixData),
let suffixRange = data.range(of: suffixData) else { return "" }
// prefixの文字列のrangeの最後のIndexの一文字先の文字のindex
let startIndex = prefixRange.endIndex + 1
// prefixの文字列のrangeの最初のIndexの一文字前の文字のindex
let endIndex = suffixRange.startIndex - 1
let verStrData = data.subdata(in: startIndex ..< endIndex)
return String(data: verStrData, encoding: .utf8) ?? ""
}
}
/// バージョンを格納する構造体
struct Versions {
let createVersion: String
let saveVersion: String
var description: String {
return "createVersion: \(createVersion) saveVersion: \(saveVersion)"
}
}
let filePath = "(file_path)"
// 10MBずつ読み込む
let kb = 1024 * 1024 * 1
let steramReader = StreamReader(filePath: filePath, maxLength: kb)
steramReader.start { result in
// とりだしたバージョンを出力する
print(result.description)
}
// createVersion: 24.2.3 saveVersion: 24.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment