Files
yallie 9fa3874800 Added the contents of the archive.
Moved the original file to the archive subfolder.
2017-11-20 16:11:42 +03:00

181 lines
7.8 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Default Resource File Format</title>
<link rel="stylesheet" type="text/css" href="../rotor.css">
</head>
<body>
<h1>Default Resource File Format</h1>
<p>There are four sections to the default file format: </p>
<ul>
<li>Section 1 - Resource Manager header.</li>
<li>Section 2 - RuntimeResourceReader header.</li>
<li>Section 3 - RuntimeResourceReader Name section.</li>
<li>Section 4 - RuntimeResourceReader Data section.</li>
</ul>
<table border="1" width="90%">
<tr>
<th width="50%">Field</th>
<th width="50%">Type of data</th>
</tr>
<tr>
<td width="100%" colspan="2" align="center">Section 1: Resource Manager header</td>
</tr>
<tr>
<td width="50%">Magic Number (0xBEEFCACE) </td>
<td width="50%">Int32 </td>
</tr>
<tr>
<td width="50%">Resource Manager header version </td>
<td width="50%">Int32 </td>
</tr>
<tr>
<td width="50%">Number of bytes to skip from here to get past this header </td>
<td width="50%">Int32 </td>
</tr>
<tr>
<td width="50%">Class name of <b>IResourceReader</b> to parse this file </td>
<td width="50%">String </td>
</tr>
<tr>
<td width="50%">Class name of <b>ResourceSet</b> to parse this file </td>
<td width="50%">String </td>
</tr>
<tr>
<td width="100%" colspan="2" align="center">Section 2: RuntimeResourceReader header</td>
</tr>
<tr>
<td width="50%"><b>RuntimeResourceReader</b> version number </td>
<td width="50%">Int32 </td>
</tr>
<tr>
<td width="50%">Number of resources in the file </td>
<td width="50%">Int32 </td>
</tr>
<tr>
<td width="50%">Number of types in the type table </td>
<td width="50%">Int32 </td>
</tr>
<tr>
<td width="50%">Padding bytes for 8-byte alignment (use PAD)</td>
<td width="50%">Bytes (0-7) </td>
</tr>
<tr>
<td width="50%">Name of each type </td>
<td width="50%">Set of Strings</td>
</tr>
<tr>
<td width="50%">Hash values for each resource name </td>
<td width="50%">Int32 array, sorted </td>
</tr>
<tr>
<td width="50%">Virtual offset of each resource name </td>
<td width="50%">Int32 array, coupled with hash values </td>
</tr>
<tr>
<td width="100%" colspan="2" align="center">Section 3: RuntimeResourceReader Name Section</td>
</tr>
<tr>
<td width="50%">Name and virtual offset of each resource </td>
<td width="50%">Set of [UTF-16 String, Int32] pairs</td>
</tr>
<tr>
<td width="100%" colspan="2" align="center">Section 4: RuntimeResourceReader Data Section</td>
</tr>
<tr>
<td width="50%">Type and Value of each resource </td>
<td width="50%">Set of [Int32, BLOB of bytes] pairs </td>
</tr>
</table>
<p>The first section is the Resource Manager header, which consists of a
magic number that identifies this as a Resource file, and a <b>ResourceSet</b>
class name.
<p>The second section in the system default file format is the
RuntimeResourceSet specific header. This contains a version number for
the .resources file, the number of resources in this file, and the number of
different types contained in the file, followed by a list of fully
qualified type names. This is followed by an array of hash values for
each resource name, then an array of virtual offsets into the name section
of the file. The hashes allow you to do a binary search on an array of
integers to find a resource name very quickly without doing many string
compares (until you have found the target type). If a hash
matches, the index into the array of hash values is used as the index
into the name position array to find the name of the resource. The hash
function used to compute these values is as follows:
<pre> uint hash = 5381;
for(int i=0; i &lt; key.Length; i++)
hash = ((hash &lt;&lt; 5) + hash) ^ key[i];
return (int) hash;
</pre>
You must use exactly this hash function for reading and writing .resources
files, because the values are saved to files on the disk. Do not use the
<b>String.GetHashCode</b> method because its implementation might change in the
future as developers find better and faster hash functions. The type table
allows you to read multiple different classes from the same
file, including user-defined types, in a more efficient way than using
serialization, at least when your .resources file contains a reasonable
proportion of base data types such as strings or integers. All non-intrinsic types are saved using serialization.
<p>The third section of the file is the name section. It contains a
series of resource names, written out as byte-length prefixed little-endian Unicode strings (UTF-16). After each name is a four-byte virtual
offset into the data section of the file, pointing to the relevant
string or serialized BLOB for this resource name.
<p>The fourth section in the file is the data section, which consists
of a type and a BLOB of bytes for each item in the file. The type is
an integer index into the type table. The data is specific to that type,
but can be a number written in binary format, a String, or a serialized
Object.
<p>This implementation, when used with the default <b>ResourceReader</b> class,
loads only the strings that you look up. The implementation can do string comparisons without
having to create a new <b>String</b> instance due to some memory-mapped file
optimizations in the <b>ResourceReader</b> and <b>FastResourceComparer</b> classes.
Therefore the memory that is touched when loading
resources is kept to a minimum.
<p>In addition, the resource implementation supports object serialization in a
similar fashion. The ResourceManager builds an array of class types contained
in this file and writes it to the RuntimeResourceReader header section of the
file. Every resource will contain its type (as an index into the array of
classes) with the data for that resource. The Resource Manager will use the CLI serialization support.
<p>All strings in the file format are written with <b>BinaryReader</b> and
<b>BinaryWriter</b>, which write out the length of the string as a 7-bit-encoded
integer, and then the contents as Unicode characters encoded in UTF-8.&nbsp; The
7-bit encoding works as follows: If the value will fit completely in
seven bits, then a single byte is written; otherwise the high bit on the
first byte is set and a second byte is created by shifting the value
by 7 bits. This is repeated until there are enough bytes to hold
the value.&nbsp; In the name table, each resource name is written in UTF-16 so
it is possible to do a byte-by-byte comparison against the contents of the file
without allocating objects.
<p>Support for serialization is required for objects that will be embedded in
resource files. CLI implementers should ensure that their
<b>BinaryReader</b>, <b>BinaryWriter</b>, and <b>BinaryFormatter</b> classes are working correctly.
<p>The offsets of each resource string are relative to the beginning of the
Data section of the file. This way, if a tool decides to add
one resource to a file, it needs to increment only the number of
resources, add the hash and location of the last byte in the name section
to the array of resource hashes and resource name positions (carefully
keeping these arrays sorted), add the name to the end of the name and
offset list, possibly add the list of types (and increase
the number of items in the type table), and add the resource value at
the end of the file. The other offsets would not need to be updated to
reflect the longer header section.
<p>Resource files are currently limited to 2 gigabytes because of these
design parameters.
<hr>
<p><i>Copyright (c) 2002 Microsoft Corporation. All rights reserved.</i></p>
</body>
</html>