Beispiel #1
0
        /// <summary>
        /// Get field with builder.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fieldName"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        public T Field <T>(string fieldName, PortableBuilderImpl builder)
        {
            IPortableTypeDescriptor desc = _marsh.Descriptor(true, _typeId);

            InitializeFields();

            int fieldId = PortableUtils.FieldId(_typeId, fieldName, desc.NameConverter, desc.Mapper);

            int pos;

            if (_fields.TryGetValue(fieldId, out pos))
            {
                if (builder != null)
                {
                    // Read in scope of build process.
                    T res;

                    if (!builder.CachedField(pos, out res))
                    {
                        res = Field0 <T>(pos, builder);

                        builder.CacheField(pos, res);
                    }

                    return(res);
                }
                return(Field0 <T>(pos, null));
            }
            return(default(T));
        }
Beispiel #2
0
        /// <summary>
        /// Set new builder.
        /// </summary>
        /// <param name="builder">Builder.</param>
        /// <returns>Previous builder.</returns>
        internal PortableBuilderImpl Builder(PortableBuilderImpl builder)
        {
            PortableBuilderImpl ret = _builder;

            _builder = builder;

            return(ret);
        }
Beispiel #3
0
        /// <summary>
        /// Gets field value on the given object.
        /// </summary>
        /// <param name="pos">Position.</param>
        /// <param name="builder">Builder.</param>
        /// <returns>Field value.</returns>
        private T Field0 <T>(int pos, PortableBuilderImpl builder)
        {
            IPortableStream stream = new PortableHeapStream(_data);

            stream.Seek(pos, SeekOrigin.Begin);

            return(_marsh.Unmarshal <T>(stream, PortableMode.ForcePortable, builder));
        }
