Пример #1
0
        /// <summary>
        /// ToString implementation.
        /// </summary>
        /// <param name="handled">Already handled objects.</param>
        /// <returns>Object string.</returns>
        private string ToString(IDictionary <int, int> handled)
        {
            int idHash;

            bool alreadyHandled = handled.TryGetValue(_offset, out idHash);

            if (!alreadyHandled)
            {
                idHash = RuntimeHelpers.GetHashCode(this);
            }

            StringBuilder sb;

            IBinaryTypeDescriptor desc = _marsh.GetDescriptor(true, _header.TypeId);

            IBinaryType meta;

            try
            {
                meta = _marsh.GetBinaryType(_header.TypeId);
            }
            catch (IgniteException)
            {
                meta = null;
            }

            if (meta == null)
            {
                sb = new StringBuilder("BinaryObject [typeId=").Append(_header.TypeId).Append(", idHash=" + idHash);
            }
            else
            {
                sb = new StringBuilder(meta.TypeName).Append(" [idHash=" + idHash);

                if (!alreadyHandled)
                {
                    handled[_offset] = idHash;

                    InitializeFields();

                    foreach (string fieldName in meta.Fields)
                    {
                        sb.Append(", ");

                        int fieldId = BinaryUtils.FieldId(_header.TypeId, fieldName, desc.NameMapper, desc.IdMapper);

                        int fieldPos;

                        if (_fields.TryGetValue(fieldId, out fieldPos))
                        {
                            sb.Append(fieldName).Append('=');

                            ToString0(sb, GetField <object>(fieldPos, null), handled);
                        }
                    }
                }
                else
                {
                    sb.Append(", ...");
                }
            }

            sb.Append(']');

            return(sb.ToString());
        }
Пример #2
0
 /** <inheritdoc /> */
 public ICollection ReadCollection(Func <int, ICollection> factory, Action <ICollection, object> adder)
 {
     return(Read(r => BinaryUtils.ReadCollection(r, factory, adder), BinaryUtils.TypeCollection));
 }
Пример #3
0
 /** <inheritdoc /> */
 public IDictionary ReadDictionary(Func <int, IDictionary> factory)
 {
     return(Read(r => BinaryUtils.ReadDictionary(r, factory), BinaryUtils.TypeDictionary));
 }
Пример #4
0
 /** <inheritdoc /> */
 public Guid?[] ReadGuidArray()
 {
     return(Read(r => BinaryUtils.ReadArray <Guid?>(r, false), BinaryUtils.TypeArrayGuid));
 }
Пример #5
0
 /** <inheritdoc /> */
 public T[] ReadArray <T>()
 {
     return(Read(r => BinaryUtils.ReadArray <T>(r, true), BinaryUtils.TypeArray));
 }
Пример #6
0
        /// <summary>
        /// Generate a bundle, given the specification of embedded files
        /// </summary>
        /// <param name="fileSpecs">
        /// An enumeration FileSpecs for the files to be embedded.
        ///
        /// Files in fileSpecs that are not bundled within the single file bundle,
        /// and should be published as separate files are marked as "IsExcluded" by this method.
        /// This doesn't include unbundled files that should be dropped, and not publised as output.
        /// </param>
        /// <returns>
        /// The full path the the generated bundle file
        /// </returns>
        /// <exceptions>
        /// ArgumentException if input is invalid
        /// IOExceptions and ArgumentExceptions from callees flow to the caller.
        /// </exceptions>
        public string GenerateBundle(IReadOnlyList <FileSpec> fileSpecs)
        {
            Tracer.Log($"Bundler Version: {BundlerMajorVersion}.{BundlerMinorVersion}");
            Tracer.Log($"Bundle  Version: {BundleManifest.BundleVersion}");
            Tracer.Log($"Target Runtime: {Target}");
            Tracer.Log($"Bundler Options: {Options}");

            if (fileSpecs.Any(x => !x.IsValid()))
            {
                throw new ArgumentException("Invalid input specification: Found entry with empty source-path or bundle-relative-path.");
            }

            string hostSource;

            try
            {
                hostSource = fileSpecs.Where(x => x.BundleRelativePath.Equals(HostName)).Single().SourcePath;
            }
            catch (InvalidOperationException)
            {
                throw new ArgumentException("Invalid input specification: Must specify the host binary");
            }

            var bundleRelativePathCollision = fileSpecs.GroupBy(file => file.BundleRelativePath).FirstOrDefault(g => g.Count() > 1);

            if (bundleRelativePathCollision != null)
            {
                string fileSpecPaths = string.Join(", ", bundleRelativePathCollision.Select(file => "'" + file.SourcePath + "'"));
                throw new ArgumentException($"Invalid input specification: Found entries {fileSpecPaths} with the same BundleRelativePath '{bundleRelativePathCollision.Key}'");
            }

            string bundlePath = Path.Combine(OutputDir, HostName);

            if (File.Exists(bundlePath))
            {
                Tracer.Log($"Ovewriting existing File {bundlePath}");
            }

            BinaryUtils.CopyFile(hostSource, bundlePath);

            long headerOffset = 0;

            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(bundlePath)))
            {
                Stream bundle = writer.BaseStream;
                bundle.Position = bundle.Length;

                foreach (var fileSpec in fileSpecs)
                {
                    string relativePath = fileSpec.BundleRelativePath;

                    if (IsHost(relativePath))
                    {
                        continue;
                    }

                    if (ShouldIgnore(relativePath))
                    {
                        Tracer.Log($"Ignore: {relativePath}");
                        continue;
                    }

                    FileType type = InferType(fileSpec);

                    if (ShouldExclude(type, relativePath))
                    {
                        Tracer.Log($"Exclude [{type}]: {relativePath}");
                        fileSpec.Excluded = true;
                        continue;
                    }

                    using (FileStream file = File.OpenRead(fileSpec.SourcePath))
                    {
                        FileType targetType = Target.TargetSpecificFileType(type);
                        (long startOffset, long compressedSize) = AddToBundle(bundle, file, targetType);
                        FileEntry entry = BundleManifest.AddEntry(targetType, relativePath, startOffset, file.Length, compressedSize, Target.BundleMajorVersion);
                        Tracer.Log($"Embed: {entry}");
                    }
                }

                // Write the bundle manifest
                headerOffset = BundleManifest.Write(writer);
                Tracer.Log($"Header Offset={headerOffset}");
                Tracer.Log($"Meta-data Size={writer.BaseStream.Position - headerOffset}");
                Tracer.Log($"Bundle: Path={bundlePath}, Size={bundle.Length}");
            }

            HostWriter.SetAsBundle(bundlePath, headerOffset);

            return(bundlePath);
        }
