CommandLineToolkit

Форк
0
/
BlockingArrayBasedJSONStream.swift 
83 строки · 1.7 Кб
1
import AtomicModels
2
import Dispatch
3
import Foundation
4

5
public final class BlockingArrayBasedJSONStream: AppendableJSONStream {
6
    private let readLock = NSLock()
7
    private let writeLock = DispatchSemaphore(value: 0)
8
    
9
    private let storage = AtomicValue<[UInt8]>([])
10
    
11
    private var willProvideMoreData = true
12
    
13
    public init() {}
14
    
15
    public func append(bytes: [UInt8]) {
16
        storage.withExclusiveAccess {
17
            $0.insert(contentsOf: bytes.reversed(), at: 0)
18
        }
19
        onNewData()
20
    }
21
    
22
    // MARK: - JSONStream
23
    
24
    public func touch() -> UInt8? {
25
        return lastByte(delete: false)
26
    }
27
    
28
    public func read() -> UInt8? {
29
        return lastByte(delete: true)
30
    }
31
    
32
    public func close() {
33
        willProvideMoreData = false
34
        onStreamClose()
35
    }
36
    
37
    private func lastByte(delete: Bool) -> UInt8? {
38
        readLock.lock()
39
        defer {
40
            readLock.unlock()
41
        }
42
        
43
        if storage.currentValue().isEmpty {
44
            if willProvideMoreData {
45
                waitForNewDataOrStreamCloseEvent()
46
            } else {
47
                return nil
48
            }
49
        }
50
        
51
        return storage.withExclusiveAccess {
52
            if delete {
53
                return $0.popLast()
54
            } else {
55
                return $0.last
56
            }
57
        }
58
    }
59
    
60
    private func waitForNewDataOrStreamCloseEvent() {
61
        writeLock.waitForUnblocking()
62
    }
63
    
64
    private func onNewData() {
65
        writeLock.unblock()
66
    }
67
    
68
    private func onStreamClose() {
69
        writeLock.unblock()
70
    }
71
}
72

73
extension DispatchSemaphore {
74
    func waitForUnblocking() {
75
        wait()
76
        signal()
77
    }
78
    
79
    func unblock() {
80
        signal()
81
        wait()
82
    }
83
}
84

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.