internal Object LoadObjectV2(int pos, out ResourceTypeCode typeCode)
{
BCLDebug.Assert(_store != null, "ResourceReader is closed!");
BCLDebug.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!");
_store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
typeCode = (ResourceTypeCode) _store.Read7BitEncodedInt();
BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: "+typeCode+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture));
switch(typeCode) {
case ResourceTypeCode.Null:
return null;
case ResourceTypeCode.String:
return _store.ReadString();
case ResourceTypeCode.Boolean:
return _store.ReadBoolean();
case ResourceTypeCode.Char:
return (char) _store.ReadUInt16();
case ResourceTypeCode.Byte:
return _store.ReadByte();
case ResourceTypeCode.SByte:
return _store.ReadSByte();
case ResourceTypeCode.Int16:
return _store.ReadInt16();
case ResourceTypeCode.UInt16:
return _store.ReadUInt16();
case ResourceTypeCode.Int32:
return _store.ReadInt32();
case ResourceTypeCode.UInt32:
return _store.ReadUInt32();
case ResourceTypeCode.Int64:
return _store.ReadInt64();
case ResourceTypeCode.UInt64:
return _store.ReadUInt64();
case ResourceTypeCode.Single:
return _store.ReadSingle();
case ResourceTypeCode.Double:
return _store.ReadDouble();
case ResourceTypeCode.Decimal:
return _store.ReadDecimal();
case ResourceTypeCode.DateTime:
// Use DateTime's ToBinary & FromBinary.
Int64 data = _store.ReadInt64();
return DateTime.FromBinary(data);
case ResourceTypeCode.TimeSpan:
Int64 ticks = _store.ReadInt64();
return new TimeSpan(ticks);
// Special types
case ResourceTypeCode.ByteArray:
{
int len = _store.ReadInt32();
if (_ums == null)
return _store.ReadBytes(len);
if (len > _ums.Length - _ums.Position)
throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataTooLong"));
byte[] bytes = new byte[len];
int r = _ums.Read(bytes, 0, len);
BCLDebug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)");
return bytes;
}
case ResourceTypeCode.Stream:
{
int len = _store.ReadInt32();
if (_ums == null) {
byte[] bytes = _store.ReadBytes(len);
// Lifetime of memory == lifetime of this stream.
return new PinnedBufferMemoryStream(bytes);
}
// make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream.
if (len > _ums.Length - _ums.Position)
throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataTooLong"));
// For the case that we've memory mapped in the .resources
// file, just return a Stream pointing to that block of memory.
unsafe {
return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read, true);
}
}
default:
BCLDebug.Assert(typeCode >= ResourceTypeCode.StartOfUserTypes, String.Format(CultureInfo.InvariantCulture, "ResourceReader: Unsupported ResourceTypeCode in .resources file! {0}", typeCode));
// Throw new exception?
break;
}
// Normal serialized objects
int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes;
return DeserializeObject(typeIndex);
}