1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// File: CompressedInteger.h
6//
7
8//
9// Class code:MetaData::CompressedInteger provides secure access to a compressed integer (as defined in CLI
10// ECMA specification). The integer is compressed into 1, 2 or 4 bytes. See code:CompressedInteger#Format
11// for full format description.
12//
13// ======================================================================================
14
15#pragma once
16
17#include "external.h"
18
19namespace MetaData
20{
21
22// --------------------------------------------------------------------------------------
23//
24// This class provides secure access to a compressed integer (as defined in CLI ECMA specification). The
25// integer is compressed into 1, 2 or 4 bytes. See code:CompressedInteger#Format for full format description.
26//
27class CompressedInteger
28{
29// #Format
30//
31// The format/encoding of compressed integer is (defined in ECMA CLI specification):
32// The encoding is 1, 2 or 4 bytes long and depends on the first byte value. If the first byte is (binary):
33// * 0xxx xxxx ... then it's 1 byte long and the value is 0xxx xxxx.
34// * 10xx xxxx ... then it's 2 bytes long and the value is 00xx xxxx yyyy yyyy, where yyyy yyyy is the
35// second byte. Though values smaller than code:const_Max1Byte are technically invalid
36// when encoded with 2 bytes.
37// * 110x xxxx ... then it's 4 bytes long and the value is 000x xxxx yyyy yyyy zzzz zzzz wwww wwww, where
38// yyyy yyyy is the 2nd byte, zzzz zzzz is the 3rd byte and wwww wwww is the 4th byte.
39// Though values smaller than code:const_Max2Bytes are technically invalid when encoded
40// with 4 bytes.
41// * 111x xxxx ... then it's invalid encoding.
42//
43// Note: Some encodings are invalid, but CLR accepts them (see code:DataBlob::GetCompressedU),
44// e.g. 1000 0000 0000 0000 (0x8000) encodes 0 while correct/valid encoding is 0000 0000 (0x00).
45//
46private:
47 // This class has only static methods and shouldn't be instantiated.
48 CompressedInteger() {}
49
50public:
51 static const UINT32 const_MaxEncodingSize = 4;
52
53 static const UINT32 const_Max1Byte = 0x7f;
54 static const UINT32 const_Max2Bytes = 0x3fff;
55 static const UINT32 const_Max4Bytes = 0x1fffffff;
56
57 static const UINT32 const_Max = const_Max4Bytes;
58
59public:
60 //
61 // Operations
62 //
63
64 // Returns TRUE if the value (nValue) fits into 1-byte, 2-bytes or 4-bytes encoding and fills
65 // *pcbEncodingSize with 1, 2 or 4.
66 // Returns FALSE if the value cannot be encoded as compressed integer, doesn't fill *pcbEncodingSize
67 // then.
68 __checkReturn
69 __success(return)
70 static inline BOOL GetEncodingSize(
71 UINT32 nValue,
72 __out UINT32 *pcbEncodingSize);
73 // Returns TRUE if the value (nValue) fits into 1-byte, 2-bytes or 4-bytes encoding and fills
74 // *pcbEncodingSize with 1, 2 or 4 and *pnEncodedValue with the encoded value.
75 // Returns FALSE if the value cannot be encoded as compressed integer, doesn't fill *pcbEncodingSize
76 // nor *pnEncodedValue then.
77 __success(return)
78 static inline BOOL Encode(
79 UINT32 nValue,
80 __out UINT32 *pnEncodedValue,
81 __out UINT32 *pcbEncodingSize);
82
83}; // class CompressedInteger
84
85}; // namespace MetaData
86
87#include "compressedinteger.inl"
88