forked from PerfectlySoft/Perfect
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBytes.swift
More file actions
202 lines (163 loc) · 5.86 KB
/
Copy pathBytes.swift
File metadata and controls
202 lines (163 loc) · 5.86 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//
// Bytes.swift
// PerfectLib
//
// Created by Kyle Jessup on 7/7/15.
// Copyright (C) 2015 PerfectlySoft, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version, as supplemented by the
// Perfect Additional Terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License, as supplemented by the
// Perfect Additional Terms, for more details.
//
// You should have received a copy of the GNU Affero General Public License
// and the Perfect Additional Terms that immediately follow the terms and
// conditions of the GNU Affero General Public License along with this
// program. If not, see <http://www.perfect.org/AGPL_3_0_With_Perfect_Additional_Terms.txt>.
//
/// A Bytes object represents an array of UInt8 and provides various utilities for importing and exporting values into and out of that array.
/// A Bytes object maintains a position marker which is used to denote the position from which new export operations proceed.
/// An export will advance the position by the appropriate amount.
public class Bytes {
/// The position from which new export operations begin.
public var position = 0
/// The underlying UInt8 array
public var data: [UInt8]
/// Indicates the number of bytes which may be successfully exported
public var availableExportBytes: Int { return self.data.count - self.position }
/// Create an empty Bytes object
public init() {
self.data = [UInt8]()
}
/// Initialize with existing bytes
public init(existingBytes: [UInt8]) {
self.data = existingBytes
}
/// Create a new Bytes object containing `initialSize` values of zero
/// - parameter initialSize: The size of the initial array
public init(initialSize: Int) {
self.data = [UInt8](count: initialSize, repeatedValue: 0)
}
// -- IMPORT
/// Imports one UInt8 value appending it to the end of the array
/// - returns: The Bytes object
public func import8Bits(byte: UInt8) -> Bytes {
data.append(byte)
return self
}
/// Imports one UInt16 value appending it to the end of the array
/// - returns: The Bytes object
public func import16Bits(short: UInt16) -> Bytes {
data.append(UInt8(short & 0xFF))
data.append(UInt8((short >> 8) & 0xFF))
return self
}
/// Imports one UInt32 value appending it to the end of the array
/// - returns: The Bytes object
public func import32Bits(int: UInt32) -> Bytes {
data.append(UInt8(int & 0xFF))
data.append(UInt8((int >> 8) & 0xFF))
data.append(UInt8((int >> 16) & 0xFF))
data.append(UInt8((int >> 24) & 0xFF))
return self
}
/// Imports one UInt64 value appending it to the end of the array
/// - returns: The Bytes object
public func import64Bits(int: UInt64) -> Bytes {
data.append(UInt8(int & 0xFF))
data.append(UInt8((int >> 8) & 0xFF))
data.append(UInt8((int >> 16) & 0xFF))
data.append(UInt8((int >> 24) & 0xFF))
data.append(UInt8((int >> 32) & 0xFF))
data.append(UInt8((int >> 40) & 0xFF))
data.append(UInt8((int >> 48) & 0xFF))
data.append(UInt8((int >> 56) & 0xFF))
return self
}
/// Imports an array of UInt8 values appending them to the end of the array
/// - returns: The Bytes object
public func importBytes(bytes: [UInt8]) -> Bytes {
data.appendContentsOf(bytes)
return self
}
/// Imports the array values of the given Bytes appending them to the end of the array
/// - returns: The Bytes object
public func importBytes(bytes: Bytes) -> Bytes {
data.appendContentsOf(bytes.data)
return self
}
/// Imports an `ArraySlice` of UInt8 values appending them to the end of the array
/// - returns: The Bytes object
public func importBytes(bytes: ArraySlice<UInt8>) -> Bytes {
data.appendContentsOf(bytes)
return self
}
// -- EXPORT
/// Exports one UInt8 from the current position. Advances the position marker by 1 byte.
/// - returns: The UInt8 value
public func export8Bits() -> UInt8 {
let result = data[position]
position += 1
return result
}
/// Exports one UInt16 from the current position. Advances the position marker by 2 bytes.
/// - returns: The UInt16 value
public func export16Bits() -> UInt16 {
let one = UInt16(data[position])
position += 1
let two = UInt16(data[position])
position += 1
return (two << 8) + one
}
/// Exports one UInt32 from the current position. Advances the position marker by 4 bytes.
/// - returns: The UInt32 value
public func export32Bits() -> UInt32 {
let one = UInt32(data[position])
position += 1
let two = UInt32(data[position])
position += 1
let three = UInt32(data[position])
position += 1
let four = UInt32(data[position])
position += 1
return (four << 24) + (three << 16) + (two << 8) + one
}
/// Exports one UInt64 from the current position. Advances the position marker by 8 bytes.
/// - returns: The UInt64 value
public func export64Bits() -> UInt64 {
let one = UInt64(data[position])
position += 1
let two = UInt64(data[position]) << 8
position += 1
let three = UInt64(data[position]) << 16
position += 1
let four = UInt64(data[position]) << 24
position += 1
let five = UInt64(data[position]) << 32
position += 1
let six = UInt64(data[position]) << 40
position += 1
let seven = UInt64(data[position]) << 48
position += 1
let eight = UInt64(data[position]) << 56
position += 1
return (one+two+three+four)+(five+six+seven+eight)
}
/// Exports the indicated number of bytes
public func exportBytes(count: Int) -> [UInt8] {
var sub = [UInt8]()
let end = self.position + count
while self.position < end {
sub.append(self.data[self.position])
self.position += 1
}
return sub
}
}