Last active
November 22, 2020 07:08
-
-
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
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
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