예제 #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));
        }
예제 #2
0
        /// <summary>
        /// Write field.
        /// </summary>
        /// <param name="fieldName">Field name.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="val">Value.</param>
        /// <param name="handler">Handler.</param>
        private void WriteField(string fieldName, byte typeId, object val,
                                PortableSystemWriteDelegate handler)
        {
            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);

            WriteField(fieldId, val, handler);

            if (_curMetaHnd != null)
            {
                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
            }
        }
예제 #3
0
        /// <summary>
        /// Write simple nullable field with known length.
        /// </summary>
        /// <param name="fieldName">Field name.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="val">Value.</param>
        /// <param name="handler">Handler.</param>
        /// <param name="len">Length.</param>
        private void WriteSimpleNullableField <T>(string fieldName, byte typeId, T val,
                                                  PortableSystemTypedWriteDelegate <T> handler, int len)
        {
            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);

            WriteSimpleNullableField(fieldId, val, handler, len);

            if (_curMetaHnd != null)
            {
                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
            }
        }
        /// <summary>Register type.</summary>
        /// <param name="type">Type.</param>
        /// <param name="typeId">Type ID.</param>
        /// <param name="converter">Name converter.</param>
        /// <param name="idMapper">ID mapper.</param>
        public void Register(Type type, int typeId, IPortableNameMapper converter,
                             IPortableIdMapper idMapper)
        {
            if (type.GetInterface(typeof(IPortableMarshalAware).Name) != null)
            {
                return;
            }

            List <FieldInfo> fields = new List <FieldInfo>();

            Type curType = type;

            while (curType != null)
            {
                foreach (FieldInfo field in curType.GetFields(Flags))
                {
                    if (!field.IsNotSerialized)
                    {
                        fields.Add(field);
                    }
                }

                curType = curType.BaseType;
            }

            IDictionary <int, string> idMap = new Dictionary <int, string>();

            foreach (FieldInfo field in fields)
            {
                string fieldName = PortableUtils.CleanFieldName(field.Name);

                int fieldId = PortableUtils.FieldId(typeId, fieldName, converter, idMapper);

                if (idMap.ContainsKey(fieldId))
                {
                    throw new PortableException("Conflicting field IDs [type=" +
                                                type.Name + ", field1=" + idMap[fieldId] + ", field2=" + fieldName +
                                                ", fieldId=" + fieldId + ']');
                }

                idMap[fieldId] = fieldName;
            }

            fields.Sort(Compare);

            Descriptor desc = new Descriptor(fields);

            _types[type] = desc;
        }
예제 #5
0
        /// <summary>
        /// Seeks the field by name, reads header and returns true if field is present and header is not null.
        /// </summary>
        private bool SeekField(string fieldName)
        {
            if (_curRaw)
            {
                throw new PortableException("Cannot read named fields after raw data is read.");
            }

            var fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);

            if (!SeekField(fieldId))
            {
                return(false);
            }

            return(IsNullHeader());
        }
예제 #6
0
        /** <inheritdoc /> */
        public T ReadObject <T>(string fieldName)
        {
            if (_curRaw)
            {
                throw new PortableException("Cannot read named fields after raw data is read.");
            }

            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);

            if (SeekField(fieldId))
            {
                return(Deserialize <T>());
            }

            return(default(T));
        }
예제 #7
0
        /// <summary>
        /// Callback invoked when metadata has been sent to the server and acknowledged by it.
        /// </summary>
        /// <param name="newMetas"></param>
        public void OnMetadataSent(IDictionary <int, IPortableMetadata> newMetas)
        {
            foreach (KeyValuePair <int, IPortableMetadata> metaEntry in newMetas)
            {
                PortableMetadataImpl meta = (PortableMetadataImpl)metaEntry.Value;

                IDictionary <int, Tuple <string, int> > mergeInfo =
                    new Dictionary <int, Tuple <string, int> >(meta.FieldsMap().Count);

                foreach (KeyValuePair <string, int> fieldMeta in meta.FieldsMap())
                {
                    int fieldId = PortableUtils.FieldId(metaEntry.Key, fieldMeta.Key, null, null);

                    mergeInfo[fieldId] = new Tuple <string, int>(fieldMeta.Key, fieldMeta.Value);
                }

                _metas[metaEntry.Key].Merge(mergeInfo);
            }
        }
예제 #8
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;

            IPortableTypeDescriptor desc = _marsh.Descriptor(true, _typeId);

            IPortableMetadata meta;

            try
            {
                meta = _marsh.Metadata(_typeId);
            }
            catch (IgniteException)
            {
                meta = null;
            }

            if (meta == null)
            {
                sb = new StringBuilder("PortableObject [typeId=").Append(_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 = PortableUtils.FieldId(_typeId, fieldName, desc.NameConverter, desc.Mapper);

                        int fieldPos;

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

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

            sb.Append(']');

            return(sb.ToString());
        }
예제 #9
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);
            }
        }