Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

144 lines
4.1 KiB
C#

/*
* CodeTable.cs - Implementation of the "System.Text.CodeTable" class.
*
* Copyright (c) 2002 Southern Storm Software, Pty Ltd
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
namespace I18N.CJK
{
using System;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using I18N.Common;
// This class assists encoding classes for the large CJK character
// sets by providing pointer access to table data in the resource
// section of the current assembly.
//
// Code tables are named by their resource (e.g. "jis.table") and
// contain one or more sections. Each section has an 8-byte header,
// consisting of a 32-bit section number and a 32-bit section length.
// The alignment of the data in the table is not guaranteed.
internal unsafe sealed class CodeTable : IDisposable
{
// Internal state.
private Stream stream;
// Load a code table from the resource section of this assembly.
public CodeTable(String name)
{
stream = (Assembly.GetExecutingAssembly()
.GetManifestResourceStream(name));
if(stream == null)
{
throw new NotSupportedException
(String.Format
(Strings.GetString("NotSupp_MissingCodeTable"),
name));
}
}
// Implement the IDisposable interface.
public void Dispose()
{
if(stream != null)
{
stream.Close();
stream = null;
}
}
// Get the starting address for a particular section within
// the code table. This address is guaranteed to persist
// after "Dispose" is called.
#if __PNET__
public byte *GetSection(int num)
#else
public byte[] GetSection(int num)
#endif
{
// If the table has been disposed, then bail out.
if(stream == null)
{
return null;
}
// Scan through the stream looking for the section.
long posn = 0;
long length = stream.Length;
byte[] header = new byte [8];
int sectNum, sectLen;
while((posn + 8) <= length)
{
// Read the next header block.
stream.Position = posn;
if(stream.Read(header, 0, 8) != 8)
{
break;
}
// Decode the fields in the header block.
sectNum = ((int)(header[0])) |
(((int)(header[1])) << 8) |
(((int)(header[2])) << 16) |
(((int)(header[3])) << 24);
sectLen = ((int)(header[4])) |
(((int)(header[5])) << 8) |
(((int)(header[6])) << 16) |
(((int)(header[7])) << 24);
// Is this the section we are looking for?
if(sectNum == num)
{
#if __PNET__
return GetAddress(stream, posn + 8);
#else
byte[] buf = new byte [sectLen];
if(stream.Read(buf, 0, sectLen) != sectLen)
{
break;
}
return buf;
#endif
}
// Advance to the next section.
posn += 8 + sectLen;
}
// We were unable to find the requested section.
return null;
}
#if __PNET__
// Back door access into the engine to get the address of
// an offset within a manifest resource stream.
[MethodImpl(MethodImplOptions.InternalCall)]
extern private static byte *GetAddress(Stream stream, long position);
#endif
}; // class CodeTable
}; // namespace I18N.CJK