http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs deleted file mode 100644 index 8be8b7f..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectHeader.cs +++ /dev/null @@ -1,469 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.IO; - using System.Runtime.InteropServices; - using Apache.Ignite.Core.Impl.Portable.IO; - - /// <summary> - /// Portable object header structure. - /// </summary> - [StructLayout(LayoutKind.Sequential, Pack = 0)] - internal struct PortableObjectHeader : IEquatable<PortableObjectHeader> - { - /** Size, equals to sizeof(PortableObjectHeader). */ - public const int Size = 24; - - /** User type flag. */ - public const short FlagUserType = 0x1; - - /** Raw only flag. */ - public const short FlagRawOnly = 0x2; - - /** Byte-sized field offsets flag. */ - public const short FlagByteOffsets = 0x4; - - /** Short-sized field offsets flag. */ - public const short FlagShortOffsets = 0x8; - - /** Actual header layout */ - public readonly byte Header; // Header code, always 103 (HdrFull) - public readonly byte Version; // Protocol version - public readonly short Flags; // Flags - public readonly int TypeId; // Type ID - public readonly int HashCode; // Hash code - public readonly int Length; // Length, including header - public readonly int SchemaId; // Schema ID (Fnv1 of field type ids) - public readonly int SchemaOffset; // Schema offset, or raw offset when RawOnly flag is set. - - /// <summary> - /// Initializes a new instance of the <see cref="PortableObjectHeader" /> struct. - /// </summary> - /// <param name="userType">User type flag.</param> - /// <param name="typeId">Type ID.</param> - /// <param name="hashCode">Hash code.</param> - /// <param name="length">Length.</param> - /// <param name="schemaId">Schema ID.</param> - /// <param name="schemaOffset">Schema offset.</param> - /// <param name="rawOnly">Raw flag.</param> - /// <param name="flags">The flags.</param> - public PortableObjectHeader(bool userType, int typeId, int hashCode, int length, int schemaId, int schemaOffset, - bool rawOnly, short flags) - { - Header = PortableUtils.HdrFull; - Version = PortableUtils.ProtoVer; - - Debug.Assert(schemaOffset <= length); - Debug.Assert(schemaOffset >= Size); - - if (userType) - flags |= FlagUserType; - - if (rawOnly) - flags |= FlagRawOnly; - - Flags = flags; - - TypeId = typeId; - HashCode = hashCode; - Length = length; - SchemaId = schemaId; - SchemaOffset = schemaOffset; - } - - /// <summary> - /// Initializes a new instance of the <see cref="PortableObjectHeader"/> struct from specified stream. - /// </summary> - /// <param name="stream">The stream.</param> - private PortableObjectHeader(IPortableStream stream) - { - Header = stream.ReadByte(); - Version = stream.ReadByte(); - Flags = stream.ReadShort(); - Length = stream.ReadInt(); - TypeId = stream.ReadInt(); - HashCode = stream.ReadInt(); - SchemaId = stream.ReadInt(); - SchemaOffset = stream.ReadInt(); - } - - /// <summary> - /// Writes this instance to the specified stream. - /// </summary> - /// <param name="stream">The stream.</param> - private void Write(IPortableStream stream) - { - stream.WriteByte(Header); - stream.WriteByte(Version); - stream.WriteShort(Flags); - stream.WriteInt(Length); - stream.WriteInt(TypeId); - stream.WriteInt(HashCode); - stream.WriteInt(SchemaId); - stream.WriteInt(SchemaOffset); - } - - /// <summary> - /// Gets a user type flag. - /// </summary> - public bool IsUserType - { - get { return (Flags & FlagUserType) == FlagUserType; } - } - - /// <summary> - /// Gets a raw-only flag. - /// </summary> - public bool IsRawOnly - { - get { return (Flags & FlagRawOnly) == FlagRawOnly; } - } - - /// <summary> - /// Gets a value indicating whether this instance has raw offset. - /// </summary> - public bool HasRawOffset - { - get - { - // Remainder => raw offset is the very last 4 bytes in object. - return !IsRawOnly && ((Length - SchemaOffset) % SchemaFieldSize) == 4; - } - } - - /// <summary> - /// Gets the size of the schema field offset (1, 2 or 4 bytes). - /// </summary> - public int SchemaFieldOffsetSize - { - get - { - if ((Flags & FlagByteOffsets) == FlagByteOffsets) - return 1; - - if ((Flags & FlagShortOffsets) == FlagShortOffsets) - return 2; - - return 4; - } - } - - /// <summary> - /// Gets the size of the schema field. - /// </summary> - public int SchemaFieldSize - { - get { return SchemaFieldOffsetSize + 4; } - } - - /// <summary> - /// Gets the schema field count. - /// </summary> - public int SchemaFieldCount - { - get - { - if (IsRawOnly) - return 0; - - var schemaSize = Length - SchemaOffset; - - return schemaSize / SchemaFieldSize; - } - } - - /// <summary> - /// Gets the raw offset of this object in specified stream. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="position">The position.</param> - /// <returns>Raw offset.</returns> - public int GetRawOffset(IPortableStream stream, int position) - { - Debug.Assert(stream != null); - - if (!HasRawOffset) - return SchemaOffset; - - stream.Seek(position + Length - 4, SeekOrigin.Begin); - - return stream.ReadInt(); - } - - /// <summary> - /// Reads the schema as dictionary according to this header data. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="position">The position.</param> - /// <returns>Schema.</returns> - public Dictionary<int, int> ReadSchemaAsDictionary(IPortableStream stream, int position) - { - Debug.Assert(stream != null); - - var schemaSize = SchemaFieldCount; - - if (schemaSize == 0) - return null; - - stream.Seek(position + SchemaOffset, SeekOrigin.Begin); - - var schema = new Dictionary<int, int>(schemaSize); - - var offsetSize = SchemaFieldOffsetSize; - - if (offsetSize == 1) - { - for (var i = 0; i < schemaSize; i++) - schema.Add(stream.ReadInt(), stream.ReadByte()); - } - else if (offsetSize == 2) - { - for (var i = 0; i < schemaSize; i++) - schema.Add(stream.ReadInt(), stream.ReadShort()); - } - else - { - for (var i = 0; i < schemaSize; i++) - schema.Add(stream.ReadInt(), stream.ReadInt()); - } - - return schema; - } - - /// <summary> - /// Reads the schema according to this header data. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="position">The position.</param> - /// <returns>Schema.</returns> - public PortableObjectSchemaField[] ReadSchema(IPortableStream stream, int position) - { - Debug.Assert(stream != null); - - var schemaSize = SchemaFieldCount; - - if (schemaSize == 0) - return null; - - stream.Seek(position + SchemaOffset, SeekOrigin.Begin); - - var schema = new PortableObjectSchemaField[schemaSize]; - - var offsetSize = SchemaFieldOffsetSize; - - if (offsetSize == 1) - { - for (var i = 0; i < schemaSize; i++) - schema[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadByte()); - } - else if (offsetSize == 2) - { - for (var i = 0; i < schemaSize; i++) - schema[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadShort()); - } - else - { - for (var i = 0; i < schemaSize; i++) - schema[i] = new PortableObjectSchemaField(stream.ReadInt(), stream.ReadInt()); - } - - return schema; - } - - /// <summary> - /// Writes an array of fields to a stream. - /// </summary> - /// <param name="fields">Fields.</param> - /// <param name="stream">Stream.</param> - /// <param name="offset">Offset in the array.</param> - /// <param name="count">Field count to write.</param> - /// <returns> - /// Flags according to offset sizes: <see cref="PortableObjectHeader.FlagByteOffsets" />, - /// <see cref="PortableObjectHeader.FlagShortOffsets" />, or 0. - /// </returns> - public static unsafe short WriteSchema(PortableObjectSchemaField[] fields, IPortableStream stream, int offset, - int count) - { - Debug.Assert(fields != null); - Debug.Assert(stream != null); - Debug.Assert(count > 0); - Debug.Assert(offset >= 0); - Debug.Assert(offset < fields.Length); - - unchecked - { - // Last field is the farthest in the stream - var maxFieldOffset = fields[offset + count - 1].Offset; - - if (maxFieldOffset <= byte.MaxValue) - { - for (int i = offset; i < count + offset; i++) - { - var field = fields[i]; - - stream.WriteInt(field.Id); - stream.WriteByte((byte)field.Offset); - } - - return FlagByteOffsets; - } - - if (maxFieldOffset <= ushort.MaxValue) - { - for (int i = offset; i < count + offset; i++) - { - var field = fields[i]; - - stream.WriteInt(field.Id); - - stream.WriteShort((short)field.Offset); - } - - return FlagShortOffsets; - } - - if (BitConverter.IsLittleEndian) - { - fixed (PortableObjectSchemaField* ptr = &fields[offset]) - { - stream.Write((byte*)ptr, count / PortableObjectSchemaField.Size); - } - } - else - { - for (int i = offset; i < count + offset; i++) - { - var field = fields[i]; - - stream.WriteInt(field.Id); - stream.WriteInt(field.Offset); - } - } - - return 0; - } - - } - - /// <summary> - /// Writes specified header to a stream. - /// </summary> - /// <param name="header">The header.</param> - /// <param name="stream">The stream.</param> - /// <param name="position">The position.</param> - public static unsafe void Write(PortableObjectHeader header, IPortableStream stream, int position) - { - Debug.Assert(stream != null); - Debug.Assert(position >= 0); - - stream.Seek(position, SeekOrigin.Begin); - - if (BitConverter.IsLittleEndian) - stream.Write((byte*) &header, Size); - else - header.Write(stream); - } - - /// <summary> - /// Reads an instance from stream. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="position">The position.</param> - /// <returns>Instance of the header.</returns> - public static unsafe PortableObjectHeader Read(IPortableStream stream, int position) - { - Debug.Assert(stream != null); - Debug.Assert(position >= 0); - - stream.Seek(position, SeekOrigin.Begin); - - if (BitConverter.IsLittleEndian) - { - var hdr = new PortableObjectHeader(); - - stream.Read((byte*) &hdr, Size); - - Debug.Assert(hdr.Version == PortableUtils.ProtoVer); - Debug.Assert(hdr.SchemaOffset <= hdr.Length); - Debug.Assert(hdr.SchemaOffset >= Size); - - // Only one of the flags can be set - var f = hdr.Flags; - Debug.Assert((f & (FlagShortOffsets | FlagByteOffsets)) != (FlagShortOffsets | FlagByteOffsets)); - - return hdr; - } - - return new PortableObjectHeader(stream); - } - - /** <inheritdoc> */ - public bool Equals(PortableObjectHeader other) - { - return Header == other.Header && - Version == other.Version && - Flags == other.Flags && - TypeId == other.TypeId && - HashCode == other.HashCode && - Length == other.Length && - SchemaId == other.SchemaId && - SchemaOffset == other.SchemaOffset; - } - - /** <inheritdoc> */ - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - - return obj is PortableObjectHeader && Equals((PortableObjectHeader) obj); - } - - /** <inheritdoc> */ - public override int GetHashCode() - { - unchecked - { - var hashCode = Header.GetHashCode(); - hashCode = (hashCode*397) ^ Version.GetHashCode(); - hashCode = (hashCode*397) ^ Flags.GetHashCode(); - hashCode = (hashCode*397) ^ TypeId; - hashCode = (hashCode*397) ^ HashCode; - hashCode = (hashCode*397) ^ Length; - hashCode = (hashCode*397) ^ SchemaId; - hashCode = (hashCode*397) ^ SchemaOffset; - return hashCode; - } - } - - /** <inheritdoc> */ - public static bool operator ==(PortableObjectHeader left, PortableObjectHeader right) - { - return left.Equals(right); - } - - /** <inheritdoc> */ - public static bool operator !=(PortableObjectHeader left, PortableObjectHeader right) - { - return !left.Equals(right); - } - } -}
http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs deleted file mode 100644 index 51ae34e..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchema.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System.Collections.Generic; - - /// <summary> - /// Holds and manages portable object schemas for a specific type. - /// </summary> - internal class PortableObjectSchema - { - /** First schema id. */ - private volatile int _schemaId1; - - /** First schema. */ - private volatile int[] _schema1; - - /** Second schema id. */ - private volatile int _schemaId2; - - /** Second schema. */ - private volatile int[] _schema2; - - /** Other schemas. */ - private volatile Dictionary<int, int[]> _schemas; - - /// <summary> - /// Gets the schema by id. - /// </summary> - /// <param name="id">Schema id.</param> - /// <returns>Schema or null.</returns> - public int[] Get(int id) - { - if (_schemaId1 == id) - return _schema1; - - if (_schemaId2 == id) - return _schema2; - - int[] res; - - if (_schemas != null && _schemas.TryGetValue(id, out res)) - return res; - - return null; - } - - /// <summary> - /// Adds the schema. - /// </summary> - /// <param name="id">Schema id.</param> - /// <param name="schema">Schema.</param> - public void Add(int id, int[] schema) - { - lock (this) - { - if (_schemaId1 == id || _schemaId2 == id || (_schemas != null && _schemas.ContainsKey(id))) - return; - - if (_schema1 == null) - { - _schemaId1 = id; - _schema1 = schema; - } - else if (_schema2 == null) - { - _schemaId2 = id; - _schema2 = schema; - } - else - { - var schemas = _schemas == null - ? new Dictionary<int, int[]>() - : new Dictionary<int, int[]>(_schemas); - - schemas.Add(id, schema); - - _schemas = schemas; - } - } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs deleted file mode 100644 index bc18191..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaField.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System.Runtime.InteropServices; - - /// <summary> - /// Portable schema field DTO (as it is stored in a stream). - /// </summary> - [StructLayout(LayoutKind.Sequential, Pack = 0)] - internal struct PortableObjectSchemaField - { - /* Field ID */ - public readonly int Id; - - /** Offset. */ - public readonly int Offset; - - /** Size, equals to sizeof(PortableObjectSchemaField) */ - public const int Size = 8; - - /// <summary> - /// Initializes a new instance of the <see cref="PortableObjectSchemaField"/> struct. - /// </summary> - /// <param name="id">The id.</param> - /// <param name="offset">The offset.</param> - public PortableObjectSchemaField(int id, int offset) - { - Id = id; - Offset = offset; - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaHolder.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaHolder.cs deleted file mode 100644 index 3e99b6e..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableObjectSchemaHolder.cs +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System; - using System.Threading; - using Apache.Ignite.Core.Impl.Common; - using Apache.Ignite.Core.Impl.Portable.IO; - - /// <summary> - /// Shared schema holder. - /// </summary> - internal class PortableObjectSchemaHolder - { - /** Current schema. */ - private static readonly ThreadLocal<PortableObjectSchemaHolder> CurrentHolder = - new ThreadLocal<PortableObjectSchemaHolder>(() => new PortableObjectSchemaHolder()); - - /** Fields. */ - private PortableObjectSchemaField[] _fields = new PortableObjectSchemaField[32]; - - /** Current field index. */ - private int _idx; - - /// <summary> - /// Gets the schema holder for the current thread. - /// </summary> - public static PortableObjectSchemaHolder Current - { - get { return CurrentHolder.Value; } - } - - /// <summary> - /// Adds a field to the holder. - /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="offset">The offset.</param> - public void PushField(int id, int offset) - { - if (_idx == _fields.Length) - Array.Resize(ref _fields, _fields.Length * 2); - - _fields[_idx] = new PortableObjectSchemaField(id, offset); - - _idx++; - } - - /// <summary> - /// Gets the start of a new schema - /// </summary> - public int PushSchema() - { - return _idx; - } - - /// <summary> - /// Resets schema position to specified index. - /// </summary> - public void PopSchema(int idx) - { - _idx = idx; - } - - /// <summary> - /// Writes collected schema to the stream and pops it. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="schemaOffset">The schema offset.</param> - /// <param name="schemaId">The schema identifier.</param> - /// <param name="flags">Flags according to offset sizes: <see cref="PortableObjectHeader.FlagByteOffsets" />, - /// <see cref="PortableObjectHeader.FlagShortOffsets" />, or 0.</param> - /// <returns> - /// True if current schema was non empty; false otherwise. - /// </returns> - public bool WriteSchema(IPortableStream stream, int schemaOffset, out int schemaId, out short flags) - { - schemaId = Fnv1Hash.Basis; - flags = 0; - - var count = _idx - schemaOffset; - - if (count == 0) - return false; - - flags = PortableObjectHeader.WriteSchema(_fields, stream, schemaOffset, count); - - for (var i = schemaOffset; i < _idx; i++) - schemaId = Fnv1Hash.Update(schemaId, _fields[i].Id); - - return true; - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs deleted file mode 100644 index 3f0de91..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System.Collections.Generic; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Reader extensions. - /// </summary> - internal static class PortableReaderExtensions - { - /// <summary> - /// Reads untyped collection as a generic list. - /// </summary> - /// <typeparam name="T">Type of list element.</typeparam> - /// <param name="reader">The reader.</param> - /// <returns>Resulting generic list.</returns> - public static List<T> ReadCollectionAsList<T>(this IPortableRawReader reader) - { - return ((List<T>) reader.ReadCollection(size => new List<T>(size), - (col, elem) => ((List<T>) col).Add((T) elem))); - } - - /// <summary> - /// Reads untyped dictionary as generic dictionary. - /// </summary> - /// <typeparam name="TKey">The type of the key.</typeparam> - /// <typeparam name="TValue">The type of the value.</typeparam> - /// <param name="reader">The reader.</param> - /// <returns>Resulting dictionary.</returns> - public static Dictionary<TKey, TValue> ReadDictionaryAsGeneric<TKey, TValue>(this IPortableRawReader reader) - { - return (Dictionary<TKey, TValue>) reader.ReadDictionary(size => new Dictionary<TKey, TValue>(size)); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderHandleDictionary.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderHandleDictionary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderHandleDictionary.cs deleted file mode 100644 index 6a765c3..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderHandleDictionary.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - /// <summary> - /// Object handle dictionary for PortableReader. - /// </summary> - internal class PortableReaderHandleDictionary : PortableHandleDictionary<int, object> - { - /// <summary> - /// Constructor with initial key-value pair. - /// </summary> - /// <param name="key">Key.</param> - /// <param name="val">Value.</param> - public PortableReaderHandleDictionary(int key, object val) - : base(key, val) - { - // No-op. - } - - /** <inheritdoc /> */ - protected override int EmptyKey - { - get { return -1; } - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs deleted file mode 100644 index 2b7ddb8..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs +++ /dev/null @@ -1,940 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Runtime.Serialization; - using Apache.Ignite.Core.Impl.Common; - using Apache.Ignite.Core.Impl.Portable.IO; - using Apache.Ignite.Core.Impl.Portable.Structure; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Portable reader implementation. - /// </summary> - internal class PortableReaderImpl : IPortableReader, IPortableRawReader - { - /** Marshaller. */ - private readonly PortableMarshaller _marsh; - - /** Type descriptors. */ - private readonly IDictionary<long, IPortableTypeDescriptor> _descs; - - /** Parent builder. */ - private readonly PortableBuilderImpl _builder; - - /** Handles. */ - private PortableReaderHandleDictionary _hnds; - - /** Current position. */ - private int _curPos; - - /** Current raw flag. */ - private bool _curRaw; - - /** Detach flag. */ - private bool _detach; - - /** Portable read mode. */ - private PortableMode _mode; - - /** Current type structure tracker. */ - private PortableStructureTracker _curStruct; - - /** Current schema. */ - private int[] _curSchema; - - /** Current schema with positions. */ - private Dictionary<int, int> _curSchemaMap; - - /** Current header. */ - private PortableObjectHeader _curHdr; - - /// <summary> - /// Constructor. - /// </summary> - /// <param name="marsh">Marshaller.</param> - /// <param name="descs">Descriptors.</param> - /// <param name="stream">Input stream.</param> - /// <param name="mode">The mode.</param> - /// <param name="builder">Builder.</param> - public PortableReaderImpl - (PortableMarshaller marsh, - IDictionary<long, IPortableTypeDescriptor> descs, - IPortableStream stream, - PortableMode mode, - PortableBuilderImpl builder) - { - _marsh = marsh; - _descs = descs; - _mode = mode; - _builder = builder; - - Stream = stream; - } - - /// <summary> - /// Gets the marshaller. - /// </summary> - public PortableMarshaller Marshaller - { - get { return _marsh; } - } - - /** <inheritdoc /> */ - public IPortableRawReader GetRawReader() - { - MarkRaw(); - - return this; - } - - /** <inheritdoc /> */ - public bool ReadBoolean(string fieldName) - { - return ReadField(fieldName, r => r.ReadBoolean(), PortableUtils.TypeBool); - } - - /** <inheritdoc /> */ - public bool ReadBoolean() - { - return Stream.ReadBool(); - } - - /** <inheritdoc /> */ - public bool[] ReadBooleanArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadBooleanArray, PortableUtils.TypeArrayBool); - } - - /** <inheritdoc /> */ - public bool[] ReadBooleanArray() - { - return Read(PortableUtils.ReadBooleanArray, PortableUtils.TypeArrayBool); - } - - /** <inheritdoc /> */ - public byte ReadByte(string fieldName) - { - return ReadField(fieldName, ReadByte, PortableUtils.TypeByte); - } - - /** <inheritdoc /> */ - public byte ReadByte() - { - return Stream.ReadByte(); - } - - /** <inheritdoc /> */ - public byte[] ReadByteArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadByteArray, PortableUtils.TypeArrayByte); - } - - /** <inheritdoc /> */ - public byte[] ReadByteArray() - { - return Read(PortableUtils.ReadByteArray, PortableUtils.TypeArrayByte); - } - - /** <inheritdoc /> */ - public short ReadShort(string fieldName) - { - return ReadField(fieldName, ReadShort, PortableUtils.TypeShort); - } - - /** <inheritdoc /> */ - public short ReadShort() - { - return Stream.ReadShort(); - } - - /** <inheritdoc /> */ - public short[] ReadShortArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadShortArray, PortableUtils.TypeArrayShort); - } - - /** <inheritdoc /> */ - public short[] ReadShortArray() - { - return Read(PortableUtils.ReadShortArray, PortableUtils.TypeArrayShort); - } - - /** <inheritdoc /> */ - public char ReadChar(string fieldName) - { - return ReadField(fieldName, ReadChar, PortableUtils.TypeChar); - } - - /** <inheritdoc /> */ - public char ReadChar() - { - return Stream.ReadChar(); - } - - /** <inheritdoc /> */ - public char[] ReadCharArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadCharArray, PortableUtils.TypeArrayChar); - } - - /** <inheritdoc /> */ - public char[] ReadCharArray() - { - return Read(PortableUtils.ReadCharArray, PortableUtils.TypeArrayChar); - } - - /** <inheritdoc /> */ - public int ReadInt(string fieldName) - { - return ReadField(fieldName, ReadInt, PortableUtils.TypeInt); - } - - /** <inheritdoc /> */ - public int ReadInt() - { - return Stream.ReadInt(); - } - - /** <inheritdoc /> */ - public int[] ReadIntArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadIntArray, PortableUtils.TypeArrayInt); - } - - /** <inheritdoc /> */ - public int[] ReadIntArray() - { - return Read(PortableUtils.ReadIntArray, PortableUtils.TypeArrayInt); - } - - /** <inheritdoc /> */ - public long ReadLong(string fieldName) - { - return ReadField(fieldName, ReadLong, PortableUtils.TypeLong); - } - - /** <inheritdoc /> */ - public long ReadLong() - { - return Stream.ReadLong(); - } - - /** <inheritdoc /> */ - public long[] ReadLongArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadLongArray, PortableUtils.TypeArrayLong); - } - - /** <inheritdoc /> */ - public long[] ReadLongArray() - { - return Read(PortableUtils.ReadLongArray, PortableUtils.TypeArrayLong); - } - - /** <inheritdoc /> */ - public float ReadFloat(string fieldName) - { - return ReadField(fieldName, ReadFloat, PortableUtils.TypeFloat); - } - - /** <inheritdoc /> */ - public float ReadFloat() - { - return Stream.ReadFloat(); - } - - /** <inheritdoc /> */ - public float[] ReadFloatArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadFloatArray, PortableUtils.TypeArrayFloat); - } - - /** <inheritdoc /> */ - public float[] ReadFloatArray() - { - return Read(PortableUtils.ReadFloatArray, PortableUtils.TypeArrayFloat); - } - - /** <inheritdoc /> */ - public double ReadDouble(string fieldName) - { - return ReadField(fieldName, ReadDouble, PortableUtils.TypeDouble); - } - - /** <inheritdoc /> */ - public double ReadDouble() - { - return Stream.ReadDouble(); - } - - /** <inheritdoc /> */ - public double[] ReadDoubleArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadDoubleArray, PortableUtils.TypeArrayDouble); - } - - /** <inheritdoc /> */ - public double[] ReadDoubleArray() - { - return Read(PortableUtils.ReadDoubleArray, PortableUtils.TypeArrayDouble); - } - - /** <inheritdoc /> */ - public decimal? ReadDecimal(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadDecimal, PortableUtils.TypeDecimal); - } - - /** <inheritdoc /> */ - public decimal? ReadDecimal() - { - return Read(PortableUtils.ReadDecimal, PortableUtils.TypeDecimal); - } - - /** <inheritdoc /> */ - public decimal?[] ReadDecimalArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadDecimalArray, PortableUtils.TypeArrayDecimal); - } - - /** <inheritdoc /> */ - public decimal?[] ReadDecimalArray() - { - return Read(PortableUtils.ReadDecimalArray, PortableUtils.TypeArrayDecimal); - } - - /** <inheritdoc /> */ - public DateTime? ReadTimestamp(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadTimestamp, PortableUtils.TypeTimestamp); - } - - /** <inheritdoc /> */ - public DateTime? ReadTimestamp() - { - return Read(PortableUtils.ReadTimestamp, PortableUtils.TypeTimestamp); - } - - /** <inheritdoc /> */ - public DateTime?[] ReadTimestampArray(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadTimestampArray, PortableUtils.TypeArrayTimestamp); - } - - /** <inheritdoc /> */ - public DateTime?[] ReadTimestampArray() - { - return Read(PortableUtils.ReadTimestampArray, PortableUtils.TypeArrayTimestamp); - } - - /** <inheritdoc /> */ - public string ReadString(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadString, PortableUtils.TypeString); - } - - /** <inheritdoc /> */ - public string ReadString() - { - return Read(PortableUtils.ReadString, PortableUtils.TypeString); - } - - /** <inheritdoc /> */ - public string[] ReadStringArray(string fieldName) - { - return ReadField(fieldName, r => PortableUtils.ReadArray<string>(r, false), PortableUtils.TypeArrayString); - } - - /** <inheritdoc /> */ - public string[] ReadStringArray() - { - return Read(r => PortableUtils.ReadArray<string>(r, false), PortableUtils.TypeArrayString); - } - - /** <inheritdoc /> */ - public Guid? ReadGuid(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadGuid, PortableUtils.TypeGuid); - } - - /** <inheritdoc /> */ - public Guid? ReadGuid() - { - return Read(PortableUtils.ReadGuid, PortableUtils.TypeGuid); - } - - /** <inheritdoc /> */ - public Guid?[] ReadGuidArray(string fieldName) - { - return ReadField(fieldName, r => PortableUtils.ReadArray<Guid?>(r, false), PortableUtils.TypeArrayGuid); - } - - /** <inheritdoc /> */ - public Guid?[] ReadGuidArray() - { - return Read(r => PortableUtils.ReadArray<Guid?>(r, false), PortableUtils.TypeArrayGuid); - } - - /** <inheritdoc /> */ - public T ReadEnum<T>(string fieldName) - { - return ReadField(fieldName, PortableUtils.ReadEnum<T>, PortableUtils.TypeEnum); - } - - /** <inheritdoc /> */ - public T ReadEnum<T>() - { - return Read(PortableUtils.ReadEnum<T>, PortableUtils.TypeEnum); - } - - /** <inheritdoc /> */ - public T[] ReadEnumArray<T>(string fieldName) - { - return ReadField(fieldName, r => PortableUtils.ReadArray<T>(r, true), PortableUtils.TypeArrayEnum); - } - - /** <inheritdoc /> */ - public T[] ReadEnumArray<T>() - { - return Read(r => PortableUtils.ReadArray<T>(r, true), PortableUtils.TypeArrayEnum); - } - - /** <inheritdoc /> */ - public T ReadObject<T>(string fieldName) - { - if (_curRaw) - throw new PortableException("Cannot read named fields after raw data is read."); - - if (SeekField(fieldName)) - return Deserialize<T>(); - - return default(T); - } - - /** <inheritdoc /> */ - public T ReadObject<T>() - { - return Deserialize<T>(); - } - - /** <inheritdoc /> */ - public T[] ReadArray<T>(string fieldName) - { - return ReadField(fieldName, r => PortableUtils.ReadArray<T>(r, true), PortableUtils.TypeArray); - } - - /** <inheritdoc /> */ - public T[] ReadArray<T>() - { - return Read(r => PortableUtils.ReadArray<T>(r, true), PortableUtils.TypeArray); - } - - /** <inheritdoc /> */ - public ICollection ReadCollection(string fieldName) - { - return ReadCollection(fieldName, null, null); - } - - /** <inheritdoc /> */ - public ICollection ReadCollection() - { - return ReadCollection(null, null); - } - - /** <inheritdoc /> */ - public ICollection ReadCollection(string fieldName, PortableCollectionFactory factory, - PortableCollectionAdder adder) - { - return ReadField(fieldName, r => PortableUtils.ReadCollection(r, factory, adder), PortableUtils.TypeCollection); - } - - /** <inheritdoc /> */ - public ICollection ReadCollection(PortableCollectionFactory factory, - PortableCollectionAdder adder) - { - return Read(r => PortableUtils.ReadCollection(r, factory, adder), PortableUtils.TypeCollection); - } - - /** <inheritdoc /> */ - public IDictionary ReadDictionary(string fieldName) - { - return ReadDictionary(fieldName, null); - } - - /** <inheritdoc /> */ - public IDictionary ReadDictionary() - { - return ReadDictionary((PortableDictionaryFactory)null); - } - - /** <inheritdoc /> */ - public IDictionary ReadDictionary(string fieldName, PortableDictionaryFactory factory) - { - return ReadField(fieldName, r => PortableUtils.ReadDictionary(r, factory), PortableUtils.TypeDictionary); - } - - /** <inheritdoc /> */ - public IDictionary ReadDictionary(PortableDictionaryFactory factory) - { - return Read(r => PortableUtils.ReadDictionary(r, factory), PortableUtils.TypeDictionary); - } - - /// <summary> - /// Enable detach mode for the next object read. - /// </summary> - public void DetachNext() - { - _detach = true; - } - - /// <summary> - /// Deserialize object. - /// </summary> - /// <returns>Deserialized object.</returns> - public T Deserialize<T>() - { - int pos = Stream.Position; - - byte hdr = Stream.ReadByte(); - - var doDetach = _detach; // save detach flag into a var and reset so it does not go deeper - - _detach = false; - - switch (hdr) - { - case PortableUtils.HdrNull: - if (default(T) != null) - throw new PortableException(string.Format("Invalid data on deserialization. " + - "Expected: '{0}' But was: null", typeof (T))); - - return default(T); - - case PortableUtils.HdrHnd: - return ReadHandleObject<T>(pos); - - case PortableUtils.HdrFull: - return ReadFullObject<T>(pos); - - case PortableUtils.TypePortable: - return ReadPortableObject<T>(doDetach); - } - - if (PortableUtils.IsPredefinedType(hdr)) - return PortableSystemHandlers.ReadSystemType<T>(hdr, this); - - throw new PortableException("Invalid header on deserialization [pos=" + pos + ", hdr=" + hdr + ']'); - } - - /// <summary> - /// Reads the portable object. - /// </summary> - private T ReadPortableObject<T>(bool doDetach) - { - var len = Stream.ReadInt(); - - var portableBytesPos = Stream.Position; - - if (_mode != PortableMode.Deserialize) - return TypeCaster<T>.Cast(ReadAsPortable(portableBytesPos, len, doDetach)); - - Stream.Seek(len, SeekOrigin.Current); - - var offset = Stream.ReadInt(); - - var retPos = Stream.Position; - - Stream.Seek(portableBytesPos + offset, SeekOrigin.Begin); - - _mode = PortableMode.KeepPortable; - - try - { - return Deserialize<T>(); - } - finally - { - _mode = PortableMode.Deserialize; - - Stream.Seek(retPos, SeekOrigin.Begin); - } - } - - /// <summary> - /// Reads the portable object in portable form. - /// </summary> - private PortableUserObject ReadAsPortable(int portableBytesPos, int dataLen, bool doDetach) - { - try - { - Stream.Seek(dataLen + portableBytesPos, SeekOrigin.Begin); - - var offs = Stream.ReadInt(); // offset inside data - - var pos = portableBytesPos + offs; - - var hdr = PortableObjectHeader.Read(Stream, pos); - - if (!doDetach) - return new PortableUserObject(_marsh, Stream.GetArray(), pos, hdr); - - Stream.Seek(pos, SeekOrigin.Begin); - - return new PortableUserObject(_marsh, Stream.ReadByteArray(hdr.Length), 0, hdr); - } - finally - { - Stream.Seek(portableBytesPos + dataLen + 4, SeekOrigin.Begin); - } - } - - /// <summary> - /// Reads the full object. - /// </summary> - [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "hashCode")] - private T ReadFullObject<T>(int pos) - { - var hdr = PortableObjectHeader.Read(Stream, pos); - - // Validate protocol version. - PortableUtils.ValidateProtocolVersion(hdr.Version); - - try - { - // Already read this object? - object hndObj; - - if (_hnds != null && _hnds.TryGetValue(pos, out hndObj)) - return (T) hndObj; - - if (hdr.IsUserType && _mode == PortableMode.ForcePortable) - { - PortableUserObject portObj; - - if (_detach) - { - Stream.Seek(pos, SeekOrigin.Begin); - - portObj = new PortableUserObject(_marsh, Stream.ReadByteArray(hdr.Length), 0, hdr); - } - else - portObj = new PortableUserObject(_marsh, Stream.GetArray(), pos, hdr); - - T obj = _builder == null ? TypeCaster<T>.Cast(portObj) : TypeCaster<T>.Cast(_builder.Child(portObj)); - - AddHandle(pos, obj); - - return obj; - } - else - { - // Find descriptor. - IPortableTypeDescriptor desc; - - if (!_descs.TryGetValue(PortableUtils.TypeKey(hdr.IsUserType, hdr.TypeId), out desc)) - throw new PortableException("Unknown type ID: " + hdr.TypeId); - - // Instantiate object. - if (desc.Type == null) - throw new PortableException("No matching type found for object [typeId=" + - desc.TypeId + ", typeName=" + desc.TypeName + ']'); - - // Preserve old frame. - var oldHdr = _curHdr; - int oldPos = _curPos; - var oldStruct = _curStruct; - bool oldRaw = _curRaw; - var oldSchema = _curSchema; - var oldSchemaMap = _curSchemaMap; - - // Set new frame. - _curHdr = hdr; - _curPos = pos; - - _curSchema = desc.Schema.Get(hdr.SchemaId); - - if (_curSchema == null) - { - _curSchema = ReadSchema(); - - desc.Schema.Add(hdr.SchemaId, _curSchema); - } - - _curStruct = new PortableStructureTracker(desc, desc.ReaderTypeStructure); - _curRaw = false; - - // Read object. - Stream.Seek(pos + PortableObjectHeader.Size, SeekOrigin.Begin); - - object obj; - - var sysSerializer = desc.Serializer as IPortableSystemTypeSerializer; - - if (sysSerializer != null) - obj = sysSerializer.ReadInstance(this); - else - { - try - { - obj = FormatterServices.GetUninitializedObject(desc.Type); - - // Save handle. - AddHandle(pos, obj); - } - catch (Exception e) - { - throw new PortableException("Failed to create type instance: " + - desc.Type.AssemblyQualifiedName, e); - } - - desc.Serializer.ReadPortable(obj, this); - } - - _curStruct.UpdateReaderStructure(); - - // Restore old frame. - _curHdr = oldHdr; - _curPos = oldPos; - _curStruct = oldStruct; - _curRaw = oldRaw; - _curSchema = oldSchema; - _curSchemaMap = oldSchemaMap; - - // Process wrappers. We could introduce a common interface, but for only 2 if-else is faster. - var wrappedSerializable = obj as SerializableObjectHolder; - - if (wrappedSerializable != null) - return (T) wrappedSerializable.Item; - - var wrappedDateTime = obj as DateTimeHolder; - - if (wrappedDateTime != null) - return TypeCaster<T>.Cast(wrappedDateTime.Item); - - return (T) obj; - } - } - finally - { - // Advance stream pointer. - Stream.Seek(pos + hdr.Length, SeekOrigin.Begin); - } - } - - /// <summary> - /// Reads the schema. - /// </summary> - private int[] ReadSchema() - { - Stream.Seek(_curPos + _curHdr.SchemaOffset, SeekOrigin.Begin); - - var count = _curHdr.SchemaFieldCount; - - var offsetSize = _curHdr.SchemaFieldOffsetSize; - - var res = new int[count]; - - for (int i = 0; i < count; i++) - { - res[i] = Stream.ReadInt(); - Stream.Seek(offsetSize, SeekOrigin.Current); - } - - return res; - } - /// <summary> - /// Reads the handle object. - /// </summary> - private T ReadHandleObject<T>(int pos) - { - // Get handle position. - int hndPos = pos - Stream.ReadInt(); - - int retPos = Stream.Position; - - try - { - object hndObj; - - if (_builder == null || !_builder.TryGetCachedField(hndPos, out hndObj)) - { - if (_hnds == null || !_hnds.TryGetValue(hndPos, out hndObj)) - { - // No such handler, i.e. we trying to deserialize inner object before deserializing outer. - Stream.Seek(hndPos, SeekOrigin.Begin); - - hndObj = Deserialize<T>(); - } - - // Notify builder that we deserialized object on other location. - if (_builder != null) - _builder.CacheField(hndPos, hndObj); - } - - return (T) hndObj; - } - finally - { - // Position stream to correct place. - Stream.Seek(retPos, SeekOrigin.Begin); - } - } - - /// <summary> - /// Adds a handle to the dictionary. - /// </summary> - /// <param name="pos">Position.</param> - /// <param name="obj">Object.</param> - private void AddHandle(int pos, object obj) - { - if (_hnds == null) - _hnds = new PortableReaderHandleDictionary(pos, obj); - else - _hnds.Add(pos, obj); - } - - /// <summary> - /// Underlying stream. - /// </summary> - public IPortableStream Stream - { - get; - private set; - } - - /// <summary> - /// Mark current output as raw. - /// </summary> - private void MarkRaw() - { - if (!_curRaw) - { - _curRaw = true; - - Stream.Seek(_curPos + _curHdr.GetRawOffset(Stream, _curPos), SeekOrigin.Begin); - } - } - - /// <summary> - /// Determines whether header at current position is HDR_NULL. - /// </summary> - private bool IsNotNullHeader(byte expHdr) - { - var hdr = ReadByte(); - - if (hdr == PortableUtils.HdrNull) - return false; - - if (expHdr != hdr) - throw new PortableException(string.Format("Invalid header on deserialization. " + - "Expected: {0} but was: {1}", expHdr, hdr)); - - return true; - } - - /// <summary> - /// Seeks the field by name, reads header and returns true if field is present and header is not null. - /// </summary> - private bool SeekField(string fieldName, byte expHdr) - { - if (!SeekField(fieldName)) - return false; - - // Expected read order, no need to seek. - return IsNotNullHeader(expHdr); - } - - /// <summary> - /// Seeks the field by name. - /// </summary> - private bool SeekField(string fieldName) - { - if (_curRaw) - throw new PortableException("Cannot read named fields after raw data is read."); - - if (_curHdr.IsRawOnly) - return false; - - var actionId = _curStruct.CurStructAction; - - var fieldId = _curStruct.GetFieldId(fieldName); - - if (_curSchema == null || actionId >= _curSchema.Length || fieldId != _curSchema[actionId]) - { - _curSchema = null; // read order is different, ignore schema for future reads - - _curSchemaMap = _curSchemaMap ?? _curHdr.ReadSchemaAsDictionary(Stream, _curPos); - - int pos; - - if (!_curSchemaMap.TryGetValue(fieldId, out pos)) - return false; - - Stream.Seek(pos, SeekOrigin.Begin); - } - - return true; - } - - /// <summary> - /// Seeks specified field and invokes provided func. - /// </summary> - private T ReadField<T>(string fieldName, Func<IPortableStream, T> readFunc, byte expHdr) - { - return SeekField(fieldName, expHdr) ? readFunc(Stream) : default(T); - } - - /// <summary> - /// Seeks specified field and invokes provided func. - /// </summary> - private T ReadField<T>(string fieldName, Func<PortableReaderImpl, T> readFunc, byte expHdr) - { - return SeekField(fieldName, expHdr) ? readFunc(this) : default(T); - } - - /// <summary> - /// Seeks specified field and invokes provided func. - /// </summary> - private T ReadField<T>(string fieldName, Func<T> readFunc, byte expHdr) - { - return SeekField(fieldName, expHdr) ? readFunc() : default(T); - } - - /// <summary> - /// Reads header and invokes specified func if the header is not null. - /// </summary> - private T Read<T>(Func<PortableReaderImpl, T> readFunc, byte expHdr) - { - return IsNotNullHeader(expHdr) ? readFunc(this) : default(T); - } - - /// <summary> - /// Reads header and invokes specified func if the header is not null. - /// </summary> - private T Read<T>(Func<IPortableStream, T> readFunc, byte expHdr) - { - return IsNotNullHeader(expHdr) ? readFunc(Stream) : default(T); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs deleted file mode 100644 index 4aff797..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs +++ /dev/null @@ -1,440 +0,0 @@ -/* - * 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. - */ - -namespace Apache.Ignite.Core.Impl.Portable -{ - using System; - using System.Collections; - using System.Diagnostics; - using System.Linq.Expressions; - using System.Reflection; - using Apache.Ignite.Core.Common; - using Apache.Ignite.Core.Impl.Common; - using Apache.Ignite.Core.Portable; - - /// <summary> - /// Write action delegate. - /// </summary> - /// <param name="obj">Target object.</param> - /// <param name="writer">Writer.</param> - internal delegate void PortableReflectiveWriteAction(object obj, IPortableWriter writer); - - /// <summary> - /// Read action delegate. - /// </summary> - /// <param name="obj">Target object.</param> - /// <param name="reader">Reader.</param> - internal delegate void PortableReflectiveReadAction(object obj, IPortableReader reader); - - /// <summary> - /// Routines for reflective reads and writes. - /// </summary> - internal static class PortableReflectiveActions - { - /** Method: read enum. */ - private static readonly MethodInfo MthdReadEnum = - typeof(IPortableReader).GetMethod("ReadEnum", new[] { typeof(string) }); - - /** Method: read enum array. */ - private static readonly MethodInfo MthdReadEnumArray = - typeof(IPortableReader).GetMethod("ReadEnumArray", new[] { typeof(string) }); - - /** Method: read array. */ - private static readonly MethodInfo MthdReadObjArray = - typeof(IPortableReader).GetMethod("ReadArray", new[] { typeof(string) }); - - /** Method: read object. */ - private static readonly MethodInfo MthdReadObj= - typeof(IPortableReader).GetMethod("ReadObject", new[] { typeof(string) }); - - /** Method: write enum array. */ - private static readonly MethodInfo MthdWriteEnumArray = - typeof(IPortableWriter).GetMethod("WriteEnumArray"); - - /** Method: write array. */ - private static readonly MethodInfo MthdWriteObjArray = - typeof(IPortableWriter).GetMethod("WriteArray"); - - /** Method: read object. */ - private static readonly MethodInfo MthdWriteObj = - typeof(IPortableWriter).GetMethod("WriteObject"); - - /// <summary> - /// Lookup read/write actions for the given type. - /// </summary> - /// <param name="field">The field.</param> - /// <param name="writeAction">Write action.</param> - /// <param name="readAction">Read action.</param> - public static void TypeActions(FieldInfo field, out PortableReflectiveWriteAction writeAction, - out PortableReflectiveReadAction readAction) - { - var type = field.FieldType; - - if (type.IsPrimitive) - HandlePrimitive(field, out writeAction, out readAction); - else if (type.IsArray) - HandleArray(field, out writeAction, out readAction); - else - HandleOther(field, out writeAction, out readAction); - } - - /// <summary> - /// Handle primitive type. - /// </summary> - /// <param name="field">The field.</param> - /// <param name="writeAction">Write action.</param> - /// <param name="readAction">Read action.</param> - /// <exception cref="IgniteException">Unsupported primitive type: + type.Name</exception> - private static void HandlePrimitive(FieldInfo field, out PortableReflectiveWriteAction writeAction, - out PortableReflectiveReadAction readAction) - { - var type = field.FieldType; - - if (type == typeof(bool)) - { - writeAction = GetWriter<bool>(field, (f, w, o) => w.WriteBoolean(f, o)); - readAction = GetReader(field, (f, r) => r.ReadBoolean(f)); - } - else if (type == typeof(sbyte)) - { - writeAction = GetWriter<sbyte>(field, (f, w, o) => w.WriteByte(f, unchecked((byte) o))); - readAction = GetReader(field, (f, r) => unchecked ((sbyte)r.ReadByte(f))); - } - else if (type == typeof(byte)) - { - writeAction = GetWriter<byte>(field, (f, w, o) => w.WriteByte(f, o)); - readAction = GetReader(field, (f, r) => r.ReadByte(f)); - } - else if (type == typeof(short)) - { - writeAction = GetWriter<short>(field, (f, w, o) => w.WriteShort(f, o)); - readAction = GetReader(field, (f, r) => r.ReadShort(f)); - } - else if (type == typeof(ushort)) - { - writeAction = GetWriter<ushort>(field, (f, w, o) => w.WriteShort(f, unchecked((short) o))); - readAction = GetReader(field, (f, r) => unchecked((ushort) r.ReadShort(f))); - } - else if (type == typeof(char)) - { - writeAction = GetWriter<char>(field, (f, w, o) => w.WriteChar(f, o)); - readAction = GetReader(field, (f, r) => r.ReadChar(f)); - } - else if (type == typeof(int)) - { - writeAction = GetWriter<int>(field, (f, w, o) => w.WriteInt(f, o)); - readAction = GetReader(field, (f, r) => r.ReadInt(f)); - } - else if (type == typeof(uint)) - { - writeAction = GetWriter<uint>(field, (f, w, o) => w.WriteInt(f, unchecked((int) o))); - readAction = GetReader(field, (f, r) => unchecked((uint) r.ReadInt(f))); - } - else if (type == typeof(long)) - { - writeAction = GetWriter<long>(field, (f, w, o) => w.WriteLong(f, o)); - readAction = GetReader(field, (f, r) => r.ReadLong(f)); - } - else if (type == typeof(ulong)) - { - writeAction = GetWriter<ulong>(field, (f, w, o) => w.WriteLong(f, unchecked((long) o))); - readAction = GetReader(field, (f, r) => unchecked((ulong) r.ReadLong(f))); - } - else if (type == typeof(float)) - { - writeAction = GetWriter<float>(field, (f, w, o) => w.WriteFloat(f, o)); - readAction = GetReader(field, (f, r) => r.ReadFloat(f)); - } - else if (type == typeof(double)) - { - writeAction = GetWriter<double>(field, (f, w, o) => w.WriteDouble(f, o)); - readAction = GetReader(field, (f, r) => r.ReadDouble(f)); - } - else - throw new IgniteException("Unsupported primitive type: " + type.Name); - } - - /// <summary> - /// Handle array type. - /// </summary> - /// <param name="field">The field.</param> - /// <param name="writeAction">Write action.</param> - /// <param name="readAction">Read action.</param> - private static void HandleArray(FieldInfo field, out PortableReflectiveWriteAction writeAction, - out PortableReflectiveReadAction readAction) - { - Type elemType = field.FieldType.GetElementType(); - - if (elemType == typeof(bool)) - { - writeAction = GetWriter<bool[]>(field, (f, w, o) => w.WriteBooleanArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadBooleanArray(f)); - } - else if (elemType == typeof(byte)) - { - writeAction = GetWriter<byte[]>(field, (f, w, o) => w.WriteByteArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadByteArray(f)); - } - else if (elemType == typeof(sbyte)) - { - writeAction = GetWriter<sbyte[]>(field, (f, w, o) => w.WriteByteArray(f, (byte[]) (Array) o)); - readAction = GetReader(field, (f, r) => (sbyte[]) (Array) r.ReadByteArray(f)); - } - else if (elemType == typeof(short)) - { - writeAction = GetWriter<short[]>(field, (f, w, o) => w.WriteShortArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadShortArray(f)); - } - else if (elemType == typeof(ushort)) - { - writeAction = GetWriter<ushort[]>(field, (f, w, o) => w.WriteShortArray(f, (short[]) (Array) o)); - readAction = GetReader(field, (f, r) => (ushort[]) (Array) r.ReadShortArray(f)); - } - else if (elemType == typeof(char)) - { - writeAction = GetWriter<char[]>(field, (f, w, o) => w.WriteCharArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadCharArray(f)); - } - else if (elemType == typeof(int)) - { - writeAction = GetWriter<int[]>(field, (f, w, o) => w.WriteIntArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadIntArray(f)); - } - else if (elemType == typeof(uint)) - { - writeAction = GetWriter<uint[]>(field, (f, w, o) => w.WriteIntArray(f, (int[]) (Array) o)); - readAction = GetReader(field, (f, r) => (uint[]) (Array) r.ReadIntArray(f)); - } - else if (elemType == typeof(long)) - { - writeAction = GetWriter<long[]>(field, (f, w, o) => w.WriteLongArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadLongArray(f)); - } - else if (elemType == typeof(ulong)) - { - writeAction = GetWriter<ulong[]>(field, (f, w, o) => w.WriteLongArray(f, (long[]) (Array) o)); - readAction = GetReader(field, (f, r) => (ulong[]) (Array) r.ReadLongArray(f)); - } - else if (elemType == typeof(float)) - { - writeAction = GetWriter<float[]>(field, (f, w, o) => w.WriteFloatArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadFloatArray(f)); - } - else if (elemType == typeof(double)) - { - writeAction = GetWriter<double[]>(field, (f, w, o) => w.WriteDoubleArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadDoubleArray(f)); - } - else if (elemType == typeof(decimal?)) - { - writeAction = GetWriter<decimal?[]>(field, (f, w, o) => w.WriteDecimalArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadDecimalArray(f)); - } - else if (elemType == typeof(string)) - { - writeAction = GetWriter<string[]>(field, (f, w, o) => w.WriteStringArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadStringArray(f)); - } - else if (elemType == typeof(Guid?)) - { - writeAction = GetWriter<Guid?[]>(field, (f, w, o) => w.WriteGuidArray(f, o)); - readAction = GetReader(field, (f, r) => r.ReadGuidArray(f)); - } - else if (elemType.IsEnum) - { - writeAction = GetWriter(field, MthdWriteEnumArray, elemType); - readAction = GetReader(field, MthdReadEnumArray, elemType); - } - else - { - writeAction = GetWriter(field, MthdWriteObjArray, elemType); - readAction = GetReader(field, MthdReadObjArray, elemType); - } - } - - /// <summary> - /// Handle other type. - /// </summary> - /// <param name="field">The field.</param> - /// <param name="writeAction">Write action.</param> - /// <param name="readAction">Read action.</param> - private static void HandleOther(FieldInfo field, out PortableReflectiveWriteAction writeAction, - out PortableReflectiveReadAction readAction) - { - var type = field.FieldType; - - var genericDef = type.IsGenericType ? type.GetGenericTypeDefinition() : null; - - bool nullable = genericDef == typeof(Nullable<>); - - var nullableType = nullable ? type.GetGenericArguments()[0] : null; - - if (type == typeof(decimal)) - { - writeAction = GetWriter<decimal>(field, (f, w, o) => w.WriteDecimal(f, o)); - readAction = GetReader(field, (f, r) => r.ReadDecimal(f)); - } - else if (type == typeof(string)) - { - writeAction = GetWriter<string>(field, (f, w, o) => w.WriteString(f, o)); - readAction = GetReader(field, (f, r) => r.ReadString(f)); - } - else if (type == typeof(Guid)) - { - writeAction = GetWriter<Guid>(field, (f, w, o) => w.WriteGuid(f, o)); - readAction = GetReader(field, (f, r) => r.ReadObject<Guid>(f)); - } - else if (nullable && nullableType == typeof(Guid)) - { - writeAction = GetWriter<Guid?>(field, (f, w, o) => w.WriteGuid(f, o)); - readAction = GetReader(field, (f, r) => r.ReadGuid(f)); - } - else if (type.IsEnum) - { - writeAction = GetWriter<object>(field, (f, w, o) => w.WriteEnum(f, o), true); - readAction = GetReader(field, MthdReadEnum); - } - else if (type == PortableUtils.TypDictionary || type.GetInterface(PortableUtils.TypDictionary.FullName) != null && !type.IsGenericType) - { - writeAction = GetWriter<IDictionary>(field, (f, w, o) => w.WriteDictionary(f, o)); - readAction = GetReader(field, (f, r) => r.ReadDictionary(f)); - } - else if (type == PortableUtils.TypCollection || type.GetInterface(PortableUtils.TypCollection.FullName) != null && !type.IsGenericType) - { - writeAction = GetWriter<ICollection>(field, (f, w, o) => w.WriteCollection(f, o)); - readAction = GetReader(field, (f, r) => r.ReadCollection(f)); - } - else - { - writeAction = GetWriter(field, MthdWriteObj); - readAction = GetReader(field, MthdReadObj); - } - } - - /// <summary> - /// Gets the reader with a specified write action. - /// </summary> - private static PortableReflectiveWriteAction GetWriter<T>(FieldInfo field, - Expression<Action<string, IPortableWriter, T>> write, - bool convertFieldValToObject = false) - { - Debug.Assert(field != null); - Debug.Assert(field.DeclaringType != null); // non-static - - // Get field value - var targetParam = Expression.Parameter(typeof(object)); - var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); - Expression fldExpr = Expression.Field(targetParamConverted, field); - - if (convertFieldValToObject) - fldExpr = Expression.Convert(fldExpr, typeof (object)); - - // Call IPortableWriter method - var writerParam = Expression.Parameter(typeof(IPortableWriter)); - var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); - var writeExpr = Expression.Invoke(write, fldNameParam, writerParam, fldExpr); - - // Compile and return - return Expression.Lambda<PortableReflectiveWriteAction>(writeExpr, targetParam, writerParam).Compile(); - } - - /// <summary> - /// Gets the writer with a specified generic method. - /// </summary> - private static PortableReflectiveWriteAction GetWriter(FieldInfo field, MethodInfo method, - params Type[] genericArgs) - { - Debug.Assert(field != null); - Debug.Assert(field.DeclaringType != null); // non-static - - if (genericArgs.Length == 0) - genericArgs = new[] {field.FieldType}; - - // Get field value - var targetParam = Expression.Parameter(typeof(object)); - var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); - var fldExpr = Expression.Field(targetParamConverted, field); - - // Call IPortableWriter method - var writerParam = Expression.Parameter(typeof(IPortableWriter)); - var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); - var writeMethod = method.MakeGenericMethod(genericArgs); - var writeExpr = Expression.Call(writerParam, writeMethod, fldNameParam, fldExpr); - - // Compile and return - return Expression.Lambda<PortableReflectiveWriteAction>(writeExpr, targetParam, writerParam).Compile(); - } - - /// <summary> - /// Gets the reader with a specified read action. - /// </summary> - private static PortableReflectiveReadAction GetReader<T>(FieldInfo field, - Expression<Func<string, IPortableReader, T>> read) - { - Debug.Assert(field != null); - Debug.Assert(field.DeclaringType != null); // non-static - - // Call IPortableReader method - var readerParam = Expression.Parameter(typeof(IPortableReader)); - var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); - Expression readExpr = Expression.Invoke(read, fldNameParam, readerParam); - - if (typeof(T) != field.FieldType) - readExpr = Expression.Convert(readExpr, field.FieldType); - - // Assign field value - var targetParam = Expression.Parameter(typeof(object)); - var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); - var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParamConverted, - readExpr); - - // Compile and return - return Expression.Lambda<PortableReflectiveReadAction>(assignExpr, targetParam, readerParam).Compile(); - } - - /// <summary> - /// Gets the reader with a specified generic method. - /// </summary> - private static PortableReflectiveReadAction GetReader(FieldInfo field, MethodInfo method, - params Type[] genericArgs) - { - Debug.Assert(field != null); - Debug.Assert(field.DeclaringType != null); // non-static - - if (genericArgs.Length == 0) - genericArgs = new[] {field.FieldType}; - - // Call IPortableReader method - var readerParam = Expression.Parameter(typeof (IPortableReader)); - var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); - var readMethod = method.MakeGenericMethod(genericArgs); - Expression readExpr = Expression.Call(readerParam, readMethod, fldNameParam); - - if (readMethod.ReturnType != field.FieldType) - readExpr = Expression.Convert(readExpr, field.FieldType); - - // Assign field value - var targetParam = Expression.Parameter(typeof(object)); - var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); - var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParamConverted, - readExpr); - - // Compile and return - return Expression.Lambda<PortableReflectiveReadAction>(assignExpr, targetParam, readerParam).Compile(); - } - } -}
