private static CompressedWorkItems ReadPacketFromStream(Stream stream) { const int headerSize = 9; var buffer = Util.ReadNext(stream, headerSize, out _); if (buffer.Length != headerSize) { throw new InvalidDataException($"invalid header length for compressed data chunk"); } if (buffer[0] != 'Z') { throw new InvalidDataException($"expected header byte of 'Z', got {buffer[0]} instead."); } var originalDataSizeBytes = ByteUtil.ByteArrayToInt32(buffer, 1); var compressedDataSize = ByteUtil.ByteArrayToInt32(buffer, 5); buffer = Util.ReadNext(stream, compressedDataSize, out _); if (buffer.Length != compressedDataSize) { throw new InvalidDataException( $"compressed data: expected {compressedDataSize} bytes, only got {buffer.Length}"); } return(new CompressedWorkItems() { Bytes = buffer, UncompressedSize = originalDataSizeBytes }); }
public int GetRomCheckSumsFromRomBytes() { return(ByteUtil.ByteArrayToInt32(GetRomBytes(0xFFDC, 4))); }
public override (Project project, string warning) Load(byte[] data) { if (!IsBinaryFileFormat(data)) { throw new InvalidDataException($"This is not a binary serialized project file!"); } byte version = data[0]; ValidateProjectFileVersion(version); var project = new Project { Data = new Data() }; // version 0 needs to convert PC to SNES for some addresses ByteUtil.AddressConverter converter = address => address; if (version == 0) { converter = project.Data.ConvertPCtoSnes; } // read mode, speed, size project.Data.RomMapMode = (RomMapMode)data[HeaderSize]; project.Data.RomSpeed = (RomSpeed)data[HeaderSize + 1]; var size = ByteUtil.ByteArrayToInt32(data, HeaderSize + 2); // read internal title var pointer = HeaderSize + 6; project.InternalRomGameName = RomUtil.ReadStringFromByteArray(data, RomUtil.LengthOfTitleName, pointer); pointer += RomUtil.LengthOfTitleName; // read checksums project.InternalCheckSum = ByteUtil.ByteArrayToInt32(data, pointer); pointer += 4; // read full filepath to the ROM .sfc file while (data[pointer] != 0) { project.AttachedRomFilename += (char)data[pointer++]; } pointer++; project.Data.RomBytes.Create(size); for (int i = 0; i < size; i++) { project.Data.SetDataBank(i, data[pointer + i]); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetDirectPage(i, data[pointer + size + i] | (data[pointer + 1 * size + i] << 8)); } pointer += 2; for (int i = 0; i < size; i++) { project.Data.SetXFlag(i, data[pointer * size + i] != 0); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetMFlag(i, data[pointer * size + i] != 0); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetFlag(i, (Data.FlagType)data[pointer * size + i]); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetArchitecture(i, (Data.Architecture)data[pointer * size + i]); } pointer++; for (int i = 0; i < size; i++) { project.Data.SetInOutPoint(i, (Data.InOutPoint)data[pointer * size + i]); } pointer++; //for (int i = 0; i < size; i++) project.Data.SetBaseAddr(i, (Data.InOutPoint)data[pointer * size + i]); pointer++; ReadLabels(project, data, ref pointer, converter, version >= 2); ReadComments(project, data, ref pointer, converter); project.UnsavedChanges = false; var warning = ""; if (version != LatestFileFormatVersion) { warning = "This project file is in an older format.\n" + "You may want to back up your work or 'Save As' in case the conversion goes wrong.\n" + "The project file will be untouched until it is saved again."; } return(project, warning); }
private CompressedWorkItem ReadPacketFromStream(Stream stream) { #if PROFILING var mainSpan = Markers.EnterSpan("BSNES socket read"); #endif var item = AllocateCompressedWorkItem(); try { Util.ReadNext(stream, item.Header, CompressedWorkItem.headerSize); } catch (EndOfStreamException) { FreeCompressedWorkItem(ref item); return(null); } #if PROFILING Markers.WriteFlag("initial read"); #endif if (item.Header.Length != CompressedWorkItem.headerSize) { throw new InvalidDataException($"invalid header length for compressed data chunk"); } if (item.Header[0] != 'Z') { throw new InvalidDataException($"expected header byte of 'Z', got {item.Header[0]} instead."); } item.UncompressedSize = ByteUtil.ByteArrayToInt32(item.Header, 1); item.CompressedSize = ByteUtil.ByteArrayToInt32(item.Header, 5); // allocation pool. if we need to allocate for compressed data, let's go slightly higher so that // we have a chance of re-using this buffer without needing to re-allocate. const float unscientificGuessAtExtraWeShouldAdd = 1.3f; // total guess. adjust higher if you do too many allocations if (item.CompressedBuffer == null || item.CompressedBuffer.Length < item.CompressedSize) { item.CompressedBuffer = new byte[(int)(item.CompressedSize * unscientificGuessAtExtraWeShouldAdd)]; } #if PROFILING Markers.WriteFlag("big read start"); #endif int bytesRead; try { bytesRead = Util.ReadNext(stream, item.CompressedBuffer, item.CompressedSize); } catch (EndOfStreamException) { FreeCompressedWorkItem(ref item); return(null); } #if PROFILING Markers.WriteFlag("big read done"); #endif if (bytesRead != item.CompressedSize) { throw new InvalidDataException( $"compressed data: expected {item.CompressedSize} bytes, only got {bytesRead}"); } #if PROFILING mainSpan.Leave(); #endif return(item); }