<commit_before>//
//  The MIT License (MIT)
//
//  Copyright (c) 2016 <NAME> (@srdanrasic)
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation
import ObjectiveC
import ReactiveKit

#if !BUILDING_WITH_XCODE
import BNDProtocolProxyBase
#endif

private extension BNDInvocation {

 func readArgument<T>(_ index: Int) -> T {
    let size = Int(methodSignature.getArgumentSize(at: UInt(index)))
    let alignment = Int(methodSignature.getArgumentAlignment(at: UInt(index)))

    let pointer = UnsafeMutableRawPointer.allocate(bytes: size, alignedTo: alignment)
    getArgument(pointer, at: index)

    defer {
      pointer.deallocate(bytes: size, alignedTo: alignment)
    }

    let type = methodSignature.getArgumentType(at: UInt(index))
    switch type {
    case NSObjCCharType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CChar.self).pointee) as! T
    case NSObjCShortType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CShort.self).pointee) as! T
    case NSObjCIntType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CInt.self).pointee) as! T
    case NSObjCLongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CLong.self).pointee) as! T
    case NSObjCLonglongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CLongLong.self).pointee) as! T
    case NSObjCUCharType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedChar.self).pointee) as! T
    case NSObjCUShortType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedShort.self).pointee) as! T
    case NSObjCUIntType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedInt.self).pointee) as! T
    case NSObjCULongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedLong.self).pointee) as! T
    case NSObjCULonglongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedLongLong.self).pointee) as! T
    case NSObjCFloatType:
     return NSNumber(value: pointer.assumingMemoryBound(to: CFloat.self).pointee) as! T
    case NSObjCDoubleType:
     return NSNumber(value: pointer.assumingMemoryBound(to: CDouble.self).pointee) as! T
    case NSObjCBoolType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CBool.self).pointee) as! T
    case NSObjCSelectorType:
      return pointer.assumingMemoryBound(to: Optional<Selector>.self).pointee as! T
    case NSObjCObjectType:
      return pointer.assumingMemoryBound(to: Optional<AnyObject>.self).pointee as! T
   default:
      return pointer.assumingMemoryBound(to: T.self).pointee
    }
  }

 func writeReturnValue<T>(_ value: T) {
    guard methodSignature.methodReturnLength > 0 else { return }

    let size = methodSignature.getReturnArgumentSize()
    let alignment = methodSignature.getReturnArgumentAlignment()
    let type = methodSignature.getReturnArgumentType()

  func write<U, V>(_ value: V, as type: U.Type) {
      let pointer = UnsafeMutablePointer<U>.allocate(capacity: 1)
      pointer.initialize(to: value as! U, count: 1)
      setReturnValue(pointer)
      pointer.deinitialize()
      pointer.deallocate(capacity: 1)
    }

    switch type {
    case NSObjCCharType:
      write(value as! NSNumber, as: CChar.self)
    case NSObjCShortType:
      write(value as! NSNumber, as: CShort.self)
    case NSObjCIntType:
      write(value as! NSNumber, as: CInt.self)
    case NSObjCLongType:
      write(value as! NSNumber, as: CLong.self)
    case NSObjCLonglongType:
      write(value as! NSNumber, as: CLongLong.self)
    case NSObjCUCharType:
      write(value as! NSNumber, as: CUnsignedChar.self)
    case NSObjCUShortType:
      write(value as! NSNumber, as: CUnsignedShort.self)
    case NSObjCUIntType:
      write(value as! NSNumber, as: CUnsignedInt.self)
    case NSObjCULongType:
      write(value as! NSNumber, as: CUnsignedLong.self)
    case NSObjCULonglongType:
      write(value as! NSNumber, as: CUnsignedLongLong.self)
    case NSObjCFloatType:
      write(value as! NSNumber, as: CFloat.self)
    case NSObjCDoubleType:
      write(value as! NSNumber, as: CDouble.self)
    case NSObjCBoolType:
      write(value as! NSNumber, as: CBool.self)
    case NSObjCSelectorType:
      write(value, as: Optional<Selector>.self)
    case NSObjCObjectType:
      write(value, as: Optional<AnyObject>.self)
    default:
      write(value, as: T.self)
    }
  }
}

public class ProtocolProxy: BNDProtocolProxyBase {

  private var invokers: [Selector: (BNDInvocation) -> Void] = [:]
  private var handlers: [Selector: Any] = [:]
  private weak var object: NSObject?
  private let setter: Selector

  public init(object: NSObject, `protocol`: Protocol, setter: Selector) {
    self.object = object
    self.setter = setter
    super.init(with: `protocol`)
  }

  public override var forwardTo: NSObject? {
    get {
      return super.forwardTo
    }
    set {
      super.forwardTo = newValue
      registerDelegate()
    }
  }

  public override func hasHandler(for selector: Selector) -> Bool {
    return invokers[selector] != nil
  }

  public override func handle(_ invocation: BNDInvocation) {
    guard let invoker = invokers[invocation.selector] else { return }
    invoker(invocation)
  }

