/// <summary> /// Save all the dictionary to the specified MESH file (in binary format). /// </summary> public void SaveToDat(String Path) { using (var Stream = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { var Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; var Pointers = new IntPtr[0]; lock (Entries) { Pointers = new IntPtr[Entries.Count]; Entries.Values.CopyTo(Pointers, 0); } Header *pHeader = stackalloc Header[1]; pHeader->Identifier = MESH_IDENTIFIER; pHeader->Amount = Pointers.Length; Kernel.memcpy(Buffer, pHeader, sizeof(Header)); Stream.Write(Buffer, 0, sizeof(Header)); for (var i = 0; i < Pointers.Length; i++) { var Length = sizeof(Entry) + (((Entry *)Pointers[i])->Amount * sizeof(Part)); Kernel.memcpy(Buffer, (Entry *)Pointers[i], Length); Stream.Write(Buffer, 0, Length - 1); } } }
/// <summary> /// Save all the dictionary to the specified EMOI file (in binary format). /// </summary> public void SaveToDat(String Path) { using (FileStream Stream = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; IntPtr[] Pointers = new IntPtr[0]; lock (Entries) { Pointers = new IntPtr[Entries.Count]; Entries.Values.CopyTo(Pointers, 0); } Header *pHeader = stackalloc Header[1]; pHeader->Identifier = EMOI_IDENTIFIER; pHeader->Amount = Pointers.Length; Kernel.memcpy(Buffer, pHeader, sizeof(Header)); Stream.Write(Buffer, 0, sizeof(Header)); for (Int32 i = 0; i < Pointers.Length; i++) { Kernel.memcpy(Buffer, (Entry *)Pointers[i], sizeof(Entry)); Stream.Write(Buffer, 0, sizeof(Entry)); } } }
/// <summary> /// Save all the dictionary to the specified magictype file (in binary format). /// </summary> public void SaveToDat(String Path) { using (FileStream Stream = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; IntPtr[] Pointers = new IntPtr[0]; lock (Entries) { Pointers = new IntPtr[Entries.Count]; Entries.Values.CopyTo(Pointers, 0); } Int32 Length = (Pointers.Length + 1) * sizeof(Int32); Header *pHeader = (Header *)Kernel.malloc(Length); pHeader->Amount = Pointers.Length; for (Int32 i = 0; i < Pointers.Length; i++) { pHeader->UIDs[i] = (Int32)((((Entry *)Pointers[i])->MagicType * 10) + ((Entry *)Pointers[i])->Level); } Kernel.memcpy(Buffer, pHeader, Length); Stream.Write(Buffer, 0, Length); for (Int32 i = 0; i < Pointers.Length; i++) { Kernel.memcpy(Buffer, (Entry *)Pointers[i], sizeof(Entry)); Stream.Write(Buffer, 0, sizeof(Entry)); } Kernel.free(pHeader); } }
/// <summary> /// Load the specified EMOI file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Entries) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Header *pHeader = stackalloc Header[1]; Stream.Read(Buffer, 0, sizeof(Header)); Kernel.memcpy(pHeader, Buffer, sizeof(Header)); if (pHeader->Identifier != EMOI_IDENTIFIER) { throw new Exception("Invalid EMOI Header in file: " + Path); } for (Int32 i = 0; i < pHeader->Amount; i++) { Entry *pEntry = (Entry *)Kernel.malloc(sizeof(Entry)); Stream.Read(Buffer, 0, sizeof(Entry)); Kernel.memcpy(pEntry, Buffer, sizeof(Entry)); if (!Entries.ContainsKey(pEntry->ID)) { Entries.Add(pEntry->ID, (IntPtr)pEntry); } } } } }
public static void DumpSerial() { //if (!Serial.Initialized) // return; Debug.COM1.WriteLine("-------------"); Debug.COM1.WriteLine("Memory dump: "); Header *currentNode = firstNode; if (currentNode == null) { Debug.COM1.WriteLine("null"); } while (currentNode != null) { DumpNodeSerial(currentNode); currentNode = currentNode->Next; if (currentNode == firstNode) { break; } } Debug.COM1.WriteLine(); }
private static unsafe void DumpAllocation(string text, Header *node) { //if (!Serial.Initialized) // return; Debug.COM1.WriteLine("--------------"); Debug.COM1.Write(text); Debug.COM1.Write(": "); Debug.COM1.Write((uint)node); Debug.COM1.Write(", Next node: "); Debug.COM1.Write((uint)node->Next); Debug.COM1.Write(", Prev node: "); Debug.COM1.Write((uint)node->Previous); Debug.COM1.Write(", Size: "); Debug.COM1.Write((uint)node->Size); Debug.COM1.Write(", IsFree: "); if (node->Free == 1) { Debug.COM1.Write("true"); } else { Debug.COM1.Write("false"); } Debug.COM1.WriteLine("--------------"); ExceptionHandling.DumpCallingStack(); Debug.COM1.WriteLine(); }
/// <summary> /// Sets the <see cref="ShuttingDown"/> flag, and disposes of the MemoryMappedFile and MemoryMappedViewAccessor.<br /> /// Attempting to read/write to the buffer after closing will result in a <see cref="System.NullReferenceException"/>. /// </summary> public virtual void Close() { if (IsOwnerOfSharedMemory && View != null) { // Indicates to any open instances that the owner is no longer open #pragma warning disable 0420 // ignore ref to volatile warning - Interlocked API Interlocked.Exchange(ref Header->Shutdown, 1); #pragma warning restore 0420 } // Allow additional close logic DoClose(); // Close the MemoryMappedFile and MemoryMappedViewAccessor if (View != null) { View.SafeMemoryMappedViewHandle.ReleasePointer(); View.Dispose(); } if (Mmf != null) { Mmf.Dispose(); } Header = null; ViewPtr = null; BufferStartPtr = null; View = null; Mmf = null; }
public static unsafe void Setup() { memoryStart = (uint)Pager.PageAlign((void *)startAddress, 0); memoryEnd = UInt32.MaxValue; Sentinel = (Header *)memoryStart; firstNode = Sentinel + 1; RBHead = firstNode; firstNode->Previous = null; firstNode->Next = firstNode; //RB initialization firstNode->Left = Sentinel; firstNode->Right = Sentinel; firstNode->Parent = null; firstNode->SPrevious = null; firstNode->SNext = null; firstNode->Size = memoryEnd - (uint)firstNode - (uint)sizeof(Header); firstNode->Free = 1; firstNode->Color = 1; Sentinel->Size = 0; Sentinel->Free = 0; Sentinel->Next = null; Sentinel->Previous = null; Sentinel->Left = null; Sentinel->Right = null; Sentinel->SNext = null; Sentinel->SPrevious = null; Sentinel->Parent = null; Sentinel->Color = 1; lastFreeNode = firstNode; }
public static unsafe void GenerateHeader(Header *pkt, UInt16 size, Byte type) { pkt->Type = type; pkt->Size = (UInt16)(size - Marshal.SizeOf(*pkt)); pkt->DataChecksum = CRC16.Generate((Byte *)pkt + Marshal.SizeOf(*pkt), pkt->Size); pkt->HeaderChecksum = CRC16.Generate((Byte *)pkt + Marshal.SizeOf(pkt->HeaderChecksum), Marshal.SizeOf(*pkt) - Marshal.SizeOf(pkt->HeaderChecksum)); }
public static Flw0 FromPtr(byte *ptr) { Header *header = (Header *)ptr; if (header->tag != 0x30574C46) // FLW0 { throw new FormatException("Data could not be wrapped with Flw0 class."); } Flw0 result = new Flw0(); SectionEntry *sections = (SectionEntry *)(ptr + Header.SIZE); TrackLabel * trackLabels = (TrackLabel *)(ptr + sections[0].offset); TrackLabel * gotoLabels = (TrackLabel *)(ptr + sections[1].offset); int * trackData = (int *)(ptr + sections[2].offset); byte * msg1Data = (ptr + sections[3].offset); byte * padData = (ptr + sections[4].offset); for (int i = 0; i < sections[0].elementCount; i++) { FlowTrack track = new FlowTrack(); track.Name = new string((sbyte *)trackLabels[i].name); int index = trackLabels[i].dataIndex; track.Data.Add(trackData[index]); while (trackData[index] != 0x9 && (index + 1) < sections[2].elementCount) { track.Data.Add(trackData[++index]); } result._Tracks.Add(track); int startIndex = trackLabels[i].dataIndex; int endIndex = trackLabels[i].dataIndex + track.Data.Count; for (int j = 0; j < sections[1].elementCount; j++) { if (gotoLabels[j].dataIndex >= startIndex && gotoLabels[j].dataIndex < endIndex) { string name = new string((sbyte *)gotoLabels[j].name); int trackIndex = gotoLabels[j].dataIndex - startIndex; track.Labels.Add(new KeyValuePair <string, int>(name, trackIndex)); } } } if (sections[3].elementCount > 0) { result._Msg1 = Msg1.FromPtr(msg1Data); } result._PadData = new byte[sections[4].elementCount]; for (int i = 0; i < result._PadData.Length; i++) { result._PadData[i] = padData[i]; } return(result); }
public void BuildDatabase(Database[] Databases, KeyValuePair <char, char>[] Remaps, KeyValuePair <char, char>[] RemapsAlt) { File.Position = 0; Header Header = new Header(); Header *pHeader = &Header; pHeader->Signature = Signature; byte *Buffer = (byte *)pHeader; Writer.Write(Buffer, 0, sizeof(Header)); Writer.Flush(); pHeader->DatabaseOffset = (uint)Writer.BaseStream.Position; Writer.Write((uint)Databases.LongCount()); foreach (var Database in Databases) { Writer.Write(Database.Name); List <string> LinesA = new List <string>(); List <string> LinesB = new List <string>(); foreach (var Entry in Database) { LinesA.Add(Entry.OriginalFlags.GetFlags() + Entry.OriginalLine); LinesB.Add(Entry.TranslationFlags.GetFlags() + Entry.TranslationLine); } Writer.WriteArray(LinesA.ToArray()); Writer.WriteArray(LinesB.ToArray()); } Writer.Flush(); pHeader->CharsOffset = (uint)Writer.BaseStream.Position; Writer.Write((uint)Remaps.Length); foreach (var Remap in Remaps) { Writer.Write(Remap.Key); Writer.Write(Remap.Value); } pHeader->CharsAltOffset = (uint)Writer.BaseStream.Position; Writer.Write((uint)RemapsAlt.Length); foreach (var Remap in RemapsAlt) { Writer.Write(Remap.Key); Writer.Write(Remap.Value); } Writer.Flush(); Writer.BaseStream.Position = 0; Writer.Write(Buffer, 0, sizeof(Header)); Writer.Flush(); }
private static unsafe void RestoreAddBalance(Header *node) { Header *temp; while (node != RBHead && node->Parent->Color == 0) { if (node->Parent == node->Parent->Parent->Left) { temp = node->Parent->Parent->Left; if (temp != null && temp->Color == 0) { node->Parent->Color = 1; temp->Color = 1; node->Parent->Parent->Color = 0; node = node->Parent->Parent; } else { if (node == node->Parent->Right) { node = node->Parent; RotateLeft(node); } node->Parent->Color = 1; node->Parent->Parent->Color = 0; RotateRight(node->Parent->Parent); } } else { temp = node->Parent->Parent->Left; if (temp != null && temp->Color == 0) { node->Parent->Color = 1; temp->Color = 1; node->Parent->Parent->Color = 0; node = node->Parent->Parent; } else { if (node == node->Parent->Left) { node = node->Parent; RotateRight(node); } node->Parent->Color = 1; node->Parent->Parent->Color = 0; RotateLeft(node->Parent->Parent); } } } RBHead->Color = 1; }
public void FreeAll() { for (Header *ptr = First; ptr != null; ptr = ptr->Next) { Marshal.FreeHGlobal(new IntPtr(ptr)); } First = null; }
public TypedPointer <T> Alloc <T>() where T : unmanaged, IDisposable { int size = Marshal.SizeOf <T>() + Header.Size; Header *ptr = (Header *)Marshal.AllocHGlobal(size).ToPointer(); ptr->Next = First; First = ptr; return(new TypedPointer <T>((T *)(ptr + 1))); }
/// <summary> /// Load the specified RSDB_BIG file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Entries) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Header *pHeader = stackalloc Header[1]; Stream.Read(Buffer, 0, sizeof(Header)); Kernel.memcpy(pHeader, Buffer, sizeof(Header)); if (pHeader->Identifier != RSDB_BIG_IDENTIFIER) { throw new Exception("Invalid RSDB_BIG Header in file: " + Path); } Int64 Address = 0; Console.WriteLine(pHeader->Amount); for (Int32 i = 0; i < pHeader->Amount; i++) { Console.Write("\r{0}", (Int32)((Double)(i + 1) / (Double)pHeader->Amount * 100.0)); Entry *pEntry = (Entry *)Kernel.calloc(sizeof(Entry)); Stream.Read(Buffer, 0, sizeof(Entry) - 1); Kernel.memcpy(pEntry, Buffer, sizeof(Entry) - 1); Address = Stream.Position; Stream.Seek(pEntry->Offset, SeekOrigin.Begin); StringBuilder Builder = new StringBuilder(Kernel.MAX_BUFFER_SIZE); Int32 Read = Stream.ReadByte(); while (Read != '\0') { Builder.Append((Char)Read); Read = Stream.ReadByte(); } Builder.Append('\0'); Stream.Seek(Address, SeekOrigin.Begin); Byte *pPath = Builder.ToString().ToPointer(); pEntry = (Entry *)Kernel.realloc(pEntry, sizeof(Entry) + Kernel.strlen(pPath)); Kernel.memcpy(pEntry->Path, pPath, Kernel.strlen(pPath) + 1); if (!Entries.ContainsKey(pEntry->UniqId)) { Entries.Add(pEntry->UniqId, (IntPtr)pEntry); } Kernel.free(pPath); } } } }
public static unsafe void Free_New(void *memory) { uint memoryHeaderPointer = (uint)memory - (uint)sizeof(Header); Header *temp = (Header *)memoryHeaderPointer; /* * Basically this will scan for adjacent free blocks and * remove them from the tree, before combining the blocks * and adding the final big block into the tree */ }
public static List <GameObject> Read(Byte[] data) { unsafe { fixed(Byte *ptr = data) { if (ptr == null) { return(null); } Header * header = (Header *)ptr; Group * areas = (Group *)(ptr + sizeof(Header)); Group * doors = areas + header->CountAreas; Group * modules = doors + header->CountDoors; Group * objects = modules + header->CountModules; Group * end = objects + header->CountObjects; Script * scripts = (Script *)(ptr + header->ScriptsOffset); Operation *operation = (Operation *)(ptr + header->OperationsOffset); Int64 groupNumber = end - areas; Group[] groups = new Group[groupNumber]; for (Group *group = areas; group < end; group++) { groups[--groupNumber] = *group; } List <GameObject> gameObjects = new List <GameObject>(groups.Length); foreach (Group group in groups.OrderBy(g => g.Label)) { List <GameScript> objectScripts = new List <GameScript>(group.ScriptsCount + 1); for (Int32 s = 0; s <= group.ScriptsCount; s++) { Int32 scriptLabel = group.Label + s; UInt16 position = scripts->Position; scripts++; UInt16 count = (UInt16)(scripts->Position - position); Jsm.ExecutableSegment scriptSegment = MakeScript(operation + position, count); objectScripts.Add(new GameScript(scriptLabel, scriptSegment)); } gameObjects.Add(new GameObject(group.Label, objectScripts)); } return(gameObjects); } } }
public static unsafe void *Allocate_New(uint allocate_size) { /* * Simplistically, this finds the first block big enough * to accommodate the requested size and splits as necessary. * Haven't put in any of the asserts yet, but look at how * elegant and clean this code is compared to the old search! */ Header *temp = RBHead; while (temp != Sentinel) { if (temp->Size > allocate_size) { allocated += allocate_size; RBDelete(temp); uint memoryLeft = temp->Size - allocate_size; if (memoryEnd > (uint)sizeof(Header)) { /* * The number 4 is a placeholder until I figure out a * more appropriate value. At a certain point, we need * to decide on what to do regarding those small slivers * of memory that slip through */ if ((memoryLeft - (uint)sizeof(Header)) > 4) { uint memoryHeaderPointer = (uint)(temp + 1) + allocate_size; Header *newNode = (Header *)memoryHeaderPointer; newNode->Previous = temp; newNode->Next = temp->Next; newNode->Size = memoryLeft - (uint)sizeof(Header); temp->Next = newNode; RBAdd(newNode); return((void *)(temp + 1)); } } temp->Size = allocate_size; return((void *)(temp + 1)); } temp = temp->Right; } return(null); }
public static void Dump() { ADC.TextMode.WriteLine("Memory dump: "); Header *currentNode = firstNode; do { DumpNode("MemoryManager", currentNode); currentNode = currentNode->Next; } while (currentNode != firstNode); ADC.TextMode.WriteLine(); }
/// <summary> /// Load the specified MESH file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Entries) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Header *pHeader = stackalloc Header[1]; Stream.Read(Buffer, 0, sizeof(Header)); Kernel.memcpy(pHeader, Buffer, sizeof(Header)); if (pHeader->Identifier != MESH_IDENTIFIER) { throw new Exception("Invalid MESH Header in file: " + Path); } for (Int32 i = 0; i < pHeader->Amount; i++) { Stream.Read(Buffer, 0, sizeof(Int32) * 2); Int32 UniqId = 0; Int32 Amount = 0; fixed(Byte *pBuffer = Buffer) { UniqId = *((Int32 *)pBuffer); Amount = *((Int32 *)pBuffer + 1); } Int32 Length = (sizeof(Entry)) + (Amount * sizeof(Part)); Entry *pEntry = (Entry *)Kernel.malloc(Length); Stream.Read(Buffer, 0, Length - sizeof(Entry)); Kernel.memcpy(pEntry->Parts, Buffer, Length - sizeof(Entry)); pEntry->UniqId = UniqId; pEntry->Amount = Amount; if (!Entries.ContainsKey(pEntry->UniqId)) { Entries.Add(pEntry->UniqId, (IntPtr)pEntry); } } } } }
/// <summary> /// Load the specified ROPT file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Parts) lock (Dumies) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Header *pHeader = stackalloc Header[1]; Stream.Read(Buffer, 0, sizeof(Header)); Kernel.memcpy(pHeader, Buffer, sizeof(Header)); if (pHeader->Identifier != ROPT_IDENTIFIER) { throw new Exception("Invalid ROPT Header in file: " + Path); } for (Int32 i = 0; i < pHeader->PartAmount; i++) { Part *pPart = (Part *)Kernel.malloc(sizeof(Part)); Stream.Read(Buffer, 0, sizeof(Part)); Kernel.memcpy(pPart, Buffer, sizeof(Part)); if (!Parts.ContainsKey(Kernel.cstring(pPart->Name, MAX_NAMESIZE))) { Parts.Add(Kernel.cstring(pPart->Name, MAX_NAMESIZE), (IntPtr)pPart); } } for (Int32 i = 0; i < pHeader->DumyAmount; i++) { Dumy *pDumy = (Dumy *)Kernel.malloc(sizeof(Dumy)); Stream.Read(Buffer, 0, sizeof(Dumy)); Kernel.memcpy(pDumy, Buffer, sizeof(Dumy)); if (!Dumies.ContainsKey(pDumy->UniqId)) { Dumies.Add(pDumy->UniqId, (IntPtr)pDumy); } } } } }
/// <summary> /// Load the specified EFFE file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Entries) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Header *pHeader = stackalloc Header[1]; Stream.Read(Buffer, 0, sizeof(Header)); Kernel.memcpy(pHeader, Buffer, sizeof(Header)); if (pHeader->Identifier != EFFE_IDENTIFIER) { Kernel.free(pHeader); throw new Exception("Invalid EFFE Header in file: " + Path); } for (Int32 i = 0; i < pHeader->Amount; i++) { Stream.Seek(MAX_NAMESIZE, SeekOrigin.Current); Stream.Read(Buffer, 0, sizeof(Int16)); Int16 Amount = 0; fixed(Byte *pBuffer = Buffer) Amount = *((Int16 *)pBuffer); Stream.Seek(-1 * (MAX_NAMESIZE + sizeof(Int16)), SeekOrigin.Current); Int32 Length = (sizeof(Entry)) + (Amount * sizeof(Part)); Entry *pEntry = (Entry *)Kernel.calloc(Length); Stream.Read(Buffer, 0, Length - 1); Kernel.memcpy(pEntry, Buffer, Length - 1); if (!Entries.ContainsKey(Kernel.cstring(pEntry->Name, MAX_NAMESIZE))) { Entries.Add(Kernel.cstring(pEntry->Name, MAX_NAMESIZE), (IntPtr)pEntry); } } } } }
public static void Free(void *p) { fixed(byte *basePtr = m_buffer.Mem) { Header *pHeader = (Header *)p - 1; var offset = (byte *)pHeader - basePtr; Runtime.RTCheck(offset >= 0 && offset < HEAP_SIZE, "disposing an invalid pointer"); Runtime.RTCheck(pHeader->Magic == HEAP_MAGIC, "corrupted heap block"); var realSize = pHeader->Size; Runtime.RTCheck(offset + realSize <= HEAP_SIZE, "heap overflow"); Memset((byte *)pHeader, realSize); m_freeBlocks.Add(new FreeBlock((int)offset, realSize)); } }
/// <summary> /// Save all the dictionary to the specified RSDB_BIG file (in binary format). /// </summary> public void SaveToDat(String Path) { using (FileStream Stream = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; IntPtr[] Pointers = new IntPtr[0]; lock (Entries) { Pointers = new IntPtr[Entries.Count]; Entries.Values.CopyTo(Pointers, 0); } Header *pHeader = stackalloc Header[1]; pHeader->Identifier = RSDB_BIG_IDENTIFIER; pHeader->Amount = Pointers.Length; Kernel.memcpy(Buffer, pHeader, sizeof(Header)); Stream.Write(Buffer, 0, sizeof(Header)); UInt32 Offset = (UInt32)(sizeof(Header) + (pHeader->Amount * (sizeof(Entry) - 1))); for (Int32 i = 0; i < Pointers.Length; i++) { Entry *pEntry = (Entry *)Pointers[i]; pEntry->Offset = Offset; Offset += (UInt32)Kernel.strlen(pEntry->Path) + 1; } for (Int32 i = 0; i < Pointers.Length; i++) { Entry *pEntry = (Entry *)Pointers[i]; Kernel.memcpy(Buffer, pEntry, sizeof(Entry) - 1); Stream.Write(Buffer, 0, sizeof(Entry) - 1); } for (Int32 i = 0; i < Pointers.Length; i++) { Entry *pEntry = (Entry *)Pointers[i]; Kernel.memcpy(Buffer, pEntry->Path, Kernel.strlen(pEntry->Path) + 1); Stream.Write(Buffer, 0, Kernel.strlen(pEntry->Path) + 1); } } }
Header GetHeader() { File.Position = 0; byte[] Buffer = new byte[sizeof(Header)]; if (File.Read(Buffer, 0, Buffer.Length) != Buffer.Length) throw new InternalBufferOverflowException(); fixed(byte *pBuffer = &Buffer[0]) { Header *pHeader = (Header *)pBuffer; if (pHeader->Signature != Signature) { throw new Exception("Invalid SRL Cache File"); } return(*pHeader); } }
/// <summary> /// Save all the dictionary to the specified autoallot file (in binary format). /// </summary> public void SaveToDat(String Path) { using (FileStream Stream = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; lock (Entries) { Int32 Length = (Entries.Count + 2) * sizeof(Int32); Header *pHeader = (Header *)Kernel.malloc(Length); pHeader->Amount = Entries.Count; pHeader->Level = Int32.MaxValue; foreach (IntPtr[] Stats in Entries.Values) { pHeader->Level = Math.Min(pHeader->Level, Stats.Length); } Int32 i = 0; foreach (Int32 Profession in Entries.Keys) { pHeader->Professions[i] = Profession; i++; } Kernel.memcpy(Buffer, pHeader, Length); Stream.Write(Buffer, 0, Length); foreach (IntPtr[] Stats in Entries.Values) { for (i = 0; i < pHeader->Level; i++) { Kernel.memcpy(Buffer, (Entry *)Stats[i], sizeof(Entry)); Stream.Write(Buffer, 0, sizeof(Entry)); } } Kernel.free(pHeader); } } }
/// <summary> /// Load the specified autoallot file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Entries) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Stream.Read(Buffer, 0, sizeof(Int32)); Int32 Amount = 0; fixed(Byte *pBuffer = Buffer) Amount = *((Int32 *)pBuffer); Int32 Length = (Amount + 2) * sizeof(Int32); Header *pHeader = (Header *)Kernel.malloc(Length); Stream.Seek(0, SeekOrigin.Begin); Stream.Read(Buffer, 0, Length); Kernel.memcpy(pHeader, Buffer, Length); Entries = new Dictionary <Int32, IntPtr[]>(Amount); for (Int32 i = 0; i < pHeader->Amount; i++) { Entries.Add(pHeader->Professions[i], new IntPtr[pHeader->Level]); for (Int32 j = 0; j < pHeader->Level; j++) { Entry *pEntry = (Entry *)Kernel.malloc(sizeof(Entry)); Stream.Read(Buffer, 0, sizeof(Entry)); Kernel.memcpy(pEntry, Buffer, sizeof(Entry)); Entries[pHeader->Professions[i]][j] = (IntPtr)pEntry; } } Kernel.free(pHeader); } } }
/// <summary> /// Save all the dictionary to the specified ROPT file (in binary format). /// </summary> public void SaveToDat(String Path) { using (FileStream Stream = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { lock (Parts) lock (Dumies) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; IntPtr[] Pointers = new IntPtr[0]; Header *pHeader = stackalloc Header[1]; pHeader->Identifier = ROPT_IDENTIFIER; pHeader->PartAmount = Parts.Count; pHeader->DumyAmount = Dumies.Count; Kernel.memcpy(Buffer, pHeader, sizeof(Header)); Stream.Write(Buffer, 0, sizeof(Header)); Pointers = new IntPtr[Parts.Count]; Parts.Values.CopyTo(Pointers, 0); for (Int32 i = 0; i < Pointers.Length; i++) { Part *pPart = (Part *)Pointers[i]; Kernel.memcpy(Buffer, pPart, sizeof(Part)); Stream.Write(Buffer, 0, sizeof(Part)); } Pointers = new IntPtr[Dumies.Count]; Dumies.Values.CopyTo(Pointers, 0); for (Int32 i = 0; i < Pointers.Length; i++) { Dumy *pDumy = (Dumy *)Pointers[i]; Kernel.memcpy(Buffer, pDumy, sizeof(Dumy)); Stream.Write(Buffer, 0, sizeof(Dumy)); } } } }
/// <summary> /// Load the specified magictype file (in binary format) into the dictionary. /// </summary> public void LoadFromDat(String Path) { Clear(); lock (Entries) { using (FileStream Stream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { Byte[] Buffer = new Byte[Kernel.MAX_BUFFER_SIZE]; Stream.Read(Buffer, 0, sizeof(Int32)); Int32 Amount = 0; fixed(Byte *pBuffer = Buffer) Amount = *((Int32 *)pBuffer); Int32 Length = (Amount + 1) * sizeof(Int32); Header *pHeader = (Header *)Kernel.malloc(Length); Stream.Seek(0, SeekOrigin.Begin); Stream.Read(Buffer, 0, Length); Kernel.memcpy((Byte *)pHeader, Buffer, Length); Entries = new Dictionary <Int32, IntPtr>(Amount); for (Int32 i = 0; i < Amount; i++) { Entry *pEntry = (Entry *)Kernel.malloc(sizeof(Entry)); Stream.Read(Buffer, 0, sizeof(Entry)); Kernel.memcpy((Byte *)pEntry, Buffer, sizeof(Entry)); if (!Entries.ContainsKey(pHeader->UIDs[i])) { Entries.Add(pHeader->UIDs[i], (IntPtr)pEntry); } } Kernel.free(pHeader); } } }
public static void *Malloc(Int32 size) { fixed(byte *basePtr = m_buffer.Mem) { // minimum allocation size is 4 bytes // int realSize = sizeof(Header) + Math.Max(size, 4); // sort the free blocks by size for a "best-fit" allocation // m_freeBlocks.Sort((a, b) => a.Size.CompareTo(a.Size)); // find a free block that will fit the requested size // int index = m_freeBlocks.FindIndex(a => a.Size >= realSize); Runtime.RTCheck(index >= 0, "out of heap memory"); var freeBlock = m_freeBlocks[index]; // remove the free block and add back the rest of the block if any // m_freeBlocks.RemoveAt(index); if (freeBlock.Size > realSize) { m_freeBlocks.Add(new FreeBlock(freeBlock.Start + realSize, freeBlock.Size - realSize)); } // setup the newly allocated chunk and return it... // Header *pHeader = (Header *)(basePtr + freeBlock.Start); pHeader->Magic = HEAP_MAGIC; pHeader->Size = realSize; return((byte *)(pHeader + 1)); } }