internal bool ReadStartToken() { if (!RequestData(5)) { return(false); } byte objType = _buffer[_consumed]; ValueSpan = _buffer.Slice(_consumed + 1, 4); _consumed += 5; if (objType == 0x00) { //正常 _tokenType = BinaryTokenType.StartObject; } else if (objType == 0xFF) { _tokenType = BinaryTokenType.ObjectRef; } else { ThrowHelper.ThrowBinaryReaderException(ref this, ExceptionResource.ExpectedBinaryTokens); } return(true); }
internal bool ReadTypeSeq() { if (!RequestData(2)) { return(false); } _tokenType = BinaryTokenType.TypeSeq; ValueSpan = _buffer.Slice(_consumed, 2); _typeSeq = BitConverter.ToUInt16(ValueSpan); if (_typeSeq == TypeMap.NullTypeSeq) { _tokenType = BinaryTokenType.Null; CurrentTypeInfo = null; } else { CurrentTypeInfo = _typeMap.GetTypeInfo(_typeSeq); } if (CurrentTypeInfo == null && _tokenType != BinaryTokenType.Null) { throw new Exception(); } _consumed += 2; return(true); }
public BinaryReader(ReadOnlySpan <byte> binaryData, bool isFinalBlock, BinaryReaderState state) { _buffer = binaryData; _isFinalBlock = isFinalBlock; //_isInputSequence = false; _typeSeq = state._typeSeq; _dicKeySeq = state._dicKeySeq; CurrentTypeInfo = state._typeInfo; CurrentPropertySeq = state._propertySeq; _typeMap = state._typeMap; _version = state._version; _tokenType = state._tokenType; _previousTokenType = state._previousTokenType; _consumed = 0; TokenStartIndex = 0; _totalConsumed = 0; ValueSpan = ReadOnlySpan <byte> .Empty; _sequence = default; }
private bool ReadCreatorArgumentsWithContinuation(ref ReadStack state, ref BinaryReader reader, BinarySerializerOptions options) { // Process all properties. while (true) { // Determine the property. if (state.Current.PropertyState == StackFramePropertyState.None) { if (!reader.ReadPropertyName()) { return(false); } state.Current.PropertyState = StackFramePropertyState.ReadName; } BinaryPropertyInfo binaryPropertyInfo; if (state.Current.PropertyState <= StackFramePropertyState.Name) { state.Current.PropertyState = StackFramePropertyState.Name; BinaryTokenType tokenType = reader.TokenType; if (tokenType == BinaryTokenType.EndObject) { return(true); } // Read method would have thrown if otherwise. Debug.Assert(tokenType == BinaryTokenType.PropertyName); ushort propertySeq = reader.CurrentPropertySeq; BinaryMemberInfo mi = state.GetMemberInfo(propertySeq); Debug.Assert(mi != null); binaryPropertyInfo = BinarySerializer.LookupProperty( obj: null !, mi.NameAsUtf8Bytes, ref state, out bool useExtensionProperty, createExtensionProperty: false); state.Current.UseExtensionProperty = useExtensionProperty; } else { binaryPropertyInfo = state.Current.BinaryPropertyInfo; } if (!HandlePropertyWithContinuation(ref state, ref reader, binaryPropertyInfo !)) { return(false); } } }
private void ResetHelper() { BytesPending = default; BytesCommitted = default; _memory = default; //_inObject = default; _tokenType = default; _currentDepth = default; // _bitStack = default; }
/// <summary> /// 读取指定字节数,并返回 /// 此方法会修改Reader的读取位置及Reader的ValueSpan属性 /// </summary> /// <param name="len">待读取的长度</param> /// <param name="output">读取结果</param> /// <returns>成功返回ture,如果没有足够的数据返回false</returns> internal bool ReadBytes(int len) { if ((_consumed + len) > _buffer.Length) { return(false); } _tokenType = BinaryTokenType.Bytes; ValueSpan = _buffer.Slice(_consumed, len); _consumed += len; return(true); }
/// <summary> /// 读取包含长度信息的字节组 /// </summary> /// <returns></returns> public bool ReadBytes() { // 长度 16位或32位 if (!RequestData(2)) { return(false); } byte b1 = _buffer[_consumed]; // 如果最高位是1,表示31位长度,否则表示15位长度 int len; int lenBytes; if ((b1 & 0x80) == 0x80) { if (!RequestData(4)) { return(false); } len = ((_buffer[_consumed] & 0x7F) << 24) | (_buffer[_consumed + 1] << 16) | (_buffer[_consumed + 2] << 8) | _buffer[_consumed + 3]; lenBytes = 4; } else { len = _buffer[_consumed] << 8 | _buffer[_consumed + 1]; lenBytes = 2; } if (len == 0) { ValueSpan = ReadOnlySpan <byte> .Empty; } if (!RequestData(len + lenBytes)) { return(false); } _consumed += lenBytes; _tokenType = BinaryTokenType.Bytes; ValueSpan = _buffer.Slice(_consumed, len); _consumed += len; return(true); }
//internal BitStack _bitStack; public BinaryReaderState(TypeMap typeMap, int version, BinaryReaderOptions options = default) { _bytePosition = default; _inObject = default; _isNotPrimitive = default; _tokenType = default; _previousTokenType = default; _readerOptions = options; _typeMap = typeMap; _typeSeq = default; _version = version; _typeInfo = default; _propertySeq = default; _dicKeySeq = default; }
internal bool ReadPropertyName() { if (!RequestData(1)) { return(false); } byte b = _buffer[_consumed]; if ((b & 0x80) == 0x80) { // 键值对方式 } else { if (!RequestData(2)) { return(false); } ValueSpan = _buffer.Slice(_consumed, 2); ushort seq = (ushort)((ValueSpan[0] << 8) | ValueSpan[1]); if (seq == BinarySerializerConstants.EndObjectSeq) { // 对象结束 _tokenType = BinaryTokenType.EndObject; CurrentPropertySeq = default; } else { _tokenType = BinaryTokenType.PropertyName; CurrentPropertySeq = seq; } _consumed += 2; return(true); } return(false); }
internal bool ReadDictionaryKeySeq() { if (!RequestData(1)) { return(false); } ValueSpan = _buffer.Slice(_consumed, 1); _dicKeySeq = ValueSpan[0]; if (_dicKeySeq == BinarySerializerConstants.EndDictionaryKey) { _tokenType = BinaryTokenType.EndDictionaryKey; } else if (_dicKeySeq == BinarySerializerConstants.DictionaryKeySeq) { _tokenType = BinaryTokenType.DictionaryKeySeq; } else { ThrowHelper.ThrowBinaryReaderException(ref this, ExceptionResource.InvalidByte); } _consumed++; return(true); }
private static string GetResourceString(ExceptionResource resource, int currentDepth, byte token, BinaryTokenType tokenType) { string message = ""; switch (resource) { case ExceptionResource.DepthTooLarge: message = string.Format(Strings.DepthTooLarge, currentDepth & BinarySerializerConstants.RemoveFlagsBitMask, BinarySerializerConstants.MaxWriterDepth); break; default: Debug.Fail($"The ExceptionResource enum value: {resource} is not part of the switch. Add the appropriate case and exception message."); break; } return(message); }
public static InvalidOperationException GetInvalidOperationException(ExceptionResource resource, int currentDepth, byte token, BinaryTokenType tokenType) { string message = GetResourceString(resource, currentDepth, token, tokenType); InvalidOperationException ex = GetInvalidOperationException(message); ex.Source = ExceptionSourceValueToRethrowAsBinaryException; return(ex); }
public static void ThrowInvalidOperationException(ExceptionResource resource, int currentDepth, byte token, BinaryTokenType tokenType) { throw GetInvalidOperationException(resource, currentDepth, token, tokenType); }
public static InvalidOperationException GetInvalidOperationException_ExpectedString(BinaryTokenType tokenType) { return(GetInvalidOperationException("string", tokenType)); }
private static InvalidOperationException GetInvalidOperationException(string message, BinaryTokenType tokenType) { return(GetInvalidOperationException(string.Format(Strings.InvalidCast, tokenType, message))); }
internal bool TryRead(ref BinaryReader reader, Type typeToConvert, BinarySerializerOptions options, ref ReadStack state, out ReferenceID refId, out T value) { //if (state.Current.BinaryPropertyInfo != null && state.Current.BinaryPropertyInfo.ClassType != ClassType) //{ // // TODO // throw new Exception(); //}else if(state.Current.BinaryPropertyInfo == null && state.Current.BinaryClassInfo!=null && state.Current.BinaryClassInfo.ClassType != ClassType) //{ // throw new Exception(); //} refId = default; if (ClassType == ClassType.Value) { // A value converter should never be within a continuation. //Debug.Assert(!state.IsContinuation); // For perf and converter simplicity, handle null here instead of forwarding to the converter. if (reader.TokenType == BinaryTokenType.Null && !HandleNullOnRead) { if (!CanBeNull) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } value = default; return(true); } if (reader.CurrentTypeInfo.Type == TypeEnum.Nullable || // 当Nullable读取需要请求更多数据时,通过此判断进入 //(此时Converter可能已经读取了Nullable的实际类型,reader的当前类型信息已经发生了变化) (state.Current.BinaryClassInfo != null && state.Current.PropertyState > StackFramePropertyState.None && state.Current.BinaryPropertyInfo != null && state.TypeMap.GetTypeInfo(state.Current.BinaryPropertyInfo.TypeSeq).Type == TypeEnum.Nullable)) { state.Push(reader.CurrentTypeInfo); bool isSuccess = OnTryRead(ref reader, typeToConvert, options, ref state, out value); state.Pop(isSuccess); return(isSuccess); } int readCount = GetBytesCount(ref reader, options); // 读取指定数量的字节 if (readCount > 0) { if (!reader.ReadBytes(readCount)) { value = default; return(false); } } else if (readCount == BinarySerializerConstants.BytesCount_Dynamic) { if (!reader.ReadBytes()) { value = default; return(false); } } else if (readCount == BinarySerializerConstants.BytesCount_Auto) { // 自动 bool isContinue = !reader.TryReadValue(out bool isOk); if (!isOk) { ThrowHelper.ThrowBinaryException(); } else if (isContinue) { value = default; return(false); } } // #if !DEBUG // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { value = Read(ref reader, typeToConvert, options); } else // #endif { BinaryTokenType originalPropertyTokenType = reader.TokenType; // int originalPropertyDepth = reader.CurrentDepth; long originalPropertyBytesConsumed = reader.BytesConsumed; value = Read(ref reader, typeToConvert, options); //VerifyRead( // originalPropertyTokenType, // originalPropertyDepth, // originalPropertyBytesConsumed, // isValueConverter: true, // ref reader); } //if (CanBePolymorphic && options.ReferenceHandler != null && value is BinaryElement element) //{ // // Edge case where we want to lookup for a reference when parsing into typeof(object) // // instead of return `value` as a BinaryElement. // Debug.Assert(TypeToConvert == typeof(object)); // if (BinarySerializer.TryGetReferenceFromBinaryElement(ref state, element, out object? referenceValue)) // { // value = (T?)referenceValue; // } //} return(true); } bool success; bool wasContinuation = state.IsContinuation; if (!wasContinuation && reader.TokenType == BinaryTokenType.Null && state.Current.ObjectState < StackFrameObjectState.CreatedObject) { value = default; return(true); } // Remember if we were a continuation here since Push() may affect IsContinuation. // Console.WriteLine(reader.CurrentTypeInfo); // if (!isPolymorphic) // { state.Push(reader.CurrentTypeInfo); // } //if (CanBePolymorphic) //{ // Type type = state.TypeMap.GetType((state.Current.PolymorphicBinaryTypeInfo?? state.Current.BinaryTypeInfo).Seq); // if (type != TypeToConvert) // { // // state.Current // var binaryConverter = state.Current.InitializeReEntry(type, options); // if (binaryConverter != this) // { // // We found a different converter; forward to that. // if (binaryConverter.TryReadAsObject(ref reader, options, ref state, out object tmpValue)) // { // value = (T)tmpValue; // return true; // } // else // { // value = default; // return false; // } // } // } // else // { // } //} // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { if (reader.TokenType == BinaryTokenType.Null && !HandleNullOnRead && !wasContinuation) { if (!CanBeNull) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } // For perf and converter simplicity, handle null here instead of forwarding to the converter. value = default; success = true; } else { success = OnTryRead(ref reader, typeToConvert, options, ref state, out value); } } else { if (!wasContinuation) { // For perf and converter simplicity, handle null here instead of forwarding to the converter. if (reader.TokenType == BinaryTokenType.Null && !HandleNullOnRead) { if (!CanBeNull) { ThrowHelper.ThrowBinaryException_DeserializeUnableToConvertValue(TypeToConvert); } value = default; state.Pop(true); return(true); } Debug.Assert(state.Current.OriginalTokenType == BinaryTokenType.None); state.Current.OriginalTokenType = reader.TokenType; Debug.Assert(state.Current.OriginalDepth == 0); // state.Current.OriginalDepth = reader.CurrentDepth; } success = OnTryRead(ref reader, typeToConvert, options, ref state, out value); if (success) { if (state.IsContinuation) { // The resumable converter did not forward to the next converter that previously returned false. ThrowHelper.ThrowBinaryException_SerializationConverterRead(this); } VerifyRead( state.Current.OriginalTokenType, state.Current.OriginalDepth, bytesConsumed: 0, isValueConverter: false, ref reader); // No need to clear state.Current.* since a stack pop will occur. } } if (success && state.Current.RefState == RefState.Start) { refId = (ReferenceID)state.Current.ReturnValue; } // if (!isPolymorphic) // { state.Pop(success); // } return(success); }
internal void WriteStart(BinaryTokenType tokenType) { if (CurrentDepth >= BinarySerializerConstants.MaxWriterDepth) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.DepthTooLarge, _currentDepth, token: default, tokenType: default);