-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMems.swift
More file actions
161 lines (143 loc) · 4.98 KB
/
Mems.swift
File metadata and controls
161 lines (143 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//
// Mems.swift
// Mems
//
// Created by MJ Lee on 2019/6/22.
// Copyright © 2019 MJ Lee. All rights reserved.
//
import Foundation
public enum MemAlign : Int {
case one = 1, two = 2, four = 4, eight = 8
}
private let _EMPTY_PTR = UnsafeRawPointer(bitPattern: 0x1)!
/// 辅助查看内存的小工具类
public struct Mems<T> {
private static func _memStr(_ ptr: UnsafeRawPointer,
_ size: Int,
_ aligment: Int) ->String {
if ptr == _EMPTY_PTR { return "" }
var rawPtr = ptr
var string = ""
let fmt = "0x%0\(aligment << 1)lx"
let count = size / aligment
for i in 0..<count {
if i > 0 {
string.append(" ")
rawPtr += aligment
}
let value: CVarArg
switch aligment {
case MemAlign.eight.rawValue:
value = rawPtr.load(as: UInt64.self)
case MemAlign.four.rawValue:
value = rawPtr.load(as: UInt32.self)
case MemAlign.two.rawValue:
value = rawPtr.load(as: UInt16.self)
default:
value = rawPtr.load(as: UInt8.self)
}
string.append(String(format: fmt, value))
}
return string
}
private static func _memBytes(_ ptr: UnsafeRawPointer,
_ size: Int) -> [UInt8] {
var arr: [UInt8] = []
if ptr == _EMPTY_PTR { return arr }
for i in 0..<size {
arr.append((ptr + i).load(as: UInt8.self))
}
return arr
}
/// 获得变量的内存数据(字节数组格式)
public static func memBytes(ofVal v: inout T) -> [UInt8] {
return _memBytes(ptr(ofVal: &v), MemoryLayout.stride(ofValue: v))
}
/// 获得引用所指向的内存数据(字节数组格式)
public static func memBytes(ofRef v: T) -> [UInt8] {
let p = ptr(ofRef: v)
return _memBytes(p, malloc_size(p))
}
/// 获得变量的内存数据(字符串格式)
///
/// - Parameter alignment: 决定了多少个字节为一组
public static func memStr(ofVal v: inout T, alignment: MemAlign? = nil) -> String {
let p = ptr(ofVal: &v)
return _memStr(p, MemoryLayout.stride(ofValue: v),
alignment != nil ? alignment!.rawValue : MemoryLayout.alignment(ofValue: v))
}
/// 获得引用所指向的内存数据(字符串格式)
///
/// - Parameter alignment: 决定了多少个字节为一组
public static func memStr(ofRef v: T, alignment: MemAlign? = nil) -> String {
let p = ptr(ofRef: v)
return _memStr(p, malloc_size(p),
alignment != nil ? alignment!.rawValue : MemoryLayout.alignment(ofValue: v))
}
/// 获得变量的内存地址
public static func ptr(ofVal v: inout T) -> UnsafeRawPointer {
return MemoryLayout.size(ofValue: v) == 0 ? _EMPTY_PTR : withUnsafePointer(to: &v) {
UnsafeRawPointer($0)
}
}
/// 获得引用所指向内存的地址
public static func ptr(ofRef v: T) -> UnsafeRawPointer {
if v is Array<Any>
|| Swift.type(of: v) is AnyClass
|| v is AnyClass {
return UnsafeRawPointer(bitPattern: unsafeBitCast(v, to: UInt.self))!
} else if v is String {
var mstr = v as! String
if mstr.mems.type() != .heap {
return _EMPTY_PTR
}
return UnsafeRawPointer(bitPattern: unsafeBitCast(v, to: (UInt, UInt).self).1)!
} else {
return _EMPTY_PTR
}
}
/// 获得变量所占用的内存大小
public static func size(ofVal v: inout T) -> Int {
return MemoryLayout.size(ofValue: v) > 0 ? MemoryLayout.stride(ofValue: v) : 0
}
/// 获得引用所指向内存的大小
public static func size(ofRef v: T) -> Int {
return malloc_size(ptr(ofRef: v))
}
}
public enum StringMemType : UInt8 {
/// TEXT段(常量区)
case text = 0xd0
/// taggerPointer
case tagPtr = 0xe0
/// 堆空间
case heap = 0xf0
/// 未知
case unknow = 0xff
}
public struct MemsWrapper<Base> {
public private(set) var base: Base
public init(_ base: Base) {
self.base = base
}
}
public protocol MemsCompatible {}
public extension MemsCompatible {
static var mems: MemsWrapper<Self>.Type {
get { return MemsWrapper<Self>.self }
set {}
}
var mems: MemsWrapper<Self> {
get { return MemsWrapper(self) }
set {}
}
}
extension String: MemsCompatible {}
public extension MemsWrapper where Base == String {
mutating func type() -> StringMemType {
let ptr = Mems.ptr(ofVal: &base)
return StringMemType(rawValue: (ptr + 15).load(as: UInt8.self) & 0xf0)
?? StringMemType(rawValue: (ptr + 7).load(as: UInt8.self) & 0xf0)
?? .unknow
}
}