1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
//------------------------------------------------------------------------------
// <copyright file="LosWriter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if !OBJECTSTATEFORMATTER
namespace System.Web.UI {
using System.Text;
using System.IO;
using System.Collections;
using System.Globalization;
using System.Web.Configuration;
internal class LosWriter : TextWriter{
private const int BUFFER_SIZE = 4096;
private const int MAX_FREE_BUFFERS = 16;
private static CharBufferAllocator _charBufferAllocator;
private static CharBufferAllocator _charBufferAllocatorBase64;
private static UbyteBufferAllocator _byteBufferAllocator;
private char[] _charBuffer;
private byte[] _byteBuffer;
private int _size;
private int _freePos;
private bool _recyclable;
static LosWriter() {
_charBufferAllocator = new CharBufferAllocator(BUFFER_SIZE, MAX_FREE_BUFFERS);
int byteBufferSize = Encoding.UTF8.GetMaxByteCount(BUFFER_SIZE);
_byteBufferAllocator = new UbyteBufferAllocator(byteBufferSize, MAX_FREE_BUFFERS);
// base64 increases data by up to 33%, so we err on the side of caution here
_charBufferAllocatorBase64 = new CharBufferAllocator((int) (byteBufferSize * 1.35), MAX_FREE_BUFFERS);
}
internal LosWriter() {
_charBuffer = (char[])_charBufferAllocator.GetBuffer();
_size = _charBuffer.Length;
_freePos = 0;
_recyclable = true;
}
internal void Dispose() {
if (_recyclable) {
if (_charBuffer != null)
_charBufferAllocator.ReuseBuffer(_charBuffer);
if (_byteBuffer != null)
_byteBufferAllocator.ReuseBuffer(_byteBuffer);
}
_byteBuffer = null;
_charBuffer = null;
}
public override Encoding Encoding {
get { return null; }
}
private void Grow(int newSize) {
if (newSize <= _size)
return;
if (newSize < _size*2)
newSize = _size*2;
char[] newBuffer = new char[newSize];
if (_freePos > 0)
Array.Copy(_charBuffer, newBuffer, _freePos);
_charBuffer = newBuffer;
_size = newSize;
_recyclable = false;
}
public override void Write(char ch) {
if (_freePos >= _size)
Grow(_freePos+1);
_charBuffer[_freePos++] = ch;
}
public override void Write(String s) {
int len = s.Length;
int newFreePos = _freePos + len;
if (newFreePos > _size)
Grow(newFreePos);
s.CopyTo(0, _charBuffer, _freePos, len);
_freePos = newFreePos;
}
internal /*public*/ void CompleteTransforms(TextWriter output, bool enableMac, byte[] macKey) {
int len = 0;
// convert to bytes
if (_recyclable) {
// still using the original recyclable char buffer
// -- can use recyclable byte buffer
_byteBuffer = (byte[])_byteBufferAllocator.GetBuffer();
if (_freePos > 0)
len = Encoding.UTF8.GetBytes(_charBuffer, 0, _freePos, _byteBuffer, 0);
// do the mac encoding if requested
if (enableMac) {
// the size of the output array depends on the key length and encryption type
// so we can't use the recyclable buffers after this
byte[] data = MachineKeySection.GetEncodedData(_byteBuffer, macKey, 0, ref len);
string serialized = Convert.ToBase64String(data, 0, len);
output.Write(serialized);
}
else {
char[] base64chars = (char[]) _charBufferAllocatorBase64.GetBuffer();
len = Convert.ToBase64CharArray(_byteBuffer, 0, len, base64chars, 0);
output.Write(base64chars, 0, len);
_charBufferAllocatorBase64.ReuseBuffer(base64chars);
}
}
else {
_byteBuffer = Encoding.UTF8.GetBytes(_charBuffer, 0, _freePos);
len = _byteBuffer.Length;
if (enableMac)
_byteBuffer = MachineKeySection.GetEncodedData(_byteBuffer, macKey, 0, ref len);
string serialized = Convert.ToBase64String(_byteBuffer);
output.Write(serialized);
}
}
}
}
#endif // !OBJECTSTATEFORMATTER
|