// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace Thrift.Transport { abstract public class TEndpointTransport : TTransport { protected long MaxMessageSize { get => Configuration.MaxMessageSize; } protected long KnownMessageSize { get; private set; } protected long RemainingMessageSize { get; private set; } private readonly TConfiguration _configuration; public override TConfiguration Configuration { get => _configuration; } public TEndpointTransport( TConfiguration config) { _configuration = config ?? new TConfiguration(); Debug.Assert(Configuration != null); ResetMessageSizeAndConsumedBytes(); } /// /// Resets RemainingMessageSize to the configured maximum /// public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { // full reset if (newSize < 0) { KnownMessageSize = MaxMessageSize; RemainingMessageSize = MaxMessageSize; return; } // update only: message size can shrink, but not grow Debug.Assert(KnownMessageSize <= MaxMessageSize); if (newSize > KnownMessageSize) throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "MaxMessageSize reached"); KnownMessageSize = newSize; RemainingMessageSize = newSize; } /// /// Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). /// Will throw if we already consumed too many bytes or if the new size is larger than allowed. /// /// public override void UpdateKnownMessageSize(long size) { var consumed = KnownMessageSize - RemainingMessageSize; ResetMessageSizeAndConsumedBytes(size); CountConsumedMessageBytes(consumed); } /// /// Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data /// /// public override void CheckReadBytesAvailable(long numBytes) { if ((RemainingMessageSize < numBytes) || (numBytes < 0)) throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "MaxMessageSize reached"); } /// /// Consumes numBytes from the RemainingMessageSize. /// /// protected void CountConsumedMessageBytes(long numBytes) { if (RemainingMessageSize >= numBytes) { RemainingMessageSize -= numBytes; } else { RemainingMessageSize = 0; throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "MaxMessageSize reached"); } } } }