/// <summary> /// Updates the target of a reference. /// </summary> /// <param name = "name">The canonical name of the reference.</param> /// <param name = "canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param> /// <param name = "refsColl">The <see cref="ReferenceCollection"/> being worked with.</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> of the <paramref name="name"/> reference.</param> /// <returns>A new <see cref = "Reference" />.</returns> public static Reference UpdateTarget(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, string logMessage = null) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish"); if (name == "HEAD") { return refsColl.Add("HEAD", canonicalRefNameOrObjectish, true); } Reference reference = refsColl[name]; var directReference = reference as DirectReference; if (directReference != null) { return refsColl.UpdateTarget(directReference, canonicalRefNameOrObjectish, logMessage); } var symbolicReference = reference as SymbolicReference; if (symbolicReference != null) { Reference targetRef; RefState refState = TryResolveReference(out targetRef, refsColl, canonicalRefNameOrObjectish); if (refState == RefState.DoesNotLookValid) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The reference specified by {0} is a Symbolic reference, you must provide a reference canonical name as the target.", name), "canonicalRefNameOrObjectish"); } return refsColl.UpdateTarget(symbolicReference, targetRef, logMessage); } throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, "Reference '{0}' has an unexpected type ('{1}').", name, reference.GetType())); }
/// <summary> /// Creates a direct or symbolic reference with the specified name and target /// </summary> /// <param name="name">The name of the reference to create.</param> /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="Reference"/></param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param> /// <returns>A new <see cref="Reference"/>.</returns> public virtual Reference Add(string name, string canonicalRefNameOrObjectish, string logMessage, bool allowOverwrite) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish"); Reference reference; RefState refState = TryResolveReference(out reference, this, canonicalRefNameOrObjectish); var gitObject = repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None); if (refState == RefState.Exists) { return(Add(name, reference, logMessage, allowOverwrite)); } if (refState == RefState.DoesNotExistButLooksValid && gitObject == null) { using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite, logMessage)) { return(Reference.BuildFromPtr <Reference>(handle, repo)); } } Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish); if (logMessage == null) { logMessage = string.Format(CultureInfo.InvariantCulture, "{0}: Created from {1}", name.LooksLikeLocalBranch() ? "branch" : "reference", canonicalRefNameOrObjectish); } EnsureHasLog(name); return(Add(name, gitObject.Id, logMessage, allowOverwrite)); }
/// <summary> /// Creates a direct or symbolic reference with the specified name and target /// </summary> /// <param name="name">The name of the reference to create.</param> /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param> /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="Reference"/></param> /// <returns>A new <see cref="Reference"/>.</returns> public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false, string logMessage = null) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish"); Reference reference; RefState refState = TryResolveReference(out reference, refsColl, canonicalRefNameOrObjectish); var gitObject = refsColl.repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None); if (refState == RefState.Exists) { return(refsColl.Add(name, reference, allowOverwrite, logMessage)); } if (refState == RefState.DoesNotExistButLooksValid && gitObject == null) { using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(refsColl.repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite)) { return(Reference.BuildFromPtr <Reference>(handle, refsColl.repo)); } } Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish); return(refsColl.Add(name, gitObject.Id, allowOverwrite, logMessage)); }
/// <summary> /// Generates a new reference that can be used within a sync transaction /// </summary> internal static Ref <A> NewRef <A>(A value, Func <A, bool> validator = null) { var id = Interlocked.Increment(ref refIdNext); var r = new Ref <A>(id); var v = new RefState <A>(0, value, validator, r); state.Add(id, v); return(r); }
internal sealed override bool OnTryRead(ref BinaryReader reader, Type typeToConvert, BinarySerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { object obj = default; // Slower path that supports continuation. if (state.Current.ObjectState == StackFrameObjectState.None) { if (!reader.ReadStartToken()) { value = default; return(false); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { state.Current.ObjectState = StackFrameObjectState.StartToken; BeginRead(ref state, ref reader, options); } else if (refState == RefState.Created) { state.Current.ObjectState = StackFrameObjectState.CreatedObject; obj = (T)refValue; } else { value = default; return(false); } } // 读取构造参数 if (!ReadCreatorArgumentsWithContinuation(ref state, ref reader, options)) { value = default; return(false); } if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { obj = CreateObject(ref state.Current); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); } EndRead(ref state); value = (T)obj; return(true); }
protected override object Visit(ExcelReference value) { AppendValue("#Ref-" + value.GetRange() + "="); var refState = new RefState(); state_.Push(refState); object visited = base.Visit(value); state_.Pop(); return(visited); }
/// <summary> /// Generates a new reference that can be used within a sync transaction /// </summary> internal static Ref <A> NewRef <A>(A value, Func <A, bool> validator = null) { var valid = validator == null ? True : CastPredicate(validator); var id = Interlocked.Increment(ref refIdNext); var v = new RefState(0, value, valid); state.Swap(s => s.Add(id, v)); return(new Ref <A>(id)); }
internal sealed override bool OnTryRead(ref BinaryReader reader, Type typeToConvert, BinarySerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { object obj; ArgumentState argumentState = state.Current.CtorArgumentState !; if (state.Current.ObjectState == StackFrameObjectState.None) { if (!reader.ReadStartToken()) { value = default; return(false); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { state.Current.ObjectState = StackFrameObjectState.StartToken; BeginRead(ref state, ref reader, options); // 初始化中可能会修改状态对象 argumentState = state.Current.CtorArgumentState !; } else { state.Current.ObjectState = StackFrameObjectState.CreatedObject; state.Current.ReturnValue = refValue; state.Current.RefState = refState; } } // 读取构造参数 if (!ReadConstructorArgumentsWithContinuation(ref state, ref reader, options)) { value = default; return(false); } if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { obj = CreateObject(ref state.Current); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); } else { obj = state.Current.ReturnValue; } if (argumentState.FoundPropertyCount > 0) { for (int i = 0; i < argumentState.FoundPropertyCount; i++) { BinaryPropertyInfo binaryPropertyInfo = argumentState.FoundPropertiesAsync ![i].Item1;
public void Reset() { CtorArgumentStateIndex = 0; CtorArgumentState = null; BinaryClassInfo = null !; PolymorphicBinaryClassInfo = null; PolymorphicBinaryTypeInfo = null; BinaryTypeInfo = null; PropertyPolymorphicConverter = null; ObjectState = StackFrameObjectState.None; OriginalDepth = 0; PropertyIndex = 0; PropertyRefCache = null; ReturnValue = null; EnumerableIndexBytes = 0; EnumerableLength = 0; EnumerableIndex = 0; PropertyValueCache = null; RefState = RefState.None; EndProperty(); }
public override bool AddReferenceCallback(object instance, object propertyValue, Func <object, object, bool> action) { if (instance.IsRefId() || propertyValue.IsRefId()) { uint?insRefId = null; uint?propRefId = null; if (instance is ReferenceID insId) { RefState s = TryGetReference(insId.RefSeq, out object tmpObj); if (s == RefState.Created) { instance = tmpObj; } else { insRefId = insId.RefSeq; } } if (propertyValue is ReferenceID propId) { RefState s = TryGetReference(propId.RefSeq, out object tmpObj); if (s == RefState.Created) { propertyValue = tmpObj; } else { propRefId = propId.RefSeq; } } if (!insRefId.HasValue && !propRefId.HasValue) { return(action(instance, propertyValue)); } bool callback() { object actualInstance; object actualPropValue; if (instance is ReferenceID insId) { RefState s = TryGetReference(insId.RefSeq, out actualInstance); if (s != RefState.Created) { return(false); } } else { actualInstance = instance; } if (propertyValue is ReferenceID propId) { RefState s = TryGetReference(propId.RefSeq, out actualPropValue); if (s != RefState.Created) { return(false); } } else { actualPropValue = propertyValue; } return(action(actualInstance, actualPropValue)); } if (insRefId.HasValue) { AddReferenceCallback(insRefId.Value, callback); } if (propRefId.HasValue) { AddReferenceCallback(propRefId.Value, callback); } return(true); } return(action(instance, propertyValue)); }
internal override bool OnTryRead(ref BinaryReader reader, Type typeToConvert, BinarySerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { object obj; if (state.UseFastPath) { // 刚进入对象读取 if (reader.CurrentTypeInfo == null || reader.CurrentTypeInfo.SerializeType != ClassType.Object) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } reader.AheadReadStartToken(); if (state.Current.BinaryClassInfo.CreateObject == null) { ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.BinaryClassInfo.Type, ref reader, ref state); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { obj = state.Current.BinaryClassInfo.CreateObject(); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); } else { obj = refValue; } // Process all properties. while (true) { reader.AheadReadPropertyName(); BinaryPropertyInfo binaryPropertyInfo = null; state.Current.PropertyState = StackFramePropertyState.Name; if (reader.TokenType == BinaryTokenType.EndObject) { break; } Debug.Assert(reader.TokenType == BinaryTokenType.PropertyName); ushort propertySeq = reader.CurrentPropertySeq; BinaryMemberInfo mi = state.GetMemberInfo(propertySeq); // Debug.Assert(mi != null); binaryPropertyInfo = BinarySerializer.LookupProperty( obj, mi.NameAsUtf8Bytes, ref state, out bool useExtensionProperty); state.Current.UseExtensionProperty = useExtensionProperty; // binaryPropertyInfo = state.LookupProperty(mi.NameAsString); state.Current.BinaryPropertyInfo = binaryPropertyInfo; state.Current.PropertyPolymorphicConverter = null; if (binaryPropertyInfo == null) { if (!reader.TrySkip(options)) { value = default; return(false); } state.Current.EndProperty(); continue; } if (!binaryPropertyInfo.ShouldDeserialize) { if (!reader.TrySkip(options)) { state.Current.ReturnValue = obj; value = default; return(false); } state.Current.EndProperty(); continue; } // Obtain the CLR value from the Binary and set the member. if (!state.Current.UseExtensionProperty) { binaryPropertyInfo.ReadBinaryAndSetMember(obj, ref state, ref reader); } else { // TODO 扩展属性 } state.Current.EndProperty(); } } else { // Slower path that supports continuation and preserved references. if (state.Current.ObjectState == StackFrameObjectState.None) { // 刚进入对象读取 if (reader.CurrentTypeInfo == null || reader.CurrentTypeInfo.SerializeType != ClassType.Object) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } if (!reader.ReadStartToken()) { value = default; return(false); } RefState refState = BinarySerializer.ReadReferenceForObject(this, ref state, ref reader, out object refValue); if (refState == RefState.None) { state.Current.ObjectState = StackFrameObjectState.StartToken; } else if (refState == RefState.Created) { state.Current.ObjectState = StackFrameObjectState.CreatedObject; state.Current.ReturnValue = refValue; } } // 创建对象 if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { if (state.Current.BinaryClassInfo.CreateObject == null) { ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.BinaryClassInfo.Type, ref reader, ref state); } obj = state.Current.BinaryClassInfo.CreateObject(); state.ReferenceResolver.AddReferenceObject(state.Current.RefId, obj); state.Current.ReturnValue = obj; state.Current.ObjectState = StackFrameObjectState.CreatedObject; } else { obj = state.Current.ReturnValue !; Debug.Assert(obj != null); } // Process all properties. while (true) { // Determine the property. // 读取属性索引 if (state.Current.PropertyState == StackFramePropertyState.None) { if (!reader.ReadPropertyName()) { state.Current.ReturnValue = obj; value = default; return(false); } state.Current.PropertyState = StackFramePropertyState.ReadName; // } BinaryPropertyInfo binaryPropertyInfo; if (state.Current.PropertyState <= StackFramePropertyState.ReadName) { state.Current.PropertyState = StackFramePropertyState.Name; if (reader.TokenType == BinaryTokenType.EndObject) { break; } Debug.Assert(reader.TokenType == BinaryTokenType.PropertyName); ushort propertySeq = reader.CurrentPropertySeq; BinaryMemberInfo mi = state.GetMemberInfo(propertySeq); Debug.Assert(mi != null); binaryPropertyInfo = BinarySerializer.LookupProperty( obj, mi.NameAsUtf8Bytes, ref state, out bool useExtensionProperty); state.Current.UseExtensionProperty = useExtensionProperty; // binaryPropertyInfo = state.LookupProperty(mi.NameAsString); state.Current.BinaryPropertyInfo = binaryPropertyInfo; state.Current.PropertyPolymorphicConverter = null; if (binaryPropertyInfo == null) { state.Current.EndProperty(); continue; } } else { Debug.Assert(state.Current.BinaryPropertyInfo != null); binaryPropertyInfo = state.Current.BinaryPropertyInfo !; } if (state.Current.PropertyState < StackFramePropertyState.ReadValue) { if (!binaryPropertyInfo.ShouldDeserialize) { if (!reader.TrySkip(options)) { state.Current.ReturnValue = obj; value = default; return(false); } state.Current.EndProperty(); continue; } } if (state.Current.PropertyState < StackFramePropertyState.TryRead) { // Obtain the CLR value from the Binary and set the member. if (!state.Current.UseExtensionProperty) { if (!binaryPropertyInfo.ReadBinaryAndSetMember(obj, ref state, ref reader)) { state.Current.ReturnValue = obj; value = default; return(false); } } else { // TODO 扩展属性 } state.Current.EndProperty(); } } } // Check if we are trying to build the sorted cache. if (state.Current.PropertyRefCache != null) { state.Current.BinaryClassInfo.UpdateSortedPropertyCache(ref state.Current); } value = (T)obj; return(true); }