summary refs log tree commit diff
path: root/crypto/src/asn1/IndefiniteLengthInputStream.cs
blob: 09d0e3a4294b1bc14f70cc7d3204190d387a2dd9 (plain) (blame)
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
using System;
using System.IO;

namespace Org.BouncyCastle.Asn1
{
	class IndefiniteLengthInputStream
		: LimitedInputStream
	{
        private int _lookAhead;
        private bool _eofOn00 = true;

		internal IndefiniteLengthInputStream(
			Stream	inStream,
			int		limit)
			: base(inStream, limit)
		{
            _lookAhead = RequireByte();
            CheckForEof();
		}

		internal void SetEofOn00(
			bool eofOn00)
		{
			_eofOn00 = eofOn00;
            if (_eofOn00)
            {
                CheckForEof();
            }
        }

        private bool CheckForEof()
		{
            if (_lookAhead == 0x00)
            {
                int extra = RequireByte();
                if (extra != 0)
                {
                    throw new IOException("malformed end-of-contents marker");
                }

                _lookAhead = -1;
                SetParentEofDetect(true);
                return true;
            }
            return _lookAhead < 0;
        }

		public override int Read(
			byte[]	buffer,
			int		offset,
			int		count)
		{
			// Only use this optimisation if we aren't checking for 00
			if (_eofOn00 || count <= 1)
				return base.Read(buffer, offset, count);

			if (_lookAhead < 0)
				return 0;

			int numRead = _in.Read(buffer, offset + 1, count - 1);

			if (numRead <= 0)
			{
				// Corrupted stream
				throw new EndOfStreamException();
			}

			buffer[offset] = (byte)_lookAhead;
			_lookAhead = RequireByte();

			return numRead + 1;
		}

		public override int ReadByte()
		{
            if (_eofOn00 && CheckForEof())
				return -1;

            int result = _lookAhead;
            _lookAhead = RequireByte();
            return result;
		}

        private int RequireByte()
        {
            int b = _in.ReadByte();
            if (b < 0)
            {
                // Corrupted stream
                throw new EndOfStreamException();
            }
            return b;
        }
	}
}

//using System;
//using System.IO;

//namespace Org.BouncyCastle.Asn1
//{
//    class IndefiniteLengthInputStream
//        : LimitedInputStream
//    {
//        private bool _eofReached = false;
//        private bool _eofOn00 = true;

//        internal IndefiniteLengthInputStream(
//            Stream	inStream,
//            int		limit)
//            : base(inStream, limit)
//        {
//        }

//        internal void SetEofOn00(
//            bool eofOn00)
//        {
//            _eofOn00 = eofOn00;
//        }

//        public override int Read(
//            byte[]	buffer,
//            int		offset,
//            int		count)
//        {
//            if (_eofReached)
//                return 0;

//            if (_eofOn00)
//                return base.Read(buffer, offset, count);

//            int numRead = _in.Read(buffer, offset, count);

//            if (numRead <= 0)
//                throw new EndOfStreamException();

//            return numRead;
//        }

//        public override int ReadByte()
//        {
//            if (_eofReached)
//                return -1;

//            int b1 = _in.ReadByte();

//            if (b1 < 0)
//                throw new EndOfStreamException();

//            if (b1 == 0 && _eofOn00)
//            {
//                int b2 = _in.ReadByte();

//                if (b2 < 0)
//                    throw new EndOfStreamException();

//                if (b2 == 0)
//                {
//                    _eofReached = true;
//                    SetParentEofDetect(true);
//                    return -1;
//                }

//                throw new InvalidDataException();
//            }

//            return b1;
//        }
//    }
//}