public byte this[ByteAddress address] { get { return this.ReadByte(address); } }
public byte ReadAddress(ByteAddress address) { if (this.edits.ContainsKey(address)) { return this.edits[address]; } return this.InitialState[address.Value]; }
public ImmutableByteWrapper WriteToAddress(ByteAddress address, byte newValue) { ValidateAddress(address); ImmutableByteWrapper retval = new ImmutableByteWrapper(); retval.InitialState = this.InitialState; //it's immutable, so every instance can share a pointer to it. retval.edits = new Dictionary<ByteAddress, byte>(this.edits); retval.edits[address] = newValue; return retval; }
public byte ReadByte(ByteAddress address) { if(this.dynamicState.IsInRange(address)) { return this.dynamicState[address]; } else { return ReadAddressFromStaticMemory(address); } }
/* Structure of Dictionary Header: [0] => n := byte containing number of word separator characters [1:n] => word separator characters, I believe in ASCII [n+1] => size := size of each entry [n+2:n+3] => as word, numOfEntries := number of entries [n+4:n+(numOfEntires * 2 * size)] => the actual entries NOTE that we care about both "entry number" (index into this structure) AND about the entry address (offset into file of a given entry) */ public WordAddress GetOffSetOfNthEntry(int n, GameMemory zorkFile) { ByteAddress startOfDictionary = ptrToDictionary(zorkFile); int dictionaryBaseOffset = startOfDictionary.Value; int sizeOfSepCountEntry = 1; int numberOfSeps = CountOfSeparatorCharacters(zorkFile); int sizeOfSizeEntry = 1; int sizeOfEntryCountEntry = 2; int offsetFirstEntry = dictionaryBaseOffset + sizeOfSepCountEntry + numberOfSeps + sizeOfSizeEntry + sizeOfEntryCountEntry; ByteAddress ptrSizeEntry = new ByteAddress(startOfDictionary.Value + numberOfSeps + sizeOfSepCountEntry); int sizeOfEntry = zorkFile.ReadByte(ptrSizeEntry); return new WordAddress(offsetFirstEntry + (n * sizeOfEntry)); }
private int ReadCustomSizeFromFile(GameMemory zorkFile) { ByteAddress startOfDictionary = ptrToDictionary(zorkFile); int numberOfSeps = CountOfSeparatorCharacters(zorkFile); ByteAddress ptrSizeEntry = new ByteAddress(startOfDictionary.Value + numberOfSeps + 1); int sizeOfEntry = zorkFile.ReadByte(ptrSizeEntry); return sizeOfEntry; }
public void WriteByte(ByteAddress address, byte toWrite) { this.dynamicState = this.dynamicState.WriteToAddress(address, toWrite); }
private void ValidateAddressToStatic(ByteAddress address) { if(!IsInStaticRange(address)) { throw new IndexOutOfRangeException(); } }
private byte ReadAddressFromStaticMemory(ByteAddress address) { ValidateAddressToStatic(address); return this.staticMemory[ByteAddressToStaticIx(address)]; }
private bool IsInStaticRange(ByteAddress address) { return lengthOfDynamicState <= address.Value && address.Value < lengthOfDynamicState + staticMemory.Length; }
private int ByteAddressToStaticIx(ByteAddress address) { return address.Value - lengthOfDynamicState; }
private void ValidateAddress(ByteAddress address) { if (IsOutOfRange(address)) { throw new IndexOutOfRangeException(); } }
private bool IsOutOfRange(ByteAddress address) { return !IsInRange(address); }
public bool IsInRange(ByteAddress address) { return 0 <= address.Value && address.Value < InitialState.Length; }
private static void TestReadVersionNumberFromFile(string pathToMiniZork) { GameMemory miniZork = GameMemory.OpenFile(pathToMiniZork); ByteAddress versionAddress = new ByteAddress(0); byte versionNumber = miniZork.ReadByte(versionAddress); Console.WriteLine($"Mini-Zork version {versionNumber}"); }
private static void TestMemoryBase() { byte[] bytes = Encoding.UTF8.GetBytes("Hello World"); ImmutableByteWrapper initialState = new ImmutableByteWrapper(bytes); ByteAddress address1 = new ByteAddress(1); ImmutableByteWrapper edited = initialState.WriteToAddress(address1, 0x00); //owerwrite "world" byte[] newBytes = Encoding.UTF8.GetBytes("woid!"); IEnumerable<int> sixThruTen = Enumerable.Range(6, 5); var multiEdits = sixThruTen.Select(val => { var address = new ByteAddress(val); var toWrite = newBytes[val - 6]; return new Tuple<ByteAddress, byte>(address, toWrite); }); ImmutableByteWrapper bulkEdits = initialState.WriteMultipleAddress(multiEdits); var toPrint = ReadAsUtf8String(bulkEdits); var oldToPrint = ReadAsUtf8String(initialState); Console.WriteLine($"Initial state has {oldToPrint} and bulk edited has {toPrint}"); int length = initialState.Length; Console.WriteLine(edited.ReadAddress(address1)); Console.WriteLine(initialState.ReadAddress(address1)); }