Generics.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // Generics.swift
  3. // CryptoSwift
  4. //
  5. // Created by Marcin Krzyzanowski on 02/09/14.
  6. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. import Foundation
  9. /** Protocol and extensions for integerFromBitsArray. Bit hakish for me, but I can't do it in any other way */
  10. protocol Initiable {
  11. init(_ v: Int)
  12. init(_ v: UInt)
  13. }
  14. extension Int:Initiable {}
  15. extension UInt:Initiable {}
  16. extension UInt8:Initiable {}
  17. extension UInt16:Initiable {}
  18. extension UInt32:Initiable {}
  19. extension UInt64:Initiable {}
  20. /** build bit pattern from array of bits */
  21. func integerFromBitsArray<T: UnsignedIntegerType where T: IntegerLiteralConvertible, T: Initiable>(bits: [Bit]) -> T
  22. {
  23. var bitPattern:T = 0
  24. for (idx,b) in enumerate(bits) {
  25. if (b == Bit.One) {
  26. let bit = T(1 << idx)
  27. bitPattern = bitPattern | bit
  28. }
  29. }
  30. return bitPattern
  31. }
  32. /** initialize integer from array of bytes */
  33. func integerWithBytes<T: IntegerType>(bytes: [Byte]) -> T {
  34. var totalBytes = Swift.min(bytes.count, sizeof(T))
  35. // get slice of Int
  36. var start = Swift.max(bytes.count - sizeof(T),0)
  37. var intarr = [Byte](bytes[start..<(start + totalBytes)])
  38. // pad size if necessary
  39. while (intarr.count < sizeof(T)) {
  40. intarr.insert(0 as Byte, atIndex: 0)
  41. }
  42. intarr = intarr.reverse()
  43. var i:T = 0
  44. var data = NSData(bytes: intarr, length: intarr.count)
  45. data.getBytes(&i, length: sizeofValue(i));
  46. return i
  47. }
  48. /** array of bytes, little-endian representation */
  49. func arrayOfBytes<T>(value:T, totalBytes:Int) -> [Byte] {
  50. var bytes = [Byte](count: totalBytes, repeatedValue: 0)
  51. var data = NSData(bytes: [value] as [T], length: min(sizeof(T),totalBytes))
  52. // then convert back to bytes, byte by byte
  53. for i in 0..<data.length {
  54. data.getBytes(&bytes[totalBytes - 1 - i], range:NSRange(location:i, length:sizeof(Byte)))
  55. }
  56. return bytes
  57. }
  58. // MARK: - shiftLeft
  59. // helper to be able tomake shift operation on T
  60. func <<<T:SignedIntegerType>(lhs: T, rhs: Int) -> Int {
  61. let a = lhs as Int
  62. let b = rhs
  63. return a << b
  64. }
  65. func <<<T:UnsignedIntegerType>(lhs: T, rhs: Int) -> UInt {
  66. let a = lhs as UInt
  67. let b = rhs
  68. return a << b
  69. }
  70. // Generic function itself
  71. // FIXME: this generic function is not as generic as I would. It crashes for smaller types
  72. func shiftLeft<T: SignedIntegerType where T: Initiable>(value: T, count: Int) -> T {
  73. if (value == 0) {
  74. return 0;
  75. }
  76. var bitsCount = (sizeofValue(value) * 8)
  77. var shiftCount = Int(Swift.min(count, bitsCount - 1))
  78. var shiftedValue:T = 0;
  79. for bitIdx in 0..<bitsCount {
  80. var bit = T.from(IntMax(1 << bitIdx))
  81. if ((value & bit) == bit) {
  82. shiftedValue = shiftedValue | T(bit << shiftCount)
  83. }
  84. }
  85. if (shiftedValue != 0 && count >= bitsCount) {
  86. // clear last bit that couldn't be shifted out of range
  87. shiftedValue = shiftedValue & T(~(1 << (bitsCount - 1)))
  88. }
  89. return shiftedValue
  90. }
  91. // for any f*** other Integer type - this part is so non-Generic
  92. func shiftLeft(value: UInt, count: Int) -> UInt {
  93. return UInt(shiftLeft(Int(value), count))
  94. }
  95. func shiftLeft(value: UInt8, count: Int) -> UInt8 {
  96. return UInt8(shiftLeft(UInt(value), count))
  97. }
  98. func shiftLeft(value: UInt16, count: Int) -> UInt16 {
  99. return UInt16(shiftLeft(UInt(value), count))
  100. }
  101. func shiftLeft(value: UInt32, count: Int) -> UInt32 {
  102. return UInt32(shiftLeft(UInt(value), count))
  103. }
  104. func shiftLeft(value: UInt64, count: Int) -> UInt64 {
  105. return UInt64(shiftLeft(UInt(value), count))
  106. }
  107. func shiftLeft(value: Int8, count: Int) -> Int8 {
  108. return Int8(shiftLeft(Int(value), count))
  109. }
  110. func shiftLeft(value: Int16, count: Int) -> Int16 {
  111. return Int16(shiftLeft(Int(value), count))
  112. }
  113. func shiftLeft(value: Int32, count: Int) -> Int32 {
  114. return Int32(shiftLeft(Int(value), count))
  115. }
  116. func shiftLeft(value: Int64, count: Int) -> Int64 {
  117. return Int64(shiftLeft(Int(value), count))
  118. }