Пример #7
0
 /** <inheritdoc /> */
 public string[] ReadStringArray()
 {
     return(Read(r => BinaryUtils.ReadArray <string>(r, false), BinaryUtils.TypeArrayString));
 }
Пример #8
0
        /// <summary>
        /// Generate a bundle, given the specification of embedded files
        /// </summary>
        /// <param name="fileSpecs">
        /// An enumeration FileSpecs for the files to be embedded.
        /// </param>
        /// <returns>
        /// The full path the the generated bundle file
        /// </returns>
        /// <exceptions>
        /// ArgumentException if input is invalid
        /// IOExceptions and ArgumentExceptions from callees flow to the caller.
        /// </exceptions>
        public string GenerateBundle(IReadOnlyList <FileSpec> fileSpecs)
        {
            trace.Log($"Bundler version {Version}");

            if (fileSpecs.Any(x => !x.IsValid()))
            {
                throw new ArgumentException("Invalid input specification: Found entry with empty source-path or bundle-relative-path.");
            }

            string hostSource;

            try
            {
                hostSource = fileSpecs.Where(x => x.BundleRelativePath.Equals(HostName)).Single().SourcePath;
            }
            catch (InvalidOperationException)
            {
                throw new ArgumentException("Invalid input specification: Must specify the host binary");
            }

            if (fileSpecs.GroupBy(file => file.BundleRelativePath).Where(g => g.Count() > 1).Any())
            {
                throw new ArgumentException("Invalid input specification: Found multiple entries with the same BundleRelativePath");
            }

            string bundlePath = Path.Combine(OutputDir, HostName);

            if (File.Exists(bundlePath))
            {
                trace.Log($"Ovewriting existing File {bundlePath}");
            }

            BinaryUtils.CopyFile(hostSource, bundlePath);

            long headerOffset = 0;

            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(bundlePath)))
            {
                Stream bundle = writer.BaseStream;
                bundle.Position = bundle.Length;

                // Write the files from the specification into the bundle
                foreach (var fileSpec in fileSpecs)
                {
                    if (!ShouldEmbed(fileSpec.BundleRelativePath))
                    {
                        trace.Log($"Skip: {fileSpec.BundleRelativePath}");
                        continue;
                    }

                    using (FileStream file = File.OpenRead(fileSpec.SourcePath))
                    {
                        FileType  type        = InferType(fileSpec.BundleRelativePath, file);
                        long      startOffset = AddToBundle(bundle, file, type);
                        FileEntry entry       = BundleManifest.AddEntry(type, fileSpec.BundleRelativePath, startOffset, file.Length);
                        trace.Log($"Embed: {entry}");
                    }
                }

                // Write the bundle manifest
                headerOffset = BundleManifest.Write(writer);
                trace.Log($"Header Offset={headerOffset}");
                trace.Log($"Meta-data Size={writer.BaseStream.Position - headerOffset}");
                trace.Log($"Bundle: Path={bundlePath}, Size={bundle.Length}");
            }

            HostWriter.SetAsBundle(bundlePath, headerOffset);

            return(bundlePath);
        }
Пример #9
0
 /** <inheritdoc /> */
 public Guid?ReadGuid(string fieldName)
 {
     return(ReadField <Guid?>(fieldName, r => BinaryUtils.ReadGuid(r), BinaryTypeId.Guid));
 }
Пример #10
0
 private long FutureDoubleResult(long futPtr, long res, long unused, void *arg)
 {
     return(ProcessFuture <double>(futPtr, fut => { fut.OnResult(BinaryUtils.LongToDoubleBits(res)); }));
 }
 public Msg_0x0301(LogLevel logLevel, string msg, string destClientName = "") : base(P2PCommandType.Msg0x0301)
 {
     BinaryUtils.Write(Data, logLevel);
     BinaryUtils.Write(Data, msg);
     BinaryUtils.Write(Data, destClientName);
 }
