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

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)
}
}