Sources/SparkConnect/ArrowWriterHelper.swift (115 lines of code) (raw):
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
import FlatBuffers
import Foundation
extension Data {
func hexEncodedString() -> String {
return map { String(format: "%02hhx", $0) }.joined()
}
}
func toFBTypeEnum(_ arrowType: ArrowType) -> Result<org_apache_arrow_flatbuf_Type_, ArrowError> {
let infoType = arrowType.info
if infoType == ArrowType.ArrowInt8 || infoType == ArrowType.ArrowInt16
|| infoType == ArrowType.ArrowInt64 || infoType == ArrowType.ArrowUInt8
|| infoType == ArrowType.ArrowUInt16 || infoType == ArrowType.ArrowUInt32
|| infoType == ArrowType.ArrowUInt64 || infoType == ArrowType.ArrowInt32
{
return .success(org_apache_arrow_flatbuf_Type_.int)
} else if infoType == ArrowType.ArrowFloat || infoType == ArrowType.ArrowDouble {
return .success(org_apache_arrow_flatbuf_Type_.floatingpoint)
} else if infoType == ArrowType.ArrowString {
return .success(org_apache_arrow_flatbuf_Type_.utf8)
} else if infoType == ArrowType.ArrowBinary {
return .success(org_apache_arrow_flatbuf_Type_.binary)
} else if infoType == ArrowType.ArrowBool {
return .success(org_apache_arrow_flatbuf_Type_.bool)
} else if infoType == ArrowType.ArrowDate32 || infoType == ArrowType.ArrowDate64 {
return .success(org_apache_arrow_flatbuf_Type_.date)
} else if infoType == ArrowType.ArrowTime32 || infoType == ArrowType.ArrowTime64 {
return .success(org_apache_arrow_flatbuf_Type_.time)
}
return .failure(.unknownType("Unable to find flatbuf type for Arrow type: \(infoType)"))
}
func toFBType( // swiftlint:disable:this cyclomatic_complexity
_ fbb: inout FlatBufferBuilder,
arrowType: ArrowType
) -> Result<Offset, ArrowError> {
let infoType = arrowType.info
if infoType == ArrowType.ArrowInt8 || infoType == ArrowType.ArrowUInt8 {
return .success(
org_apache_arrow_flatbuf_Int.createInt(
&fbb, bitWidth: 8, isSigned: infoType == ArrowType.ArrowInt8))
} else if infoType == ArrowType.ArrowInt16 || infoType == ArrowType.ArrowUInt16 {
return .success(
org_apache_arrow_flatbuf_Int.createInt(
&fbb, bitWidth: 16, isSigned: infoType == ArrowType.ArrowInt16))
} else if infoType == ArrowType.ArrowInt32 || infoType == ArrowType.ArrowUInt32 {
return .success(
org_apache_arrow_flatbuf_Int.createInt(
&fbb, bitWidth: 32, isSigned: infoType == ArrowType.ArrowInt32))
} else if infoType == ArrowType.ArrowInt64 || infoType == ArrowType.ArrowUInt64 {
return .success(
org_apache_arrow_flatbuf_Int.createInt(
&fbb, bitWidth: 64, isSigned: infoType == ArrowType.ArrowInt64))
} else if infoType == ArrowType.ArrowFloat {
return .success(
org_apache_arrow_flatbuf_FloatingPoint.createFloatingPoint(&fbb, precision: .single))
} else if infoType == ArrowType.ArrowDouble {
return .success(
org_apache_arrow_flatbuf_FloatingPoint.createFloatingPoint(&fbb, precision: .double))
} else if infoType == ArrowType.ArrowString {
return .success(
org_apache_arrow_flatbuf_Utf8.endUtf8(
&fbb, start: org_apache_arrow_flatbuf_Utf8.startUtf8(&fbb)))
} else if infoType == ArrowType.ArrowBinary {
return .success(
org_apache_arrow_flatbuf_Binary.endBinary(
&fbb, start: org_apache_arrow_flatbuf_Binary.startBinary(&fbb)))
} else if infoType == ArrowType.ArrowBool {
return .success(
org_apache_arrow_flatbuf_Bool.endBool(
&fbb, start: org_apache_arrow_flatbuf_Bool.startBool(&fbb)))
} else if infoType == ArrowType.ArrowDate32 {
let startOffset = org_apache_arrow_flatbuf_Date.startDate(&fbb)
org_apache_arrow_flatbuf_Date.add(unit: .day, &fbb)
return .success(org_apache_arrow_flatbuf_Date.endDate(&fbb, start: startOffset))
} else if infoType == ArrowType.ArrowDate64 {
let startOffset = org_apache_arrow_flatbuf_Date.startDate(&fbb)
org_apache_arrow_flatbuf_Date.add(unit: .millisecond, &fbb)
return .success(org_apache_arrow_flatbuf_Date.endDate(&fbb, start: startOffset))
} else if infoType == ArrowType.ArrowTime32 {
let startOffset = org_apache_arrow_flatbuf_Time.startTime(&fbb)
if let timeType = arrowType as? ArrowTypeTime32 {
org_apache_arrow_flatbuf_Time.add(
unit: timeType.unit == .seconds ? .second : .millisecond, &fbb)
return .success(org_apache_arrow_flatbuf_Time.endTime(&fbb, start: startOffset))
}
return .failure(.invalid("Unable to case to Time32"))
} else if infoType == ArrowType.ArrowTime64 {
let startOffset = org_apache_arrow_flatbuf_Time.startTime(&fbb)
if let timeType = arrowType as? ArrowTypeTime64 {
org_apache_arrow_flatbuf_Time.add(
unit: timeType.unit == .microseconds ? .microsecond : .nanosecond, &fbb)
return .success(org_apache_arrow_flatbuf_Time.endTime(&fbb, start: startOffset))
}
return .failure(.invalid("Unable to case to Time64"))
}
return .failure(.unknownType("Unable to add flatbuf type for Arrow type: \(infoType)"))
}
func addPadForAlignment(_ data: inout Data, alignment: Int = 8) {
let padding = data.count % Int(alignment)
if padding > 0 {
data.append(Data([UInt8](repeating: 0, count: alignment - padding)))
}
}
func addPadForAlignment(_ writer: inout DataWriter, alignment: Int = 8) {
let padding = writer.count % Int(alignment)
if padding > 0 {
writer.append(Data([UInt8](repeating: 0, count: alignment - padding)))
}
}
func getPadForAlignment(_ count: Int, alignment: Int = 8) -> Int {
let padding = count % Int(alignment)
if padding > 0 {
return count + (alignment - padding)
}
return count
}