  private func registerInvoker0<R>(for selector: Selector, block: @escaping () -> R) -> Disposable {
    invokers[selector] = { invocation in
      let result = block()
      invocation.writeReturnValue(result)
    }
    registerDelegate()
    return BlockDisposable { [weak self] in
      self?.invokers[selector] = nil
      self?.registerDelegate()
    }<commit_msg>Retain NSInvocation arguments in protocol proxies.<commit_after>//
//  The MIT License (MIT)
//
//  Copyright (c) 2016 <NAME> (@srdanrasic)
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation
import ObjectiveC
import ReactiveKit

#if !BUILDING_WITH_XCODE
import BNDProtocolProxyBase
#endif

private extension BNDInvocation {

 func readArgument<T>(_ index: Int) -> T {
    let size = Int(methodSignature.getArgumentSize(at: UInt(index)))
    let alignment = Int(methodSignature.getArgumentAlignment(at: UInt(index)))

    let pointer = UnsafeMutableRawPointer.allocate(bytes: size, alignedTo: alignment)
    getArgument(pointer, at: index)

    defer {
      pointer.deallocate(bytes: size, alignedTo: alignment)
    }

    let type = methodSignature.getArgumentType(at: UInt(index))
    switch type {
    case NSObjCCharType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CChar.self).pointee) as! T
    case NSObjCShortType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CShort.self).pointee) as! T
    case NSObjCIntType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CInt.self).pointee) as! T
    case NSObjCLongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CLong.self).pointee) as! T
    case NSObjCLonglongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CLongLong.self).pointee) as! T
    case NSObjCUCharType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedChar.self).pointee) as! T
    case NSObjCUShortType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedShort.self).pointee) as! T
    case NSObjCUIntType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedInt.self).pointee) as! T
    case NSObjCULongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedLong.self).pointee) as! T
    case NSObjCULonglongType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CUnsignedLongLong.self).pointee) as! T
    case NSObjCFloatType:
     return NSNumber(value: pointer.assumingMemoryBound(to: CFloat.self).pointee) as! T
    case NSObjCDoubleType:
     return NSNumber(value: pointer.assumingMemoryBound(to: CDouble.self).pointee) as! T
    case NSObjCBoolType:
      return NSNumber(value: pointer.assumingMemoryBound(to: CBool.self).pointee) as! T
    case NSObjCSelectorType:
      return pointer.assumingMemoryBound(to: Optional<Selector>.self).pointee as! T
    case NSObjCObjectType:
      return pointer.assumingMemoryBound(to: Optional<AnyObject>.self).pointee as! T
   default:
      return pointer.assumingMemoryBound(to: T.self).pointee
    }
  }

 func writeReturnValue<T>(_ value: T) {
    guard methodSignature.methodReturnLength > 0 else { return }

    let size = methodSignature.getReturnArgumentSize()
    let alignment = methodSignature.getReturnArgumentAlignment()
    let type = methodSignature.getReturnArgumentType()

  func write<U, V>(_ value: V, as type: U.Type) {
      let pointer = UnsafeMutablePointer<U>.allocate(capacity: 1)
      pointer.initialize(to: value as! U, count: 1)
      setReturnValue(pointer)
      pointer.deinitialize()
      pointer.deallocate(capacity: 1)
    }

    switch type {
    case NSObjCCharType:
      write(value as! NSNumber, as: CChar.self)
    case NSObjCShortType:
      write(value as! NSNumber, as: CShort.self)
    case NSObjCIntType:
      write(value as! NSNumber, as: CInt.self)
    case NSObjCLongType:
      write(value as! NSNumber, as: CLong.self)
    case NSObjCLonglongType:
      write(value as! NSNumber, as: CLongLong.self)
    case NSObjCUCharType:
      write(value as! NSNumber, as: CUnsignedChar.self)
    case NSObjCUShortType:
      write(value as! NSNumber, as: CUnsignedShort.self)
    case NSObjCUIntType:
      write(value as! NSNumber, as: CUnsignedInt.self)
    case NSObjCULongType:
      write(value as! NSNumber, as: CUnsignedLong.self)
    case NSObjCULonglongType:
      write(value as! NSNumber, as: CUnsignedLongLong.self)
    case NSObjCFloatType:
      write(value as! NSNumber, as: CFloat.self)
    case NSObjCDoubleType:
      write(value as! NSNumber, as: CDouble.self)
    case NSObjCBoolType:
      write(value as! NSNumber, as: CBool.self)
    case NSObjCSelectorType:
      write(value, as: Optional<Selector>.self)
    case NSObjCObjectType:
      write(value, as: Optional<AnyObject>.self)
    default:
      write(value, as: T.self)
    }
  }
}

public class ProtocolProxy: BNDProtocolProxyBase {

  private var invokers: [Selector: (BNDInvocation) -> Void] = [:]
  private var handlers: [Selector: Any] = [:]
  private weak var object: NSObject?
  private let setter: Selector

  public init(object: NSObject, `protocol`: Protocol, setter: Selector) {
    self.object = object
    self.setter = setter
    super.init(with: `protocol`)
  }

  public override var forwardTo: NSObject? {
    get {
      return super.forwardTo
    }
    set {
      super.forwardTo = newValue
      registerDelegate()
    }
  }

  public override func hasHandler(for selector: Selector) -> Bool {
    return invokers[selector] != nil
  }

  public override func handle(_ invocation: BNDInvocation) {
    guard let invoker = invokers[invocation.selector] else { return }
    invocation.retainArguments()
    invoker(invocation)
  }

  private func registerInvoker0<R>(for selector: Selector, block: @escaping () -> R) -> Disposable {
    invokers[selector] = { invocation in
      let result = block()
      invocation.writeReturnValue(result)
    }
    registerDelegate()
    return BlockDisposable { [weak self] in
      self?.invokers[selector] = nil
      self?.registerDelegate()
    }
{'fraction_non_alphanumeric': 0.092498505678422, 'fraction_numerical': 0.0013448894202032278, 'mean_word_length': 3.76165065812878, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 35, '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': '4017881', 'n_tokens_mistral': 4160, 'n_tokens_neox': 4015, 'n_words': 1176}