Пример #12
0
 private long FutureFloatResult(long futPtr, long res, long unused, void *arg)
 {
     return(ProcessFuture <float>(futPtr, fut => { fut.OnResult(BinaryUtils.IntToFloatBits((int)res)); }));
 }
Пример #13
0
        /// <summary>
        /// Write primitive type.
        /// </summary>
        /// <param name="val">Object.</param>
        /// <param name="type">Type.</param>
        private unsafe void WritePrimitive <T>(T val, Type type)
        {
            // .Net defines 14 primitive types. We support 12 - excluding IntPtr and UIntPtr.
            // Types check sequence is designed to minimize comparisons for the most frequent types.

            if (type == typeof(int))
            {
                WriteIntField(TypeCaster <int> .Cast(val));
            }
            else if (type == typeof(long))
            {
                WriteLongField(TypeCaster <long> .Cast(val));
            }
            else if (type == typeof(bool))
            {
                WriteBooleanField(TypeCaster <bool> .Cast(val));
            }
            else if (type == typeof(byte))
            {
                WriteByteField(TypeCaster <byte> .Cast(val));
            }
            else if (type == typeof(short))
            {
                WriteShortField(TypeCaster <short> .Cast(val));
            }
            else if (type == typeof(char))
            {
                WriteCharField(TypeCaster <char> .Cast(val));
            }
            else if (type == typeof(float))
            {
                WriteFloatField(TypeCaster <float> .Cast(val));
            }
            else if (type == typeof(double))
            {
                WriteDoubleField(TypeCaster <double> .Cast(val));
            }
            else if (type == typeof(sbyte))
            {
                var val0 = TypeCaster <sbyte> .Cast(val);

                WriteByteField(*(byte *)&val0);
            }
            else if (type == typeof(ushort))
            {
                var val0 = TypeCaster <ushort> .Cast(val);

                WriteShortField(*(short *)&val0);
            }
            else if (type == typeof(uint))
            {
                var val0 = TypeCaster <uint> .Cast(val);

                WriteIntField(*(int *)&val0);
            }
            else if (type == typeof(ulong))
            {
                var val0 = TypeCaster <ulong> .Cast(val);

                WriteLongField(*(long *)&val0);
            }
            else
            {
                throw BinaryUtils.GetUnsupportedTypeException(type, val);
            }
        }
Пример #14
0
        /// <summary>
        /// Write object.
        /// </summary>
        /// <param name="obj">Object.</param>
        public void Write <T>(T obj)
        {
            // Handle special case for null.
            // ReSharper disable once CompareNonConstrainedGenericWithNull
            if (obj == null)
            {
                _stream.WriteByte(BinaryUtils.HdrNull);

                return;
            }

            // We use GetType() of a real object instead of typeof(T) to take advantage of
            // automatic Nullable'1 unwrapping.
            Type type = obj.GetType();

            // Handle common case when primitive is written.
            if (type.IsPrimitive)
            {
                WritePrimitive(obj, type);

                return;
            }

            // Handle enums.
            if (type.IsEnum)
            {
                WriteEnum(obj);

                return;
            }

            // Handle special case for builder.
            if (WriteBuilderSpecials(obj))
            {
                return;
            }

            // Suppose that we faced normal object and perform descriptor lookup.
            IBinaryTypeDescriptor desc = _marsh.GetDescriptor(type);

            if (desc != null)
            {
                // Writing normal object.
                var pos = _stream.Position;

                // Dealing with handles.
                if (desc.Serializer.SupportsHandles && WriteHandle(pos, obj))
                {
                    return;
                }

                // Skip header length as not everything is known now
                _stream.Seek(BinaryObjectHeader.Size, SeekOrigin.Current);

                // Preserve old frame.
                int oldTypeId = _curTypeId;
                IBinaryNameMapper oldConverter = _curConverter;
                IBinaryIdMapper   oldMapper    = _curMapper;
                int oldRawPos = _curRawPos;
                var oldPos    = _curPos;

                var oldStruct = _curStruct;

                // Push new frame.
                _curTypeId    = desc.TypeId;
                _curConverter = desc.NameMapper;
                _curMapper    = desc.IdMapper;
                _curRawPos    = 0;
                _curPos       = pos;

                _curStruct = new BinaryStructureTracker(desc, desc.WriterTypeStructure);
                var schemaIdx = _schema.PushSchema();

                try
                {
                    // Write object fields.
                    desc.Serializer.WriteBinary(obj, this);
                    var dataEnd = _stream.Position;

                    // Write schema
                    var schemaOffset = dataEnd - pos;

                    int schemaId;

                    var flags = desc.UserType
                        ? BinaryObjectHeader.Flag.UserType
                        : BinaryObjectHeader.Flag.None;

                    if (Marshaller.CompactFooter && desc.UserType)
                    {
                        flags |= BinaryObjectHeader.Flag.CompactFooter;
                    }

                    var hasSchema = _schema.WriteSchema(_stream, schemaIdx, out schemaId, ref flags);

                    if (hasSchema)
                    {
                        flags |= BinaryObjectHeader.Flag.HasSchema;

                        // Calculate and write header.
                        if (_curRawPos > 0)
                        {
                            _stream.WriteInt(_curRawPos - pos); // raw offset is in the last 4 bytes
                        }
                        // Update schema in type descriptor
                        if (desc.Schema.Get(schemaId) == null)
                        {
                            desc.Schema.Add(schemaId, _schema.GetSchema(schemaIdx));
                        }
                    }
                    else
                    {
                        schemaOffset = BinaryObjectHeader.Size;
                    }

                    if (_curRawPos > 0)
                    {
                        flags |= BinaryObjectHeader.Flag.HasRaw;
                    }

                    var len = _stream.Position - pos;

                    var hashCode = desc.EqualityComparer != null
                        ? desc.EqualityComparer.GetHashCode(Stream, pos + BinaryObjectHeader.Size,
                                                            dataEnd - pos - BinaryObjectHeader.Size, _schema, schemaIdx, _marsh, desc)
                        : obj.GetHashCode();

                    var header = new BinaryObjectHeader(desc.TypeId, hashCode, len, schemaId, schemaOffset, flags);

                    BinaryObjectHeader.Write(header, _stream, pos);

                    Stream.Seek(pos + len, SeekOrigin.Begin); // Seek to the end
                }
                finally
                {
                    _schema.PopSchema(schemaIdx);
                }

                // Apply structure updates if any.
                _curStruct.UpdateWriterStructure(this);

                // Restore old frame.
                _curTypeId    = oldTypeId;
                _curConverter = oldConverter;
                _curMapper    = oldMapper;
                _curRawPos    = oldRawPos;
                _curPos       = oldPos;

                _curStruct = oldStruct;
            }
            else
            {
                // Are we dealing with a well-known type?
                var handler = BinarySystemHandlers.GetWriteHandler(type);

                if (handler == null) // We did our best, object cannot be marshalled.
                {
                    throw BinaryUtils.GetUnsupportedTypeException(type, obj);
                }

                if (handler.SupportsHandles && WriteHandle(_stream.Position, obj))
                {
                    return;
                }

                handler.Write(this, obj);
            }
        }
