UserPhrases // Implement .removeFromFilter() method, etc.

This commit is contained in:
ShikiSuen 2023-09-06 22:07:11 +08:00
parent 1cc2929d95
commit ee11682edb
1 changed files with 97 additions and 5 deletions

View File

@ -67,8 +67,24 @@ public extension LMMgr {
}
public func write(toFilter: Bool) -> Bool {
guard isValid, LMMgr.chkUserLMFilesExist(inputMode) else { return false }
guard isValid else {
vCLog("UserPhrase.write(toFilter: \(toFilter.description)) Error: UserPhrase invalid.")
return false
}
guard LMMgr.chkUserLMFilesExist(inputMode) else {
vCLog("UserPhrase.write(toFilter: \(toFilter.description)) Error: UserLMFiles not exist.")
return false
}
if !toFilter, isAlreadyFiltered {
vCLog("START REMOVING THIS PHRASE FROM FILTER.")
removeFromFilter()
//
//
if isAlreadyFiltered {
removeFromFilter(forceConsolidate: true)
}
return !isAlreadyFiltered
}
///
/// 使
///
@ -80,11 +96,21 @@ public extension LMMgr {
let dict = try FileManager.default.attributesOfItem(atPath: theURL.path)
if let value = dict[FileAttributeKey.size] as? UInt64 { fileSize = value }
} catch {
vCLog("UserPhrase.write(toFilter: \(toFilter.description)) Error: Target file size is null.")
return false
}
guard let fileSize = fileSize else {
vCLog("UserPhrase.write(toFilter: \(toFilter.description)) Error: Target file size is null.")
return false
}
guard var dataToInsert = "\(description)\n".data(using: .utf8) else {
vCLog("UserPhrase.write(toFilter: \(toFilter.description)) Error: Failed from preparing insertion data.")
return false
}
guard let writeFile = FileHandle(forUpdatingAtPath: theURL.path) else {
vCLog("UserPhrase.write(toFilter: \(toFilter.description)) Error: Failed from initiating file handle.")
return false
}
guard let fileSize = fileSize else { return false }
guard var dataToInsert = "\(description)\n".data(using: .utf8) else { return false }
guard let writeFile = FileHandle(forUpdatingAtPath: theURL.path) else { return false }
defer { writeFile.closeFile() }
if fileSize > 0 {
writeFile.seek(toFileOffset: fileSize - 1)
@ -96,5 +122,71 @@ public extension LMMgr {
writeFile.write(dataToInsert)
return true
}
///
///
/// NULL0x0
///
/// - Parameter confirm:
@discardableResult public func removeFromFilter(confirm: Bool = false, forceConsolidate: Bool = false) -> Bool {
let debugOutput = NSMutableString()
defer {
if debugOutput.length > 0 { vCLog(debugOutput.description) }
}
if confirm {
guard isValid else {
debugOutput.append("removeFromFilter(): This user phrase pair is invalid. \(descriptionCells.prefix(2).joined(separator: " "))")
return false
}
guard isAlreadyFiltered else {
debugOutput.append("removeFromFilter(): This user phrase pair is not in the filtered list.")
return false
}
}
let theURL = LMMgr.userDictDataURL(mode: inputMode, type: .theFilter)
if forceConsolidate, !vChewingLM.LMConsolidator.consolidate(path: theURL.path, pragma: false) { return false }
// Get FileSize.
var fileSize: UInt64?
do {
let dict = try FileManager.default.attributesOfItem(atPath: theURL.path)
if let value = dict[FileAttributeKey.size] as? UInt64 { fileSize = value }
} catch {
debugOutput.append("removeFromFilter(): Failed from getting the file size of the filter list file.")
return false
}
guard let fileSize = fileSize else { return false }
// Prepare FileHandle.
guard let fileHandle = FileHandle(forUpdatingAtPath: theURL.path) else {
debugOutput.append("removeFromFilter(): Failed from handling the filter list file.")
return false
}
defer { fileHandle.closeFile() }
// Get bytes for matching.
let usefulCells = descriptionCells.prefix(2)
guard usefulCells.count == 2 else { return false }
guard let data1 = usefulCells.joined(separator: " ").data(using: .utf8) else { return false }
guard let data2 = usefulCells.joined(separator: "\t").data(using: .utf8) else { return false }
let bufferLength = data1.count // data1 data2
guard fileSize >= bufferLength else { return true }
let blankData = Data([UInt8](repeating: 0x0, count: bufferLength)) //
let sharpData = Data([0x23]) // Sharp Sign (#)
fileHandle.seek(toFileOffset: 0) //
for currentOffset in -1 ..< (Int(fileSize) - bufferLength - 1) {
/// !! FileHandle seek readData() / write()
//
let currentWorkingOffset = UInt64(currentOffset + 1)
//
fileHandle.seek(toFileOffset: UInt64(max(0, currentOffset)))
let currentByte = fileHandle.readData(ofLength: 1)
guard currentByte != sharpData else { continue }
//
fileHandle.seek(toFileOffset: currentWorkingOffset)
let dataScoped = fileHandle.readData(ofLength: bufferLength)
guard [data1, data2].contains(dataScoped) else { continue }
fileHandle.seek(toFileOffset: currentWorkingOffset)
fileHandle.write(blankData)
}
return true
}
}
}