本文整理汇总了C#中IStream.SeekTo方法的典型用法代码示例。如果您正苦于以下问题:C# IStream.SeekTo方法的具体用法?C# IStream.SeekTo怎么用?C# IStream.SeekTo使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IStream
的用法示例。
在下文中一共展示了IStream.SeekTo方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: PatchSegments
/// <summary>
/// Patches the file segments in a stream.
/// </summary>
/// <param name="changes">The changes to make to the segments and their data.</param>
/// <param name="stream">The stream to write changes to.</param>
public static void PatchSegments(IEnumerable<SegmentChange> changes, IStream stream)
{
// Sort changes by their offsets
var changesByOffset = new SortedList<uint, SegmentChange>();
foreach (SegmentChange change in changes)
changesByOffset[change.OldOffset] = change;
// Now adjust each segment
foreach (SegmentChange change in changesByOffset.Values)
{
// Resize it if necessary
if (change.NewSize != change.OldSize)
{
if (change.ResizeAtEnd)
stream.SeekTo(change.NewOffset + change.OldSize);
else
stream.SeekTo(change.NewOffset);
StreamUtil.Insert(stream, change.NewSize - change.OldSize, 0);
}
// Patch its data
DataPatcher.PatchData(change.DataChanges, change.NewOffset, stream);
}
}
示例2: InjectPage
public int InjectPage(IStream cacheStream, ResourcePage page, byte[] data)
{
const int pageSize = 0x1000;
// Calculate how many pages we need to add to the raw table
var pagesNeeded = (int)(Math.Ceiling(page.CompressedSize / (double)pageSize));
// calculate sizes, positions and resize the raw table
var injectSize = pagesNeeded * pageSize;
var offsetInCache = (_rawTable.Offset + _rawTable.Size);
var offsetInRaw = (_rawTable.Size);
_rawTable.Resize(_rawTable.Size + injectSize, cacheStream);
// write the raw page into the table
cacheStream.SeekTo(offsetInCache);
cacheStream.WriteBlock(data);
return offsetInRaw;
}
示例3: SaveChanges
public void SaveChanges(IStream stream)
{
if (!_changed)
return;
var scenarioLayout = _buildInfo.Layouts.GetLayout("scnr");
stream.SeekTo(_scenario.MetaLocation.AsOffset());
var scenarioData = StructureReader.ReadStructure(stream, scenarioLayout);
var oldCount = (int)scenarioData.GetInteger("simulation definition table count");
var oldAddress = scenarioData.GetInteger("simulation definition table address");
var entryLayout = _buildInfo.Layouts.GetLayout("simulation definition table entry");
var newTable = _table.Select(SerializeTag);
var newAddr = ReflexiveWriter.WriteReflexive(newTable, oldCount, oldAddress, _table.Count, entryLayout, _metaArea, _allocator, stream);
scenarioData.SetInteger("simulation definition table count", (uint)_table.Count);
scenarioData.SetInteger("simulation definition table address", newAddr);
stream.SeekTo(_scenario.MetaLocation.AsOffset());
StructureWriter.WriteStructure(scenarioData, scenarioLayout, stream);
_changed = false;
}
示例4: ResizeSegment
/// <summary>
/// Resizes a segment in the file.
/// </summary>
/// <param name="id">The ID of the segment to resize.</param>
/// <param name="newSize">The minimum amount of space that the segment must occupy.</param>
/// <param name="stream">The stream to write padding to.</param>
/// <returns>The new size of the segment after alignment has been applied.</returns>
public int ResizeSegment(int id, int newSize, IStream stream)
{
InternalSegment segment = GetSegmentFromID(id);
int oldSize = segment.Size;
if (newSize == oldSize)
return oldSize;
// Change the size of the segment
int oldActualSize = segment.ActualSize;
int oldSegmentEnd = segment.Offset + segment.ActualSize;
segment.Size = Align(newSize, segment.SizeAlignment);
segment.ActualSize = Math.Max(segment.Size, segment.ActualSize);
// Recalculate the segment offsets,
// and then use the recalculated offsets to recalculate the sizes
RecalculateOffsets();
RecalculateActualSizes();
int resizeOffset;
switch (segment.ResizeOrigin)
{
case SegmentResizeOrigin.Beginning:
resizeOffset = segment.Offset;
break;
case SegmentResizeOrigin.End:
resizeOffset = oldSegmentEnd;
break;
default:
throw new ArgumentException("The segment cannot be resized.");
}
// Insert/remove data into/from the stream
// FIXME: There's a bug here where changing the size of a SegmentResizeOrigin.Beginning segment won't move the data back if ActualSize doesn't change
// Some sort of StreamUtil.Copy() method is necessary for that
stream.SeekTo(resizeOffset);
if (oldActualSize < segment.ActualSize)
StreamUtil.Insert(stream, segment.ActualSize - oldActualSize, 0);
else if (segment.ActualSize < oldActualSize)
throw new NotImplementedException("Segment shrinking is not supported yet.");
OnSegmentResized(new SegmentResizedEventArgs(id, oldSize, segment.Size, segment.ResizeOrigin));
return segment.Size;
}
示例5: ImportShader
/// <summary>
/// Deserializes a serialized shader and injects it into the cache file.
/// </summary>
/// <param name="serializedShader">The serialized shader data to inject.</param>
/// <param name="stream">The stream to manipulate. It should be positioned where the shader pointer should be written.</param>
/// <returns>
/// <c>true</c> if the shader was successfully deserialized and injected.
/// </returns>
public bool ImportShader(byte[] serializedShader, IStream stream)
{
if (serializedShader == null || serializedShader.Length == 0)
{
// Null shader
stream.WriteUInt32(0);
return true;
}
var pointerOffset = stream.Position + _cacheFile.MetaArea.OffsetToPointer(0);
using (var reader = new EndianReader(new MemoryStream(serializedShader), Endian.BigEndian))
{
// Check the magic
if (reader.ReadInt32() != SerializationMagic)
return false;
// Read the shader type and determine which info layout to use
var type = (ShaderType)reader.ReadByte();
StructureLayout infoLayout = null;
if (type == ShaderType.Pixel)
infoLayout = _pixelShaderInfoLayout;
else if (type == ShaderType.Vertex)
infoLayout = _vertexShaderInfoLayout;
if (infoLayout == null)
return false;
// Read and verify the layout size
var infoLayoutSize = reader.ReadInt32();
if (infoLayoutSize != infoLayout.Size)
return false;
// Read the raw debug info and data
var debugInfoSize = reader.ReadUInt32();
var debugInfo = reader.ReadBlock((int)debugInfoSize);
var dataSize = reader.ReadUInt32();
var data = reader.ReadBlock((int)dataSize);
// Allocate space for the shader data and write it in
var dataAddr = _cacheFile.Allocator.Allocate((int)dataSize, 0x10, stream); // 16-byte aligned
var dataOffset = _cacheFile.MetaArea.PointerToOffset(dataAddr);
stream.SeekTo(dataOffset);
stream.WriteBlock(data);
// Allocate and zero space for the info structures
var infoSize = infoLayoutSize + (int)debugInfoSize;
var infoAddr = _cacheFile.Allocator.Allocate(infoSize, stream);
var infoOffset = _cacheFile.MetaArea.PointerToOffset(infoAddr);
stream.SeekTo(infoOffset);
StreamUtil.Fill(stream, 0, infoSize);
// Write the basic info structure
stream.SeekTo(infoOffset);
var infoValues = new StructureValueCollection();
infoValues.SetInteger("shader data address", dataAddr);
StructureWriter.WriteStructure(infoValues, infoLayout, stream);
// Write the debug info structure
stream.WriteBlock(debugInfo);
// Finally, write the shader pointer
stream.SeekTo(pointerOffset - _cacheFile.MetaArea.OffsetToPointer(0));
stream.WriteUInt32(infoAddr);
}
return true;
}
示例6: SaveResourceInfoBuffer
private void SaveResourceInfoBuffer(byte[] buffer, StructureValueCollection values, IStream stream)
{
// Free the old info buffer
var oldSize = (int) values.GetInteger("resource info buffer size");
uint oldAddress = values.GetInteger("resource info buffer address");
if (oldAddress >= 0 && oldSize > 0)
_allocator.Free(oldAddress, oldSize);
// Write a new one
uint newAddress = 0;
if (buffer.Length > 0)
{
newAddress = _allocator.Allocate(buffer.Length, 0x10, stream);
stream.SeekTo(_metaArea.PointerToOffset(newAddress));
stream.WriteBlock(buffer);
}
// Update values
values.SetInteger("resource info buffer size", (uint) buffer.Length);
values.SetInteger("resource info buffer address", newAddress);
}
示例7: Reallocate
/// <summary>
/// Reallocates a block of memory in the cache file's meta area.
/// The contents of the old block will be copied to the new block and then zeroed.
/// </summary>
/// <param name="address">The starting address of the data to reallocate.</param>
/// <param name="oldSize">The old size of the data to reallocate.</param>
/// <param name="newSize">The requested size of the newly-allocated data block.</param>
/// <param name="stream">The stream to write cache file changes to.</param>
/// <returns>The memory address of the new block.</returns>
public uint Reallocate(uint address, int oldSize, int newSize, IStream stream)
{
// Pretty basic for now
// In the future, we could make an allocator that's biased toward the old address in order to prevent copying
Free(address, oldSize);
uint newAddress = Allocate(newSize, stream);
// If the addresses differ, then copy the data across and zero the old data
if (newAddress != address)
{
long oldOffset = _cacheFile.MetaArea.PointerToOffset(address);
long newOffset = _cacheFile.MetaArea.PointerToOffset(newAddress);
StreamUtil.Copy(stream, oldOffset, newOffset, oldSize);
stream.SeekTo(oldOffset);
StreamUtil.Fill(stream, 0, oldSize);
}
return newAddress;
}
示例8: WriteDataBlock
private void WriteDataBlock(DataBlock block, SegmentPointer location, IStream stream, ITag tag = null)
{
if (tag == null && _dataBlockAddresses.ContainsKey(block)) // Don't write anything if the block has already been written
return;
// Associate the location with the block
_dataBlockAddresses[block] = location.AsPointer();
// Create a MemoryStream and write the block data to it (so fixups can be performed before writing it to the file)
using (var buffer = new MemoryStream(block.Data.Length))
{
var bufferWriter = new EndianWriter(buffer, stream.Endianness);
bufferWriter.WriteBlock(block.Data);
// Apply fixups
FixBlockReferences(block, bufferWriter, stream);
FixTagReferences(block, bufferWriter, stream);
FixResourceReferences(block, bufferWriter, stream);
FixStringIdReferences(block, bufferWriter);
if (tag != null)
FixUnicListReferences(block, tag, bufferWriter, stream);
// Write the buffer to the file
stream.SeekTo(location.AsOffset());
stream.WriteBlock(buffer.GetBuffer(), 0, (int) buffer.Length);
}
// Write shader fixups (they can't be done in-memory because they require cache file expansion)
FixShaderReferences(block, stream, location);
}
示例9: Insert
/// <summary>
/// Inserts space into a stream by copying everything back by a certain number of bytes.
/// </summary>
/// <param name="stream">The stream to insert space into.</param>
/// <param name="size">The size of the space to insert.</param>
/// <param name="fill">The byte to fill the inserted space with. See <see cref="Fill"/>.</param>
public static void Insert(IStream stream, int size, byte fill)
{
if (size == 0)
return;
if (size < 0)
throw new ArgumentException("The size of the data to insert must be >= 0");
if (stream.Position == stream.Length)
return; // Seeking past the end automatically increases the file size
const int BufferSize = 0x1000;
byte[] buffer = new byte[BufferSize];
int endPos = (int)stream.Position;
int oldLength = (int)stream.Length;
int pos = Math.Max(endPos, oldLength - BufferSize);
while (pos >= endPos)
{
int read = Math.Min(BufferSize, oldLength - pos);
stream.SeekTo(pos);
stream.ReadBlock(buffer, 0, read);
stream.SeekTo(pos + size);
stream.WriteBlock(buffer, 0, read);
pos -= read;
}
stream.SeekTo(endPos);
Fill(stream, fill, size);
}
示例10: Copy
/// <summary>
/// Copies data between two locations in the same stream.
/// The source and destination areas may overlap.
/// </summary>
/// <param name="stream">The stream to copy data in.</param>
/// <param name="originalPos">The position of the block of data to copy.</param>
/// <param name="targetPos">The position to copy the block to.</param>
/// <param name="size">The number of bytes to copy.</param>
public static void Copy(IStream stream, long originalPos, long targetPos, long size)
{
if (size == 0)
return;
if (size < 0)
throw new ArgumentException("The size of the data to copy must be >= 0");
const int BufferSize = 0x1000;
var buffer = new byte[BufferSize];
long remaining = size;
while (remaining > 0)
{
var read = (int) Math.Min(BufferSize, remaining);
if (targetPos > originalPos)
stream.SeekTo(originalPos + remaining - read);
else
stream.SeekTo(originalPos + size - remaining);
stream.ReadBlock(buffer, 0, read);
if (targetPos > originalPos)
stream.SeekTo(targetPos + remaining - read);
else
stream.SeekTo(targetPos + size - remaining);
stream.WriteBlock(buffer, 0, read);
remaining -= read;
}
}
示例11: Insert
/// <summary>
/// Inserts space into a stream by copying everything back by a certain number of bytes.
/// </summary>
/// <param name="stream">The stream to insert space into.</param>
/// <param name="size">The size of the space to insert.</param>
/// <param name="fill">The byte to fill the inserted space with. See <see cref="Fill" />.</param>
public static void Insert(IStream stream, int size, byte fill)
{
if (size == 0)
return;
if (size < 0)
throw new ArgumentException("The size of the data to insert must be >= 0");
if (stream.Position == stream.Length)
return; // Seeking past the end automatically increases the file size
long startPos = stream.Position;
Copy(stream, startPos, startPos + size, stream.Length - startPos);
stream.SeekTo(startPos);
Fill(stream, fill, size);
}
示例12: Insert
/// <summary>
/// Inserts space into a stream by copying everything back by a certain number of bytes.
/// </summary>
/// <param name="stream">The stream to insert space into.</param>
/// <param name="size">The size of the space to insert.</param>
/// <param name="fill">The byte to fill the inserted space with. See <see cref="Fill" />.</param>
public static void Insert(IStream stream, int size, byte fill)
{
if (size == 0)
return;
if (size < 0)
throw new ArgumentException("The size of the data to insert must be >= 0");
long startPos = stream.Position;
if (startPos < stream.Length)
{
Copy(stream, startPos, startPos + size, stream.Length - startPos);
stream.SeekTo(startPos);
}
Fill(stream, fill, size);
}
示例13: Reallocate
/// <summary>
/// Reallocates a block of memory in the cache file's meta area.
/// The contents of the old block will be copied to the new block and then the old block will be zeroed.
/// </summary>
/// <param name="address">The starting address of the data to reallocate. If this is 0, a new block will be allocated.</param>
/// <param name="oldSize">The old size of the data to reallocate. If this is 0, a new block will be allocated.</param>
/// <param name="newSize">The requested size of the newly-allocated data block. If this is 0, the block will be freed and 0 will be returned.</param>
/// <param name="align">The power of two to align the block to.</param>
/// <param name="stream">The stream to write cache file changes to.</param>
/// <returns>The memory address of the new block, or 0 if the block was freed.</returns>
public uint Reallocate(uint address, int oldSize, int newSize, uint align, IStream stream)
{
if (newSize == oldSize)
return address;
// If the new size is 0, free the block
if (newSize == 0)
{
Free(address, oldSize);
return 0;
}
// If the old size or address is 0, allocate a new block
if (address == 0 || oldSize == 0)
return Allocate(newSize, align, stream);
// If the block is being made smaller, just free and zero the data at the end
if (newSize < oldSize)
{
Free(address + (uint)newSize, oldSize - newSize);
long offset = _cacheFile.MetaArea.PointerToOffset(address);
stream.SeekTo(offset + newSize);
StreamUtil.Fill(stream, 0, oldSize - newSize);
return address;
}
// If the block is being made larger, check if there's free space immediately after the block that can be used to avoid a copy
FreeArea area;
if (newSize > oldSize && _freeAreasByAddr.TryGetValue(address + (uint)oldSize, out area) &&
area.Size >= newSize - oldSize)
{
ChangeStartAddress(area, area.Address + (uint)(newSize - oldSize));
return address;
}
// Free the block and allocate a new one
Free(address, oldSize);
uint newAddress = Allocate(newSize, align, stream);
// If the addresses differ, then copy the data across and zero the old data
if (newAddress != address)
{
long oldOffset = _cacheFile.MetaArea.PointerToOffset(address);
long newOffset = _cacheFile.MetaArea.PointerToOffset(newAddress);
StreamUtil.Copy(stream, oldOffset, newOffset, oldSize);
stream.SeekTo(oldOffset);
StreamUtil.Fill(stream, 0, oldSize);
}
return newAddress;
}
示例14: SaveStrings
public void SaveStrings(IStream stream, LocaleTable locales)
{
MemoryStream offsetData = new MemoryStream();
MemoryStream stringData = new MemoryStream();
IWriter offsetWriter = new EndianWriter(offsetData, Endian.BigEndian);
IWriter stringWriter = new EndianWriter(stringData, Endian.BigEndian);
try
{
// Write the string and offset data to buffers
foreach (Locale locale in locales.Strings)
{
WriteLocalePointer(offsetWriter, locale.ID, (int)stringWriter.Position);
stringWriter.WriteUTF8(locale.Value);
}
// Round the size of the string data up to the nearest multiple of 0x10 (AES block size)
stringData.SetLength((stringData.Position + 0xF) & ~0xF);
// Update the two locale data hashes if we need to
// (the hash arrays are set to null if the build doesn't need them)
if (IndexTableHash != null)
IndexTableHash = SHA1.Transform(offsetData.GetBuffer(), 0, (int)offsetData.Length);
if (StringDataHash != null)
StringDataHash = SHA1.Transform(stringData.GetBuffer(), 0, (int)stringData.Length);
// Make sure there's free space for the offset table and then write it to the file
LocaleDataLocation += StreamUtil.MakeFreeSpace(stream, LocaleIndexTableLocation.AsOffset(), LocaleDataLocation.AsOffset(), offsetData.Length, _pageSize);
stream.SeekTo(LocaleIndexTableLocation.AsOffset());
stream.WriteBlock(offsetData.GetBuffer(), 0, (int)offsetData.Length);
// Encrypt the string data if necessary
byte[] strings = stringData.GetBuffer();
if (_encryptionKey != null)
strings = AES.Encrypt(strings, 0, (int)stringData.Length, _encryptionKey.Key, _encryptionKey.IV);
// Make free space for the string data
uint oldDataEnd = (uint)((LocaleDataLocation.AsOffset() + LocaleTableSize + _pageSize - 1) & ~(_pageSize - 1)); // Add the old table size and round it up
StreamUtil.MakeFreeSpace(stream, LocaleDataLocation.AsOffset(), oldDataEnd, stringData.Length, _pageSize);
LocaleTableSize = (int)stringData.Length;
// Write it to the file
stream.SeekTo(LocaleDataLocation.AsOffset());
stream.WriteBlock(strings, 0, (int)stringData.Length);
// Update the string count and recalculate the language table offsets
StringCount = locales.Strings.Count;
int localePointerSize = (int)(offsetData.Length / locales.Strings.Count);
_languageGlobals.RecalculateLanguageOffsets(localePointerSize);
}
finally
{
offsetWriter.Close();
stringWriter.Close();
}
}
示例15: SaveBitArray
private void SaveBitArray(BitArray bits, string countName, string addressName, MetaAllocator allocator, IStream stream, ReflexiveCache<int> cache, StructureValueCollection values)
{
if (bits.Length == 0)
{
values.SetInteger(countName, 0);
values.SetInteger(addressName, 0);
return;
}
var ints = new int[((bits.Length + 31) & ~31)/32];
bits.CopyTo(ints, 0);
// If the address isn't cached, then allocate space and write a new array
uint newAddress;
if (!cache.TryGetAddress(ints, out newAddress))
{
newAddress = allocator.Allocate(ints.Length*4, stream);
stream.SeekTo(_metaArea.PointerToOffset(newAddress));
foreach (int i in ints)
stream.WriteInt32(i);
cache.Add(newAddress, ints);
}
values.SetInteger(countName, (uint)ints.Length);
values.SetInteger(addressName, newAddress);
}