Пример #15
0
        /// <summary>
        /// Write object as a predefined type if possible.
        /// </summary>
        /// <param name="hdr">Header.</param>
        /// <param name="inStream">Input stream.</param>
        /// <param name="outStream">Output stream.</param>
        /// <param name="ctx">Context.</param>
        /// <returns><c>True</c> if was written.</returns>
        private bool WriteAsPredefined(byte hdr, BinaryHeapStream inStream, IBinaryStream outStream,
                                       Context ctx)
        {
            switch (hdr)
            {
            case BinaryUtils.TypeByte:
                TransferBytes(inStream, outStream, 1);

                break;

            case BinaryUtils.TypeShort:
                TransferBytes(inStream, outStream, 2);

                break;

            case BinaryUtils.TypeInt:
                TransferBytes(inStream, outStream, 4);

                break;

            case BinaryUtils.TypeLong:
                TransferBytes(inStream, outStream, 8);

                break;

            case BinaryUtils.TypeFloat:
                TransferBytes(inStream, outStream, 4);

                break;

            case BinaryUtils.TypeDouble:
                TransferBytes(inStream, outStream, 8);

                break;

            case BinaryUtils.TypeChar:
                TransferBytes(inStream, outStream, 2);

                break;

            case BinaryUtils.TypeBool:
                TransferBytes(inStream, outStream, 1);

                break;

            case BinaryUtils.TypeDecimal:
                TransferBytes(inStream, outStream, 4); // Transfer scale

                int magLen = inStream.ReadInt();       // Transfer magnitude length.

                outStream.WriteInt(magLen);

                TransferBytes(inStream, outStream, magLen);     // Transfer magnitude.

                break;

            case BinaryUtils.TypeString:
                BinaryUtils.WriteString(BinaryUtils.ReadString(inStream), outStream);

                break;

            case BinaryUtils.TypeGuid:
                TransferBytes(inStream, outStream, 16);

                break;

            case BinaryUtils.TypeTimestamp:
                TransferBytes(inStream, outStream, 12);

                break;

            case BinaryUtils.TypeArrayByte:
                TransferArray(inStream, outStream, 1);

                break;

            case BinaryUtils.TypeArrayShort:
                TransferArray(inStream, outStream, 2);

                break;

            case BinaryUtils.TypeArrayInt:
                TransferArray(inStream, outStream, 4);

                break;

            case BinaryUtils.TypeArrayLong:
                TransferArray(inStream, outStream, 8);

                break;

            case BinaryUtils.TypeArrayFloat:
                TransferArray(inStream, outStream, 4);

                break;

            case BinaryUtils.TypeArrayDouble:
                TransferArray(inStream, outStream, 8);

                break;

            case BinaryUtils.TypeArrayChar:
                TransferArray(inStream, outStream, 2);

                break;

            case BinaryUtils.TypeArrayBool:
                TransferArray(inStream, outStream, 1);

                break;

            case BinaryUtils.TypeArrayDecimal:
            case BinaryUtils.TypeArrayString:
            case BinaryUtils.TypeArrayGuid:
            case BinaryUtils.TypeArrayTimestamp:
            case BinaryUtils.TypeArrayEnum:
            case BinaryUtils.TypeArray:
                int arrLen = inStream.ReadInt();

                outStream.WriteInt(arrLen);

                for (int i = 0; i < arrLen; i++)
                {
                    Mutate0(ctx, inStream, outStream, false, 0, null);
                }

                break;

            case BinaryUtils.TypeCollection:
                int colLen = inStream.ReadInt();

                outStream.WriteInt(colLen);

                outStream.WriteByte(inStream.ReadByte());

                for (int i = 0; i < colLen; i++)
                {
                    Mutate0(ctx, inStream, outStream, false, 0, EmptyVals);
                }

                break;

            case BinaryUtils.TypeDictionary:
                int dictLen = inStream.ReadInt();

                outStream.WriteInt(dictLen);

                outStream.WriteByte(inStream.ReadByte());

                for (int i = 0; i < dictLen; i++)
                {
                    Mutate0(ctx, inStream, outStream, false, 0, EmptyVals);
                    Mutate0(ctx, inStream, outStream, false, 0, EmptyVals);
                }

                break;

            case BinaryUtils.TypeBinary:
                TransferArray(inStream, outStream, 1);     // Data array.
                TransferBytes(inStream, outStream, 4);     // Offset in array.

                break;

            case BinaryUtils.TypeEnum:
                TransferBytes(inStream, outStream, 4);     // Integer ordinal.

                break;

            default:
                return(false);
            }

            return(true);
        }
