You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/11/11 10:14:47 UTC
[05/25] ignite git commit: IGNITE-1845: Adopted new binary API in
.Net.
http://git-wip-us.apache.org/repos/asf/ignite/blob/894057e5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
deleted file mode 100644
index 773ec23..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
+++ /dev/null
@@ -1,1824 +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.Concurrent;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.IO;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Text;
-
- using Apache.Ignite.Core.Impl.Common;
- using Apache.Ignite.Core.Impl.Portable.IO;
- using Apache.Ignite.Core.Portable;
-
- /**
- * <summary>Utilities for portable serialization.</summary>
- */
- static class PortableUtils
- {
- /** Header of NULL object. */
- public const byte HdrNull = 101;
-
- /** Header of object handle. */
- public const byte HdrHnd = 102;
-
- /** Header of object in fully serialized form. */
- public const byte HdrFull = 103;
-
- /** Protocol versnion. */
- public const byte ProtoVer = 1;
-
- /** Type: object. */
- public const byte TypeObject = HdrFull;
-
- /** Type: unsigned byte. */
- public const byte TypeByte = 1;
-
- /** Type: short. */
- public const byte TypeShort = 2;
-
- /** Type: int. */
- public const byte TypeInt = 3;
-
- /** Type: long. */
- public const byte TypeLong = 4;
-
- /** Type: float. */
- public const byte TypeFloat = 5;
-
- /** Type: double. */
- public const byte TypeDouble = 6;
-
- /** Type: char. */
- public const byte TypeChar = 7;
-
- /** Type: boolean. */
- public const byte TypeBool = 8;
-
- /** Type: decimal. */
- public const byte TypeDecimal = 30;
-
- /** Type: string. */
- public const byte TypeString = 9;
-
- /** Type: GUID. */
- public const byte TypeGuid = 10;
-
- /** Type: date. */
- public const byte TypeTimestamp = 33;
-
- /** Type: unsigned byte array. */
- public const byte TypeArrayByte = 12;
-
- /** Type: short array. */
- public const byte TypeArrayShort = 13;
-
- /** Type: int array. */
- public const byte TypeArrayInt = 14;
-
- /** Type: long array. */
- public const byte TypeArrayLong = 15;
-
- /** Type: float array. */
- public const byte TypeArrayFloat = 16;
-
- /** Type: double array. */
- public const byte TypeArrayDouble = 17;
-
- /** Type: char array. */
- public const byte TypeArrayChar = 18;
-
- /** Type: boolean array. */
- public const byte TypeArrayBool = 19;
-
- /** Type: decimal array. */
- public const byte TypeArrayDecimal = 31;
-
- /** Type: string array. */
- public const byte TypeArrayString = 20;
-
- /** Type: GUID array. */
- public const byte TypeArrayGuid = 21;
-
- /** Type: date array. */
- public const byte TypeArrayTimestamp = 34;
-
- /** Type: object array. */
- public const byte TypeArray = 23;
-
- /** Type: collection. */
- public const byte TypeCollection = 24;
-
- /** Type: map. */
- public const byte TypeDictionary = 25;
-
- /** Type: map entry. */
- public const byte TypeMapEntry = 26;
-
- /** Type: portable object. */
- public const byte TypePortable = 27;
-
- /** Type: enum. */
- public const byte TypeEnum = 28;
-
- /** Type: enum array. */
- public const byte TypeArrayEnum = 29;
-
- /** Type: native job holder. */
- public const byte TypeNativeJobHolder = 77;
-
- /** Type: Ignite proxy. */
- public const byte TypeIgniteProxy = 74;
-
- /** Type: function wrapper. */
- public const byte TypeComputeOutFuncJob = 80;
-
- /** Type: function wrapper. */
- public const byte TypeComputeFuncJob = 81;
-
- /** Type: continuous query remote filter. */
- public const byte TypeContinuousQueryRemoteFilterHolder = 82;
-
- /** Type: Compute out func wrapper. */
- public const byte TypeComputeOutFuncWrapper = 83;
-
- /** Type: Compute func wrapper. */
- public const byte TypeComputeFuncWrapper = 85;
-
- /** Type: Compute job wrapper. */
- public const byte TypeComputeJobWrapper = 86;
-
- /** Type: Serializable wrapper. */
- public const byte TypeSerializableHolder = 87;
-
- /** Type: DateTime wrapper. */
- public const byte TypeDateTimeHolder = 93;
-
- /** Type: action wrapper. */
- public const byte TypeComputeActionJob = 88;
-
- /** Type: entry processor holder. */
- public const byte TypeCacheEntryProcessorHolder = 89;
-
- /** Type: entry predicate holder. */
- public const byte TypeCacheEntryPredicateHolder = 90;
-
- /** Type: message filter holder. */
- public const byte TypeMessageListenerHolder = 92;
-
- /** Type: stream receiver holder. */
- public const byte TypeStreamReceiverHolder = 94;
-
- /** Collection: custom. */
- public const byte CollectionCustom = 0;
-
- /** Collection: array list. */
- public const byte CollectionArrayList = 1;
-
- /** Collection: linked list. */
- public const byte CollectionLinkedList = 2;
-
- /** Collection: hash set. */
- public const byte CollectionHashSet = 3;
-
- /** Collection: hash set. */
- public const byte CollectionLinkedHashSet = 4;
-
- /** Collection: sorted set. */
- public const byte CollectionSortedSet = 5;
-
- /** Collection: concurrent bag. */
- public const byte CollectionConcurrentBag = 6;
-
- /** Map: custom. */
- public const byte MapCustom = 0;
-
- /** Map: hash map. */
- public const byte MapHashMap = 1;
-
- /** Map: linked hash map. */
- public const byte MapLinkedHashMap = 2;
-
- /** Map: sorted map. */
- public const byte MapSortedMap = 3;
-
- /** Map: concurrent hash map. */
- public const byte MapConcurrentHashMap = 4;
-
- /** Byte "0". */
- public const byte ByteZero = 0;
-
- /** Byte "1". */
- public const byte ByteOne = 1;
-
- /** Indicates object array. */
- public const int ObjTypeId = -1;
-
- /** Length of array size. */
- public const int LengthArraySize = 4;
-
- /** Int type. */
- public static readonly Type TypInt = typeof(int);
-
- /** Collection type. */
- public static readonly Type TypCollection = typeof(ICollection);
-
- /** Dictionary type. */
- public static readonly Type TypDictionary = typeof(IDictionary);
-
- /** Ticks for Java epoch. */
- private static readonly long JavaDateTicks = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks;
-
- /** Bindig flags for static search. */
- private static BindingFlags _bindFlagsStatic =
- BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
-
- /** Default poratble marshaller. */
- private static readonly PortableMarshaller Marsh = new PortableMarshaller(null);
-
- /** Method: ReadArray. */
- public static readonly MethodInfo MtdhReadArray =
- typeof(PortableUtils).GetMethod("ReadArray", _bindFlagsStatic);
-
- /** Cached UTF8 encoding. */
- private static readonly Encoding Utf8 = Encoding.UTF8;
-
- /** Cached generic array read funcs. */
- private static readonly CopyOnWriteConcurrentDictionary<Type, Func<PortableReaderImpl, bool, object>>
- ArrayReaders = new CopyOnWriteConcurrentDictionary<Type, Func<PortableReaderImpl, bool, object>>();
-
- /// <summary>
- /// Default marshaller.
- /// </summary>
- public static PortableMarshaller Marshaller
- {
- get { return Marsh; }
- }
-
- /**
- * <summary>Write boolean array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteBooleanArray(bool[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteBoolArray(vals);
- }
-
- /**
- * <summary>Read boolean array.</summary>
- * <param name="stream">Output stream.</param>
- * <returns>Value.</returns>
- */
- public static bool[] ReadBooleanArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- return stream.ReadBoolArray(len);
- }
-
- /**
- * <summary>Write byte array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- * <returns>Length of written data.</returns>
- */
- public static void WriteByteArray(byte[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteByteArray(vals);
- }
-
- /**
- * <summary>Read byte array.</summary>
- * <param name="stream">Output stream.</param>
- * <returns>Value.</returns>
- */
- public static byte[] ReadByteArray(IPortableStream stream)
- {
- return stream.ReadByteArray(stream.ReadInt());
- }
-
- /**
- * <summary>Read byte array.</summary>
- * <param name="stream">Output stream.</param>
- * <returns>Value.</returns>
- */
- public static unsafe sbyte[] ReadSbyteArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- sbyte[] res = new sbyte[len];
-
- fixed (sbyte* res0 = res)
- {
- stream.Read((byte*) res0, len);
- }
-
- return res;
- }
-
- /**
- * <summary>Read byte array.</summary>
- * <param name="data">Data.</param>
- * <param name="pos">Position.</param>
- * <returns>Value.</returns>
- */
- public static byte[] ReadByteArray(byte[] data, int pos) {
- int len = ReadInt(data, pos);
-
- pos += 4;
-
- byte[] res = new byte[len];
-
- Buffer.BlockCopy(data, pos, res, 0, len);
-
- return res;
- }
-
- /**
- * <summary>Write short array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteShortArray(short[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteShortArray(vals);
- }
-
- /**
- * <summary>Read short array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static unsafe ushort[] ReadUshortArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- ushort[] res = new ushort[len];
-
- fixed (ushort* res0 = res)
- {
- stream.Read((byte*) res0, len * 2);
- }
-
- return res;
- }
-
- /**
- * <summary>Read short array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static short[] ReadShortArray(IPortableStream stream)
- {
- return stream.ReadShortArray(stream.ReadInt());
- }
-
- /**
- * <summary>Read int value.</summary>
- * <param name="data">Data array.</param>
- * <param name="pos">Position.</param>
- * <returns>Value.</returns>
- */
- public static int ReadInt(byte[] data, int pos) {
- int val = data[pos];
-
- val |= data[pos + 1] << 8;
- val |= data[pos + 2] << 16;
- val |= data[pos + 3] << 24;
-
- return val;
- }
-
- /**
- * <summary>Read long value.</summary>
- * <param name="data">Data array.</param>
- * <param name="pos">Position.</param>
- * <returns>Value.</returns>
- */
- public static long ReadLong(byte[] data, int pos) {
- long val = (long)(data[pos]) << 0;
-
- val |= (long)(data[pos + 1]) << 8;
- val |= (long)(data[pos + 2]) << 16;
- val |= (long)(data[pos + 3]) << 24;
- val |= (long)(data[pos + 4]) << 32;
- val |= (long)(data[pos + 5]) << 40;
- val |= (long)(data[pos + 6]) << 48;
- val |= (long)(data[pos + 7]) << 56;
-
- return val;
- }
-
- /**
- * <summary>Write int array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteIntArray(int[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteIntArray(vals);
- }
-
- /**
- * <summary>Read int array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static int[] ReadIntArray(IPortableStream stream)
- {
- return stream.ReadIntArray(stream.ReadInt());
- }
-
- /**
- * <summary>Read int array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static unsafe uint[] ReadUintArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- uint[] res = new uint[len];
-
- fixed (uint* res0 = res)
- {
- stream.Read((byte*) res0, len * 4);
- }
-
- return res;
- }
-
- /**
- * <summary>Write long array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteLongArray(long[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteLongArray(vals);
- }
-
- /**
- * <summary>Read long array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static long[] ReadLongArray(IPortableStream stream)
- {
- return stream.ReadLongArray(stream.ReadInt());
- }
-
- /**
- * <summary>Read ulong array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static unsafe ulong[] ReadUlongArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- ulong[] res = new ulong[len];
-
- fixed (ulong* res0 = res)
- {
- stream.Read((byte*) res0, len * 8);
- }
-
- return res;
- }
-
- /**
- * <summary>Write char array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteCharArray(char[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteCharArray(vals);
- }
-
- /**
- * <summary>Read char array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static char[] ReadCharArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- return stream.ReadCharArray(len);
- }
-
- /**
- * <summary>Write float array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteFloatArray(float[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteFloatArray(vals);
- }
-
- /**
- * <summary>Read float array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static float[] ReadFloatArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- return stream.ReadFloatArray(len);
- }
-
- /**
- * <summary>Write double array.</summary>
- * <param name="vals">Value.</param>
- * <param name="stream">Output stream.</param>
- */
- public static void WriteDoubleArray(double[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- stream.WriteDoubleArray(vals);
- }
-
- /**
- * <summary>Read double array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Value.</returns>
- */
- public static double[] ReadDoubleArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- return stream.ReadDoubleArray(len);
- }
-
- /**
- * <summary>Write date.</summary>
- * <param name="val">Date.</param>
- * <param name="stream">Stream.</param>
- */
- public static void WriteTimestamp(DateTime val, IPortableStream stream)
- {
- long high;
- int low;
-
- ToJavaDate(val, out high, out low);
-
- stream.WriteLong(high);
- stream.WriteInt(low);
- }
-
- /**
- * <summary>Read date.</summary>
- * <param name="stream">Stream.</param>
- * <param name="local">Local flag.</param>
- * <returns>Date</returns>
- */
- public static DateTime? ReadTimestamp(IPortableStream stream)
- {
- long high = stream.ReadLong();
- int low = stream.ReadInt();
-
- return new DateTime(JavaDateTicks + high * TimeSpan.TicksPerMillisecond + low / 100, DateTimeKind.Utc);
- }
-
- /// <summary>
- /// Write nullable date array.
- /// </summary>
- /// <param name="vals">Values.</param>
- /// <param name="stream">Stream.</param>
- public static void WriteTimestampArray(DateTime?[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- foreach (DateTime? val in vals)
- {
- if (val.HasValue)
- {
- stream.WriteByte(TypeTimestamp);
-
- WriteTimestamp(val.Value, stream);
- }
- else
- stream.WriteByte(HdrNull);
- }
- }
-
- /**
- * <summary>Write string in UTF8 encoding.</summary>
- * <param name="val">String.</param>
- * <param name="stream">Stream.</param>
- */
- public static unsafe void WriteString(string val, IPortableStream stream)
- {
- int charCnt = val.Length;
-
- fixed (char* chars = val)
- {
- int byteCnt = Utf8.GetByteCount(chars, charCnt);
-
- stream.WriteInt(byteCnt);
-
- stream.WriteString(chars, charCnt, byteCnt, Utf8);
- }
- }
-
- /**
- * <summary>Read string in UTF8 encoding.</summary>
- * <param name="stream">Stream.</param>
- * <returns>String.</returns>
- */
- public static string ReadString(IPortableStream stream)
- {
- byte[] bytes = ReadByteArray(stream);
-
- return bytes != null ? Utf8.GetString(bytes) : null;
- }
-
- /**
- * <summary>Write string array in UTF8 encoding.</summary>
- * <param name="vals">String array.</param>
- * <param name="stream">Stream.</param>
- */
- public static void WriteStringArray(string[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- foreach (string val in vals)
- {
- if (val != null)
- {
- stream.WriteByte(TypeString);
- WriteString(val, stream);
- }
- else
- stream.WriteByte(HdrNull);
- }
- }
-
- /**
- * <summary>Read string array in UTF8 encoding.</summary>
- * <param name="stream">Stream.</param>
- * <returns>String array.</returns>
- */
- public static string[] ReadStringArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- string[] vals = new string[len];
-
- for (int i = 0; i < len; i++)
- vals[i] = ReadString(stream);
-
- return vals;
- }
-
- /**
- * <summary>Write decimal value.</summary>
- * <param name="val">Decimal value.</param>
- * <param name="stream">Stream.</param>
- */
- public static void WriteDecimal(decimal val, IPortableStream stream)
- {
- // Vals are:
- // [0] = lo
- // [1] = mid
- // [2] = high
- // [3] = flags
- int[] vals = decimal.GetBits(val);
-
- // Get start index skipping leading zeros.
- int idx = vals[2] != 0 ? 2 : vals[1] != 0 ? 1 : vals[0] != 0 ? 0 : -1;
-
- // Write scale and negative flag.
- int scale = (vals[3] & 0x00FF0000) >> 16;
-
- stream.WriteInt(((vals[3] & 0x80000000) == 0x80000000) ? (int)((uint)scale | 0x80000000) : scale);
-
- if (idx == -1)
- {
- // Writing zero.
- stream.WriteInt(1);
- stream.WriteByte(0);
- }
- else
- {
- int len = (idx + 1) << 2;
-
- // Write data.
- for (int i = idx; i >= 0; i--)
- {
- int curPart = vals[i];
-
- int part24 = (curPart >> 24) & 0xFF;
- int part16 = (curPart >> 16) & 0xFF;
- int part8 = (curPart >> 8) & 0xFF;
- int part0 = curPart & 0xFF;
-
- if (i == idx)
- {
- // Possibly skipping some values here.
- if (part24 != 0)
- {
- if ((part24 & 0x80) == 0x80)
- {
- stream.WriteInt(len + 1);
-
- stream.WriteByte(ByteZero);
- }
- else
- stream.WriteInt(len);
-
- stream.WriteByte((byte)part24);
- stream.WriteByte((byte)part16);
- stream.WriteByte((byte)part8);
- stream.WriteByte((byte)part0);
- }
- else if (part16 != 0)
- {
- if ((part16 & 0x80) == 0x80)
- {
- stream.WriteInt(len);
-
- stream.WriteByte(ByteZero);
- }
- else
- stream.WriteInt(len - 1);
-
- stream.WriteByte((byte)part16);
- stream.WriteByte((byte)part8);
- stream.WriteByte((byte)part0);
- }
- else if (part8 != 0)
- {
- if ((part8 & 0x80) == 0x80)
- {
- stream.WriteInt(len - 1);
-
- stream.WriteByte(ByteZero);
- }
- else
- stream.WriteInt(len - 2);
-
- stream.WriteByte((byte)part8);
- stream.WriteByte((byte)part0);
- }
- else
- {
- if ((part0 & 0x80) == 0x80)
- {
- stream.WriteInt(len - 2);
-
- stream.WriteByte(ByteZero);
- }
- else
- stream.WriteInt(len - 3);
-
- stream.WriteByte((byte)part0);
- }
- }
- else
- {
- stream.WriteByte((byte)part24);
- stream.WriteByte((byte)part16);
- stream.WriteByte((byte)part8);
- stream.WriteByte((byte)part0);
- }
- }
- }
- }
-
- /**
- * <summary>Read decimal value.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Decimal value.</returns>
- */
- public static decimal? ReadDecimal(IPortableStream stream)
- {
- int scale = stream.ReadInt();
-
- bool neg;
-
- if (scale < 0)
- {
- scale = scale & 0x7FFFFFFF;
-
- neg = true;
- }
- else
- neg = false;
-
- byte[] mag = ReadByteArray(stream);
-
- if (scale < 0 || scale > 28)
- throw new PortableException("Decimal value scale overflow (must be between 0 and 28): " + scale);
-
- if (mag.Length > 13)
- throw new PortableException("Decimal magnitude overflow (must be less than 96 bits): " +
- mag.Length * 8);
-
- if (mag.Length == 13 && mag[0] != 0)
- throw new PortableException("Decimal magnitude overflow (must be less than 96 bits): " +
- mag.Length * 8);
-
- int hi = 0;
- int mid = 0;
- int lo = 0;
-
- int ctr = -1;
-
- for (int i = mag.Length - 12; i < mag.Length; i++)
- {
- if (++ctr == 4)
- {
- mid = lo;
- lo = 0;
- }
- else if (ctr == 8)
- {
- hi = mid;
- mid = lo;
- lo = 0;
- }
-
- if (i >= 0)
- lo = (lo << 8) + mag[i];
- }
-
- return new decimal(lo, mid, hi, neg, (byte)scale);
- }
-
- /**
- * <summary>Write decimal array.</summary>
- * <param name="vals">Decimal array.</param>
- * <param name="stream">Stream.</param>
- */
- public static void WriteDecimalArray(decimal?[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- foreach (var val in vals)
- {
- if (val.HasValue)
- {
- stream.WriteByte(TypeDecimal);
-
- WriteDecimal(val.Value, stream);
- }
- else
- stream.WriteByte(HdrNull);
- }
- }
-
- /**
- * <summary>Read decimal array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>Decimal array.</returns>
- */
- public static decimal?[] ReadDecimalArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- var vals = new decimal?[len];
-
- for (int i = 0; i < len; i++)
- vals[i] = stream.ReadByte() == HdrNull ? null : ReadDecimal(stream);
-
- return vals;
- }
-
- /**
- * <summary>Write GUID.</summary>
- * <param name="val">GUID.</param>
- * <param name="stream">Stream.</param>
- */
- public static unsafe void WriteGuid(Guid val, IPortableStream stream)
- {
- var jguid = new JavaGuid(val);
-
- var ptr = &jguid;
-
- stream.Write((byte*) ptr, 16);
- }
-
- /**
- * <summary>Read GUID.</summary>
- * <param name="stream">Stream.</param>
- * <returns>GUID</returns>
- */
- public static unsafe Guid? ReadGuid(IPortableStream stream)
- {
- JavaGuid jguid;
-
- var ptr = (byte*) &jguid;
-
- stream.Read(ptr, 16);
-
- var dotnetGuid = new GuidAccessor(jguid);
-
- return *(Guid*) (&dotnetGuid);
- }
-
- /// <summary>
- /// Write GUID array.
- /// </summary>
- /// <param name="vals">Values.</param>
- /// <param name="stream">Stream.</param>
- public static void WriteGuidArray(Guid?[] vals, IPortableStream stream)
- {
- stream.WriteInt(vals.Length);
-
- foreach (Guid? val in vals)
- {
- if (val.HasValue)
- {
- stream.WriteByte(TypeGuid);
-
- WriteGuid(val.Value, stream);
- }
- else
- stream.WriteByte(HdrNull);
- }
- }
-
- /**
- * <summary>Read GUID array.</summary>
- * <param name="stream">Stream.</param>
- * <returns>GUID array.</returns>
- */
- public static Guid?[] ReadGuidArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- Guid?[] vals = new Guid?[len];
-
- for (int i = 0; i < len; i++)
- vals[i] = ReadGuid(stream);
-
- return vals;
- }
-
- /// <summary>
- /// Write array.
- /// </summary>
- /// <param name="val">Array.</param>
- /// <param name="ctx">Write context.</param>
- public static void WriteArray(Array val, PortableWriterImpl ctx)
- {
- IPortableStream stream = ctx.Stream;
-
- stream.WriteInt(ObjTypeId);
-
- stream.WriteInt(val.Length);
-
- for (int i = 0; i < val.Length; i++)
- ctx.Write(val.GetValue(i));
- }
-
- /// <summary>
- /// Read array.
- /// </summary>
- /// <param name="ctx">Read context.</param>
- /// <param name="typed">Typed flag.</param>
- /// <param name="elementType">Type of the element.</param>
- /// <returns>Array.</returns>
- public static object ReadTypedArray(PortableReaderImpl ctx, bool typed, Type elementType)
- {
- Func<PortableReaderImpl, bool, object> result;
-
- if (!ArrayReaders.TryGetValue(elementType, out result))
- result = ArrayReaders.GetOrAdd(elementType, t =>
- DelegateConverter.CompileFunc<Func<PortableReaderImpl, bool, object>>(null,
- MtdhReadArray.MakeGenericMethod(t),
- new[] {typeof (PortableReaderImpl), typeof (bool)}, new[] {false, false, true}));
-
- return result(ctx, typed);
- }
-
- /// <summary>
- /// Read array.
- /// </summary>
- /// <param name="ctx">Read context.</param>
- /// <param name="typed">Typed flag.</param>
- /// <returns>Array.</returns>
- public static T[] ReadArray<T>(PortableReaderImpl ctx, bool typed)
- {
- var stream = ctx.Stream;
-
- if (typed)
- stream.ReadInt();
-
- int len = stream.ReadInt();
-
- var vals = new T[len];
-
- for (int i = 0; i < len; i++)
- vals[i] = ctx.Deserialize<T>();
-
- return vals;
- }
-
- /// <summary>
- /// Read timestamp array.
- /// </summary>
- /// <param name="stream">Stream.</param>
- /// <returns>Timestamp array.</returns>
- public static DateTime?[] ReadTimestampArray(IPortableStream stream)
- {
- int len = stream.ReadInt();
-
- DateTime?[] vals = new DateTime?[len];
-
- for (int i = 0; i < len; i++)
- vals[i] = stream.ReadByte() == HdrNull ? null : ReadTimestamp(stream);
-
- return vals;
- }
-
- /**
- * <summary>Write collection.</summary>
- * <param name="val">Value.</param>
- * <param name="ctx">Write context.</param>
- */
- public static void WriteCollection(ICollection val, PortableWriterImpl ctx)
- {
- var valType = val.GetType();
-
- byte colType;
-
- if (valType.IsGenericType)
- {
- var genType = valType.GetGenericTypeDefinition();
-
- if (genType == typeof (List<>))
- colType = CollectionArrayList;
- else if (genType == typeof (LinkedList<>))
- colType = CollectionLinkedList;
- else if (genType == typeof (SortedSet<>))
- colType = CollectionSortedSet;
- else if (genType == typeof (ConcurrentBag<>))
- colType = CollectionConcurrentBag;
- else
- colType = CollectionCustom;
- }
- else
- colType = valType == typeof (ArrayList) ? CollectionArrayList : CollectionCustom;
-
- WriteCollection(val, ctx, colType);
- }
-
- /**
- * <summary>Write non-null collection with known type.</summary>
- * <param name="val">Value.</param>
- * <param name="ctx">Write context.</param>
- * <param name="colType">Collection type.</param>
- */
- public static void WriteCollection(ICollection val, PortableWriterImpl ctx, byte colType)
- {
- ctx.Stream.WriteInt(val.Count);
-
- ctx.Stream.WriteByte(colType);
-
- foreach (object elem in val)
- ctx.Write(elem);
- }
-
- /**
- * <summary>Read collection.</summary>
- * <param name="ctx">Context.</param>
- * <param name="factory">Factory delegate.</param>
- * <param name="adder">Adder delegate.</param>
- * <returns>Collection.</returns>
- */
- public static ICollection ReadCollection(PortableReaderImpl ctx,
- PortableCollectionFactory factory, PortableCollectionAdder adder)
- {
- IPortableStream stream = ctx.Stream;
-
- int len = stream.ReadInt();
-
- byte colType = ctx.Stream.ReadByte();
-
- ICollection res;
-
- if (factory == null)
- {
- if (colType == CollectionLinkedList)
- res = new LinkedList<object>();
- else if (colType == CollectionSortedSet)
- res = new SortedSet<object>();
- else if (colType == CollectionConcurrentBag)
- res = new ConcurrentBag<object>();
- else
- res = new ArrayList(len);
- }
- else
- res = factory.Invoke(len);
-
- if (adder == null)
- adder = (col, elem) => { ((ArrayList) col).Add(elem); };
-
- for (int i = 0; i < len; i++)
- adder.Invoke(res, ctx.Deserialize<object>());
-
- return res;
- }
-
- /**
- * <summary>Write dictionary.</summary>
- * <param name="val">Value.</param>
- * <param name="ctx">Write context.</param>
- */
- public static void WriteDictionary(IDictionary val, PortableWriterImpl ctx)
- {
- var valType = val.GetType();
-
- byte dictType;
-
- if (valType.IsGenericType)
- {
- var genType = valType.GetGenericTypeDefinition();
-
- if (genType == typeof (Dictionary<,>))
- dictType = MapHashMap;
- else if (genType == typeof (SortedDictionary<,>))
- dictType = MapSortedMap;
- else if (genType == typeof (ConcurrentDictionary<,>))
- dictType = MapConcurrentHashMap;
- else
- dictType = MapCustom;
- }
- else
- dictType = valType == typeof (Hashtable) ? MapHashMap : MapCustom;
-
- WriteDictionary(val, ctx, dictType);
- }
-
- /**
- * <summary>Write non-null dictionary with known type.</summary>
- * <param name="val">Value.</param>
- * <param name="ctx">Write context.</param>
- * <param name="dictType">Dictionary type.</param>
- */
- public static void WriteDictionary(IDictionary val, PortableWriterImpl ctx, byte dictType)
- {
- ctx.Stream.WriteInt(val.Count);
-
- ctx.Stream.WriteByte(dictType);
-
- foreach (DictionaryEntry entry in val)
- {
- ctx.Write(entry.Key);
- ctx.Write(entry.Value);
- }
- }
-
- /**
- * <summary>Read dictionary.</summary>
- * <param name="ctx">Context.</param>
- * <param name="factory">Factory delegate.</param>
- * <returns>Dictionary.</returns>
- */
- public static IDictionary ReadDictionary(PortableReaderImpl ctx,
- PortableDictionaryFactory factory)
- {
- IPortableStream stream = ctx.Stream;
-
- int len = stream.ReadInt();
-
- byte colType = ctx.Stream.ReadByte();
-
- IDictionary res;
-
- if (factory == null)
- {
- if (colType == MapSortedMap)
- res = new SortedDictionary<object, object>();
- else if (colType == MapConcurrentHashMap)
- res = new ConcurrentDictionary<object, object>(Environment.ProcessorCount, len);
- else
- res = new Hashtable(len);
- }
- else
- res = factory.Invoke(len);
-
-
- for (int i = 0; i < len; i++)
- {
- object key = ctx.Deserialize<object>();
- object val = ctx.Deserialize<object>();
-
- res[key] = val;
- }
-
- return res;
- }
-
- /**
- * <summary>Write map entry.</summary>
- * <param name="ctx">Write context.</param>
- * <param name="val">Value.</param>
- */
- public static void WriteMapEntry(PortableWriterImpl ctx, DictionaryEntry val)
- {
- ctx.Write(val.Key);
- ctx.Write(val.Value);
- }
-
- /**
- * <summary>Read map entry.</summary>
- * <param name="ctx">Context.</param>
- * <returns>Map entry.</returns>
- */
- public static DictionaryEntry ReadMapEntry(PortableReaderImpl ctx)
- {
- object key = ctx.Deserialize<object>();
- object val = ctx.Deserialize<object>();
-
- return new DictionaryEntry(key, val);
- }
-
- /**
- * <summary>Write portable object.</summary>
- * <param name="stream">Stream.</param>
- * <param name="val">Value.</param>
- */
- public static void WritePortable(IPortableStream stream, PortableUserObject val)
- {
- WriteByteArray(val.Data, stream);
-
- stream.WriteInt(val.Offset);
- }
-
- /// <summary>
- /// Write enum.
- /// </summary>
- /// <param name="stream">Stream.</param>
- /// <param name="val">Value.</param>
- public static void WriteEnum(IPortableStream stream, Enum val)
- {
- if (Enum.GetUnderlyingType(val.GetType()) == TypInt)
- {
- stream.WriteInt(ObjTypeId);
- stream.WriteInt((int) (object) val);
- }
- else
- throw new PortableException("Only Int32 underlying type is supported for enums: " +
- val.GetType().Name);
- }
-
- /// <summary>
- /// Read enum.
- /// </summary>
- /// <param name="stream">Stream.</param>
- /// <returns>Enumeration.</returns>
- public static T ReadEnum<T>(IPortableStream stream)
- {
- if (!typeof(T).IsEnum || Enum.GetUnderlyingType(typeof(T)) == TypInt)
- {
- stream.ReadInt();
-
- return TypeCaster<T>.Cast(stream.ReadInt());
- }
-
- throw new PortableException("Only Int32 underlying type is supported for enums: " +
- typeof (T).Name);
- }
-
- /**
- * <summary>Gets type key.</summary>
- * <param name="userType">User type flag.</param>
- * <param name="typeId">Type ID.</param>
- * <returns>Type key.</returns>
- */
- public static long TypeKey(bool userType, int typeId)
- {
- long res = typeId;
-
- if (userType)
- res |= (long)1 << 32;
-
- return res;
- }
-
- /**
- * <summary>Get string hash code.</summary>
- * <param name="val">Value.</param>
- * <returns>Hash code.</returns>
- */
- public static int GetStringHashCode(string val)
- {
- if (val == null)
- return 0;
-
- int hash = 0;
-
- unchecked
- {
- // ReSharper disable once LoopCanBeConvertedToQuery (performance)
- foreach (var c in val)
- hash = 31 * hash + ('A' <= c && c <= 'Z' ? c | 0x20 : c);
- }
-
- return hash;
- }
-
- public static string CleanFieldName(string fieldName)
- {
- if (fieldName.StartsWith("<", StringComparison.Ordinal)
- && fieldName.EndsWith(">k__BackingField", StringComparison.Ordinal))
- return fieldName.Substring(1, fieldName.IndexOf(">", StringComparison.Ordinal) - 1);
-
- return fieldName;
- }
-
- /**
- * <summary>Check whether this is predefined type.</summary>
- * <param name="hdr">Header.</param>
- * <returns>True is this is one of predefined types with special semantics.</returns>
- */
- public static bool IsPredefinedType(byte hdr)
- {
- switch (hdr)
- {
- case TypeByte:
- case TypeShort:
- case TypeInt:
- case TypeLong:
- case TypeFloat:
- case TypeDouble:
- case TypeChar:
- case TypeBool:
- case TypeDecimal:
- case TypeString:
- case TypeGuid:
- case TypeTimestamp:
- case TypeEnum:
- case TypeArrayByte:
- case TypeArrayShort:
- case TypeArrayInt:
- case TypeArrayLong:
- case TypeArrayFloat:
- case TypeArrayDouble:
- case TypeArrayChar:
- case TypeArrayBool:
- case TypeArrayDecimal:
- case TypeArrayString:
- case TypeArrayGuid:
- case TypeArrayTimestamp:
- case TypeArrayEnum:
- case TypeArray:
- case TypeCollection:
- case TypeDictionary:
- case TypeMapEntry:
- case TypePortable:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * <summary>Convert type name.</summary>
- * <param name="typeName">Type name.</param>
- * <param name="converter">Converter.</param>
- * <returns>Converted name.</returns>
- */
- public static string ConvertTypeName(string typeName, IPortableNameMapper converter)
- {
- var typeName0 = typeName;
-
- try
- {
- if (converter != null)
- typeName = converter.GetTypeName(typeName);
- }
- catch (Exception e)
- {
- throw new PortableException("Failed to convert type name due to converter exception " +
- "[typeName=" + typeName + ", converter=" + converter + ']', e);
- }
-
- if (typeName == null)
- throw new PortableException("Name converter returned null name for type [typeName=" +
- typeName0 + ", converter=" + converter + "]");
-
- return typeName;
- }
-
- /**
- * <summary>Convert field name.</summary>
- * <param name="fieldName">Field name.</param>
- * <param name="converter">Converter.</param>
- * <returns>Converted name.</returns>
- */
- public static string ConvertFieldName(string fieldName, IPortableNameMapper converter)
- {
- var fieldName0 = fieldName;
-
- try
- {
- if (converter != null)
- fieldName = converter.GetFieldName(fieldName);
- }
- catch (Exception e)
- {
- throw new PortableException("Failed to convert field name due to converter exception " +
- "[fieldName=" + fieldName + ", converter=" + converter + ']', e);
- }
-
- if (fieldName == null)
- throw new PortableException("Name converter returned null name for field [fieldName=" +
- fieldName0 + ", converter=" + converter + "]");
-
- return fieldName;
- }
-
- /**
- * <summary>Extract simple type name.</summary>
- * <param name="typeName">Type name.</param>
- * <returns>Simple type name.</returns>
- */
- public static string SimpleTypeName(string typeName)
- {
- int idx = typeName.LastIndexOf('.');
-
- return idx < 0 ? typeName : typeName.Substring(idx + 1);
- }
-
- /**
- * <summary>Resolve type ID.</summary>
- * <param name="typeName">Type name.</param>
- * <param name="nameMapper">Name mapper.</param>
- * <param name="idMapper">ID mapper.</param>
- */
- public static int TypeId(string typeName, IPortableNameMapper nameMapper,
- IPortableIdMapper idMapper)
- {
- Debug.Assert(typeName != null);
-
- typeName = ConvertTypeName(typeName, nameMapper);
-
- int id = 0;
-
- if (idMapper != null)
- {
- try
- {
- id = idMapper.GetTypeId(typeName);
- }
- catch (Exception e)
- {
- throw new PortableException("Failed to resolve type ID due to ID mapper exception " +
- "[typeName=" + typeName + ", idMapper=" + idMapper + ']', e);
- }
- }
-
- if (id == 0)
- id = GetStringHashCode(typeName);
-
- return id;
- }
-
- /**
- * <summary>Resolve field ID.</summary>
- * <param name="typeId">Type ID.</param>
- * <param name="fieldName">Field name.</param>
- * <param name="nameMapper">Name mapper.</param>
- * <param name="idMapper">ID mapper.</param>
- */
- public static int FieldId(int typeId, string fieldName, IPortableNameMapper nameMapper,
- IPortableIdMapper idMapper)
- {
- Debug.Assert(typeId != 0);
- Debug.Assert(fieldName != null);
-
- fieldName = ConvertFieldName(fieldName, nameMapper);
-
- int id = 0;
-
- if (idMapper != null)
- {
- try
- {
- id = idMapper.GetFieldId(typeId, fieldName);
- }
- catch (Exception e)
- {
- throw new PortableException("Failed to resolve field ID due to ID mapper exception " +
- "[typeId=" + typeId + ", fieldName=" + fieldName + ", idMapper=" + idMapper + ']', e);
- }
- }
-
- if (id == 0)
- id = GetStringHashCode(fieldName);
-
- if (id == 0)
- throw new PortableException("Field ID is zero (please provide ID mapper or change field name) " +
- "[typeId=" + typeId + ", fieldName=" + fieldName + ", idMapper=" + idMapper + ']');
-
- return id;
- }
-
- /// <summary>
- /// Compare contents of two byte array chunks.
- /// </summary>
- /// <param name="arr1">Array 1.</param>
- /// <param name="offset1">Offset 1.</param>
- /// <param name="len1">Length 1.</param>
- /// <param name="arr2">Array 2.</param>
- /// <param name="offset2">Offset 2.</param>
- /// <param name="len2">Length 2.</param>
- /// <returns>True if array chunks are equal.</returns>
- public static bool CompareArrays(byte[] arr1, int offset1, int len1, byte[] arr2, int offset2, int len2)
- {
- if (len1 == len2)
- {
- for (int i = 0; i < len1; i++)
- {
- if (arr1[offset1 + i] != arr2[offset2 + i])
- return false;
- }
-
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// Writes invocation result.
- /// </summary>
- /// <param name="writer">Writer.</param>
- /// <param name="success">Success flag.</param>
- /// <param name="res">Result.</param>
- [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- public static void WriteInvocationResult(PortableWriterImpl writer, bool success, object res)
- {
- var pos = writer.Stream.Position;
-
- try
- {
- if (success)
- writer.WriteBoolean(true);
- else
- {
- writer.WriteBoolean(false); // Call failed.
- writer.WriteBoolean(true); // Exception serialized sucessfully.
- }
-
- writer.Write(res);
- }
- catch (Exception marshErr)
- {
- // Failed to serialize result, fallback to plain string.
- writer.Stream.Seek(pos, SeekOrigin.Begin);
-
- writer.WriteBoolean(false); // Call failed.
- writer.WriteBoolean(false); // Cannot serialize result or exception.
-
- if (success)
- {
- writer.WriteString("Call completed successfully, but result serialization failed [resultType=" +
- res.GetType().Name + ", serializationErrMsg=" + marshErr.Message + ']');
- }
- else
- {
- writer.WriteString("Call completed with error, but error serialization failed [errType=" +
- res.GetType().Name + ", serializationErrMsg=" + marshErr.Message + ']');
- }
- }
- }
-
- /// <summary>
- /// Reads invocation result.
- /// </summary>
- /// <param name="reader">Reader.</param>
- /// <param name="err">Error.</param>
- /// <returns>Result.</returns>
- public static object ReadInvocationResult(PortableReaderImpl reader, out object err)
- {
- err = null;
-
- if (reader.ReadBoolean())
- return reader.ReadObject<object>();
-
- err = reader.ReadBoolean()
- ? reader.ReadObject<object>()
- : ExceptionUtils.GetException(reader.ReadString(), reader.ReadString());
-
- return null;
- }
-
- /// <summary>
- /// Validate protocol version.
- /// </summary>
- /// <param name="version">The version.</param>
- public static void ValidateProtocolVersion(byte version)
- {
- if (version != ProtoVer)
- throw new PortableException("Unsupported protocol version: " + version);
- }
-
- /**
- * <summary>Convert date to Java ticks.</summary>
- * <param name="date">Date</param>
- * <param name="high">High part (milliseconds).</param>
- * <param name="low">Low part (nanoseconds)</param>
- */
- private static void ToJavaDate(DateTime date, out long high, out int low)
- {
- if (date.Kind != DateTimeKind.Utc)
- throw new InvalidOperationException(
- "DateTime is not UTC. Only UTC DateTime can be used for interop with other platforms.");
-
- long diff = date.Ticks - JavaDateTicks;
-
- high = diff / TimeSpan.TicksPerMillisecond;
-
- low = (int)(diff % TimeSpan.TicksPerMillisecond) * 100;
- }
-
- /// <summary>
- /// Read additional configuration from the stream.
- /// </summary>
- /// <param name="reader">Reader.</param>
- /// <param name="assemblies">Assemblies.</param>
- /// <param name="cfg">Portable configuration.</param>
- public static void ReadConfiguration(PortableReaderImpl reader, out ICollection<string> assemblies, out PortableConfiguration cfg)
- {
- if (reader.ReadBoolean())
- {
- int assemblyCnt = reader.ReadInt();
-
- assemblies = new List<string>(assemblyCnt);
-
- for (int i = 0; i < assemblyCnt; i++)
- assemblies.Add(reader.ReadObject<string>());
- }
- else
- assemblies = null;
-
- if (reader.ReadBoolean())
- {
- cfg = new PortableConfiguration();
-
- // Read portable types in full form.
- if (reader.ReadBoolean())
- {
- int typesCnt = reader.ReadInt();
-
- cfg.TypeConfigurations = new List<PortableTypeConfiguration>();
-
- for (int i = 0; i < typesCnt; i++)
- {
- cfg.TypeConfigurations.Add(new PortableTypeConfiguration
- {
- TypeName = reader.ReadString(),
- NameMapper = CreateInstance<IPortableNameMapper>(reader),
- IdMapper = CreateInstance<IPortableIdMapper>(reader),
- Serializer = CreateInstance<IPortableSerializer>(reader),
- AffinityKeyFieldName = reader.ReadString(),
- KeepDeserialized = reader.ReadObject<bool?>()
- });
- }
- }
-
- // Read portable types in compact form.
- if (reader.ReadBoolean())
- {
- int typesCnt = reader.ReadInt();
-
- cfg.Types = new List<string>(typesCnt);
-
- for (int i = 0; i < typesCnt; i++)
- cfg.Types.Add(reader.ReadString());
- }
-
- // Read the rest.
- cfg.DefaultNameMapper = CreateInstance<IPortableNameMapper>(reader);
- cfg.DefaultIdMapper = CreateInstance<IPortableIdMapper>(reader);
- cfg.DefaultSerializer = CreateInstance<IPortableSerializer>(reader);
- cfg.DefaultKeepDeserialized = reader.ReadBoolean();
- }
- else
- cfg = null;
- }
-
- /// <summary>
- /// Creates and instance from the type name in reader.
- /// </summary>
- private static T CreateInstance<T>(PortableReaderImpl reader)
- {
- var typeName = reader.ReadString();
-
- if (typeName == null)
- return default(T);
-
- return IgniteUtils.CreateInstance<T>(typeName);
- }
-
- /// <summary>
- /// Reverses the byte order of an unsigned long.
- /// </summary>
- private static ulong ReverseByteOrder(ulong l)
- {
- // Fastest way would be to use bswap processor instruction.
- return ((l >> 56) & 0x00000000000000FF) | ((l >> 40) & 0x000000000000FF00) |
- ((l >> 24) & 0x0000000000FF0000) | ((l >> 8) & 0x00000000FF000000) |
- ((l << 8) & 0x000000FF00000000) | ((l << 24) & 0x0000FF0000000000) |
- ((l << 40) & 0x00FF000000000000) | ((l << 56) & 0xFF00000000000000);
- }
-
- /// <summary>
- /// Struct with .Net-style Guid memory layout.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 0)]
- private struct GuidAccessor
- {
- public readonly ulong ABC;
- public readonly ulong DEGHIJK;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="GuidAccessor"/> struct.
- /// </summary>
- /// <param name="val">The value.</param>
- public GuidAccessor(JavaGuid val)
- {
- var l = val.CBA;
-
- ABC = ((l >> 32) & 0x00000000FFFFFFFF) | ((l << 48) & 0xFFFF000000000000) |
- ((l << 16) & 0x0000FFFF00000000);
-
- DEGHIJK = ReverseByteOrder(val.KJIHGED);
- }
- }
-
- /// <summary>
- /// Struct with Java-style Guid memory layout.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 0)]
- private struct JavaGuid
- {
- public readonly ulong CBA;
- public readonly ulong KJIHGED;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="JavaGuid"/> struct.
- /// </summary>
- /// <param name="val">The value.</param>
- public unsafe JavaGuid(Guid val)
- {
- // .Net returns bytes in the following order: _a(4), _b(2), _c(2), _d, _e, _g, _h, _i, _j, _k.
- // And _a, _b and _c are always in little endian format irrespective of system configuration.
- // To be compliant with Java we rearrange them as follows: _c, _b_, a_, _k, _j, _i, _h, _g, _e, _d.
- var accessor = *((GuidAccessor*)&val);
-
- var l = accessor.ABC;
-
- CBA = ((l << 32) & 0xFFFFFFFF00000000) | ((l >> 48) & 0x000000000000FFFF) |
- ((l >> 16) & 0x00000000FFFF0000);
-
- KJIHGED = ReverseByteOrder(accessor.DEGHIJK);
- }
- }
- }
-}