/// <summary> /// Checks the source string for the file ending, if the source has a valid file ending (From FileTypes enum). /// If the source is valid, gets the correct function from the FileModes sent. /// Returns a list of the read values if in read mode, returns nothing in write mode. /// </summary> /// <param name="source"></param> /// <param name="mode"></param> /// <returns></returns> private List <CardDataStructure> DataHandler(string source, FileModes mode) { string fileExtesion = GetFileExtension(source); if (Enum.IsDefined(typeof(FileTypes), fileExtesion)) { if (mode is FileModes.Read) { return(DataReader[fileExtesion](source)); } else if (mode is FileModes.Write) { DataWriter[fileExtesion](source, CardDataToCards()); } } else { throw new UnidentifiedCardSourceException(fileExtesion); } return(null); }
public void AddFile(byte[] fileBytes, string cocoFileName, FileTypes fileType = FileTypes.Basic, FileModes fileMode = FileModes.Automatic) { // One track has 2 granules, so a 34 track disk has 34 x 2 = 68 const int granulesPerDisk = 68; // GAT Table starts on track 17. This would be // 256 x 18 x 17 = 78336 bytes in const int gatStartingPosition = 78336; // GAT position inside the GAT track const int gatTrackPosition = 256; // Directory position inside the GAT track const int gatDirectoryTrackPosition = 512; byte firstGranule = 0; byte[] gatByteOrder = { 0x20, 0x21, 0x22, 0x23, 0x1e, 0x1f, 0x24, 0x25, 0x1c, 0x1d, 0x26, 0x27, 0x1a, 0x1b, 0x28, 0x29, 0x18, 0x19, 0x2a, 0x2b, 0x16, 0x17, 0x2c, 0x2d, 0x14, 0x15, 0x2e, 0x2f, 0x12, 0x13, 0x30, 0x31, 0x10, 0x11, 0x32, 0x33, 0x0e, 0x0f, 0x34, 0x35, 0x0c, 0x0d, 0x36, 0x37, 0x0a, 0x0b, 0x38, 0x39, 0x08, 0x09, 0x3a, 0x3b, 0x06, 0x07, 0x3c, 0x3d, 0x04, 0x05, 0x3e, 0x3f, 0x02, 0x03, 0x40, 0x41, 0x00, 0x01, 0x42, 0x43 }; if (fileMode == FileModes.Automatic) { fileMode = fileType == FileTypes.Basic || fileType == FileTypes.Text || fileType == FileTypes.Data ? FileModes.Ascii : FileModes.Binary; } if (fileBytes.Length > (gatByteOrder.Length - _currentGranule) * 0x900) { throw new Exceptions.VirtualDiskFullException("Virtual Disk is Full"); } string name = Path.GetFileNameWithoutExtension(cocoFileName)?.PadRight(8, ' '); string ext = Path.GetExtension(cocoFileName); ext = string.IsNullOrEmpty(ext) ? " " : ext.Remove(0, 1).PadRight(3, ' '); if (name?.Length > 8) { throw new Exceptions.FileNameTooLongException("The coco file name must be 8 characters or less"); } if (_fileNumber == 0) { for (int i = 0; i < _virtualDisk.Length; i++) { _virtualDisk[i] = 0xff; } for (int i = gatTrackPosition; i < gatTrackPosition + 0x100; i++) { _gatTrack[i] = 0; } for (int i = gatTrackPosition; i < gatTrackPosition + granulesPerDisk; i++) { _gatTrack[i] = 0xff; } } firstGranule = _nextGranule; int bytesRead = 0; using (var reader = new BinaryReader(new MemoryStream(fileBytes))) { while (_nextGranule < gatByteOrder.Length) { _currentGranule = _nextGranule; byte[] data = reader.ReadBytes(0x900); bytesRead = data.Length; if (data.Length == 0) { break; } Array.Copy(data, 0, _virtualDisk, gatByteOrder[_nextGranule] * 0x900, data.Length); _nextGranule++; _gatTrack[0x100 + gatByteOrder[_currentGranule]] = (byte)(data.Length == 0x900 ? gatByteOrder[_nextGranule] : 0xc1 + data.Length / 0x100); if (bytesRead < 0x900) { break; } } } for (int i = gatDirectoryTrackPosition + _fileNumber * 0x20; i < gatDirectoryTrackPosition + _fileNumber * 0x20 + 0x20; i++) { _gatTrack[i] = 0; } for (int i = 0; i < 11; i++) { _gatTrack[gatDirectoryTrackPosition + _fileNumber * 0x20 + i] = Encoding.ASCII.GetBytes(name?.ToUpper() + ext.ToUpper())[i]; } _gatTrack[gatDirectoryTrackPosition + _fileNumber * 0x20 + 0x0b] = (byte)fileType; _gatTrack[gatDirectoryTrackPosition + _fileNumber * 0x20 + 0x0c] = (byte)fileMode; _gatTrack[gatDirectoryTrackPosition + _fileNumber * 0x20 + 0x0d] = gatByteOrder[firstGranule]; _gatTrack[gatDirectoryTrackPosition + _fileNumber * 0x20 + 0x0e] = (byte)(bytesRead != 0 && bytesRead % 0x100 == 0 ? 0x01 : 0x00); _gatTrack[gatDirectoryTrackPosition + _fileNumber * 0x20 + 0x0f] = (byte)(bytesRead % 0x100); Array.Copy(_virtualDisk, gatStartingPosition, _virtualDisk, gatStartingPosition + 0x900 * 2, _virtualDisk.Length - gatStartingPosition - 0x900 * 2); Array.Copy(_gatTrack, 0, _virtualDisk, gatStartingPosition, _gatTrack.Length); _fileNumber++; }