Пример #16
0
 /** <inheritdoc /> */
 public Guid?ReadGuid()
 {
     return(Read <Guid?>(r => BinaryUtils.ReadGuid(r), BinaryTypeId.Guid));
 }
Пример #17
0
        public static SC3String FromHexString(string hexString, SC3Game game)
        {
            var bytes = BinaryUtils.HexStrToBytes(hexString);

            return(FromBytes(bytes, game));
        }
Пример #18
0
 /** <inheritdoc /> */
 public T[] ReadEnumArray <T>(string fieldName)
 {
     return(ReadField(fieldName, r => BinaryUtils.ReadArray <T>(r, true), BinaryTypeId.ArrayEnum));
 }
Пример #19
0
 /** <inheritdoc /> */
 public string[] ReadStringArray(string fieldName)
 {
     return(ReadField(fieldName, r => BinaryUtils.ReadArray <string>(r, false), BinaryUtils.TypeArrayString));
 }
Пример #20
0
 /** <inheritdoc /> */
 public T[] ReadEnumArray <T>()
 {
     return(Read(r => BinaryUtils.ReadArray <T>(r, true), BinaryTypeId.ArrayEnum));
 }
Пример #21
0
 /** <inheritdoc /> */
 public Guid?[] ReadGuidArray(string fieldName)
 {
     return(ReadField(fieldName, r => BinaryUtils.ReadArray <Guid?>(r, false), BinaryUtils.TypeArrayGuid));
 }
Пример #22
0
        private T ReadFullObject <T>(int pos, Type typeOverride)
        {
            var hdr = BinaryObjectHeader.Read(Stream, pos);

            // Validate protocol version.
            BinaryUtils.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 == BinaryMode.ForceBinary)
                {
                    BinaryObject portObj;

                    if (_detach || !Stream.CanGetArray)
                    {
                        Stream.Seek(pos, SeekOrigin.Begin);

                        portObj = new BinaryObject(_marsh, Stream.ReadByteArray(hdr.Length), 0, hdr);
                    }
                    else
                    {
                        portObj = new BinaryObject(_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.
                    var desc = hdr.TypeId == BinaryTypeId.Unregistered
                        ? _marsh.GetDescriptor(ReadUnregisteredType(typeOverride))
                        : _marsh.GetDescriptor(hdr.IsUserType, hdr.TypeId, true, null, typeOverride);

                    if (desc == null)
                    {
                        throw new BinaryObjectException(string.Format(
                                                            "No matching type found for object [typeId={0}, userType={1}].",
                                                            hdr.TypeId, hdr.IsUserType));
                    }

                    if (desc.Type == null)
                    {
                        throw new BinaryObjectException(string.Format(
                                                            "No matching type found for object [typeId={0}, typeName={1}]. " +
                                                            "This usually indicates that assembly with specified type is not loaded on a node. " +
                                                            "When using Apache.Ignite.exe, make sure to load assemblies with -assembly parameter. " +
                                                            "Alternatively, set IgniteConfiguration.PeerAssemblyLoadingMode to CurrentAppDomain.",
                                                            desc.TypeId, desc.TypeName));
                    }

                    // Preserve old frame.
                    var oldFrame = _frame;

                    // Set new frame.
                    _frame.Hdr = hdr;
                    _frame.Pos = pos;
                    SetCurSchema(desc);
                    _frame.Struct = new BinaryStructureTracker(desc, desc.ReaderTypeStructure);
                    _frame.Raw    = false;

                    // Read object.
                    var obj = desc.Serializer.ReadBinary <T>(this, desc, pos, typeOverride);

                    _frame.Struct.UpdateReaderStructure();

                    // Restore old frame.
                    _frame = oldFrame;

                    return(obj);
                }
            }
            finally
            {
                // Advance stream pointer.
                Stream.Seek(pos + hdr.Length, SeekOrigin.Begin);
            }
        }
Пример #23
0
 /** <inheritdoc /> */
 public T[] ReadArray <T>(string fieldName)
 {
     return(ReadField(fieldName, r => BinaryUtils.ReadArray <T>(r, true), BinaryUtils.TypeArray));
 }