Beispiel #4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="portables">Portables.</param>
        /// <param name="parent">Parent builder.</param>
        /// <param name="obj">Initial portable object.</param>
        /// <param name="desc">Type descriptor.</param>
        public PortableBuilderImpl(PortablesImpl portables, PortableBuilderImpl parent,
                                   PortableUserObject obj, IPortableTypeDescriptor desc)
        {
            _portables = portables;
            _parent    = parent ?? this;
            _obj       = obj;
            _desc      = desc;

            _hashCode = obj.GetHashCode();
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="marsh">Marshaller.</param>
        /// <param name="descs">Descriptors.</param>
        /// <param name="stream">Input stream.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="builder">Builder.</param>
        public PortableReaderImpl
            (PortableMarshaller marsh,
            IDictionary <long, IPortableTypeDescriptor> descs,
            IPortableStream stream,
            PortableMode mode,
            PortableBuilderImpl builder)
        {
            _marsh   = marsh;
            _descs   = descs;
            _mode    = mode;
            _builder = builder;

            Stream = stream;
        }
Beispiel #6
0
        /// <summary>
        /// Process child builder.
        /// </summary>
        /// <param name="outStream">Output stream.</param>
        /// <param name="builder">Builder.</param>
        internal void ProcessBuilder(IPortableStream outStream, PortableBuilderImpl builder)
        {
            PortableHeapStream inStream = new PortableHeapStream(builder._obj.Data);

            inStream.Seek(builder._obj.Offset, SeekOrigin.Begin);

            // Builder parent context might be null only in one case: if we never met this group of
            // builders before. In this case we set context to their parent and track it. Context
            // cleanup will be performed at the very end of build process.
            if (builder._parent._ctx == null || builder._parent._ctx.Closed)
            {
                builder._parent._ctx = new Context(_parent._ctx);
            }

            builder.Mutate(inStream, outStream as PortableHeapStream, builder._desc,
                           builder._hashCode, builder._vals);
        }
Beispiel #7
0
        internal void Write <T>(T obj, object handler)
        {
            // Apply detach mode if needed.
            PortableHandleDictionary <object, long> oldHnds = null;

            bool resetDetach = false;

            if (_detach)
            {
                _detach     = false;
                _detachMode = true;
                resetDetach = true;

                oldHnds = _hnds;

                _hnds = null;
            }

            try
            {
                // Write null.
                if (obj == null)
                {
                    _stream.WriteByte(PortableUtils.HdrNull);

                    return;
                }

                if (_builder != null)
                {
                    // Special case for portable object during build.
                    PortableUserObject portObj = obj as PortableUserObject;

                    if (portObj != null)
                    {
                        if (!WriteHandle(_stream.Position, portObj))
                        {
                            _builder.ProcessPortable(_stream, portObj);
                        }

                        return;
                    }

                    // Special case for builder during build.
                    PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;

                    if (portBuilder != null)
                    {
                        if (!WriteHandle(_stream.Position, portBuilder))
                        {
                            _builder.ProcessBuilder(_stream, portBuilder);
                        }

                        return;
                    }
                }

                // Try writting as well-known type.
                if (InvokeHandler(handler, handler as PortableSystemWriteDelegate, obj))
                {
                    return;
                }

                Type type = obj.GetType();

                IPortableTypeDescriptor desc = _marsh.Descriptor(type);

                object typedHandler;
                PortableSystemWriteDelegate untypedHandler;

                if (desc == null)
                {
                    typedHandler   = null;
                    untypedHandler = PortableSystemHandlers.WriteHandler(type);
                }
                else
                {
                    typedHandler   = desc.TypedHandler;
                    untypedHandler = desc.UntypedHandler;
                }

                if (InvokeHandler(typedHandler, untypedHandler, obj))
                {
                    return;
                }

                if (desc == null)
                {
                    if (!type.IsSerializable)
                    {
                        // If neither handler, nor descriptor exist, and not serializable, this is an exception.
                        throw new PortableException("Unsupported object type [type=" + type +
                                                    ", object=" + obj + ']');
                    }

                    Write(new SerializableObjectHolder(obj));

                    return;
                }

                int pos = _stream.Position;

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

                // Write header.
                _stream.WriteByte(PortableUtils.HdrFull);

                _stream.WriteBool(desc.UserType);
                _stream.WriteInt(desc.TypeId);
                _stream.WriteInt(obj.GetHashCode());

                // Skip length as it is not known in the first place.
                _stream.Seek(8, SeekOrigin.Current);

                // Preserve old frame.
                int oldTypeId = _curTypeId;
                IPortableNameMapper      oldConverter = _curConverter;
                IPortableIdMapper        oldMapper    = _curMapper;
                IPortableMetadataHandler oldMetaHnd   = _curMetaHnd;
                bool oldRaw    = _curRaw;
                long oldRawPos = _curRawPos;

                // Push new frame.
                _curTypeId    = desc.TypeId;
                _curConverter = desc.NameConverter;
                _curMapper    = desc.Mapper;
                _curMetaHnd   = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
                _curRaw       = false;
                _curRawPos    = 0;

                // Write object fields.
                desc.Serializer.WritePortable(obj, this);

                // Calculate and write length.
                int retPos = _stream.Position;

                _stream.Seek(pos + 10, SeekOrigin.Begin);

                int len = retPos - pos;

                _stream.WriteInt(len);

                if (_curRawPos != 0)
                {
                    // When set, it is difference between object head and raw position.
                    _stream.WriteInt((int)(_curRawPos - pos));
                }
                else
                {
                    // When no set, it is equal to object length.
                    _stream.WriteInt(len);
                }

                _stream.Seek(retPos, SeekOrigin.Begin);

                // 13. Collect metadata.
                if (_curMetaHnd != null)
                {
                    IDictionary <string, int> meta = _curMetaHnd.OnObjectWriteFinished();

                    if (meta != null)
                    {
                        SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
                    }
                }

                // Restore old frame.
                _curTypeId    = oldTypeId;
                _curConverter = oldConverter;
                _curMapper    = oldMapper;
                _curMetaHnd   = oldMetaHnd;
                _curRaw       = oldRaw;
                _curRawPos    = oldRawPos;
            }
            finally
            {
                // Restore handles if needed.
                if (resetDetach)
                {
                    // Add newly recorded handles without overriding already existing ones.
                    if (_hnds != null)
                    {
                        if (oldHnds == null)
                        {
                            oldHnds = _hnds;
                        }
                        else
                        {
                            oldHnds.Merge(_hnds);
                        }
                    }

                    _hnds = oldHnds;

                    _detachMode = false;
                }
            }
        }
Beispiel #8
0
 /// <summary>
 /// Internal builder creation routine.
 /// </summary>
 /// <param name="parent">Parent builder.</param>
 /// <param name="obj">Portable object.</param>
 /// <param name="desc">Type descriptor.</param>
 /// <returns>Builder.</returns>
 private PortableBuilderImpl Builder0(PortableBuilderImpl parent, PortableUserObject obj,
                                      IPortableTypeDescriptor desc)
 {
     return(new PortableBuilderImpl(this, parent, obj, desc));
 }
Beispiel #9
0
        /// <summary>
        /// Create child builder.
        /// </summary>
        /// <param name="parent">Parent builder.</param>
        /// <param name="obj">Portable object.</param>
        /// <returns></returns>
        internal PortableBuilderImpl ChildBuilder(PortableBuilderImpl parent, PortableUserObject obj)
        {
            IPortableTypeDescriptor desc = _marsh.Descriptor(true, obj.TypeId());

            return(Builder0(null, obj, desc));
        }
Beispiel #10
0
 /// <summary>
 /// Unmarshal object.
 /// </summary>
 /// <param name="stream">Stream over underlying byte array with correct position.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="builder">Builder.</param>
 /// <returns>
 /// Object.
 /// </returns>
 public T Unmarshal <T>(IPortableStream stream, PortableMode mode, PortableBuilderImpl builder)
 {
     return(new PortableReaderImpl(this, _idToDesc, stream, mode, builder).Deserialize <T>());
 }
Beispiel #11
0
        /// <summary>
        /// Mutate portable object.
        /// </summary>
        /// <param name="inStream">Input stream with initial object.</param>
        /// <param name="outStream">Output stream.</param>
        /// <param name="desc">Portable type descriptor.</param>
        /// <param name="hashCode">Hash code.</param>
        /// <param name="vals">Values.</param>
        internal void Mutate(
            PortableHeapStream inStream,
            PortableHeapStream outStream,
            IPortableTypeDescriptor desc,
            int hashCode,
            IDictionary <string, PortableBuilderField> vals)
        {
            // Set correct builder to writer frame.
            PortableBuilderImpl oldBuilder = _parent._ctx.Writer.Builder(_parent);

            int streamPos = inStream.Position;

            try
            {
                // Prepare fields.
                IPortableMetadataHandler metaHnd = _portables.Marshaller.MetadataHandler(desc);

                IDictionary <int, object> vals0;

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

                    foreach (KeyValuePair <string, PortableBuilderField> valEntry in vals)
                    {
                        int fieldId = PortableUtils.FieldId(desc.TypeId, valEntry.Key, desc.NameConverter, desc.Mapper);

                        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.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, TypeId(valEntry.Value.Type));
                        }
                    }
                }

                // 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.TypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
                    }
                }
            }
            finally
            {
                // Restore builder frame.
                _parent._ctx.Writer.Builder(oldBuilder);

                inStream.Seek(streamPos, SeekOrigin.Begin);
            }
        }