Measuable.swift 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //
  2. // Measuable.swift
  3. // HandyJSON
  4. //
  5. // Created by zhouzhuo on 15/07/2017.
  6. // Copyright © 2017 aliyun. All rights reserved.
  7. //
  8. import Foundation
  9. typealias Byte = Int8
  10. public protocol _Measurable {}
  11. extension _Measurable {
  12. // locate the head of a struct type object in memory
  13. mutating func headPointerOfStruct() -> UnsafeMutablePointer<Byte> {
  14. return withUnsafeMutablePointer(to: &self) {
  15. return UnsafeMutableRawPointer($0).bindMemory(to: Byte.self, capacity: MemoryLayout<Self>.stride)
  16. }
  17. }
  18. // locating the head of a class type object in memory
  19. mutating func headPointerOfClass() -> UnsafeMutablePointer<Byte> {
  20. let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque()
  21. let mutableTypedPointer = opaquePointer.bindMemory(to: Byte.self, capacity: MemoryLayout<Self>.stride)
  22. return UnsafeMutablePointer<Byte>(mutableTypedPointer)
  23. }
  24. // locating the head of an object
  25. mutating func headPointer() -> UnsafeMutablePointer<Byte> {
  26. if Self.self is AnyClass {
  27. return self.headPointerOfClass()
  28. } else {
  29. return self.headPointerOfStruct()
  30. }
  31. }
  32. func isNSObjectType() -> Bool {
  33. return (type(of: self) as? NSObject.Type) != nil
  34. }
  35. func getBridgedPropertyList() -> Set<String> {
  36. if let anyClass = type(of: self) as? AnyClass {
  37. return _getBridgedPropertyList(anyClass: anyClass)
  38. }
  39. return []
  40. }
  41. func _getBridgedPropertyList(anyClass: AnyClass) -> Set<String> {
  42. if !(anyClass is HandyJSON.Type) {
  43. return []
  44. }
  45. var propertyList = Set<String>()
  46. if let superClass = class_getSuperclass(anyClass), superClass != NSObject.self {
  47. propertyList = propertyList.union(_getBridgedPropertyList(anyClass: superClass))
  48. }
  49. let count = UnsafeMutablePointer<UInt32>.allocate(capacity: 1)
  50. if let props = class_copyPropertyList(anyClass, count) {
  51. for i in 0 ..< count.pointee {
  52. let name = String(cString: property_getName(props.advanced(by: Int(i)).pointee))
  53. propertyList.insert(name)
  54. }
  55. free(props)
  56. }
  57. #if swift(>=4.1)
  58. count.deallocate()
  59. #else
  60. count.deallocate(capacity: 1)
  61. #endif
  62. return propertyList
  63. }
  64. // memory size occupy by self object
  65. static func size() -> Int {
  66. return MemoryLayout<Self>.size
  67. }
  68. // align
  69. static func align() -> Int {
  70. return MemoryLayout<Self>.alignment
  71. }
  72. // Returns the offset to the next integer that is greater than
  73. // or equal to Value and is a multiple of Align. Align must be
  74. // non-zero.
  75. static func offsetToAlignment(value: Int, align: Int) -> Int {
  76. let m = value % align
  77. return m == 0 ? 0 : (align - m)
  78. }
  79. }