Пример #24
0
        /** <inheritDoc /> */
        public void DestroyCache(string name)
        {
            IgniteArgumentCheck.NotNull(name, "name");

            DoOutOp(ClientOp.CacheDestroy, ctx => ctx.Stream.WriteInt(BinaryUtils.GetCacheId(name)));
        }
Пример #25
0
 /** <inheritdoc /> */
 public ICollection ReadCollection(string fieldName, Func <int, ICollection> factory,
                                   Action <ICollection, object> adder)
 {
     return(ReadField(fieldName, r => BinaryUtils.ReadCollection(r, factory, adder), BinaryUtils.TypeCollection));
 }
Пример #26
0
        /// <summary>
        /// Mutate binary object.
        /// </summary>
        /// <param name="inStream">Input stream with initial object.</param>
        /// <param name="outStream">Output stream.</param>
        /// <param name="desc">Type descriptor.</param>
        /// <param name="hashCode">Hash code.</param>
        /// <param name="vals">Values.</param>
        private void Mutate(
            BinaryHeapStream inStream,
            BinaryHeapStream outStream,
            IBinaryTypeDescriptor desc,
            int?hashCode,
            IDictionary <string, BinaryBuilderField> vals)
        {
            // Set correct builder to writer frame.
            BinaryObjectBuilder oldBuilder = _parent._ctx.Writer.SetBuilder(_parent);

            int streamPos = inStream.Position;

            try
            {
                // Prepare fields.
                IBinaryTypeHandler metaHnd = _binary.Marshaller.GetBinaryTypeHandler(desc);

                IDictionary <int, BinaryBuilderField> vals0;

                if (vals == null || vals.Count == 0)
                {
                    vals0 = EmptyVals;
                }
                else
                {
                    vals0 = new Dictionary <int, BinaryBuilderField>(vals.Count);

                    foreach (KeyValuePair <string, BinaryBuilderField> valEntry in vals)
                    {
                        int fieldId = BinaryUtils.FieldId(desc.TypeId, valEntry.Key, desc.NameMapper, desc.IdMapper);

                        if (vals0.ContainsKey(fieldId))
                        {
                            throw new IgniteException("Collision in field ID detected (change field name or " +
                                                      "define custom ID mapper) [fieldName=" + valEntry.Key + ", fieldId=" + fieldId + ']');
                        }

                        vals0[fieldId] = valEntry.Value;

                        // Write metadata if: 1) it is enabled for type; 2) type is not null (i.e. it is neither
                        // remove marker, nor a field read through "GetField" method.
                        if (metaHnd != null && valEntry.Value.Type != null)
                        {
                            metaHnd.OnFieldWrite(fieldId, valEntry.Key, valEntry.Value.TypeId);
                        }
                    }
                }

                // Actual processing.
                Mutate0(_parent._ctx, inStream, outStream, true, hashCode, vals0);

                // 3. Handle metadata.
                if (metaHnd != null)
                {
                    IDictionary <string, int> meta = metaHnd.OnObjectWriteFinished();

                    if (meta != null)
                    {
                        _parent._ctx.Writer.SaveMetadata(desc, meta);
                    }
                }
            }
            finally
            {
                // Restore builder frame.
                _parent._ctx.Writer.SetBuilder(oldBuilder);

                inStream.Seek(streamPos, SeekOrigin.Begin);
            }
        }
Пример #27
0
 /** <inheritdoc /> */
 public IDictionary ReadDictionary(string fieldName, Func <int, IDictionary> factory)
 {
     return(ReadField(fieldName, r => BinaryUtils.ReadDictionary(r, factory), BinaryUtils.TypeDictionary));
 }
