// // Buffers.cs: // // Author: // Leonardo Taglialegne // // Copyright (c) 2013 Leonardo Taglialegne. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.WebServer.FastCgi.Compatibility; namespace Mono.WebServer.FastCgi { public class Buffers { public CompatArraySegment? Header { get; private set; } public CompatArraySegment? Body { get; private set; } public CompatArraySegment? Padding { get; private set; } readonly BufferManager bigBufferManager; readonly BufferManager smallBufferManager; public Buffers () { } public Buffers (BufferManager bigBufferManager, BufferManager smallBufferManager) { if (bigBufferManager == null) throw new ArgumentNullException ("bigBufferManager"); if (smallBufferManager == null) throw new ArgumentNullException ("smallBufferManager"); this.bigBufferManager = bigBufferManager; this.smallBufferManager = smallBufferManager; Header = smallBufferManager.ClaimBuffer (); Body = bigBufferManager.ClaimBuffer (); Padding = smallBufferManager.ClaimBuffer (); } public Buffers (byte[] buffer, int headerSize, int bodySize) { Header = MaybeSegment (buffer, 0, headerSize); Body = MaybeSegment (buffer, headerSize, bodySize); Padding = MaybeSegment (buffer, headerSize + bodySize); } public CompatArraySegment EnforceHeaderLength (int length) { if (Header == null || Header.Value.Count < length) { if (Header != null) smallBufferManager.ReturnBuffer (Header.Value); Header = new CompatArraySegment (new byte[length]); } return Header.Value; } public CompatArraySegment EnforceBodyLength (int length) { if (Body == null || Body.Value.Count < length) { if (Body != null) bigBufferManager.ReturnBuffer (Body.Value); Body = new CompatArraySegment (new byte[length]); } return Body.Value; } public CompatArraySegment EnforcePaddingLength (int length) { if (Padding == null || Padding.Value.Count < length) { if (Padding != null) smallBufferManager.ReturnBuffer (Padding.Value); Padding = new CompatArraySegment (new byte[length]); } return Padding.Value; } static CompatArraySegment? MaybeSegment (byte[] buffer, int offset) { return buffer == null ? null : MaybeSegment (buffer, offset, buffer.Length - offset); } static CompatArraySegment? MaybeSegment (byte[] buffer, int offset, int count) { if (buffer == null || offset < 0 || count < 0 || offset + count > buffer.Length) return null; return new CompatArraySegment (buffer, offset, count); } public void Return () { if (smallBufferManager != null) { if (Header != null) { smallBufferManager.ReturnBuffer (Header.Value); Header = null; } if (Padding != null) { smallBufferManager.ReturnBuffer (Padding.Value); Padding = null; } } if (bigBufferManager == null || Body == null) return; bigBufferManager.ReturnBuffer (Body.Value); Body = null; } } }