1
0
mirror of git://jb55.com/damus synced 2024-09-19 19:46:51 +00:00

iter: make safer by using NdbNote instead of unsafe pointers

If we have an owned note, we could lose track of the lifetime and then
crash. Let's make sure we always have an NdbNote instead
This commit is contained in:
William Casarin 2023-07-22 16:56:13 -07:00
parent af7ea7024f
commit 58e2fb40ef
4 changed files with 35 additions and 13 deletions

View File

@ -34,7 +34,7 @@ struct NdbNote {
} }
func tags() -> TagsSequence { func tags() -> TagsSequence {
return .init(note: note) return .init(note: self)
} }
static func owned_from_json(json: String, bufsize: Int = 2 << 18) -> NdbNote? { static func owned_from_json(json: String, bufsize: Int = 2 << 18) -> NdbNote? {

View File

@ -8,22 +8,22 @@
import Foundation import Foundation
struct NdbTagElem { struct NdbTagElem {
private let note: UnsafeMutablePointer<ndb_note> private let note: NdbNote
private let tag: UnsafeMutablePointer<ndb_tag> private let tag: UnsafeMutablePointer<ndb_tag>
let index: Int32 let index: Int32
init(note: UnsafeMutablePointer<ndb_note>, tag: UnsafeMutablePointer<ndb_tag>, index: Int32) { init(note: NdbNote, tag: UnsafeMutablePointer<ndb_tag>, index: Int32) {
self.note = note self.note = note
self.tag = tag self.tag = tag
self.index = index self.index = index
} }
func matches_char(c: AsciiCharacter) -> Bool { func matches_char(_ c: AsciiCharacter) -> Bool {
return ndb_tag_matches_char(note, tag, index, c.cchar) == 1 return ndb_tag_matches_char(note.note, tag, index, c.cchar) == 1
} }
func string() -> String { func string() -> String {
return String(cString: ndb_tag_str(note, tag, index), encoding: .utf8) ?? "" return String(cString: ndb_tag_str(note.note, tag, index), encoding: .utf8) ?? ""
} }
} }

View File

@ -8,9 +8,21 @@
import Foundation import Foundation
struct TagSequence: Sequence { struct TagSequence: Sequence {
let note: UnsafeMutablePointer<ndb_note> let note: NdbNote
let tag: UnsafeMutablePointer<ndb_tag> let tag: UnsafeMutablePointer<ndb_tag>
var count: UInt16 {
tag.pointee.count
}
subscript(index: Int) -> NdbTagElem? {
if index >= tag.pointee.count {
return nil
}
return NdbTagElem(note: note, tag: tag, index: Int32(index))
}
func makeIterator() -> TagIterator { func makeIterator() -> TagIterator {
return TagIterator(note: note, tag: tag) return TagIterator(note: note, tag: tag)
} }
@ -29,10 +41,14 @@ struct TagIterator: IteratorProtocol {
} }
var index: Int32 var index: Int32
let note: UnsafeMutablePointer<ndb_note> let note: NdbNote
var tag: UnsafeMutablePointer<ndb_tag> var tag: UnsafeMutablePointer<ndb_tag>
init(note: UnsafeMutablePointer<ndb_note>, tag: UnsafeMutablePointer<ndb_tag>) { var count: UInt16 {
tag.pointee.count
}
init(note: NdbNote, tag: UnsafeMutablePointer<ndb_tag>) {
self.note = note self.note = note
self.tag = tag self.tag = tag
self.index = 0 self.index = 0

View File

@ -12,11 +12,12 @@ struct TagsIterator: IteratorProtocol {
var done: Bool var done: Bool
var iter: ndb_iterator var iter: ndb_iterator
var note: NdbNote
mutating func next() -> TagSequence? { mutating func next() -> TagSequence? {
guard !done else { return nil } guard !done else { return nil }
let tag_seq = TagSequence(note: iter.note, tag: self.iter.tag) let tag_seq = TagSequence(note: note, tag: self.iter.tag)
let ok = ndb_tags_iterate_next(&self.iter) let ok = ndb_tags_iterate_next(&self.iter)
done = ok == 0 done = ok == 0
@ -24,15 +25,20 @@ struct TagsIterator: IteratorProtocol {
return tag_seq return tag_seq
} }
init(note: UnsafeMutablePointer<ndb_note>) { var count: UInt16 {
return iter.tag.pointee.count
}
init(note: NdbNote) {
self.iter = ndb_iterator() self.iter = ndb_iterator()
let res = ndb_tags_iterate_start(note, &self.iter) let res = ndb_tags_iterate_start(note.note, &self.iter)
self.done = res == 0 self.done = res == 0
self.note = note
} }
} }
struct TagsSequence: Sequence { struct TagsSequence: Sequence {
let note: UnsafeMutablePointer<ndb_note> let note: NdbNote
func makeIterator() -> TagsIterator { func makeIterator() -> TagsIterator {
return .init(note: note) return .init(note: note)