Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/bearssl/T0/ConstData.cs
/* | |||||
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> | |||||
* | |||||
* 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 System.Collections.Generic; | |||||
using System.Text; | |||||
class ConstData { | |||||
internal long ID { get; private set; } | |||||
internal int Address { get; set; } | |||||
internal int Length { | |||||
get { | |||||
return len; | |||||
} | |||||
} | |||||
byte[] buf; | |||||
int len; | |||||
internal ConstData(T0Comp ctx) | |||||
{ | |||||
ID = ctx.NextBlobID(); | |||||
buf = new byte[4]; | |||||
len = 0; | |||||
} | |||||
void Expand(int elen) | |||||
{ | |||||
int tlen = len + elen; | |||||
if (tlen > buf.Length) { | |||||
int nlen = Math.Max(buf.Length << 1, tlen); | |||||
byte[] nbuf = new byte[nlen]; | |||||
Array.Copy(buf, 0, nbuf, 0, len); | |||||
buf = nbuf; | |||||
} | |||||
} | |||||
internal void Add8(byte b) | |||||
{ | |||||
Expand(1); | |||||
buf[len ++] = b; | |||||
} | |||||
internal void Add16(int x) | |||||
{ | |||||
Expand(2); | |||||
buf[len ++] = (byte)(x >> 8); | |||||
buf[len ++] = (byte)x; | |||||
} | |||||
internal void Add24(int x) | |||||
{ | |||||
Expand(3); | |||||
buf[len ++] = (byte)(x >> 16); | |||||
buf[len ++] = (byte)(x >> 8); | |||||
buf[len ++] = (byte)x; | |||||
} | |||||
internal void Add32(int x) | |||||
{ | |||||
Expand(4); | |||||
buf[len ++] = (byte)(x >> 24); | |||||
buf[len ++] = (byte)(x >> 16); | |||||
buf[len ++] = (byte)(x >> 8); | |||||
buf[len ++] = (byte)x; | |||||
} | |||||
internal void AddString(string s) | |||||
{ | |||||
byte[] sd = Encoding.UTF8.GetBytes(s); | |||||
Expand(sd.Length + 1); | |||||
Array.Copy(sd, 0, buf, len, sd.Length); | |||||
buf[len + sd.Length] = 0; | |||||
len += sd.Length + 1; | |||||
} | |||||
void CheckIndex(int off, int dlen) | |||||
{ | |||||
if (off < 0 || off > (len - dlen)) { | |||||
throw new IndexOutOfRangeException(); | |||||
} | |||||
} | |||||
internal void Set8(int off, byte v) | |||||
{ | |||||
CheckIndex(off, 1); | |||||
buf[off] = v; | |||||
} | |||||
internal byte Read8(int off) | |||||
{ | |||||
CheckIndex(off, 1); | |||||
return buf[off]; | |||||
} | |||||
internal int Read16(int off) | |||||
{ | |||||
CheckIndex(off, 2); | |||||
return (buf[off] << 8) | buf[off + 1]; | |||||
} | |||||
internal int Read24(int off) | |||||
{ | |||||
CheckIndex(off, 3); | |||||
return (buf[off] << 16) | (buf[off + 1] << 8) | buf[off + 2]; | |||||
} | |||||
internal int Read32(int off) | |||||
{ | |||||
CheckIndex(off, 4); | |||||
return (buf[off] << 24) | (buf[off + 1] << 16) | |||||
| (buf[off + 2] << 8) | buf[off + 3]; | |||||
} | |||||
internal string ToString(int off) | |||||
{ | |||||
StringBuilder sb = new StringBuilder(); | |||||
for (;;) { | |||||
int x = DecodeUTF8(ref off); | |||||
if (x == 0) { | |||||
return sb.ToString(); | |||||
} | |||||
if (x < 0x10000) { | |||||
sb.Append((char)x); | |||||
} else { | |||||
x -= 0x10000; | |||||
sb.Append((char)(0xD800 + (x >> 10))); | |||||
sb.Append((char)(0xDC00 + (x & 0x3FF))); | |||||
} | |||||
} | |||||
} | |||||
int DecodeUTF8(ref int off) | |||||
{ | |||||
if (off >= len) { | |||||
throw new IndexOutOfRangeException(); | |||||
} | |||||
int x = buf[off ++]; | |||||
if (x < 0xC0 || x > 0xF7) { | |||||
return x; | |||||
} | |||||
int elen, acc; | |||||
if (x >= 0xF0) { | |||||
elen = 3; | |||||
acc = x & 0x07; | |||||
} else if (x >= 0xE0) { | |||||
elen = 2; | |||||
acc = x & 0x0F; | |||||
} else { | |||||
elen = 1; | |||||
acc = x & 0x1F; | |||||
} | |||||
if (off + elen > len) { | |||||
return x; | |||||
} | |||||
for (int i = 0; i < elen; i ++) { | |||||
int y = buf[off + i]; | |||||
if (y < 0x80 || y >= 0xC0) { | |||||
return x; | |||||
} | |||||
acc = (acc << 6) + (y & 0x3F); | |||||
} | |||||
if (acc > 0x10FFFF) { | |||||
return x; | |||||
} | |||||
off += elen; | |||||
return acc; | |||||
} | |||||
internal void Encode(BlobWriter bw) | |||||
{ | |||||
for (int i = 0; i < len; i ++) { | |||||
bw.Append(buf[i]); | |||||
} | |||||
} | |||||
} |