<commit_before>//
//  ARISocket.swift
//  TestSwiftyCocoa
//
//  Created by <NAME> on 6/9/14.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//

import Darwin
import Dispatch

/**
 * Simple Socket classes for Swift.
 *
 * PassiveSockets are 'listening' sockets, ActiveSockets are open connections.
 *
 * NOTE: Those would work with Generics on any type of (constant length for now)
 *       socket, but this got my swiftc crash on unimplemented features ;-)
 *
 *        Socket<T: SocketAddress>
 *
 *      and then PassiveSocket<sockaddr_in> etc. Unfinished.
 */
class Socket {
  
  var fd           : CInt?             = nil
  var boundAddress : sockaddr_in?      = nil
  var closeCB      : ((CInt) -> Void)? = nil
  var isValid      : Bool { return fd           != nil }
  var isBound      : Bool { return boundAddress != nil }
  
  
  /* initializer / deinitializer */
  
  init(fd: CInt?) {
    self.fd = fd
  }
  deinit {
    close() // TBD: is this OK/safe?
  }
  
  convenience init(domain: CInt = AF_INET, type: CInt = SOCK_STREAM) {
    // Generics: let lfd = socket(T.domain, type, 0)
    let lfd = socket(domain, type, 0)
    var fd:  CInt?
    if lfd != -1 {
      fd = lfd
    }
    else {
      // This is lame. Would like to 'return nil' ...
      // TBD: How to do proper error handling in Swift?
      println("Could not create socket.")
    }
    
    self.init(fd: fd)
  }
  
  
  /* explicitly close the socket */
  
  func close() {
    if fd {
      let closedFD = fd!
      Darwin.close(fd!)
      fd = nil

      if let cb = closeCB {
        // can be used to unregister socket etc when the socket is really closed
        cb(closedFD)
        closeCB = nil // break potential cycles
      }
    }
    boundAddress = nil
  }
  
  func onClose(cb: ((CInt) -> Void)?) -> Self {
    closeCB = cb
    return self
  }
  
  /* bind the socket. */
  
  func bind(address: sockaddr_in) -> Bool {<commit_msg>Improved onClose handler, tracks whether the socket was closed before the handler got attached.<commit_after>//
//  ARISocket.swift
//  TestSwiftyCocoa
//
//  Created by <NAME> on 6/9/14.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//

import Darwin
import Dispatch

/**
 * Simple Socket classes for Swift.
 *
 * PassiveSockets are 'listening' sockets, ActiveSockets are open connections.
 *
 * NOTE: Those would work with Generics on any type of (constant length for now)
 *       socket, but this got my swiftc crash on unimplemented features ;-)
 *
 *        Socket<T: SocketAddress>
 *
 *      and then PassiveSocket<sockaddr_in> etc. Unfinished.
 */
class Socket {
  
  var fd           : CInt?             = nil
  var boundAddress : sockaddr_in?      = nil
  var closeCB      : ((CInt) -> Void)? = nil
  var closedFD     : CInt?             = nil // for delayed callback
  var isValid      : Bool { return fd           != nil }
  var isBound      : Bool { return boundAddress != nil }
  
  
  /* initializer / deinitializer */
  
  init(fd: CInt?) {
    self.fd = fd
  }
  deinit {
    close() // TBD: is this OK/safe?
  }
  
  convenience init(domain: CInt = AF_INET, type: CInt = SOCK_STREAM) {
    // Generics: let lfd = socket(T.domain, type, 0)
    let lfd = socket(domain, type, 0)
    var fd:  CInt?
    if lfd != -1 {
      fd = lfd
    }
    else {
      // This is lame. Would like to 'return nil' ...
      // TBD: How to do proper error handling in Swift?
      println("Could not create socket.")
    }
    
    self.init(fd: fd)
  }
  
  
  /* explicitly close the socket */
  
  func close() {
    if fd {
      closedFD = fd
      Darwin.close(fd!)
      fd       = nil
      
      if let cb = closeCB {
        // can be used to unregister socket etc when the socket is really closed
        cb(closedFD!)
        closeCB = nil // break potential cycles
      }
    }
    boundAddress = nil
  }
  
  func onClose(cb: ((CInt) -> Void)?) -> Self {
    if let fd = closedFD { // socket got closed before event-handler attached
      if let lcb = cb {
        lcb(fd)
      }
      else {
        closeCB = nil
      }
    }
    else {
      closeCB = cb
    }
    return self
  }
  
  /* bind the socket. */
  
  func bind(address: sockaddr_in) -> Bool {
{'fraction_non_alphanumeric': 0.10942321386185616, 'fraction_numerical': 0.005221932114882507, 'mean_word_length': 1.8902606310013716, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, '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': '2322726', 'n_tokens_mistral': 1401, 'n_tokens_neox': 1362, 'n_words': 452}