]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/T0/ConstData.cs
Add libbearssl
[FreeBSD/FreeBSD.git] / contrib / bearssl / T0 / ConstData.cs
1 /*
2  * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining 
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be 
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 using System;
26 using System.Collections.Generic;
27 using System.Text;
28
29 class ConstData {
30
31         internal long ID { get; private set; }
32         internal int Address { get; set; }
33         internal int Length {
34                 get {
35                         return len;
36                 }
37         }
38
39         byte[] buf;
40         int len;
41
42         internal ConstData(T0Comp ctx)
43         {
44                 ID = ctx.NextBlobID();
45                 buf = new byte[4];
46                 len = 0;
47         }
48
49         void Expand(int elen)
50         {
51                 int tlen = len + elen;
52                 if (tlen > buf.Length) {
53                         int nlen = Math.Max(buf.Length << 1, tlen);
54                         byte[] nbuf = new byte[nlen];
55                         Array.Copy(buf, 0, nbuf, 0, len);
56                         buf = nbuf;
57                 }
58         }
59
60         internal void Add8(byte b)
61         {
62                 Expand(1);
63                 buf[len ++] = b;
64         }
65
66         internal void Add16(int x)
67         {
68                 Expand(2);
69                 buf[len ++] = (byte)(x >> 8);
70                 buf[len ++] = (byte)x;
71         }
72
73         internal void Add24(int x)
74         {
75                 Expand(3);
76                 buf[len ++] = (byte)(x >> 16);
77                 buf[len ++] = (byte)(x >> 8);
78                 buf[len ++] = (byte)x;
79         }
80
81         internal void Add32(int x)
82         {
83                 Expand(4);
84                 buf[len ++] = (byte)(x >> 24);
85                 buf[len ++] = (byte)(x >> 16);
86                 buf[len ++] = (byte)(x >> 8);
87                 buf[len ++] = (byte)x;
88         }
89
90         internal void AddString(string s)
91         {
92                 byte[] sd = Encoding.UTF8.GetBytes(s);
93                 Expand(sd.Length + 1);
94                 Array.Copy(sd, 0, buf, len, sd.Length);
95                 buf[len + sd.Length] = 0;
96                 len += sd.Length + 1;
97         }
98
99         void CheckIndex(int off, int dlen)
100         {
101                 if (off < 0 || off > (len - dlen)) {
102                         throw new IndexOutOfRangeException();
103                 }
104         }
105
106         internal void Set8(int off, byte v)
107         {
108                 CheckIndex(off, 1);
109                 buf[off] = v;
110         }
111
112         internal byte Read8(int off)
113         {
114                 CheckIndex(off, 1);
115                 return buf[off];
116         }
117
118         internal int Read16(int off)
119         {
120                 CheckIndex(off, 2);
121                 return (buf[off] << 8) | buf[off + 1];
122         }
123
124         internal int Read24(int off)
125         {
126                 CheckIndex(off, 3);
127                 return (buf[off] << 16) | (buf[off + 1] << 8) | buf[off + 2];
128         }
129
130         internal int Read32(int off)
131         {
132                 CheckIndex(off, 4);
133                 return (buf[off] << 24) | (buf[off + 1] << 16)
134                         | (buf[off + 2] << 8) | buf[off + 3];
135         }
136
137         internal string ToString(int off)
138         {
139                 StringBuilder sb = new StringBuilder();
140                 for (;;) {
141                         int x = DecodeUTF8(ref off);
142                         if (x == 0) {
143                                 return sb.ToString();
144                         }
145                         if (x < 0x10000) {
146                                 sb.Append((char)x);
147                         } else {
148                                 x -= 0x10000;
149                                 sb.Append((char)(0xD800 + (x >> 10)));
150                                 sb.Append((char)(0xDC00 + (x & 0x3FF)));
151                         }
152                 }
153         }
154
155         int DecodeUTF8(ref int off)
156         {
157                 if (off >= len) {
158                         throw new IndexOutOfRangeException();
159                 }
160                 int x = buf[off ++];
161                 if (x < 0xC0 || x > 0xF7) {
162                         return x;
163                 }
164                 int elen, acc;
165                 if (x >= 0xF0) {
166                         elen = 3;
167                         acc = x & 0x07;
168                 } else if (x >= 0xE0) {
169                         elen = 2;
170                         acc = x & 0x0F;
171                 } else {
172                         elen = 1;
173                         acc = x & 0x1F;
174                 }
175                 if (off + elen > len) {
176                         return x;
177                 }
178                 for (int i = 0; i < elen; i ++) {
179                         int y = buf[off + i];
180                         if (y < 0x80 || y >= 0xC0) {
181                                 return x;
182                         }
183                         acc = (acc << 6) + (y & 0x3F);
184                 }
185                 if (acc > 0x10FFFF) {
186                         return x;
187                 }
188                 off += elen;
189                 return acc;
190         }
191
192         internal void Encode(BlobWriter bw)
193         {
194                 for (int i = 0; i < len; i ++) {
195                         bw.Append(buf[i]);
196                 }
197         }
198 }