1414
1515import Foundation
1616
17- public protocol ArrowArrayProtocol {
18- associatedtype ItemType
19- subscript( _ index: Int ) -> ItemType ? { get }
17+ public protocol AnyArrowArrayProtocol {
2018 var offset : Int { get }
2119 var length : Int { get }
2220 var nullCount : Int { get }
2321 func slice( offset: Int , length: Int ) -> Self
2422 func any( at index: Int ) -> Any ?
2523 var bufferSizes : [ Int ] { get }
24+ var buffers : [ ArrowBufferProtocol ] { get }
25+ }
26+
27+ internal protocol ArrowArrayProtocol : AnyArrowArrayProtocol {
28+ associatedtype ItemType
29+ subscript( _ index: Int ) -> ItemType ? { get }
2630}
2731
2832// This exists to support type-erased struct arrays.
@@ -32,12 +36,26 @@ extension ArrowArrayProtocol {
3236 }
3337}
3438
39+ // MARK: Capability protocols.
40+
41+ public protocol ArrowArrayOfString {
42+ subscript( index: Int ) -> String ? { get }
43+ }
44+ extension ArrowArrayVariable : ArrowArrayOfString where ItemType == String { }
45+
46+ public protocol ArrowArrayOfData {
47+ subscript( index: Int ) -> Data ? { get }
48+ }
49+ extension ArrowArrayFixedSizeBinary : ArrowArrayOfData where ItemType == Data { }
50+ extension ArrowArrayVariable : ArrowArrayOfData where ItemType == Data { }
51+
3552/// An Arrow array of booleans using the three-valued logical model (true / false / null).
3653public struct ArrowArrayBoolean : ArrowArrayProtocol {
3754 public typealias ItemType = Bool
3855 public let offset : Int
3956 public let length : Int
4057 public var bufferSizes : [ Int ] { [ nullBuffer. length, valueBuffer. length] }
58+ public var buffers : [ ArrowBufferProtocol ] { [ nullBuffer, valueBuffer] }
4159 public var nullCount : Int { nullBuffer. nullCount }
4260 let nullBuffer : NullBuffer
4361 let valueBuffer : NullBuffer
84102 public let offset : Int
85103 public let length : Int
86104 public var bufferSizes : [ Int ] { [ nullBuffer. length, valueBuffer. length] }
105+ public var buffers : [ ArrowBufferProtocol ] { [ nullBuffer, valueBuffer] }
87106 public var nullCount : Int { nullBuffer. nullCount }
88107 let nullBuffer : NullBuffer
89108 let valueBuffer : ValueBuffer
@@ -119,6 +138,54 @@ where
119138 }
120139}
121140
141+ public struct ArrowArrayFixedSizeBinary < ValueBuffer> : ArrowArrayProtocol
142+ where
143+ ValueBuffer: VariableLengthBufferProtocol < Data >
144+ {
145+ public typealias ItemType = Data
146+ public let offset : Int
147+ public let length : Int
148+ public let byteWidth : Int
149+
150+ public var bufferSizes : [ Int ] { [ nullBuffer. length, valueBuffer. length] }
151+ public var buffers : [ ArrowBufferProtocol ] { [ nullBuffer, valueBuffer] }
152+
153+ public var nullCount : Int { nullBuffer. nullCount }
154+
155+ let nullBuffer : NullBuffer
156+ let valueBuffer : ValueBuffer
157+
158+ public init (
159+ offset: Int = 0 ,
160+ length: Int ,
161+ byteWidth: Int ,
162+ nullBuffer: NullBuffer ,
163+ valueBuffer: ValueBuffer
164+ ) {
165+ self . offset = offset
166+ self . length = length
167+ self . byteWidth = byteWidth
168+ self . nullBuffer = nullBuffer
169+ self . valueBuffer = valueBuffer
170+ }
171+
172+ public subscript( index: Int ) -> ValueBuffer . ElementType ? {
173+ guard nullBuffer. isSet ( index) else { return nil }
174+ let startIndex = index * byteWidth
175+ return valueBuffer. loadVariable ( at: startIndex, arrayLength: byteWidth)
176+ }
177+
178+ public func slice( offset: Int , length: Int ) -> Self {
179+ . init(
180+ offset: self . offset + offset, // relative to current offset
181+ length: length,
182+ byteWidth: byteWidth,
183+ nullBuffer: nullBuffer,
184+ valueBuffer: valueBuffer
185+ )
186+ }
187+ }
188+
122189/// An Arrow array of variable-length types.
123190public struct ArrowArrayVariable < OffsetsBuffer, ValueBuffer> :
124191 ArrowArrayProtocol
@@ -133,6 +200,9 @@ where
133200 public var bufferSizes : [ Int ] {
134201 [ nullBuffer. length, offsetsBuffer. length, valueBuffer. length]
135202 }
203+ public var buffers : [ ArrowBufferProtocol ] {
204+ [ nullBuffer, offsetsBuffer, valueBuffer]
205+ }
136206 public var nullCount : Int { nullBuffer. nullCount }
137207 let nullBuffer : NullBuffer
138208 let offsetsBuffer : OffsetsBuffer
@@ -183,6 +253,7 @@ where
183253{
184254 public typealias ItemType = Date
185255 public var bufferSizes : [ Int ] { array. bufferSizes }
256+ public var buffers : [ ArrowBufferProtocol ] { array. buffers }
186257 public var nullCount : Int { array. nullCount }
187258 public var offset : Int { array. offset }
188259 public var length : Int { array. length }
@@ -212,6 +283,7 @@ where
212283{
213284 public typealias ItemType = Date
214285 public var bufferSizes : [ Int ] { array. bufferSizes }
286+ public var buffers : [ ArrowBufferProtocol ] { array. buffers }
215287 public var nullCount : Int { array. nullCount }
216288 public var offset : Int { array. offset }
217289 public var length : Int { array. length }
@@ -238,13 +310,16 @@ where
238310public struct ArrowListArray < Element, OffsetsBuffer> : ArrowArrayProtocol
239311where
240312 OffsetsBuffer: FixedWidthBufferProtocol < Int32 > ,
241- Element: ArrowArrayProtocol
313+ Element: AnyArrowArrayProtocol
242314{
243315 public typealias ItemType = Element
244316 public let offset : Int
245317 public let length : Int
246318 public var bufferSizes : [ Int ] {
247- [ nullBuffer. length, offsetsBuffer. length, values. length]
319+ [ nullBuffer. length, offsetsBuffer. length]
320+ }
321+ public var buffers : [ ArrowBufferProtocol ] {
322+ [ nullBuffer, offsetsBuffer]
248323 }
249324 public var nullCount : Int { nullBuffer. nullCount }
250325 let nullBuffer : NullBuffer
@@ -273,7 +348,6 @@ where
273348 }
274349 let startIndex = offsetsBuffer [ offsetIndex]
275350 let endIndex = offsetsBuffer [ offsetIndex + 1 ]
276-
277351 let length = endIndex - startIndex
278352 return values. slice ( offset: Int ( startIndex) , length: Int ( length) )
279353 }
@@ -292,20 +366,23 @@ where
292366/// A type-erased wrapper for an Arrow list array.
293367public struct AnyArrowListArray : ArrowArrayProtocol {
294368
295- public typealias ItemType = any ArrowArrayProtocol
369+ public typealias ItemType = AnyArrowArrayProtocol
296370 public var bufferSizes : [ Int ] {
297371 _base. bufferSizes
298372 }
373+ public var buffers : [ ArrowBufferProtocol ] {
374+ _base. buffers
375+ }
299376
300377 private let _base : any ArrowArrayProtocol
301- private let _subscriptImpl : ( Int ) -> ( any ArrowArrayProtocol ) ?
378+ private let _subscriptImpl : ( Int ) -> AnyArrowArrayProtocol ?
302379 private let _sliceImpl : ( Int , Int ) -> AnyArrowListArray
303380
304381 public let offset : Int
305382 public let length : Int
306383 public var nullCount : Int { _base. nullCount }
307384
308- public init < Element, OffsetsBuffer> (
385+ init < Element, OffsetsBuffer> (
309386 _ list: ArrowListArray < Element , OffsetsBuffer >
310387 )
311388 where
@@ -319,7 +396,7 @@ public struct AnyArrowListArray: ArrowArrayProtocol {
319396 self . _sliceImpl = { AnyArrowListArray ( list. slice ( offset: $0, length: $1) ) }
320397 }
321398
322- public subscript( index: Int ) -> ( any ArrowArrayProtocol ) ? {
399+ public subscript( index: Int ) -> AnyArrowArrayProtocol ? {
323400 _subscriptImpl ( index)
324401 }
325402
@@ -333,16 +410,17 @@ public struct ArrowStructArray: ArrowArrayProtocol {
333410 public typealias ItemType = [ String : Any ]
334411 public let offset : Int
335412 public let length : Int
336- public let fields : [ ( name: String , array: any ArrowArrayProtocol ) ]
413+ public let fields : [ ( name: String , array: AnyArrowArrayProtocol ) ]
337414 public var bufferSizes : [ Int ] { [ nullBuffer. length] }
415+ public var buffers : [ ArrowBufferProtocol ] { [ nullBuffer] }
338416 public var nullCount : Int { nullBuffer. nullCount }
339417 let nullBuffer : NullBuffer
340418
341419 public init (
342420 offset: Int = 0 ,
343421 length: Int ,
344422 nullBuffer: NullBuffer ,
345- fields: [ ( name: String , array: any ArrowArrayProtocol ) ]
423+ fields: [ ( name: String , array: AnyArrowArrayProtocol ) ]
346424 ) {
347425 self . offset = offset
348426 self . length = length
@@ -352,7 +430,6 @@ public struct ArrowStructArray: ArrowArrayProtocol {
352430
353431 public subscript( index: Int ) -> ItemType ? {
354432 guard nullBuffer. isSet ( offset + index) else { return nil }
355-
356433 var result : [ String : Any ] = [ : ]
357434 for (name, array) in fields {
358435 result [ name] = array. any ( at: index)
0 commit comments