private bool Read( StreamingUnpacker unpacker, UnpackingMode unpackingMode ) { while ( !this.IsInStreamTail() ) { var data = unpacker.Unpack( this._currentSource.Stream, unpackingMode ); if ( data != null ) { this._data = data; return true; } else { this._mayInTail = true; } } return false; }
private bool UnpackRawLength( Stream source, UnpackingMode unpackingMode, out MessagePackObject? unpacked ) { int feeded; this._bytesBuffer = this._bytesBuffer.Feed( source, out feeded ); this._readByteLength += feeded; if ( this._bytesBuffer.IsFilled ) { var length = this._bytesBuffer.AsUInt32(); if ( length == 0 ) { // empty collection if ( unpackingMode == UnpackingMode.SkipSubtree ) { // Set dummy unpacked = MessagePackObject.Nil; } else { unpacked = CreateEmptyCollection( this._contextValueHeader ); } // Empty raw is not considered as EmptyCollection. return true; } this.TransitToUnpackRawBytes( length ); return this.UnpackRawBytes( source, unpackingMode, out unpacked ); } // Need more info. unpacked = null; return false; }
private bool UnpackRawBytes( Stream source, UnpackingMode unpackingMode, out MessagePackObject? unpacked ) { #if DEBUG Contract.Assert( this._bytesBuffer.BackingStore != null, this._bytesBuffer.ToString() ); #endif int feeded; this._bytesBuffer = this._bytesBuffer.Feed( source, out feeded ); this._readByteLength += feeded; if ( this._bytesBuffer.IsFilled ) { if ( unpackingMode == UnpackingMode.SkipSubtree ) { // Set dummy unpacked = MessagePackObject.Nil; } else { unpacked = this._bytesBuffer.AsMessagePackObject( this._contextValueHeader.Type ); } return true; } // Need more info. unpacked = null; return false; }
private bool UnpackHeader( Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { var b = source.ReadByte(); if ( b < 0 ) { result = null; return false; } this._readByteLength++; this._contextValueHeader = _headerArray[ b ]; return _headerUnpackings[ b ]( this, b, source, unpackingMode, out result ); }
private bool UnpackCollectionLength( Stream source, UnpackingMode unpackingMode, out MessagePackObject? unpacked ) { int feeded; this._bytesBuffer = this._bytesBuffer.Feed( source, out feeded ); this._readByteLength += feeded; if ( this._bytesBuffer.IsFilled ) { // new collection var length = this._bytesBuffer.AsUInt32(); if ( length == 0 ) { // empty collection if ( unpackingMode == UnpackingMode.SkipSubtree ) { // Set dummy unpacked = MessagePackObject.Nil; } else { unpacked = CreateEmptyCollection( this._contextValueHeader ); } this._lastEmptyCollection = ToEmptyCollectionType( this._contextValueHeader.Type ); return true; } this._collectionState.NewContextCollection( this._contextValueHeader, length ); this.TransitToUnpackContextCollection(); unpacked = null; return true; } // Try next iteration. unpacked = null; return false; }
private static bool UnpackArrayOrMapHeader( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { // Transit to UnpackCollectionLength @this._next = @this._unpackCollectionLength; @this._isInCollection = false; @this._bytesBuffer = ( b % 2 ) == 0 ? BytesBuffer.TwoBytes : BytesBuffer.FourBytes; if ( [email protected]( source, unpackingMode, out result ) ) { // Need to get more data return false; } return true; }
private static bool ThrowInvalidHeaderException( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { throw new MessageTypeException( String.Format( CultureInfo.CurrentCulture, "Header '0x{0:x2}' is not available.", b ) ); }
private static bool UnpackScalarHeader( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { // Transit to UnpackScalar @this._next = @this._unpackScalar; @this._isInCollection = false; @this._bytesBuffer = _scalarBuffers[ b % 4 ]; // Try to get body. if ( [email protected]( source, unpackingMode, out result ) ) { // Need more data return false; } return true; }
private static bool UnpackRawHeader( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { @this._next = @this._unpackRawLength; @this._isInCollection = false; @this._bytesBuffer = ( b % 2 ) == 0 ? BytesBuffer.TwoBytes : BytesBuffer.FourBytes; // Try to get length. return @this.UnpackRawLength( source, unpackingMode, out result ); }
private static bool UnpackFixRawLength( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { @this.TransitToUnpackRawBytes( unchecked( ( uint )( b & 0x1f ) ) ); // Try to get body. return @this.UnpackRawBytes( source, unpackingMode, out result ); }
private static bool UnpackTrue( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { result = _true; return true; }
private static bool UnpackEmptyRaw( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { result = _emptyBinary; @this._lastEmptyCollection = EmptyCollectionType.Raw; return true; }
private static bool UnpackFixArrayLength( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { var header = _headerArray[ b ]; @this._collectionState.NewContextCollection( header, header.ValueOrLength ); result = null; @this.TransitToUnpackContextCollection(); return true; }
private static bool UnpackEmptyArray( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { result = new MessagePackObject( _emptyArray, true ); @this._lastEmptyCollection = EmptyCollectionType.Array; return true; }
private static bool UnpackNegativeFixNum( StreamingUnpacker @this, int b, Stream source, UnpackingMode unpackingMode, out MessagePackObject? result ) { result = _negavieFixNums[ b & 0x1f ]; return true; }
/// <summary> /// Try unpack object from specified source. /// </summary> /// <param name="source">Input source to unpack.</param> /// <param name="unpackingMode"><see cref="UnpackingMode"/> that controls unpacking flow.</param> /// <returns> /// Unpacked entry. The mean of the entry depends on specified <paramref name="unpackingMode"/>. /// </returns> /// <remarks> /// <para> /// When this method returns null, caller can feed extra bytes to <paramref name="source"/> and invoke this again. /// It could succeed because this instance preserves previous invocation state, and required bytes are supplied. /// </para> /// <para> /// When this method completes unpackaging single <see cref="MessagePackObject"/> tree, /// this method stops iterating <paramref name="source"/> (via <see cref="IEnumerator<T>"/>. /// This behavior is notified via <see cref="IDisposable.Dispose">IEnumerator<T>.Dispose()</see> method. /// </para> /// </remarks> public MessagePackObject? Unpack( Stream source, UnpackingMode unpackingMode ) { // FIXME:BULK LOAD Contract.Assert( source != null ); this._lastEmptyCollection = EmptyCollectionType.None; MessagePackObject? collectionItemOrRoot; while ( this._next( source, unpackingMode, out collectionItemOrRoot ) ) { if ( collectionItemOrRoot != null ) { int depth = this._collectionState.Depth; var root = this.AddToContextCollection( collectionItemOrRoot.Value ); this._hasMoreEntries = depth <= this._collectionState.Depth; if ( root != null ) { #if DEBUG Contract.Assert( this._collectionState.IsEmpty ); #endif this._next = this._unpackHeader; this._isInCollection = false; #if DEBUG Contract.Assert( this._contextValueHeader.Type == MessageType.Unknown, this._contextValueHeader.ToString() );// null Contract.Assert( this._bytesBuffer.BackingStore == null, this._bytesBuffer.ToString() ); // null #endif if ( unpackingMode == UnpackingMode.PerEntry ) { if ( this._lastEmptyCollection != EmptyCollectionType.None ) { // It was empty collection. return 0; } else { // Last item return collectionItemOrRoot.Value; } } else { // Length var readByteLength = this._readByteLength; this._readByteLength = 0L; return readByteLength; } } } else { this._hasMoreEntries = true; } // There are more entries in the tree. if ( unpackingMode == UnpackingMode.PerEntry ) { // The unpacker may return unpacked collection item. if ( this._isInCollection ) { if ( this._collectionState.UnpackedItemsCount == 0 ) { // Count return this._collectionState.UnpackingItemsCount; } else if ( this._lastEmptyCollection != EmptyCollectionType.None ) { // Empty nested collection. return 0; } else { Contract.Assert( collectionItemOrRoot.HasValue ); return collectionItemOrRoot.Value; } } } } return null; }