3232using System . Text ;
3333namespace System {
3434 // This class reads data from a byte array or file containing the terminfo capabilities
35- // information for any given terminal. The maximum allowed size is 4096 bytes.
35+ // information for any given terminal. The maximum allowed size is 4096 (or
36+ // 32768 for terminfo2) bytes.
3637 //
3738 // Terminfo database files are divided in the following sections:
3839 //
@@ -45,7 +46,7 @@ namespace System {
4546 //
4647 // The header is as follows:
4748 //
48- // Magic number (0x1 and 0x1A )
49+ // Magic number (0x11A/0432 or 0x21e/01036 for terminfo2 )
4950 // Terminal names size
5051 // Boolean section size
5152 // Numeric section size
@@ -58,8 +59,9 @@ namespace System {
5859 // The boolean capabilities section has bytes that are set to 1 if the capability is supported
5960 // and 0 otherwise. If the index of a capability is greater than the section size, 0 is assumed.
6061 //
61- // The numeric capabilities section holds 2-byte integers in little endian format. No negative
62- // values are allowed and the absence of a capability is marked as two 0xFF.
62+ // The numeric capabilities section holds 2-byte integers (4-byte integers for terminfo2) in
63+ // little endian format. No negative values are allowed and the absence of a capability is marked
64+ // as two 0xFF (four 0xFF for terminfo2).
6365 //
6466 // The string offsets section contains 2-byte integer offsets into the string capabilies section.
6567 // If the capability is not supported, the index will be two 0xFF bytes.
@@ -72,17 +74,17 @@ namespace System {
7274 //
7375
7476 class TermInfoReader {
75- //short nameSize;
76- short boolSize ;
77- short numSize ;
78- short strOffsets ;
79- //short strSize;
77+ int boolSize ;
78+ int numSize ;
79+ int strOffsets ;
8080
8181 //string [] names; // Last one is the description
8282 byte [ ] buffer ;
8383 int booleansOffset ;
8484 //string term;
8585
86+ int intOffset ;
87+
8688 public TermInfoReader ( string term , string filename )
8789 {
8890 using ( FileStream st = File . OpenRead ( filename ) ) {
@@ -114,12 +116,21 @@ public TermInfoReader (string term, byte [] buffer)
114116// get { return term; }
115117// }
116118
119+ void DetermineVersion ( short magic )
120+ {
121+ if ( magic == 0x11a )
122+ intOffset = 2 ;
123+ else if ( magic == 0x21e )
124+ intOffset = 4 ;
125+ else
126+ throw new Exception ( String . Format ( "Magic number is wrong: {0}" , magic ) ) ;
127+ }
128+
117129 void ReadHeader ( byte [ ] buffer , ref int position )
118130 {
119131 short magic = GetInt16 ( buffer , position ) ;
120132 position += 2 ;
121- if ( magic != 282 )
122- throw new Exception ( String . Format ( "Magic number is wrong: {0}" , magic ) ) ;
133+ DetermineVersion ( magic ) ;
123134
124135 /*nameSize =*/ GetInt16 ( buffer , position ) ;
125136 position += 2 ;
@@ -161,8 +172,8 @@ public int Get (TermInfoNumbers number)
161172 if ( ( offset % 2 ) == 1 )
162173 offset ++ ;
163174
164- offset += ( ( int ) number ) * 2 ;
165- return GetInt16 ( buffer , offset ) ;
175+ offset += ( ( int ) number ) * intOffset ;
176+ return GetInteger ( buffer , offset ) ;
166177 }
167178
168179 public string Get ( TermInfoStrings tstr )
@@ -175,7 +186,7 @@ public string Get (TermInfoStrings tstr)
175186 if ( ( offset % 2 ) == 1 )
176187 offset ++ ;
177188
178- offset += numSize * 2 ;
189+ offset += numSize * intOffset ;
179190 int off2 = GetInt16 ( buffer , offset + ( int ) tstr * 2 ) ;
180191 if ( off2 == - 1 )
181192 return null ;
@@ -193,7 +204,7 @@ public byte [] GetStringBytes (TermInfoStrings tstr)
193204 if ( ( offset % 2 ) == 1 )
194205 offset ++ ;
195206
196- offset += numSize * 2 ;
207+ offset += numSize * intOffset ;
197208 int off2 = GetInt16 ( buffer , offset + ( int ) tstr * 2 ) ;
198209 if ( off2 == - 1 )
199210 return null ;
@@ -211,6 +222,27 @@ short GetInt16 (byte [] buffer, int offset)
211222 return ( short ) ( uno + dos * 256 ) ;
212223 }
213224
225+ int GetInt32 ( byte [ ] buffer , int offset )
226+ {
227+ int b1 = ( int ) buffer [ offset ] ;
228+ int b2 = ( int ) buffer [ offset + 1 ] ;
229+ int b3 = ( int ) buffer [ offset + 2 ] ;
230+ int b4 = ( int ) buffer [ offset + 3 ] ;
231+ if ( b1 == 255 && b2 == 255 && b3 == 255 && b4 == 255 )
232+ return - 1 ;
233+
234+ return b1 + b2 << 8 + b3 << 16 + b4 << 24 ;
235+ }
236+
237+ int GetInteger ( byte [ ] buffer , int offset )
238+ {
239+ if ( intOffset == 2 )
240+ return GetInt16 ( buffer , offset ) ;
241+ else
242+ // intOffset == 4
243+ return GetInt32 ( buffer , offset ) ;
244+ }
245+
214246 string GetString ( byte [ ] buffer , int offset )
215247 {
216248 int length = 0 ;
@@ -249,5 +281,4 @@ internal static string Escape (string s)
249281 }
250282 }
251283}
252- #endif
253-
284+ #endif
0 commit comments