/// <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)); }
/// <summary> /// Gets metadata handler for the given type ID. /// </summary> /// <param name="desc">Type descriptor.</param> /// <returns>Metadata handler.</returns> public IPortableMetadataHandler MetadataHandler(IPortableTypeDescriptor desc) { PortableMetadataHolder holder; if (!_metas.TryGetValue(desc.TypeId, out holder)) { lock (this) { if (!_metas.TryGetValue(desc.TypeId, out holder)) { IDictionary <int, PortableMetadataHolder> metas0 = new Dictionary <int, PortableMetadataHolder>(_metas); holder = desc.MetadataEnabled ? new PortableMetadataHolder(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName) : null; metas0[desc.TypeId] = holder; _metas = metas0; } } } if (holder != null) { ICollection <int> ids = holder.FieldIds(); bool newType = ids.Count == 0 && !holder.Saved(); return(new PortableHashsetMetadataHandler(ids, newType)); } return(null); }
/** <inheritDoc /> */ public IPortableBuilder Builder(string typeName) { IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName"); IPortableTypeDescriptor desc = _marsh.Descriptor(typeName); return(Builder0(null, PortableFromDescriptor(desc), desc)); }
/// <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> /// Create empty portable object from descriptor. /// </summary> /// <param name="desc">Descriptor.</param> /// <returns>Empty portable object.</returns> private PortableUserObject PortableFromDescriptor(IPortableTypeDescriptor desc) { PortableHeapStream stream = new PortableHeapStream(18); stream.WriteByte(PortableUtils.HdrFull); stream.WriteBool(true); stream.WriteInt(desc.TypeId); stream.WriteInt(0); // Hash. stream.WriteInt(PortableUtils.FullHdrLen); // Length. stream.WriteInt(PortableUtils.FullHdrLen); // Raw data offset. return(new PortableUserObject(_marsh, stream.InternalArray, 0, desc.TypeId, 0)); }
/** <inheritDoc /> */ public IPortableBuilder Builder(Type type) { IgniteArgumentCheck.NotNull(type, "type"); IPortableTypeDescriptor desc = _marsh.Descriptor(type); if (desc == null) { throw new IgniteException("Type is not portable (add it to PortableConfiguration): " + type.FullName); } return(Builder0(null, PortableFromDescriptor(desc), desc)); }
/** <inheritDoc /> */ public IPortableBuilder Builder(IPortableObject obj) { IgniteArgumentCheck.NotNull(obj, "obj"); PortableUserObject obj0 = obj as PortableUserObject; if (obj0 == null) { throw new ArgumentException("Unsupported object type: " + obj.GetType()); } IPortableTypeDescriptor desc = _marsh.Descriptor(true, obj0.TypeId()); return(Builder0(null, obj0, desc)); }
/// <summary> /// Internal deserialization routine. /// </summary> /// <param name="mode">The mode.</param> /// <returns> /// Deserialized object. /// </returns> private T Deserialize <T>(PortableMode mode) { if (_deserialized == null) { IPortableStream stream = new PortableHeapStream(_data); stream.Seek(_offset, SeekOrigin.Begin); T res = _marsh.Unmarshal <T>(stream, mode); IPortableTypeDescriptor desc = _marsh.Descriptor(true, _typeId); if (!desc.KeepDeserialized) { return(res); } _deserialized = res; } return((T)_deserialized); }
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; } } }
/// <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)); }
/// <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)); }
/// <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()); }
/// <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); } }
/// <summary> /// Constructor. /// </summary> /// <param name="portables">Portables.</param> /// <param name="obj">Initial portable object.</param> /// <param name="desc">Type descriptor.</param> public PortableBuilderImpl(PortablesImpl portables, PortableUserObject obj, IPortableTypeDescriptor desc) : this(portables, null, obj, desc) { // No-op. }