Updatable.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //
  2. // Updatable.swift
  3. // CryptoSwift
  4. //
  5. // Copyright (C) 2014-2017 Krzyżanowski <marcin@krzyzanowskim.com>
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. //
  8. // In no event will the authors be held liable for any damages arising from the use of this software.
  9. //
  10. // Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  11. //
  12. // - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
  13. // - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  14. // - This notice may not be removed or altered from any source or binary distribution.
  15. //
  16. /// A type that supports incremental updates. For example Digest or Cipher may be updatable
  17. /// and calculate result incerementally.
  18. public protocol Updatable {
  19. /// Update given bytes in chunks.
  20. ///
  21. /// - parameter bytes: Bytes to process.
  22. /// - parameter isLast: Indicate if given chunk is the last one. No more updates after this call.
  23. /// - returns: Processed data or empty array.
  24. mutating func update<T: Collection>(withBytes bytes: T, isLast: Bool) throws -> Array<UInt8> where T.Iterator.Element == UInt8
  25. /// Update given bytes in chunks.
  26. ///
  27. /// - Parameters:
  28. /// - bytes: Bytes to process.
  29. /// - isLast: Indicate if given chunk is the last one. No more updates after this call.
  30. /// - output: Resulting bytes callback.
  31. /// - Returns: Processed data or empty array.
  32. mutating func update<T: Collection>(withBytes bytes: T, isLast: Bool, output: (_ bytes: Array<UInt8>) -> Void) throws where T.Iterator.Element == UInt8
  33. /// Finish updates. This may apply padding.
  34. /// - parameter bytes: Bytes to process
  35. /// - returns: Processed data.
  36. mutating func finish<T: Collection>(withBytes bytes: T) throws -> Array<UInt8> where T.Iterator.Element == UInt8
  37. /// Finish updates. This may apply padding.
  38. /// - parameter bytes: Bytes to process
  39. /// - parameter output: Resulting data
  40. /// - returns: Processed data.
  41. mutating func finish<T: Collection>(withBytes bytes: T, output: (_ bytes: Array<UInt8>) -> Void) throws where T.Iterator.Element == UInt8
  42. }
  43. extension Updatable {
  44. mutating public func update<T: Collection>(withBytes bytes: T, isLast: Bool = false, output: (_ bytes: Array<UInt8>) -> Void) throws where T.Iterator.Element == UInt8 {
  45. let processed = try self.update(withBytes: bytes, isLast: isLast)
  46. if (!processed.isEmpty) {
  47. output(processed)
  48. }
  49. }
  50. mutating public func finish<T: Collection>(withBytes bytes: T) throws -> Array<UInt8> where T.Iterator.Element == UInt8 {
  51. return try self.update(withBytes: bytes, isLast: true)
  52. }
  53. mutating public func finish() throws -> Array<UInt8> {
  54. return try self.update(withBytes: [], isLast: true)
  55. }
  56. mutating public func finish<T: Collection>(withBytes bytes: T, output: (_ bytes: Array<UInt8>) -> Void) throws where T.Iterator.Element == UInt8 {
  57. let processed = try self.update(withBytes: bytes, isLast: true)
  58. if (!processed.isEmpty) {
  59. output(processed)
  60. }
  61. }
  62. mutating public func finish(output: (Array<UInt8>) -> Void) throws {
  63. try self.finish(withBytes: [], output: output)
  64. }
  65. }