summaryrefslogtreecommitdiff
path: root/src/md/compressedinteger.inl
blob: 94fabfda5cb3ead143f687452ac1d964fd1c0b4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// 
// File: CompressedInteger.inl
// 

// 
// Class code:MetaData::CompressedInteger provides secure access to a compressed integer (as defined in CLI 
// ECMA specification). The integer is compressed into 1, 2 or 4 bytes. See code:CompressedInteger#Format 
// for full format description.
// 
// ======================================================================================

#pragma once

#include "compressedinteger.h"

namespace MetaData
{

// --------------------------------------------------------------------------------------
// 
// Returns TRUE if the value (nValue) fits into 1-byte, 2-bytes or 4-bytes encoding and fills 
// *pcbEncodingSize with 1, 2 or 4.
// Returns FALSE if the value cannot be encoded as compressed integer, doesn't fill *pcbEncodingSize then.
// 
__checkReturn 
//static 
inline 
BOOL 
CompressedInteger::GetEncodingSize(
          UINT32  nValue, 
    __out UINT32 *pcbEncodingSize)
{
    // Does it fit into 1-byte encoding?
    if (nValue <= const_Max1Byte)
    {   // The value fits into 1 byte (binary format 0xxx xxxx)
        *pcbEncodingSize = 1;
        return TRUE;
    }
    // Does it fit into 2-bytes encoding?
    if (nValue <= const_Max2Bytes)
    {   // The value fits into 2 bytes (binary format 10xx xxxx yyyy yyyy)
        *pcbEncodingSize = 2;
        return TRUE;
    }
    // Does it fit into 4-bytes encoding?
    if (nValue <= const_Max4Bytes)
    {   // The value fits into 4 bytes (binary format 110x xxxx yyyy yyyy zzzz zzzz wwww wwww)
        *pcbEncodingSize = 4;
        return TRUE;
    }
    // The value cannot be encoded as compressed integer
    return FALSE;
} // CompressedInteger::GetEncodingSize

// --------------------------------------------------------------------------------------
// 
// Returns TRUE if the value (nValue) fits into 1-byte, 2-bytes or 4-bytes encoding and fills 
// *pcbEncodingSize with 1, 2 or 4 and *pnEncodedValue with the encoded value.
// Returns FALSE if the value cannot be encoded as compressed integer, doesn't fill *pcbEncodingSize 
// nor *pnEncodedValue then.
// 
__checkReturn 
//static 
inline 
BOOL 
CompressedInteger::Encode(
          UINT32  nValue, 
    __out UINT32 *pnEncodedValue, 
    __out UINT32 *pcbEncodingSize)
{
    // Does it fit into 1-byte encoding?
    if (nValue <= const_Max1Byte)
    {   // The value fits into 1 byte (binary format 0xxx xxxx)
        *pnEncodedValue = nValue;
        *pcbEncodingSize = 1;
        return TRUE;
    }
    // Does it fit into 2-bytes encoding?
    if (nValue <= const_Max2Bytes)
    {   // The value fits into 2 bytes (binary format 10xx xxxx yyyy yyyy)
        *pnEncodedValue = 0x8000 | nValue;
        *pcbEncodingSize = 2;
        return TRUE;
    }
    // Does it fit into 4-bytes encoding?
    if (nValue <= const_Max4Bytes)
    {   // The value fits into 4 bytes (binary format 110x xxxx yyyy yyyy zzzz zzzz wwww wwww)
        *pnEncodedValue = 0xC0000000 | nValue;
        *pcbEncodingSize = 4;
        return TRUE;
    }
    // The value cannot be encoded as compressed integer
    return FALSE;
} // CompressedInteger::Encode

};  // namespace MetaData