Пример #28
0
        /// <summary>
        /// Internal mutation routine.
        /// </summary>
        /// <param name="inStream">Input stream.</param>
        /// <param name="outStream">Output stream.</param>
        /// <param name="ctx">Context.</param>
        /// <param name="changeHash">WHether hash should be changed.</param>
        /// <param name="hash">New hash.</param>
        /// <param name="vals">Values to be replaced.</param>
        /// <returns>Mutated object.</returns>
        private void Mutate0(Context ctx, BinaryHeapStream inStream, IBinaryStream outStream,
                             bool changeHash, int?hash, IDictionary <int, BinaryBuilderField> vals)
        {
            int inStartPos  = inStream.Position;
            int outStartPos = outStream.Position;

            byte inHdr = inStream.ReadByte();

            if (inHdr == BinaryUtils.HdrNull)
            {
                outStream.WriteByte(BinaryUtils.HdrNull);
            }
            else if (inHdr == BinaryUtils.HdrHnd)
            {
                int inHnd = inStream.ReadInt();

                int oldPos = inStartPos - inHnd;
                int newPos;

                if (ctx.OldToNew(oldPos, out newPos))
                {
                    // Handle is still valid.
                    outStream.WriteByte(BinaryUtils.HdrHnd);
                    outStream.WriteInt(outStartPos - newPos);
                }
                else
                {
                    // Handle is invalid, write full object.
                    int inRetPos = inStream.Position;

                    inStream.Seek(oldPos, SeekOrigin.Begin);

                    Mutate0(ctx, inStream, outStream, false, 0, EmptyVals);

                    inStream.Seek(inRetPos, SeekOrigin.Begin);
                }
            }
            else if (inHdr == BinaryUtils.HdrFull)
            {
                var inHeader = BinaryObjectHeader.Read(inStream, inStartPos);

                BinaryUtils.ValidateProtocolVersion(inHeader.Version);

                int hndPos;

                if (ctx.AddOldToNew(inStartPos, outStartPos, out hndPos))
                {
                    // Object could be cached in parent builder.
                    BinaryBuilderField cachedVal;

                    if (_parent._cache != null && _parent._cache.TryGetValue(inStartPos, out cachedVal))
                    {
                        WriteField(ctx, cachedVal);
                    }
                    else
                    {
                        // New object, write in full form.
                        var inSchema = BinaryObjectSchemaSerializer.ReadSchema(inStream, inStartPos, inHeader,
                                                                               _desc.Schema, _binary.Marshaller);

                        var outSchema = BinaryObjectSchemaHolder.Current;
                        var schemaIdx = outSchema.PushSchema();

                        try
                        {
                            // Skip header as it is not known at this point.
                            outStream.Seek(BinaryObjectHeader.Size, SeekOrigin.Current);

                            if (inSchema != null)
                            {
                                foreach (var inField in inSchema)
                                {
                                    BinaryBuilderField fieldVal;

                                    var fieldFound = vals.TryGetValue(inField.Id, out fieldVal);

                                    if (fieldFound && fieldVal == BinaryBuilderField.RmvMarker)
                                    {
                                        continue;
                                    }

                                    outSchema.PushField(inField.Id, outStream.Position - outStartPos);

                                    if (!fieldFound)
                                    {
                                        fieldFound = _parent._cache != null &&
                                                     _parent._cache.TryGetValue(inField.Offset + inStartPos,
                                                                                out fieldVal);
                                    }

                                    if (fieldFound)
                                    {
                                        WriteField(ctx, fieldVal);

                                        vals.Remove(inField.Id);
                                    }
                                    else
                                    {
                                        // Field is not tracked, re-write as is.
                                        inStream.Seek(inField.Offset + inStartPos, SeekOrigin.Begin);

                                        Mutate0(ctx, inStream, outStream, false, 0, EmptyVals);
                                    }
                                }
                            }

                            // Write remaining new fields.
                            foreach (var valEntry in vals)
                            {
                                if (valEntry.Value == BinaryBuilderField.RmvMarker)
                                {
                                    continue;
                                }

                                outSchema.PushField(valEntry.Key, outStream.Position - outStartPos);

                                WriteField(ctx, valEntry.Value);
                            }

                            var flags = inHeader.IsUserType
                                ? BinaryObjectHeader.Flag.UserType
                                : BinaryObjectHeader.Flag.None;

                            // Write raw data.
                            int outRawOff = outStream.Position - outStartPos;

                            if (inHeader.HasRaw)
                            {
                                var inRawOff = inHeader.GetRawOffset(inStream, inStartPos);
                                var inRawLen = inHeader.SchemaOffset - inRawOff;

                                flags |= BinaryObjectHeader.Flag.HasRaw;

                                outStream.Write(inStream.InternalArray, inStartPos + inRawOff, inRawLen);
                            }

                            // Write schema
                            int outSchemaOff = outRawOff;
                            var schemaPos    = outStream.Position;
                            int outSchemaId;

                            if (inHeader.IsCompactFooter)
                            {
                                flags |= BinaryObjectHeader.Flag.CompactFooter;
                            }

                            var hasSchema = outSchema.WriteSchema(outStream, schemaIdx, out outSchemaId, ref flags);

                            if (hasSchema)
                            {
                                outSchemaOff = schemaPos - outStartPos;

                                flags |= BinaryObjectHeader.Flag.HasSchema;

                                if (inHeader.HasRaw)
                                {
                                    outStream.WriteInt(outRawOff);
                                }

                                if (_desc.Schema.Get(outSchemaId) == null)
                                {
                                    _desc.Schema.Add(outSchemaId, outSchema.GetSchema(schemaIdx));
                                }
                            }

                            var outLen = outStream.Position - outStartPos;

                            var outHash = inHeader.HashCode;

                            if (changeHash)
                            {
                                if (hash != null)
                                {
                                    outHash = hash.Value;
                                }
                                else
                                {
                                    // Get from identity resolver.
                                    outHash = _desc.EqualityComparer != null
                                        ? _desc.EqualityComparer.GetHashCode(outStream,
                                                                             outStartPos + BinaryObjectHeader.Size,
                                                                             schemaPos - outStartPos - BinaryObjectHeader.Size,
                                                                             outSchema, outSchemaId, _binary.Marshaller, _desc)
                                        : 0;
                                }
                            }

                            var outHeader = new BinaryObjectHeader(inHeader.TypeId, outHash, outLen,
                                                                   outSchemaId, outSchemaOff, flags);

                            BinaryObjectHeader.Write(outHeader, outStream, outStartPos);

                            outStream.Seek(outStartPos + outLen, SeekOrigin.Begin);  // seek to the end of the object
                        }
                        finally
                        {
                            outSchema.PopSchema(schemaIdx);
                        }
                    }
                }
                else
                {
                    // Object has already been written, write as handle.
                    outStream.WriteByte(BinaryUtils.HdrHnd);
                    outStream.WriteInt(outStartPos - hndPos);
                }

                // Synchronize input stream position.
                inStream.Seek(inStartPos + inHeader.Length, SeekOrigin.Begin);
            }
            else
            {
                // Try writing as well-known type with fixed size.
                outStream.WriteByte(inHdr);

                if (!WriteAsPredefined(inHdr, inStream, outStream, ctx))
                {
                    throw new IgniteException("Unexpected header [position=" + (inStream.Position - 1) +
                                              ", header=" + inHdr + ']');
                }
            }
        }
