<commit_before>//
//  Characteristic.swift
//  BlueCap
//
//  Created by <NAME> on 6/8/14.
//  Copyright (c) 2014 <NAME>. The MIT License (MIT).
//

import Foundation
import CoreBluetooth

public protocol CBCharacteristicWrappable {
    
    var UUID : CBUUID                           {get}
    var isNotifying : Bool                      {get}
    var value : NSData?                         {get}
    var properties : CBCharacteristicProperties {get}
    
}

extension CBCharacteristic : CBCharacteristicWrappable {}

public class Characteristic {

    private var notificationStateChangedPromise     = Promise<Characteristic>()
    private var readPromise                         = Promise<Characteristic>()
    private var writePromise                        = Promise<Characteristic>()
    private var notificationUpdatePromise : StreamPromise<Characteristic>?
    private weak var _service : Service?
    private let profile : CharacteristicProfile
    
    private var reading                             = false
    private var writing                             = false
    
    private var readSequence                        = 0
    private var writeSequence                       = 0
    private let defaultTimeout                      = 10.0

    internal let cbCharacteristic : CBCharacteristicWrappable
    
    public var uuid : CBUUID {
        return self.cbCharacteristic.UUID
    }
    
    public var name : String {
        return self.profile.name
    }
    
    public var isNotifying : Bool {
        return self.cbCharacteristic.isNotifying
    }
    
    public var afterDiscoveredPromise : StreamPromise<Characteristic>? {
        return self.profile.afterDiscoveredPromise
    }
    
    public var canNotify : Bool {
        return self.propertyEnabled(.Notify)                    ||
               self.propertyEnabled(.Indicate)                  ||
               self.propertyEnabled(.NotifyEncryptionRequired)  ||
               self.propertyEnabled(.IndicateEncryptionRequired)
    }
    
    public var canRead : Bool {
        return self.propertyEnabled(.Read)
    }
    
    public var canWrite : Bool {
        return self.propertyEnabled(.Write) || self.propertyEnabled(.WriteWithoutResponse)
    }
    
    public var service : Service? {
        return self._service
    }
    
    public var dataValue : NSData? {
        return self.cbCharacteristic.value
    }
    
    public var stringValues : [String] {
        return self.profile.stringValues
    }

    public var stringValue :[String:String]? {
        return self.stringValue(self.dataValue)
    }
    
    public var properties : CBCharacteristicProperties {
        return self.cbCharacteristic.properties
    }
    
    public func stringValue(data:NSData?) -> [String:String]? {
        if let data = data {
            return self.profile.stringValue(data)
        } else {
            return nil
        }
    }
    
    public func dataFromStringValue(stringValue:[String:String]) -> NSData? {
        return self.profile.dataFromStringValue(stringValue)
    }
    
    public func propertyEnabled(property:CBCharacteristicProperties) -> Bool {
        return (self.properties.rawValue & property.rawValue) > 0
    }

