You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.8 KiB
96 lines
2.8 KiB
![]()
2 years ago
|
//
|
||
|
// Measuable.swift
|
||
|
// HandyJSON
|
||
|
//
|
||
|
// Created by zhouzhuo on 15/07/2017.
|
||
|
// Copyright © 2017 aliyun. All rights reserved.
|
||
|
//
|
||
|
|
||
|
import Foundation
|
||
|
|
||
|
typealias Byte = Int8
|
||
|
|
||
|
public protocol _Measurable {}
|
||
|
|
||
|
extension _Measurable {
|
||
|
|
||
|
// locate the head of a struct type object in memory
|
||
|
mutating func headPointerOfStruct() -> UnsafeMutablePointer<Byte> {
|
||
|
|
||
|
return withUnsafeMutablePointer(to: &self) {
|
||
|
return UnsafeMutableRawPointer($0).bindMemory(to: Byte.self, capacity: MemoryLayout<Self>.stride)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// locating the head of a class type object in memory
|
||
|
mutating func headPointerOfClass() -> UnsafeMutablePointer<Byte> {
|
||
|
|
||
|
let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque()
|
||
|
let mutableTypedPointer = opaquePointer.bindMemory(to: Byte.self, capacity: MemoryLayout<Self>.stride)
|
||
|
return UnsafeMutablePointer<Byte>(mutableTypedPointer)
|
||
|
}
|
||
|
|
||
|
// locating the head of an object
|
||
|
mutating func headPointer() -> UnsafeMutablePointer<Byte> {
|
||
|
if Self.self is AnyClass {
|
||
|
return self.headPointerOfClass()
|
||
|
} else {
|
||
|
return self.headPointerOfStruct()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func isNSObjectType() -> Bool {
|
||
|
return (type(of: self) as? NSObject.Type) != nil
|
||
|
}
|
||
|
|
||
|
func getBridgedPropertyList() -> Set<String> {
|
||
|
if let anyClass = type(of: self) as? AnyClass {
|
||
|
return _getBridgedPropertyList(anyClass: anyClass)
|
||
|
}
|
||
|
return []
|
||
|
}
|
||
|
|
||
|
func _getBridgedPropertyList(anyClass: AnyClass) -> Set<String> {
|
||
|
if !(anyClass is HandyJSON.Type) {
|
||
|
return []
|
||
|
}
|
||
|
var propertyList = Set<String>()
|
||
|
if let superClass = class_getSuperclass(anyClass), superClass != NSObject.self {
|
||
|
propertyList = propertyList.union(_getBridgedPropertyList(anyClass: superClass))
|
||
|
}
|
||
|
let count = UnsafeMutablePointer<UInt32>.allocate(capacity: 1)
|
||
|
if let props = class_copyPropertyList(anyClass, count) {
|
||
|
for i in 0 ..< count.pointee {
|
||
|
let name = String(cString: property_getName(props.advanced(by: Int(i)).pointee))
|
||
|
propertyList.insert(name)
|
||
|
}
|
||
|
free(props)
|
||
|
}
|
||
|
#if swift(>=4.1)
|
||
|
count.deallocate()
|
||
|
#else
|
||
|
count.deallocate(capacity: 1)
|
||
|
#endif
|
||
|
return propertyList
|
||
|
}
|
||
|
|
||
|
// memory size occupy by self object
|
||
|
static func size() -> Int {
|
||
|
return MemoryLayout<Self>.size
|
||
|
}
|
||
|
|
||
|
// align
|
||
|
static func align() -> Int {
|
||
|
return MemoryLayout<Self>.alignment
|
||
|
}
|
||
|
|
||
|
// Returns the offset to the next integer that is greater than
|
||
|
// or equal to Value and is a multiple of Align. Align must be
|
||
|
// non-zero.
|
||
|
static func offsetToAlignment(value: Int, align: Int) -> Int {
|
||
|
let m = value % align
|
||
|
return m == 0 ? 0 : (align - m)
|
||
|
}
|
||
|
}
|
||
|
|