/// <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> /// 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); } }
/// <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; }
/// <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()); }
/** <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)); }
/// <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); } }
/// <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); } }