Пример #29
0
        private T ReadFullObject <T>(int pos)
        {
            var hdr = BinaryObjectHeader.Read(Stream, pos);

            // Validate protocol version.
            BinaryUtils.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 == BinaryMode.ForceBinary)
                {
                    BinaryObject portObj;

                    if (_detach)
                    {
                        Stream.Seek(pos, SeekOrigin.Begin);

                        portObj = new BinaryObject(_marsh, Stream.ReadByteArray(hdr.Length), 0, hdr);
                    }
                    else
                    {
                        portObj = new BinaryObject(_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.
                    IBinaryTypeDescriptor desc;

                    if (!_descs.TryGetValue(BinaryUtils.TypeKey(hdr.IsUserType, hdr.TypeId), out desc))
                    {
                        throw new BinaryObjectException("Unknown type ID: " + hdr.TypeId);
                    }

                    // Instantiate object.
                    if (desc.Type == null)
                    {
                        throw new BinaryObjectException("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 BinaryStructureTracker(desc, desc.ReaderTypeStructure);
                    _curRaw    = false;

                    // Read object.
                    Stream.Seek(pos + BinaryObjectHeader.Size, SeekOrigin.Begin);

                    object obj;

                    var sysSerializer = desc.Serializer as IBinarySystemTypeSerializer;

                    if (sysSerializer != null)
                    {
                        obj = sysSerializer.ReadInstance(this);
                    }
                    else
                    {
                        try
                        {
                            obj = FormatterServices.GetUninitializedObject(desc.Type);

                            // Save handle.
                            AddHandle(pos, obj);
                        }
                        catch (Exception e)
                        {
                            throw new BinaryObjectException("Failed to create type instance: " +
                                                            desc.Type.AssemblyQualifiedName, e);
                        }

                        desc.Serializer.ReadBinary(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);
            }
        }
Пример #30
0
        /// <summary>
        /// Gets the Ignite-specific hash code for the provided value.
        /// </summary>
        public static unsafe int GetHashCode <T>(T val, Marshaller marsh, IDictionary <int, int> affinityKeyFieldIds)
        {
            Debug.Assert(marsh != null);
            Debug.Assert(val != null);

            var type = val.GetType();

            if (type == typeof(int))
            {
                return(TypeCaster <int> .Cast(val));
            }

            if (type == typeof(long))
            {
                return(GetLongHashCode(TypeCaster <long> .Cast(val)));
            }

            if (type == typeof(string))
            {
                return(BinaryUtils.GetStringHashCode((string)(object)val));
            }

            if (type == typeof(Guid))
            {
                return(GetGuidHashCode(TypeCaster <Guid> .Cast(val)));
            }

            if (type == typeof(uint))
            {
                var val0 = TypeCaster <uint> .Cast(val);

                return(*(int *)&val0);
            }

            if (type == typeof(ulong))
            {
                var val0 = TypeCaster <ulong> .Cast(val);

                return(GetLongHashCode(*(long *)&val0));
            }

            if (type == typeof(bool))
            {
                return(TypeCaster <bool> .Cast(val) ? 1231 : 1237);
            }

            if (type == typeof(byte))
            {
                return(unchecked ((sbyte)TypeCaster <byte> .Cast(val)));
            }

            if (type == typeof(short))
            {
                return(TypeCaster <short> .Cast(val));
            }

            if (type == typeof(char))
            {
                return(TypeCaster <char> .Cast(val));
            }

            if (type == typeof(float))
            {
                var floatVal = TypeCaster <float> .Cast(val);

                return(*(int *)&floatVal);
            }

            if (type == typeof(double))
            {
                var doubleVal = TypeCaster <double> .Cast(val);

                return(GetLongHashCode(*(long *)&doubleVal));
            }

            if (type == typeof(sbyte))
            {
                return(TypeCaster <sbyte> .Cast(val));
            }

            if (type == typeof(ushort))
            {
                var val0 = TypeCaster <ushort> .Cast(val);

                return(*(short *)&val0);
            }

            if (type == typeof(IntPtr))
            {
                var val0 = TypeCaster <IntPtr> .Cast(val).ToInt64();

                return(GetLongHashCode(val0));
            }

            if (type == typeof(UIntPtr))
            {
                var val0 = TypeCaster <UIntPtr> .Cast(val).ToUInt64();

                return(GetLongHashCode(*(long *)&val0));
            }

            if (type.IsArray)
            {
                return(GetArrayHashCode(val, marsh, affinityKeyFieldIds));
            }

            if (type == typeof(BinaryObject))
            {
                return(val.GetHashCode());
            }

            // DateTime, when used as key, is always written as BinaryObject.
            return(GetComplexTypeHashCode(val, marsh, affinityKeyFieldIds));
        }