/*
Copyright (c) Microsoft Corporation
All rights reserved.
Licensed 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
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and
limitations under the License.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Reflection;
using System.Linq;
using System.Data.SqlTypes;
using System.Diagnostics;
using Microsoft.Research.DryadLinq.Internal;
using Microsoft.Research.DryadLinq;
namespace Microsoft.Research.DryadLinq
{
///
/// The interface for providing user-defined serialization for a .NET type.
/// If a class T implements DryadLinqSerializer{T}, DryadLinq will use the
/// read and write methods of the class to do serialization.
///
/// The .NET type to be serialized.
public interface IDryadLinqSerializer
{
///
/// Reads a record of type T from the specified reader.
///
/// The reader to read from.
/// A record of type T
T Read(DryadLinqBinaryReader reader);
///
/// Writes a record of type T to the specified writer.
///
/// The writer to write to.
/// The record to write.
void Write(DryadLinqBinaryWriter writer, T x);
}
}
#pragma warning disable 1591
namespace Microsoft.Research.DryadLinq.Internal
{
public abstract class DryadLinqSerializer : IDryadLinqSerializer
{
public DryadLinqSerializer() { }
public abstract T Read(DryadLinqBinaryReader reader);
public abstract void Write(DryadLinqBinaryWriter writer, T x);
}
internal struct DryadLinqSequence : IEnumerable
{
private T[] elements;
internal DryadLinqSequence(T[] elems)
{
this.elements = elems;
}
internal int Count()
{
return this.elements.Length;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
internal IEnumerator GetEnumerator()
{
foreach (T x in this.elements)
{
yield return x;
}
}
}
// The only use is to handle Nullable.
public static class StructDryadLinqSerialization
where T : struct
where S : DryadLinqSerializer, new()
{
private static S serializer = new S();
public static void Read(DryadLinqBinaryReader reader, out Nullable val)
{
bool hasValue = reader.ReadBool();
if (hasValue)
{
val = serializer.Read(reader);
}
else
{
val = null;
}
}
public static void Write(DryadLinqBinaryWriter writer, Nullable val)
{
writer.Write(val.HasValue);
if (val.HasValue)
{
serializer.Write(writer, val.Value);
}
}
}
public static class StructDryadLinqSerialization
where T1 : struct
where T2 : struct
where S1 : DryadLinqSerializer, new()
where S2 : DryadLinqSerializer, new()
{
private static S1 serializer1 = new S1();
private static S2 serializer2 = new S2();
}
// A workaround to deal with some limitation of C# generics
public static class DryadLinqSerialization
where S : DryadLinqSerializer, new()
{
private static S serializer = new S();
public static void Read(DryadLinqBinaryReader reader, out List list)
{
int cnt = reader.ReadInt32();
list = new List(cnt);
for (int i = 0; i < cnt; i++)
{
list.Add(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, List list)
{
writer.Write(list.Count);
foreach (T elem in list)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out LinkedList list)
{
int cnt = reader.ReadInt32();
list = new LinkedList();
for (int i = 0; i < cnt; i++)
{
list.AddLast(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, LinkedList list)
{
writer.Write(list.Count);
foreach (T elem in list)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out Queue queue)
{
int cnt = reader.ReadInt32();
queue = new Queue(cnt);
for (int i = 0; i < cnt; i++)
{
queue.Enqueue(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, Queue queue)
{
writer.Write(queue.Count);
foreach (T elem in queue)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out Stack stack)
{
int cnt = reader.ReadInt32();
stack = new Stack(cnt);
for (int i = 0; i < cnt; i++)
{
stack.Push(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, Stack stack)
{
writer.Write(stack.Count);
foreach (T elem in stack)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out HashSet set)
{
int cnt = reader.ReadInt32();
set = new HashSet();
for (int i = 0; i < cnt; i++)
{
set.Add(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, HashSet set)
{
writer.Write(set.Count);
foreach (T elem in set)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out Collection set)
{
int cnt = reader.ReadInt32();
set = new Collection();
for (int i = 0; i < cnt; i++)
{
set.Add(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, Collection set)
{
writer.Write(set.Count);
foreach (T elem in set)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out ReadOnlyCollection set)
{
int cnt = reader.ReadInt32();
List lst = new List(cnt);
for (int i = 0; i < cnt; i++)
{
lst.Add(serializer.Read(reader));
}
set = new ReadOnlyCollection(lst);
}
public static void Write(DryadLinqBinaryWriter writer, ReadOnlyCollection set)
{
writer.Write(set.Count);
foreach (T elem in set)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out IEnumerable seq)
{
int cnt = reader.ReadInt32();
T[] elems = new T[cnt];
for (int i = 0; i < cnt; i++)
{
elems[i] = serializer.Read(reader);
}
seq = new DryadLinqSequence(elems);
}
public static void Write(DryadLinqBinaryWriter writer, IEnumerable seq)
{
writer.Write(seq.Count());
foreach (T elem in seq)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out IList seq)
{
int cnt = reader.ReadInt32();
seq = new List(cnt);
for (int i = 0; i < cnt; i++)
{
seq.Add(serializer.Read(reader));
}
}
public static void Write(DryadLinqBinaryWriter writer, IList seq)
{
writer.Write(seq.Count);
foreach (T elem in seq)
{
serializer.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out ForkValue val)
{
val = new ForkValue();
if (reader.ReadBool())
{
val.Value = serializer.Read(reader);
}
}
public static void Write(DryadLinqBinaryWriter writer, ForkValue val)
{
writer.Write(val.HasValue);
if (val.HasValue)
{
serializer.Write(writer, val.Value);
}
}
public static void Read(DryadLinqBinaryReader reader, out AggregateValue aggVal)
{
long cnt = reader.ReadInt64();
T val = default(T);
if (cnt > 0)
{
val = serializer.Read(reader);
}
aggVal = new AggregateValue(val, cnt);
}
public static void Write(DryadLinqBinaryWriter writer, AggregateValue aggVal)
{
writer.Write(aggVal.Count);
if (aggVal.Count > 0)
{
serializer.Write(writer, aggVal.Value);
}
}
public static void Read(DryadLinqBinaryReader reader, out IndexedValue indexedVal)
{
int index = reader.ReadInt32();
T val = serializer.Read(reader);
indexedVal = new IndexedValue(index, val);
}
public static void Write(DryadLinqBinaryWriter writer, IndexedValue indexedVal)
{
writer.Write(indexedVal.Index);
serializer.Write(writer, indexedVal.Value);
}
}
public static class DryadLinqSerialization
where S1 : DryadLinqSerializer, new()
where S2 : DryadLinqSerializer, new()
{
private static S1 serializer1 = new S1();
private static S2 serializer2 = new S2();
public static void Read(DryadLinqBinaryReader reader, out Dictionary dict)
{
int cnt = reader.ReadInt32();
dict = new Dictionary(cnt);
for (int i = 0; i < cnt; i++)
{
T1 key = serializer1.Read(reader);
T2 val = serializer2.Read(reader);
dict.Add(key, val);
}
}
public static void Write(DryadLinqBinaryWriter writer, Dictionary dict)
{
writer.Write(dict.Count);
foreach (KeyValuePair elem in dict)
{
serializer1.Write(writer, elem.Key);
serializer2.Write(writer, elem.Value);
}
}
public static void Read(DryadLinqBinaryReader reader, out SortedDictionary dict)
{
int cnt = reader.ReadInt32();
dict = new SortedDictionary();
for (int i = 0; i < cnt; i++)
{
T1 key = serializer1.Read(reader);
T2 val = serializer2.Read(reader);
dict.Add(key, val);
}
}
public static void Write(DryadLinqBinaryWriter writer, SortedDictionary dict)
{
writer.Write(dict.Count);
foreach (KeyValuePair elem in dict)
{
serializer1.Write(writer, elem.Key);
serializer2.Write(writer, elem.Value);
}
}
public static void Read(DryadLinqBinaryReader reader, out SortedList list)
{
int cnt = reader.ReadInt32();
list = new SortedList(cnt);
for (int i = 0; i < cnt; i++)
{
T1 key = serializer1.Read(reader);
T2 value = serializer2.Read(reader);
list.Add(key, value);
}
}
public static void Write(DryadLinqBinaryWriter writer, SortedList list)
{
writer.Write(list.Count);
foreach (KeyValuePair elem in list)
{
serializer1.Write(writer, elem.Key);
serializer2.Write(writer, elem.Value);
}
}
public static void Read(DryadLinqBinaryReader reader, out IGrouping group)
{
T1 key = serializer1.Read(reader);
int len = reader.ReadInt32();
Grouping realGroup = new Grouping(key, len);
for (int i = 0; i < len; i++)
{
realGroup.AddItem(serializer2.Read(reader));
}
group = realGroup;
}
public static void Write(DryadLinqBinaryWriter writer, IGrouping group)
{
serializer1.Write(writer, group.Key);
writer.Write(group.Count());
foreach (T2 elem in group)
{
serializer2.Write(writer, elem);
}
}
public static void Read(DryadLinqBinaryReader reader, out KeyValuePair kv)
{
T1 key = serializer1.Read(reader);
T2 val = serializer2.Read(reader);
kv = new KeyValuePair(key, val);
}
public static void Write(DryadLinqBinaryWriter writer, KeyValuePair kv)
{
serializer1.Write(writer, kv.Key);
serializer2.Write(writer, kv.Value);
}
public static void Read(DryadLinqBinaryReader reader, out Pair pair)
{
T1 x = serializer1.Read(reader);
T2 y = serializer2.Read(reader);
pair = new Pair(x, y);
}
public static void Write(DryadLinqBinaryWriter writer, Pair pair)
{
serializer1.Write(writer, pair.Key);
serializer2.Write(writer, pair.Value);
}
public static void Read(DryadLinqBinaryReader reader, out ForkTuple val)
{
val = new ForkTuple();
if (reader.ReadBool())
{
val.First = serializer1.Read(reader);
}
if (reader.ReadBool())
{
val.Second = serializer2.Read(reader);
}
}
public static void Write(DryadLinqBinaryWriter writer, ForkTuple val)
{
writer.Write(val.HasFirst);
if (val.HasFirst)
{
serializer1.Write(writer, val.First);
}
writer.Write(val.HasSecond);
if (val.HasSecond)
{
serializer2.Write(writer, val.Second);
}
}
public static void Read(DryadLinqBinaryReader reader, out DryadLinqGrouping group)
{
T1 key = serializer1.Read(reader);
int cnt = reader.ReadInt32();
T2[] elems = new T2[cnt];
for (int i = 0; i < cnt; i++)
{
elems[i] = serializer2.Read(reader);
}
group = new DryadLinqGrouping(key, elems);
}
public static void Write(DryadLinqBinaryWriter writer, DryadLinqGrouping group)
{
serializer1.Write(writer, group.Key);
writer.Write(group.Count());
foreach (T2 elem in group)
{
serializer2.Write(writer, elem);
}
}
}
public static class DryadLinqSerialization
where S1 : DryadLinqSerializer, new()
where S2 : DryadLinqSerializer, new()
where S3 : DryadLinqSerializer, new()
{
}
public sealed class ByteDryadLinqSerializer : DryadLinqSerializer
{
public override byte Read(DryadLinqBinaryReader reader)
{
return reader.ReadUByte();
}
public override void Write(DryadLinqBinaryWriter writer, byte x)
{
writer.Write(x);
}
}
public sealed class SByteDryadLinqSerializer : DryadLinqSerializer
{
public override sbyte Read(DryadLinqBinaryReader reader)
{
return reader.ReadSByte();
}
public override void Write(DryadLinqBinaryWriter writer, sbyte x)
{
writer.Write(x);
}
}
public sealed class BoolDryadLinqSerializer : DryadLinqSerializer
{
public override bool Read(DryadLinqBinaryReader reader)
{
return reader.ReadBool();
}
public override void Write(DryadLinqBinaryWriter writer, bool x)
{
writer.Write(x);
}
}
public sealed class CharDryadLinqSerializer : DryadLinqSerializer
{
public override char Read(DryadLinqBinaryReader reader)
{
return reader.ReadChar();
}
public override void Write(DryadLinqBinaryWriter writer, char x)
{
writer.Write(x);
}
}
public sealed class Int16DryadLinqSerializer : DryadLinqSerializer
{
public override Int16 Read(DryadLinqBinaryReader reader)
{
return reader.ReadInt16();
}
public override void Write(DryadLinqBinaryWriter writer, Int16 x)
{
writer.Write(x);
}
}
public sealed class UInt16DryadLinqSerializer : DryadLinqSerializer
{
public override UInt16 Read(DryadLinqBinaryReader reader)
{
return reader.ReadUInt16();
}
public override void Write(DryadLinqBinaryWriter writer, UInt16 x)
{
writer.Write(x);
}
}
public sealed class Int32DryadLinqSerializer : DryadLinqSerializer
{
public override Int32 Read(DryadLinqBinaryReader reader)
{
return reader.ReadInt32();
}
public override void Write(DryadLinqBinaryWriter writer, Int32 x)
{
writer.Write(x);
}
}
public sealed class UInt32DryadLinqSerializer : DryadLinqSerializer
{
public override UInt32 Read(DryadLinqBinaryReader reader)
{
return reader.ReadUInt32();
}
public override void Write(DryadLinqBinaryWriter writer, UInt32 x)
{
writer.Write(x);
}
}
public sealed class Int64DryadLinqSerializer : DryadLinqSerializer
{
public override Int64 Read(DryadLinqBinaryReader reader)
{
return reader.ReadInt64();
}
public override void Write(DryadLinqBinaryWriter writer, Int64 x)
{
writer.Write(x);
}
}
public sealed class UInt64DryadLinqSerializer : DryadLinqSerializer
{
public override UInt64 Read(DryadLinqBinaryReader reader)
{
return reader.ReadUInt64();
}
public override void Write(DryadLinqBinaryWriter writer, UInt64 x)
{
writer.Write(x);
}
}
public sealed class SingleDryadLinqSerializer : DryadLinqSerializer
{
public override float Read(DryadLinqBinaryReader reader)
{
return reader.ReadSingle();
}
public override void Write(DryadLinqBinaryWriter writer, float x)
{
writer.Write(x);
}
}
public sealed class DoubleDryadLinqSerializer : DryadLinqSerializer
{
public override double Read(DryadLinqBinaryReader reader)
{
return reader.ReadDouble();
}
public override void Write(DryadLinqBinaryWriter writer, double x)
{
writer.Write(x);
}
}
public sealed class DecimalDryadLinqSerializer : DryadLinqSerializer
{
public override decimal Read(DryadLinqBinaryReader reader)
{
return reader.ReadDecimal();
}
public override void Write(DryadLinqBinaryWriter writer, decimal x)
{
writer.Write(x);
}
}
public sealed class DateTimeDryadLinqSerializer : DryadLinqSerializer
{
public override DateTime Read(DryadLinqBinaryReader reader)
{
return reader.ReadDateTime();
}
public override void Write(DryadLinqBinaryWriter writer, DateTime x)
{
writer.Write(x);
}
}
public sealed class StringDryadLinqSerializer : DryadLinqSerializer
{
public override string Read(DryadLinqBinaryReader reader)
{
return reader.ReadString();
}
public override void Write(DryadLinqBinaryWriter writer, string x)
{
writer.Write(x);
}
}
public sealed class GuidDryadLinqSerializer : DryadLinqSerializer
{
public override Guid Read(DryadLinqBinaryReader reader)
{
return reader.ReadGuid();
}
public override void Write(DryadLinqBinaryWriter writer, Guid x)
{
writer.Write(x);
}
}
public sealed class SqlDateTimeDryadLinqSerializer : DryadLinqSerializer
{
public override SqlDateTime Read(DryadLinqBinaryReader reader)
{
return reader.ReadSqlDateTime();
}
public override void Write(DryadLinqBinaryWriter writer, SqlDateTime x)
{
writer.Write(x);
}
}
}