File: LosWriter.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (146 lines) | stat: -rw-r--r-- 5,033 bytes parent folder | download | duplicates (7)
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