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 27 abstract class CodeElement { 28 29 internal int Address { get; set; } 30 31 internal int LastLength { get; set; } 32 33 // internal abstract int Length { get; } 34 CodeElement()35 internal CodeElement() 36 { 37 Address = -1; 38 } 39 SetJumpTarget(CodeElement target)40 internal virtual void SetJumpTarget(CodeElement target) 41 { 42 throw new Exception("Code element accepts no target"); 43 } 44 GetLength(bool oneByteCode)45 internal abstract int GetLength(bool oneByteCode); 46 Encode(BlobWriter bw, bool oneByteCode)47 internal abstract int Encode(BlobWriter bw, bool oneByteCode); 48 EncodeOneByte(uint val, BlobWriter bw)49 internal static int EncodeOneByte(uint val, BlobWriter bw) 50 { 51 if (val > 255) { 52 throw new Exception(string.Format( 53 "Cannot encode '{0}' over one byte", val)); 54 } 55 bw.Append((byte)val); 56 return 1; 57 } 58 Encode7EUnsigned(uint val, BlobWriter bw)59 internal static int Encode7EUnsigned(uint val, BlobWriter bw) 60 { 61 int len = 1; 62 for (uint w = val; w >= 0x80; w >>= 7) { 63 len ++; 64 } 65 if (bw != null) { 66 for (int k = (len - 1) * 7; k >= 0; k -= 7) { 67 int x = (int)(val >> k) & 0x7F; 68 if (k > 0) { 69 x |= 0x80; 70 } 71 bw.Append((byte)x); 72 } 73 } 74 return len; 75 } 76 Encode7ESigned(int val, BlobWriter bw)77 internal static int Encode7ESigned(int val, BlobWriter bw) 78 { 79 int len = 1; 80 if (val < 0) { 81 for (int w = val; w < -0x40; w >>= 7) { 82 len ++; 83 } 84 } else { 85 for (int w = val; w >= 0x40; w >>= 7) { 86 len ++; 87 } 88 } 89 if (bw != null) { 90 for (int k = (len - 1) * 7; k >= 0; k -= 7) { 91 int x = (int)(val >> k) & 0x7F; 92 if (k > 0) { 93 x |= 0x80; 94 } 95 bw.Append((byte)x); 96 } 97 } 98 return len; 99 } 100 } 101