@@ -7,6 +7,12 @@ public class Cell
77 public const int MaxRefs = 4 ;
88
99 public Cell ( ReadOnlySpan < byte > content , bool isAugmented , ICollection < Cell > ? refs = null )
10+ : this ( false , 0 , content , isAugmented , refs )
11+ {
12+ // Nothing.
13+ }
14+
15+ public Cell ( bool isExotic , byte level , ReadOnlySpan < byte > content , bool isAugmented , ICollection < Cell > ? refs = null )
1016 {
1117 if ( content . Length > MaxContentLength )
1218 {
@@ -23,6 +29,8 @@ public Cell(ReadOnlySpan<byte> content, bool isAugmented, ICollection<Cell>? ref
2329 throw new ArgumentOutOfRangeException ( nameof ( refs ) , $ "Too many refs ({ refs . Count } ), only { MaxRefs } are allowed.") ;
2430 }
2531
32+ this . IsExotic = isExotic ;
33+ this . Level = level ;
2634 this . Content = content . ToArray ( ) ;
2735 BitsCount = this . Content . Length * 8 ;
2836 if ( isAugmented )
@@ -48,6 +56,10 @@ public Cell(ReadOnlySpan<byte> content, bool isAugmented, ICollection<Cell>? ref
4856 this . Refs = refs ? . ToList ( ) . AsReadOnly ( ) ?? new List < Cell > ( ) . AsReadOnly ( ) ;
4957 }
5058
59+ public bool IsExotic { get ; set ; }
60+
61+ public byte Level { get ; set ; }
62+
5163 public byte [ ] Content { get ; init ; }
5264
5365 public bool IsAugmented { get ; init ; }
@@ -56,6 +68,35 @@ public Cell(ReadOnlySpan<byte> content, bool isAugmented, ICollection<Cell>? ref
5668
5769 public int BitsCount { get ; protected set ; }
5870
71+ public static ( byte refCount , bool isExotic , byte level , int dataLength , bool isAugmented ) ParseDescriptors ( byte d1 , byte d2 )
72+ {
73+ var refCount = d1 & 0b111 ;
74+ var isExotic = ( d1 & 0b1000 ) != 0 ;
75+ var level = d1 / 32 ;
76+ var isAugmented = ( d2 % 2 ) != 0 ;
77+ var dataLength = d2 / 2 + ( isAugmented ? 1 : 0 ) ;
78+ return ( ( byte ) refCount , isExotic , ( byte ) level , dataLength , isAugmented ) ;
79+ }
80+
81+ /// <summary>
82+ /// Builds cell d1 and d2 descriptors.
83+ /// </summary>
84+ /// <remarks>
85+ /// <para>tvm.pdf, 3.1.4. Standard cell representation:</para>
86+ /// <para>
87+ /// Byte d1 equals r + 8s + 32l, where 0 ≤ r ≤ 4 is the quantity of cell references contained
88+ /// in the cell, 0 ≤ l ≤ 3 is the level of the cell, and 0 ≤ s ≤ 1 is 1 for
89+ /// exotic cells and 0 for ordinary cells.
90+ /// </para>
91+ /// <para>Byte d2 equals ⌊b / 8⌋+⌈b / 8⌉, where 0 ≤ b ≤ 1023 is the quantity of data bits in c.</para>
92+ /// </remarks>
93+ public ( byte d1 , byte d2 ) GetDescriptors ( )
94+ {
95+ var d1 = 32 * Level + ( IsExotic ? 8 : 0 ) + Refs . Count ;
96+ var d2 = Math . Ceiling ( BitsCount / 8f ) + Math . Floor ( BitsCount / 8f ) ;
97+ return ( ( byte ) d1 , ( byte ) d2 ) ;
98+ }
99+
59100 public Slice BeginRead ( )
60101 {
61102 var bits = new bool [ BitsCount ] ;
0 commit comments