Compress Int
/* * PERWAPI - An API for Reading and Writing PE Files * * Copyright (c) Diane Corney, Queensland University of Technology, 2004. * * This program is free software; you can redistribute it and/or modify * it under the terms of the PERWAPI Copyright as included with this * distribution in the file PERWAPIcopyright.rtf. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY as is explained in the copyright notice. * * The author may be contacted at d.corney@qut.edu.au * * Version Date: 26/01/07 */ using System; namespace QUT.PERWAPI { /// <summary> /// Diagnostic /// </summary> public class Diag { /// <summary> /// Flag for diagnostic output. /// </summary> public static bool DiagOn = false; } public static class BlobUtil { public static byte[] CompressInt(int val) { // This code is based on a revised version of the // ECMA-335 spec which clarifies the encoding of // array lower bounds. (kjg 2008-Feb-22 ) // uint uVal = ((uint)val) << 1; uint sign = (val < 0 ? (uint)1 : 0); if (-64 <= val && val <= 63) { uVal = uVal & 0x7f | sign; return new byte[] { (byte)uVal }; } else if (-8192 <= val && val <= 8191) { uVal = uVal & 0x3fff | 0x8000 | sign; return new byte[] { (byte)(uVal >> 8), (byte)uVal }; } else if (-268435456 <= val && val <= 268435455) { uVal = uVal & 0x1fffffff | 0xc0000000 | sign; return new byte[] { (byte)(uVal >> 24), (byte)(uVal >> 16), (byte)(uVal >> 8), (byte)uVal }; } else throw new OverflowException("Value cannot be compressed"); } public static byte[] CompressUInt(uint val) { if (val > 0x1fffffff) throw new OverflowException("Value cannot be compressed"); return CompressNum(val); } private static byte[] CompressNum(uint num) { byte[] rslt = null; if (num <= 0x7f) { rslt = new byte[1]; rslt[0] = (byte)num; } else if (num <= 0x3fff) { rslt = new byte[2]; rslt[0] = (byte)((num >> 8) | 0x80); rslt[1] = (byte)(num & 0xff); } else { rslt = new byte[4]; rslt[0] = (byte)((num >> 24) | 0xc0); rslt[1] = (byte)((num >> 16) & 0xff); rslt[2] = (byte)((num >> 8) & 0xff); rslt[3] = (byte)(num & 0xff); } return rslt; } } }