| File: System\Formats\Cbor\Reader\CborReader.SkipValue.cs | Web Access |
| Project: src\runtime\src\libraries\System.Formats.Cbor\src\System.Formats.Cbor.csproj (System.Formats.Cbor) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; namespace System.Formats.Cbor { public partial class CborReader { /// <summary>Reads the contents of the next value, discarding the result and advancing the reader.</summary> /// <param name="disableConformanceModeChecks"><see langword="true" /> to disable conformance mode validation for the skipped values, equivalent to using <see cref="CborConformanceMode.Lax" />; otherwise, <see langword="false" />.</param> /// <exception cref="InvalidOperationException">The reader is not at the start of new value.</exception> /// <exception cref="CborContentException"><para>The next value has an invalid CBOR encoding.</para> /// <para>-or-</para> /// <para>There was an unexpected end of CBOR encoding data.</para> /// <para>-or-</para> /// <para>The next value uses a CBOR encoding that is not valid under the current conformance mode.</para></exception> public void SkipValue(bool disableConformanceModeChecks = false) { SkipToAncestor(0, disableConformanceModeChecks); } /// <summary>Reads the remaining contents of the current value context, discarding results and advancing the reader to the next value in the parent context.</summary> /// <param name="disableConformanceModeChecks"><see langword="true" /> to disable conformance mode validation for the skipped values, equivalent to using <see cref="CborConformanceMode.Lax" />; otherwise, <see langword="false" />.</param> /// <exception cref="InvalidOperationException">The reader is at the root context</exception> /// <exception cref="CborContentException"><para>The next value has an invalid CBOR encoding.</para> /// <para>-or-</para> /// <para>There was an unexpected end of CBOR encoding data.</para> /// <para>-or-</para> /// <para>The next value uses a CBOR encoding that is not valid under the current conformance mode.</para></exception> public void SkipToParent(bool disableConformanceModeChecks = false) { if (_currentMajorType is null) { throw new InvalidOperationException(SR.Cbor_Reader_IsAtRootContext); } SkipToAncestor(1, disableConformanceModeChecks); } private void SkipToAncestor(int depth, bool disableConformanceModeChecks) { Debug.Assert(0 <= depth && depth <= CurrentDepth); Checkpoint checkpoint = CreateCheckpoint(); _isConformanceModeCheckEnabled = !disableConformanceModeChecks; try { do { SkipNextNode(ref depth); } while (depth > 0); } catch { RestoreCheckpoint(in checkpoint); throw; } finally { _isConformanceModeCheckEnabled = true; } } private void SkipNextNode(ref int depth) { CborReaderState state; // peek, skipping any tags we might encounter while ((state = PeekStateCore()) == CborReaderState.Tag) { ReadTag(); } switch (state) { case CborReaderState.UnsignedInteger: ReadUInt64(); break; case CborReaderState.NegativeInteger: ReadCborNegativeIntegerRepresentation(); break; case CborReaderState.ByteString: SkipString(type: CborMajorType.ByteString); break; case CborReaderState.TextString: SkipString(type: CborMajorType.TextString); break; case CborReaderState.StartIndefiniteLengthByteString: ReadStartIndefiniteLengthByteString(); depth++; break; case CborReaderState.EndIndefiniteLengthByteString: ValidatePop(state, depth); ReadEndIndefiniteLengthByteString(); depth--; break; case CborReaderState.StartIndefiniteLengthTextString: ReadStartIndefiniteLengthTextString(); depth++; break; case CborReaderState.EndIndefiniteLengthTextString: ValidatePop(state, depth); ReadEndIndefiniteLengthTextString(); depth--; break; case CborReaderState.StartArray: ReadStartArray(); depth++; break; case CborReaderState.EndArray: ValidatePop(state, depth); ReadEndArray(); depth--; break; case CborReaderState.StartMap: ReadStartMap(); depth++; break; case CborReaderState.EndMap: ValidatePop(state, depth); ReadEndMap(); depth--; break; case CborReaderState.HalfPrecisionFloat: case CborReaderState.SinglePrecisionFloat: case CborReaderState.DoublePrecisionFloat: ReadDouble(); break; case CborReaderState.Null: case CborReaderState.Boolean: case CborReaderState.SimpleValue: ReadSimpleValue(); break; default: throw new InvalidOperationException(SR.Format(SR.Cbor_Reader_Skip_InvalidState, state)); } // guards against cases where the caller attempts to skip when reader is not positioned at the start of a value static void ValidatePop(CborReaderState state, int depth) { if (depth == 0) { throw new InvalidOperationException(SR.Format(SR.Cbor_Reader_Skip_InvalidState, state)); } } } } }