blob: 3cf7519e7ad4720a6686678bb9f31ee6874cf499 [file] [log] [blame]
// 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.
using System;
using System.IO;
namespace Apache.Arrow.Ipc
{
internal class MessageSerializer
{
public const int IpcContinuationToken = -1;
public static Types.NumberType GetNumberType(int bitWidth, bool signed)
{
if (signed)
{
if (bitWidth == 8)
return Types.Int8Type.Default;
if (bitWidth == 16)
return Types.Int16Type.Default;
if (bitWidth == 32)
return Types.Int32Type.Default;
if (bitWidth == 64)
return Types.Int64Type.Default;
}
else
{
if (bitWidth == 8)
return Types.UInt8Type.Default;
if (bitWidth == 16)
return Types.UInt16Type.Default;
if (bitWidth == 32)
return Types.UInt32Type.Default;
if (bitWidth == 64)
return Types.UInt64Type.Default;
}
throw new Exception($"Unexpected bit width of {bitWidth} for " +
$"{(signed ? "signed " : "unsigned")} integer.");
}
internal static Schema GetSchema(Flatbuf.Schema schema)
{
var schemaBuilder = new Schema.Builder();
for (var i = 0; i < schema.FieldsLength; i++)
{
var field = schema.Fields(i).GetValueOrDefault();
schemaBuilder.Field(
new Field(field.Name, GetFieldArrowType(field), field.Nullable));
}
return schemaBuilder.Build();
}
private static Types.IArrowType GetFieldArrowType(Flatbuf.Field field)
{
switch (field.TypeType)
{
case Flatbuf.Type.Int:
var intMetaData = field.Type<Flatbuf.Int>().Value;
return MessageSerializer.GetNumberType(intMetaData.BitWidth, intMetaData.IsSigned);
case Flatbuf.Type.FloatingPoint:
var floatingPointTypeMetadata = field.Type<Flatbuf.FloatingPoint>().Value;
switch (floatingPointTypeMetadata.Precision)
{
case Flatbuf.Precision.SINGLE:
return Types.FloatType.Default;
case Flatbuf.Precision.DOUBLE:
return Types.DoubleType.Default;
case Flatbuf.Precision.HALF:
return Types.HalfFloatType.Default;
default:
throw new InvalidDataException("Unsupported floating point precision");
}
case Flatbuf.Type.Bool:
return new Types.BooleanType();
case Flatbuf.Type.Decimal:
var decMeta = field.Type<Flatbuf.Decimal>().Value;
return new Types.DecimalType(decMeta.Precision, decMeta.Scale);
case Flatbuf.Type.Date:
var dateMeta = field.Type<Flatbuf.Date>().Value;
switch (dateMeta.Unit)
{
case Flatbuf.DateUnit.DAY:
return Types.Date32Type.Default;
case Flatbuf.DateUnit.MILLISECOND:
return Types.Date64Type.Default;
default:
throw new InvalidDataException("Unsupported date unit");
}
case Flatbuf.Type.Time:
var timeMeta = field.Type<Flatbuf.Time>().Value;
switch (timeMeta.BitWidth)
{
case 32:
return new Types.Time32Type(timeMeta.Unit.ToArrow());
case 64:
return new Types.Time64Type(timeMeta.Unit.ToArrow());
default:
throw new InvalidDataException("Unsupported time bit width");
}
case Flatbuf.Type.Timestamp:
var timestampTypeMetadata = field.Type<Flatbuf.Timestamp>().Value;
var unit = timestampTypeMetadata.Unit.ToArrow();
var timezone = timestampTypeMetadata.Timezone;
return new Types.TimestampType(unit, timezone);
case Flatbuf.Type.Interval:
var intervalMetadata = field.Type<Flatbuf.Interval>().Value;
return new Types.IntervalType(intervalMetadata.Unit.ToArrow());
case Flatbuf.Type.Utf8:
return new Types.StringType();
case Flatbuf.Type.Binary:
return Types.BinaryType.Default;
case Flatbuf.Type.List:
if (field.ChildrenLength != 1)
{
throw new InvalidDataException($"List type must have only one child.");
}
return new Types.ListType(GetFieldArrowType(field.Children(0).GetValueOrDefault()));
default:
throw new InvalidDataException($"Arrow primitive '{field.TypeType}' is unsupported.");
}
}
}
}