    public func value<T:Deserializable>() -> T? {
        if let data = self.dataValue {
            return T.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawDeserializable where T.RawType:Deserializable>() -> T? {
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawArrayDeserializable where T.RawType:Deserializable>() -> T? {
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawPairDeserializable where T.RawType1:Deserializable, T.RawType2:Deserializable>() -> T? {
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawArrayPairDeserializable where T.RawType1:Deserializable, T.RawType2:Deserializable>() -> T? { 
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func startNotifying() -> Future<Characteristic> {
        self.notificationStateChangedPromise = Promise<Characteristic>()
        if self.canNotify {
            self.setNotifyValue(true)
        } else {
            self.notificationStateChangedPromise.failure(BCError.characteristicNotifyNotSupported)
        }
        return self.notificationStateChangedPromise.future
    }

    public func stopNotifying() -> Future<Characteristic> {
        self.notificationStateChangedPromise = Promise<Characteristic>()
        if self.canNotify {
            self.setNotifyValue(true)
        } else {
            self.notificationStateChangedPromise.failure(BCError.characteristicNotifyNotSupported)
        }
        return self.notificationStateChangedPromise.future<commit_msg>stopNotifing should set notify to false<commit_after>//
//  Characteristic.swift
//  BlueCap
//
//  Created by <NAME> on 6/8/14.
//  Copyright (c) 2014 <NAME>. The MIT License (MIT).
//

import Foundation
import CoreBluetooth

public protocol CBCharacteristicWrappable {
    
    var UUID : CBUUID                           {get}
    var isNotifying : Bool                      {get}
    var value : NSData?                         {get}
    var properties : CBCharacteristicProperties {get}
    
}

extension CBCharacteristic : CBCharacteristicWrappable {}

public class Characteristic {

    private var notificationStateChangedPromise     = Promise<Characteristic>()
    private var readPromise                         = Promise<Characteristic>()
    private var writePromise                        = Promise<Characteristic>()
    private var notificationUpdatePromise : StreamPromise<Characteristic>?
    private weak var _service : Service?
    private let profile : CharacteristicProfile
    
    private var reading                             = false
    private var writing                             = false
    
    private var readSequence                        = 0
    private var writeSequence                       = 0
    private let defaultTimeout                      = 10.0

    internal let cbCharacteristic : CBCharacteristicWrappable
    
    public var uuid : CBUUID {
        return self.cbCharacteristic.UUID
    }
    
    public var name : String {
        return self.profile.name
    }
    
    public var isNotifying : Bool {
        return self.cbCharacteristic.isNotifying
    }
    
    public var afterDiscoveredPromise : StreamPromise<Characteristic>? {
        return self.profile.afterDiscoveredPromise
    }
    
    public var canNotify : Bool {
        return self.propertyEnabled(.Notify)                    ||
               self.propertyEnabled(.Indicate)                  ||
               self.propertyEnabled(.NotifyEncryptionRequired)  ||
               self.propertyEnabled(.IndicateEncryptionRequired)
    }
    
    public var canRead : Bool {
        return self.propertyEnabled(.Read)
    }
    
    public var canWrite : Bool {
        return self.propertyEnabled(.Write) || self.propertyEnabled(.WriteWithoutResponse)
    }
    
    public var service : Service? {
        return self._service
    }
    
    public var dataValue : NSData? {
        return self.cbCharacteristic.value
    }
    
    public var stringValues : [String] {
        return self.profile.stringValues
    }

    public var stringValue :[String:String]? {
        return self.stringValue(self.dataValue)
    }
    
    public var properties : CBCharacteristicProperties {
        return self.cbCharacteristic.properties
    }
    
    public func stringValue(data:NSData?) -> [String:String]? {
        if let data = data {
            return self.profile.stringValue(data)
        } else {
            return nil
        }
    }
    
    public func dataFromStringValue(stringValue:[String:String]) -> NSData? {
        return self.profile.dataFromStringValue(stringValue)
    }
    
    public func propertyEnabled(property:CBCharacteristicProperties) -> Bool {
        return (self.properties.rawValue & property.rawValue) > 0
    }

    public func value<T:Deserializable>() -> T? {
        if let data = self.dataValue {
            return T.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawDeserializable where T.RawType:Deserializable>() -> T? {
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawArrayDeserializable where T.RawType:Deserializable>() -> T? {
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawPairDeserializable where T.RawType1:Deserializable, T.RawType2:Deserializable>() -> T? {
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func value<T:RawArrayPairDeserializable where T.RawType1:Deserializable, T.RawType2:Deserializable>() -> T? { 
        if let data = self.dataValue {
            return Serde.deserialize(data)
        } else {
            return nil
        }
    }

    public func startNotifying() -> Future<Characteristic> {
        self.notificationStateChangedPromise = Promise<Characteristic>()
        if self.canNotify {
            self.setNotifyValue(true)
        } else {
            self.notificationStateChangedPromise.failure(BCError.characteristicNotifyNotSupported)
        }
        return self.notificationStateChangedPromise.future
    }

    public func stopNotifying() -> Future<Characteristic> {
        self.notificationStateChangedPromise = Promise<Characteristic>()
        if self.canNotify {
            self.setNotifyValue(false)
        } else {
            self.notificationStateChangedPromise.failure(BCError.characteristicNotifyNotSupported)
        }
        return self.notificationStateChangedPromise.future
{'fraction_non_alphanumeric': 0.0765891771968747, 'fraction_numerical': 0.003472557152503135, 'mean_word_length': 1.9844559585492227, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6800879', 'n_tokens_mistral': 2673, 'n_tokens_neox': 2600, 'n_words': 600}