1313// See the License for the specific language governing permissions and
1414// limitations under the License.
1515
16+ import ArrowC
1617import Foundation
1718
1819/// A type-erased ArrowArray.
@@ -25,9 +26,10 @@ public protocol AnyArrowArray {
2526 var bufferDataSizes : [ Int ] { get }
2627 func asAny( _ index: UInt ) -> Any ?
2728 func asString( _ index: UInt ) -> String
29+ func setCArrayPtr( _ cArrayPtr: UnsafePointer < ArrowC . ArrowArray > ? )
2830}
2931
30- // MARK: - Core Protocol
32+ // MARK: Core Protocol
3133
3234/// The interface for Arrow array types.
3335public protocol ArrowArray < ItemType> : AnyArrowArray {
@@ -37,8 +39,42 @@ public protocol ArrowArray<ItemType>: AnyArrowArray {
3739 subscript( _ index: UInt ) -> ItemType ? { get }
3840}
3941
40- // MARK: - Default Implementations
41- extension ArrowArray {
42+ public class ArrowArrayBase < T> : ArrowArray {
43+
44+ public var arrowData : ArrowData
45+ public var cArrayPtr : UnsafePointer < ArrowC . ArrowArray > ? = nil
46+
47+ required public init ( _ arrowData: ArrowData ) throws ( ArrowError) {
48+ self . arrowData = arrowData
49+ }
50+
51+ public subscript( _ index: UInt ) -> T ? {
52+ fatalError ( " Base class is abstract. " )
53+ }
54+
55+ public func asString( _ index: UInt ) -> String {
56+ guard let value = self [ index] else {
57+ return " "
58+ }
59+ return " \( value) "
60+ }
61+
62+ public func asAny( _ index: UInt ) -> Any ? {
63+ self [ index]
64+ }
65+
66+ public func setCArrayPtr( _ cArrayPtr: UnsafePointer < ArrowC . ArrowArray > ? ) {
67+ self . cArrayPtr = cArrayPtr
68+ }
69+
70+ deinit {
71+ if let cArrayPtr = cArrayPtr {
72+ ArrowCImporter . release ( cArrayPtr)
73+ }
74+ }
75+ }
76+
77+ extension ArrowArrayBase {
4278 public var nullCount : UInt {
4379 arrowData. nullCount
4480 }
@@ -63,32 +99,19 @@ extension ArrowArray {
6399 arrowData. buffers. map { Int ( $0. capacity) }
64100 }
65101
66- public func isNull( at index: UInt ) throws -> Bool {
102+ public func isNull( at index: UInt ) throws ( ArrowError ) -> Bool {
67103 if index >= self . length {
68- throw ArrowError . outOfBounds ( index: Int64 ( index) )
104+ throw . outOfBounds( index: Int64 ( index) )
69105 }
70106 return arrowData. isNull ( index)
71107 }
72-
73- public func asString( _ index: UInt ) -> String {
74- guard let value = self [ index] else {
75- return " "
76- }
77- return " \( value) "
78- }
79-
80- public func asAny( _ index: UInt ) -> Any ? {
81- self [ index]
82- }
83108}
84109
85110// MARK: Fixed Arrays
86111
87- public protocol FixedArrayProtocol : ArrowArray where ItemType: BitwiseCopyable {
88- }
112+ public class FixedArray < T> : ArrowArrayBase < T > where T: BitwiseCopyable {
89113
90- extension FixedArrayProtocol {
91- public subscript( _ index: UInt ) -> ItemType ? {
114+ public override subscript( _ index: UInt ) -> ItemType ? {
92115 if arrowData. isNull ( index) {
93116 return nil
94117 }
@@ -106,28 +129,9 @@ extension FixedArrayProtocol {
106129 }
107130}
108131
109- public struct FixedArray < T> : FixedArrayProtocol where T: BitwiseCopyable {
110- public typealias ItemType = T
111- public let arrowData : ArrowData
132+ public class StringArray : ArrowArrayBase < String > {
112133
113- public init ( arrowData: ArrowData ) {
114- self . arrowData = arrowData
115- }
116-
117- public init ( _ arrowData: ArrowData ) {
118- self . arrowData = arrowData
119- }
120- }
121-
122- public struct StringArray : ArrowArray {
123- public typealias ItemType = String
124- public let arrowData : ArrowData
125-
126- public init ( _ arrowData: ArrowData ) {
127- self . arrowData = arrowData
128- }
129-
130- public subscript( _ index: UInt ) -> String ? {
134+ public override subscript( _ index: UInt ) -> String ? {
131135 let offsetIndex = MemoryLayout< Int32> . stride * Int( index)
132136 if self . arrowData. isNull ( index) {
133137 return nil
@@ -138,8 +142,8 @@ public struct StringArray: ArrowArray {
138142
139143 var startIndex : Int32 = 0
140144 if index > 0 {
141- startIndex = offsets. rawPointer. advanced ( by: offsetIndex) . load (
142- as: Int32 . self)
145+ startIndex = offsets. rawPointer. advanced ( by: offsetIndex)
146+ . load ( as: Int32 . self)
143147 }
144148
145149 let endIndex = offsets. rawPointer. advanced (
@@ -150,21 +154,16 @@ public struct StringArray: ArrowArray {
150154 let rawPointer = values. rawPointer. advanced ( by: Int ( startIndex) )
151155 . bindMemory ( to: UInt8 . self, capacity: arrayLength)
152156 let buffer = UnsafeBufferPointer < UInt8 > (
153- start: rawPointer, count: arrayLength)
154- let byteArray = Array ( buffer)
155- return String ( data: Data ( byteArray) , encoding: . utf8)
157+ start: rawPointer,
158+ count: arrayLength
159+ )
160+ return String ( bytes: buffer, encoding: . utf8)
156161 }
157162}
158163
159- public struct BoolArray : ArrowArray {
160- public typealias ItemType = Bool
161- public let arrowData : ArrowData
164+ public class BoolArray : ArrowArrayBase < Bool > {
162165
163- public init ( _ arrowData: ArrowData ) {
164- self . arrowData = arrowData
165- }
166-
167- public subscript( _ index: UInt ) -> Bool ? {
166+ public override subscript( _ index: UInt ) -> Bool ? {
168167 if self . arrowData. isNull ( index) {
169168 return nil
170169 }
@@ -173,15 +172,9 @@ public struct BoolArray: ArrowArray {
173172 }
174173}
175174
176- public struct Date32Array : ArrowArray {
177- public typealias ItemType = Date
178- public let arrowData : ArrowData
175+ public class Date32Array : ArrowArrayBase < Date > {
179176
180- public init ( _ arrowData: ArrowData ) {
181- self . arrowData = arrowData
182- }
183-
184- public subscript( _ index: UInt ) -> Date ? {
177+ public override subscript( _ index: UInt ) -> Date ? {
185178 if self . arrowData. isNull ( index) {
186179 return nil
187180 }
@@ -193,15 +186,9 @@ public struct Date32Array: ArrowArray {
193186 }
194187}
195188
196- public struct Date64Array : ArrowArray {
197- public typealias ItemType = Date
198- public let arrowData : ArrowData
189+ public class Date64Array : ArrowArrayBase < Date > {
199190
200- public init ( _ arrowData: ArrowData ) {
201- self . arrowData = arrowData
202- }
203-
204- public subscript( _ index: UInt ) -> Date ? {
191+ public override subscript( _ index: UInt ) -> Date ? {
205192 if self . arrowData. isNull ( index) {
206193 return nil
207194 }
@@ -217,13 +204,7 @@ public typealias Time64Array = FixedArray<Time64>
217204
218205public typealias Time32Array = FixedArray < Time32 >
219206
220- public struct TimestampArray : FixedArrayProtocol {
221- public typealias ItemType = Timestamp
222- public let arrowData : ArrowData
223-
224- public init ( _ arrowData: ArrowData ) {
225- self . arrowData = arrowData
226- }
207+ public class TimestampArray : FixedArray < Timestamp > {
227208
228209 public struct FormattingOptions : Equatable {
229210 public var dateFormat : String = " yyyy-MM-dd HH:mm:ss.SSS "
@@ -256,7 +237,7 @@ public struct TimestampArray: FixedArrayProtocol {
256237 private var cachedFormatter : DateFormatter ?
257238 private var cachedOptions : FormattingOptions ?
258239
259- public mutating func formattedDate(
240+ public func formattedDate(
260241 at index: UInt ,
261242 options: FormattingOptions = FormattingOptions ( )
262243 ) -> String ? {
@@ -300,8 +281,7 @@ public struct TimestampArray: FixedArrayProtocol {
300281 return Date ( timeIntervalSince1970: timeInterval)
301282 }
302283
303- // TODO: Mutating function to hack around cached formatter
304- public mutating func asString( _ index: UInt ) -> String {
284+ public override func asString( _ index: UInt ) -> String {
305285 if let formatted = formattedDate ( at: index) {
306286 return formatted
307287 } else {
@@ -310,13 +290,7 @@ public struct TimestampArray: FixedArrayProtocol {
310290 }
311291}
312292
313- public struct BinaryArray : ArrowArray {
314- public typealias ItemType = Data
315- public let arrowData : ArrowData
316-
317- public init ( _ arrowData: ArrowData ) {
318- self . arrowData = arrowData
319- }
293+ public class BinaryArray : ArrowArrayBase < Data > {
320294
321295 public struct Options {
322296 public var printAsHex = false
@@ -325,7 +299,7 @@ public struct BinaryArray: ArrowArray {
325299
326300 public var options = Options ( )
327301
328- public subscript( _ index: UInt ) -> Data ? {
302+ public override subscript( _ index: UInt ) -> Data ? {
329303 let offsetIndex = MemoryLayout< Int32> . stride * Int( index)
330304 if self . arrowData. isNull ( index) {
331305 return nil
@@ -350,7 +324,7 @@ public struct BinaryArray: ArrowArray {
350324 return Data ( byteArray)
351325 }
352326
353- public func asString( _ index: UInt ) -> String {
327+ public override func asString( _ index: UInt ) -> String {
354328 guard let data = self [ index] else { return " " }
355329 if options. printAsHex {
356330 return data. hexEncodedString ( )
@@ -364,13 +338,14 @@ public struct BinaryArray: ArrowArray {
364338 }
365339}
366340
367- public struct NestedArray : ArrowArray , AnyArrowArray {
368- public typealias ItemType = [ Any ? ]
369- public let arrowData : ArrowData
341+ public class NestedArray : ArrowArrayBase < [ Any ? ] > {
342+
370343 private var children : [ AnyArrowArray ] ?
371344
372- public init ( _ arrowData: ArrowData ) throws ( ArrowError) {
373- self . arrowData = arrowData
345+ public required init (
346+ _ arrowData: ArrowData
347+ ) throws ( ArrowError) {
348+ try super. init ( arrowData)
374349
375350 switch arrowData. type {
376351 case . list( let field) :
@@ -398,7 +373,7 @@ public struct NestedArray: ArrowArray, AnyArrowArray {
398373 }
399374 }
400375
401- public subscript( _ index: UInt ) -> [ Any ? ] ? {
376+ public override subscript( _ index: UInt ) -> [ Any ? ] ? {
402377 if self . arrowData. isNull ( index) {
403378 return nil
404379 }
@@ -432,7 +407,7 @@ public struct NestedArray: ArrowArray, AnyArrowArray {
432407 }
433408 }
434409
435- public func asString( _ index: UInt ) -> String {
410+ public override func asString( _ index: UInt ) -> String {
436411 switch arrowData. type {
437412 case . list( let _) :
438413 if self . arrowData. isNull ( index) {
0 commit comments