**** Merged from MCS ****
[mono-project.git] / mcs / class / Mono.PEToolkit / build / srcgen / tabs-decoder.xsl
blobe6c71d4ce589e9db77f9338fc52af8a6da863a6a
1 <?xml version="1.0" encoding="iso-8859-1"?>
4 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
6 <xsl:import href="gen-utils.xsl"/>
8 <xsl:output method="text"/>
11 <!-- ******************************************************************* -->
13 <xsl:template match="/">// Auto-generated file - DO NOT EDIT!
14 // Please edit md-schema.xml or tabs-decoder.xsl if you want to make changes.
16 using System;
18 namespace Mono.PEToolkit.Metadata {
20 <xsl:text><![CDATA[
21 /// <summary>
22 /// </summary>
23 /// <remarks>
24 /// </remarks>
25 public sealed class TabsDecoder {
27 private TabsDecoder()
32 /// <summary>
33 /// </summary>
34 /// <remarks>
35 /// </remarks>
36 public static MDToken DecodeToken(CodedTokenId id, int data)
38 MDToken res = new MDToken();
39 int tag;
40 int rid;
41 TokenType tok;
43 switch (id) {
44 ]]></xsl:text>
46 <xsl:for-each select="md-schema/coded-tokens/map">
47 case CodedTokenId.<xsl:value-of select="@name"/> :
48 tag = data &amp; 0x<xsl:value-of select="substring('000103070F1F3F7FFF',1 + (2 * @bits),2)"/>;
49 rid = (int) ((uint) data &gt;&gt; <xsl:value-of select="@bits"/>);
50 switch (tag) {
51 <xsl:for-each select="table">
52 <xsl:variable name="tok-type">
53 <xsl:choose>
54 <xsl:when test="boolean(@token-type)">
55 <xsl:value-of select="@token-type"/>
56 </xsl:when>
57 <xsl:otherwise>
58 <xsl:value-of select="@name"/>
59 </xsl:otherwise>
60 </xsl:choose>
61 </xsl:variable>
62 case <xsl:value-of select="@tag"/> :
63 tok = TokenType.<xsl:value-of select="$tok-type"/>;
64 break;
65 </xsl:for-each>
66 default :
67 throw new BadMetaDataException("Invalid coded token for <xsl:value-of select="@name"/>, unknown table tag - " + tag);
69 res = new MDToken(tok, rid);
70 break;
71 </xsl:for-each>
74 <xsl:text><![CDATA[
75 default:
76 break;
78 return res;
82 private static int GetCodedIndexSize(TablesHeap heap, CodedTokenId id, int [] rows)
84 int res = 0;
86 switch (id) {
87 ]]></xsl:text>
89 <xsl:for-each select="md-schema/coded-tokens/map">
90 case CodedTokenId.<xsl:value-of select="@name"/> :
91 res = MDUtils.Max(<xsl:call-template name="get-tables-list"/>);
92 res = res &lt; (1 &lt;&lt; (16 - <xsl:value-of select="@bits"/>)) ? 2 : 4;
93 break;
94 </xsl:for-each>
96 <xsl:text><![CDATA[
97 default:
98 break;
101 return res;
105 private static int GetIndexSize(TableId tab, int [] rows)
107 // Index is 2 bytes wide if table has less than 2^16 rows
108 // otherwise it's 4 bytes wide.
109 return ((uint) rows [(int) tab]) < (1 << 16) ? 2 : 4;
113 private static void AllocBuff(ref byte [] buff, int size)
115 if (buff == null || buff.Length < size) {
116 buff = new byte [(size + 4) & ~3];
118 Array.Clear(buff, 0, size);
122 /// <summary>
123 /// </summary>
124 unsafe public static int DecodePhysicalTables(TablesHeap heap, byte [] data, int offs, int [] rows)
126 int rowSize; // expanded row size (all indices are dwords)
127 int fldSize; // physical field size
128 int dest;
129 int nRows;
130 byte [] buff = null;
131 int si = heap.StringsIndexSize;
132 int gi = heap.GUIDIndexSize;
133 int bi = heap.BlobIndexSize;
134 ]]></xsl:text>
136 <xsl:apply-templates select="md-schema/tables/table"/>
138 <xsl:text><![CDATA[
139 return offs;
142 } // end class
143 } // end namespace
144 ]]></xsl:text>
146 </xsl:template>
150 <!-- ******************************************************************* -->
151 <xsl:template name="get-tables-list">
152 <xsl:param name="map-node" select="."/>
154 <xsl:for-each select="$map-node/table">
155 <xsl:choose>
156 <xsl:when test="@name = 'String'"><!-- HACK -->
157 <xsl:text>(heap.StringsIndexSize &gt; 2 ? 1 &lt;&lt; 17 : 1)</xsl:text>
158 </xsl:when>
159 <xsl:otherwise>
160 <xsl:text>rows [(int) TableId.</xsl:text><xsl:value-of select="@name"/><xsl:text>]</xsl:text>
161 </xsl:otherwise>
162 </xsl:choose>
163 <xsl:if test="position() != last()">
164 <xsl:text>, </xsl:text>
165 </xsl:if>
166 </xsl:for-each>
167 </xsl:template>
173 <!-- ******************************************************************* -->
174 <xsl:template name="get-field-size">
175 <xsl:param name="type" select="@type"/>
177 <xsl:choose>
178 <!-- RVA special case, PE library type -->
179 <xsl:when test="$type = 'RVA'">
180 <xsl:text>RVA.Size</xsl:text>
181 </xsl:when>
182 <!-- #Strings, #Blob or #GUID -->
183 <xsl:when test="contains($type,'#')">
184 <xsl:choose>
185 <xsl:when test="contains(substring-after($type, '#'), 'Strings')">
186 <xsl:text>si</xsl:text>
187 </xsl:when>
188 <xsl:when test="contains(substring-after($type, '#'), 'Blob')">
189 <xsl:text>bi</xsl:text>
190 </xsl:when>
191 <xsl:when test="contains(substring-after($type, '#'), 'GUID')">
192 <xsl:text>gi</xsl:text>
193 </xsl:when>
194 <xsl:otherwise>
195 <xsl:text>ERROR: Unknown index - </xsl:text>
196 <xsl:value-of select="$type"/>
197 </xsl:otherwise>
198 </xsl:choose>
199 </xsl:when>
200 <!-- table indices -->
201 <xsl:when test="starts-with($type,'index')">
202 <xsl:variable name="tab">
203 <xsl:call-template name="extract-arg"/>
204 </xsl:variable>
205 <xsl:value-of select="concat('GetIndexSize(TableId.', $tab, ', rows)')"/>
206 </xsl:when>
207 <!-- coded tokens -->
208 <xsl:when test="starts-with($type,'coded-index')">
209 <xsl:variable name="tab">
210 <xsl:call-template name="extract-arg"/>
211 </xsl:variable>
212 <xsl:value-of select="concat('GetCodedIndexSize(heap, CodedTokenId.', $tab, ', rows)')"/>
213 </xsl:when>
214 <xsl:otherwise>
215 <xsl:value-of select="concat('sizeof (', $type, ')')"/>
216 </xsl:otherwise>
217 </xsl:choose>
218 </xsl:template>
223 <!-- ******************************************************************* -->
224 <xsl:template match="md-schema/tables/table">
225 if (heap.Has<xsl:value-of select="@name"/>) {
226 rowSize = <xsl:call-template name="get-expanded-size"/>;
227 nRows = rows [(int) TableId.<xsl:value-of select="@name"/>];
228 AllocBuff(ref buff, rowSize * nRows);
229 dest = 0;
231 MDTable tab = new <xsl:value-of select="@name"/>Table(heap);
233 for (int i = nRows; --i >= 0;) {
234 <xsl:for-each select="schema/field">
235 <xsl:variable name="fld-size">
236 <xsl:call-template name="get-field-size"/>
237 </xsl:variable>
238 <xsl:variable name="exp-fld-size">
239 <xsl:call-template name="get-expanded-size">
240 <xsl:with-param name="fields" select="."/>
241 </xsl:call-template>
242 </xsl:variable>
243 // <xsl:value-of select="@name"/>, <xsl:value-of select="@type"/>
244 fldSize = <xsl:value-of select="$fld-size"/>;
245 Array.Copy(data, offs, buff, dest, fldSize);
246 offs += fldSize;
247 dest += <xsl:value-of select="$exp-fld-size"/>;
248 </xsl:for-each>
251 tab.FromRawData(buff, 0, nRows);
253 </xsl:template>
255 </xsl:stylesheet>