public DirectoryEntry(BinaryReader reader)
            {
                long position = reader.BaseStream.Position;

                recordLength = reader.ReadByte();
                extendedAttributeRecordLength = reader.ReadByte();
                extentLocation       = ReadUInt32LB(reader);
                dataLength           = ReadUInt32LB(reader);
                date                 = new DirectoryEntry.DateEntry(reader);
                flags                = reader.ReadByte();
                interleavedSize      = reader.ReadByte();
                interleaveGap        = reader.ReadByte();
                volumeSequenceNumber = ReadUInt16LB(reader);
                nameLength           = reader.ReadByte();
                name                 = new string(reader.ReadChars(nameLength));


                if (nameLength % 2 == 0)
                {
                    reader.ReadByte(); // padding
                }
                int left2Read = (int)(position + recordLength - reader.BaseStream.Position);

                if (left2Read > 0)
                {
                    systemUse = reader.ReadBytes(left2Read);
                }
                else
                {
                    systemUse = new byte[0];
                }
            }
Example #2
0
    private IEnumerable <OvertimeEntry> CreateOvertimeEntries(DateEntry day, bool isRedDay)
    {
        var overtimeEntries = new List <OvertimeEntry>();

        var overtimeHours = isRedDay ? day.GetWorkingHours() : day.GetWorkingHours() - HoursInRegularWorkday;

        foreach (var entry in day.Entries.OrderBy(task => task.CompensationRate))
        {
            if (overtimeHours <= 0)
            {
                break;
            }

            if (isRedDay && (entry.TaskId == _paidHolidayTask || entry.TaskId == _unpaidHolidayTask))
            {
                continue;
            }

            OvertimeEntry overtimeEntry = new OvertimeEntry
            {
                Hours            = Math.Min(overtimeHours, entry.Value),
                CompensationRate = entry.CompensationRate,
                Date             = day.Date,
                TaskId           = entry.TaskId
            };

            overtimeHours -= overtimeEntry.Hours;

            yield return(overtimeEntry);
        }
    }
 private void uniAddBtn_Click(object sender, EventArgs e)
 {
     if (de != null)
     {
         de.Dispose();
     }
     de = new DateEntry("University Name", this.userID);
     de.Show();
     de.submitted += updateInfo;
 }
Example #4
0
 private bool WorkedOnRedDay(DateEntry day, List <DateTime> redDays)
 {
     if ((IsWeekend(day) ||
          redDays.Contains(day.Date)) &&
         day.GetWorkingHours() > 0)
     {
         return(true);
     }
     return(false);
 }
Example #5
0
        public IDateEntry Create(string date, string location, string remarks)
        {
            IDateEntry newEntry = new DateEntry()
            {
                Date = date, Location = location, Remarks = remarks
            };

            _dateEntries.InsertOne((T)newEntry);

            return(newEntry);
        }
Example #6
0
 private bool WorkedOnRedDay(DateEntry day, List <DateTime> redDays)
 {
     if ((day.Date.DayOfWeek == DayOfWeek.Sunday ||
          day.Date.DayOfWeek == DayOfWeek.Saturday ||
          redDays.Contains(day.Date)) &&
         day.GetWorkingHours() > 0)
     {
         return(true);
     }
     return(false);
 }
Example #7
0
 public MoneyEntryViewModel(Person person)
     : base(DateTime.Now.Date.AddYears(-1), DateTime.Now.Date, person.PersonId)
 {
     _person         = person ?? throw new ArgumentNullException("person");
     CurrentType     = Repository.Types.Single(x => x.TypeId == 2);          //Debit
     CurrentCategory = Repository.Categories.Single(x => x.CategoryId == 2); //Food
     DateEntry       = Repository.LastDateEnteredByPerson(_person.PersonId)?.AddDays(1) ?? DateTime.Now.Date.AddDays(-7);
     RefreshStart    = DateEntry.AddDays(-7);
     RefreshEnd      = DateTime.Now;
     Refresh(RefreshStart, RefreshEnd, _person.PersonId);
     Validation();
 }
Example #8
0
        public Model.Data.Json.Date Copy(DateEntry source)
        {
            var destination = new Model.Data.Json.Date
            {
                Day = source.Day,
                //DayOfWeek = source.DayOfWeek,
                Month = source.Month,
                Year  = source.Year
            };

            return(destination);
        }
Example #9
0
        protected static void AddCommonProperties(IdentifiableObjectData item, PeekResult result)
        {
            if (item.VersionInfo == null)
            {
                return;
            }

            result.CreationDate = DateEntry.From(item.VersionInfo.CreationDate, Resources.LabelCreationDate);

            if (item.VersionInfo.RevisionDate.HasValue && item.VersionInfo.RevisionDate.Value != result.CreationDate.Value)
            {
                result.RevisionDate = DateEntry.From(item.VersionInfo.CreationDate, Resources.LabelRevisionDate);
            }
        }
        public IEnumerable <Entry> GetEntries([FromUri] DateEntry dateEntry)
        {
            var entries = _diaryRepository.GetEntries(dateEntry);

            if (entries.Count == 0)
            {
                // may be the case we want to add the first entry of the year. Maybe there are validly no entries in the year, therefore go back one year.
                dateEntry.Year = -1;
                entries        = _diaryRepository.GetEntries(dateEntry);
                if (entries.Count == 0)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
            }

            return(entries);
        }
Example #11
0
        public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
                           Dictionary <string, string> options, string @namespace)
        {
            _device  = imagePlugin;
            Encoding = encoding ?? Encoding.GetEncoding("IBM437");

            options ??= GetDefaultOptions();

            if (options.TryGetValue("debug", out string debugString))
            {
                bool.TryParse(debugString, out _debug);
            }

            // As the identification is so complex, just call Identify() and relay on its findings
            if (!Identify(_device, partition) ||
                !_cpmFound ||
                _workingDefinition == null ||
                _dpb == null)
            {
                return(Errno.InvalidArgument);
            }

            // Build the software interleaving sector mask
            if (_workingDefinition.sides == 1)
            {
                _sectorMask = new int[_workingDefinition.side1.sectorIds.Length];

                for (int m = 0; m < _sectorMask.Length; m++)
                {
                    _sectorMask[m] = _workingDefinition.side1.sectorIds[m] - _workingDefinition.side1.sectorIds[0];
                }
            }
            else
            {
                // Head changes after every track
                if (string.Compare(_workingDefinition.order, "SIDES", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    _sectorMask = new int[_workingDefinition.side1.sectorIds.Length +
                                          _workingDefinition.side2.sectorIds.Length];

                    for (int m = 0; m < _workingDefinition.side1.sectorIds.Length; m++)
                    {
                        _sectorMask[m] = _workingDefinition.side1.sectorIds[m] - _workingDefinition.side1.sectorIds[0];
                    }

                    // Skip first track (first side)
                    for (int m = 0; m < _workingDefinition.side2.sectorIds.Length; m++)
                    {
                        _sectorMask[m + _workingDefinition.side1.sectorIds.Length] =
                            (_workingDefinition.side2.sectorIds[m] - _workingDefinition.side2.sectorIds[0]) +
                            _workingDefinition.side1.sectorIds.Length;
                    }
                }

                // Head changes after whole side
                else if (string.Compare(_workingDefinition.order, "CYLINDERS",
                                        StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    for (int m = 0; m < _workingDefinition.side1.sectorIds.Length; m++)
                    {
                        _sectorMask[m] = _workingDefinition.side1.sectorIds[m] - _workingDefinition.side1.sectorIds[0];
                    }

                    // Skip first track (first side) and first track (second side)
                    for (int m = 0; m < _workingDefinition.side1.sectorIds.Length; m++)
                    {
                        _sectorMask[m + _workingDefinition.side1.sectorIds.Length] =
                            (_workingDefinition.side1.sectorIds[m] - _workingDefinition.side1.sectorIds[0]) +
                            _workingDefinition.side1.sectorIds.Length + _workingDefinition.side2.sectorIds.Length;
                    }

                    // TODO: Implement CYLINDERS ordering
                    AaruConsole.DebugWriteLine("CP/M Plugin", "CYLINDERS ordering not yet implemented.");

                    return(Errno.NotImplemented);
                }

                // TODO: Implement COLUMBIA ordering
                else if (string.Compare(_workingDefinition.order, "COLUMBIA",
                                        StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    AaruConsole.DebugWriteLine("CP/M Plugin",
                                               "Don't know how to handle COLUMBIA ordering, not proceeding with this definition.");

                    return(Errno.NotImplemented);
                }

                // TODO: Implement EAGLE ordering
                else if (string.Compare(_workingDefinition.order, "EAGLE",
                                        StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    AaruConsole.DebugWriteLine("CP/M Plugin",
                                               "Don't know how to handle EAGLE ordering, not proceeding with this definition.");

                    return(Errno.NotImplemented);
                }
                else
                {
                    AaruConsole.DebugWriteLine("CP/M Plugin",
                                               "Unknown order type \"{0}\", not proceeding with this definition.",
                                               _workingDefinition.order);

                    return(Errno.NotSupported);
                }
            }

            // Deinterleave whole volume
            Dictionary <ulong, byte[]> deinterleavedSectors = new Dictionary <ulong, byte[]>();

            if (_workingDefinition.sides == 1 ||
                string.Compare(_workingDefinition.order, "SIDES", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                AaruConsole.DebugWriteLine("CP/M Plugin", "Deinterleaving whole volume.");

                for (int p = 0; p <= (int)(partition.End - partition.Start); p++)
                {
                    byte[] readSector =
                        _device.ReadSector((ulong)((int)partition.Start +
                                                   ((p / _sectorMask.Length) * _sectorMask.Length) +
                                                   _sectorMask[p % _sectorMask.Length]));

                    if (_workingDefinition.complement)
                    {
                        for (int b = 0; b < readSector.Length; b++)
                        {
                            readSector[b] = (byte)(~readSector[b] & 0xFF);
                        }
                    }

                    deinterleavedSectors.Add((ulong)p, readSector);
                }
            }

            int   blockSize       = 128 << _dpb.bsh;
            var   blockMs         = new MemoryStream();
            ulong blockNo         = 0;
            int   sectorsPerBlock = 0;
            Dictionary <ulong, byte[]> allocationBlocks = new Dictionary <ulong, byte[]>();

            AaruConsole.DebugWriteLine("CP/M Plugin", "Creating allocation blocks.");

            // For each volume sector
            for (ulong a = 0; a < (ulong)deinterleavedSectors.Count; a++)
            {
                deinterleavedSectors.TryGetValue(a, out byte[] sector);

                // May it happen? Just in case, CP/M blocks are smaller than physical sectors
                if (sector.Length > blockSize)
                {
                    for (int i = 0; i < sector.Length / blockSize; i++)
                    {
                        byte[] tmp = new byte[blockSize];
                        Array.Copy(sector, blockSize * i, tmp, 0, blockSize);
                        allocationBlocks.Add(blockNo++, tmp);
                    }
                }

                // CP/M blocks are larger than physical sectors
                else if (sector.Length < blockSize)
                {
                    blockMs.Write(sector, 0, sector.Length);
                    sectorsPerBlock++;

                    if (sectorsPerBlock != blockSize / sector.Length)
                    {
                        continue;
                    }

                    allocationBlocks.Add(blockNo++, blockMs.ToArray());
                    sectorsPerBlock = 0;
                    blockMs         = new MemoryStream();
                }

                // CP/M blocks are same size than physical sectors
                else
                {
                    allocationBlocks.Add(blockNo++, sector);
                }
            }

            AaruConsole.DebugWriteLine("CP/M Plugin", "Reading directory.");

            int dirOff;
            int dirSectors = ((_dpb.drm + 1) * 32) / _workingDefinition.bytesPerSector;

            if (_workingDefinition.sofs > 0)
            {
                dirOff = _workingDefinition.sofs;
            }
            else
            {
                dirOff = _workingDefinition.ofs * _workingDefinition.sectorsPerTrack;
            }

            // Read the whole directory blocks
            var dirMs = new MemoryStream();

            for (int d = 0; d < dirSectors; d++)
            {
                deinterleavedSectors.TryGetValue((ulong)(d + dirOff), out byte[] sector);
                dirMs.Write(sector, 0, sector.Length);
            }

            byte[] directory = dirMs.ToArray();

            if (directory == null)
            {
                return(Errno.InvalidArgument);
            }

            int    dirCnt = 0;
            string file1  = null;
            string file2  = null;
            string file3  = null;

            Dictionary <string, Dictionary <int, List <ushort> > > fileExtents =
                new Dictionary <string, Dictionary <int, List <ushort> > >();

            _statCache = new Dictionary <string, FileEntryInfo>();
            _cpmStat   = new FileSystemInfo();
            bool atime = false;

            _dirList           = new List <string>();
            _labelCreationDate = null;
            _labelUpdateDate   = null;
            _passwordCache     = new Dictionary <string, byte[]>();

            AaruConsole.DebugWriteLine("CP/M Plugin", "Traversing directory.");

            // For each directory entry
            for (int dOff = 0; dOff < directory.Length; dOff += 32)
            {
                // Describes a file (does not support PDOS entries with user >= 16, because they're identical to password entries
                if ((directory[dOff] & 0x7F) < 0x10)
                {
                    if (allocationBlocks.Count > 256)
                    {
                        DirectoryEntry16 entry =
                            Marshal.ByteArrayToStructureLittleEndian <DirectoryEntry16>(directory, dOff, 32);

                        bool hidden = (entry.statusUser & 0x80) == 0x80;
                        bool rdOnly = (entry.filename[0] & 0x80) == 0x80 || (entry.extension[0] & 0x80) == 0x80;
                        bool system = (entry.filename[1] & 0x80) == 0x80 || (entry.extension[2] & 0x80) == 0x80;

                        //bool backed = (entry.filename[3] & 0x80) == 0x80 || (entry.extension[3] & 0x80) == 0x80;
                        int user = entry.statusUser & 0x0F;

                        bool validEntry = true;

                        for (int i = 0; i < 8; i++)
                        {
                            entry.filename[i] &= 0x7F;
                            validEntry        &= entry.filename[i] >= 0x20;
                        }

                        for (int i = 0; i < 3; i++)
                        {
                            entry.extension[i] &= 0x7F;
                            validEntry         &= entry.extension[i] >= 0x20;
                        }

                        if (!validEntry)
                        {
                            continue;
                        }

                        string filename  = Encoding.ASCII.GetString(entry.filename).Trim();
                        string extension = Encoding.ASCII.GetString(entry.extension).Trim();

                        // If user is != 0, append user to name to have identical filenames
                        if (user > 0)
                        {
                            filename = $"{user:X1}:{filename}";
                        }

                        if (!string.IsNullOrEmpty(extension))
                        {
                            filename = filename + "." + extension;
                        }

                        int entryNo = ((32 * entry.extentCounter) + entry.extentCounterHigh) / (_dpb.exm + 1);

                        // Do we have a stat for the file already?
                        if (_statCache.TryGetValue(filename, out FileEntryInfo fInfo))
                        {
                            _statCache.Remove(filename);
                        }
                        else
                        {
                            fInfo = new FileEntryInfo
                            {
                                Attributes = new FileAttributes()
                            }
                        };

                        // And any extent?
                        if (fileExtents.TryGetValue(filename, out Dictionary <int, List <ushort> > extentBlocks))
                        {
                            fileExtents.Remove(filename);
                        }
                        else
                        {
                            extentBlocks = new Dictionary <int, List <ushort> >();
                        }

                        // Do we already have this extent? Should never happen
                        if (extentBlocks.TryGetValue(entryNo, out List <ushort> blocks))
                        {
                            extentBlocks.Remove(entryNo);
                        }
                        else
                        {
                            blocks = new List <ushort>();
                        }

                        // Attributes
                        if (hidden)
                        {
                            fInfo.Attributes |= FileAttributes.Hidden;
                        }

                        if (rdOnly)
                        {
                            fInfo.Attributes |= FileAttributes.ReadOnly;
                        }

                        if (system)
                        {
                            fInfo.Attributes |= FileAttributes.System;
                        }

                        // Supposedly there is a value in the directory entry telling how many blocks are designated in
                        // this entry. However some implementations tend to do whatever they wish, but none will ever
                        // allocate block 0 for a file because that's where the directory resides.
                        // There is also a field telling how many bytes are used in the last block, but its meaning is
                        // non-standard so we must ignore it.
                        foreach (ushort blk in entry.allocations.Where(blk => !blocks.Contains(blk) && blk != 0))
                        {
                            blocks.Add(blk);
                        }

                        // Save the file
                        fInfo.UID = (ulong)user;
                        extentBlocks.Add(entryNo, blocks);
                        fileExtents.Add(filename, extentBlocks);
                        _statCache.Add(filename, fInfo);

                        // Add the file to the directory listing
                        if (!_dirList.Contains(filename))
                        {
                            _dirList.Add(filename);
                        }

                        // Count entries 3 by 3 for timestamps
                        switch (dirCnt % 3)
                        {
                        case 0:
                            file1 = filename;

                            break;

                        case 1:
                            file2 = filename;

                            break;

                        case 2:
                            file3 = filename;

                            break;
                        }

                        dirCnt++;
                    }
                    else
                    {
                        DirectoryEntry entry =
                            Marshal.ByteArrayToStructureLittleEndian <DirectoryEntry>(directory, dOff, 32);

                        bool hidden = (entry.statusUser & 0x80) == 0x80;
                        bool rdOnly = (entry.filename[0] & 0x80) == 0x80 || (entry.extension[0] & 0x80) == 0x80;
                        bool system = (entry.filename[1] & 0x80) == 0x80 || (entry.extension[2] & 0x80) == 0x80;

                        //bool backed = (entry.filename[3] & 0x80) == 0x80 || (entry.extension[3] & 0x80) == 0x80;
                        int user = entry.statusUser & 0x0F;

                        bool validEntry = true;

                        for (int i = 0; i < 8; i++)
                        {
                            entry.filename[i] &= 0x7F;
                            validEntry        &= entry.filename[i] >= 0x20;
                        }

                        for (int i = 0; i < 3; i++)
                        {
                            entry.extension[i] &= 0x7F;
                            validEntry         &= entry.extension[i] >= 0x20;
                        }

                        if (!validEntry)
                        {
                            continue;
                        }

                        string filename  = Encoding.ASCII.GetString(entry.filename).Trim();
                        string extension = Encoding.ASCII.GetString(entry.extension).Trim();

                        // If user is != 0, append user to name to have identical filenames
                        if (user > 0)
                        {
                            filename = $"{user:X1}:{filename}";
                        }

                        if (!string.IsNullOrEmpty(extension))
                        {
                            filename = filename + "." + extension;
                        }

                        int entryNo = ((32 * entry.extentCounterHigh) + entry.extentCounter) / (_dpb.exm + 1);

                        // Do we have a stat for the file already?
                        if (_statCache.TryGetValue(filename, out FileEntryInfo fInfo))
                        {
                            _statCache.Remove(filename);
                        }
                        else
                        {
                            fInfo = new FileEntryInfo
                            {
                                Attributes = new FileAttributes()
                            }
                        };

                        // And any extent?
                        if (fileExtents.TryGetValue(filename, out Dictionary <int, List <ushort> > extentBlocks))
                        {
                            fileExtents.Remove(filename);
                        }
                        else
                        {
                            extentBlocks = new Dictionary <int, List <ushort> >();
                        }

                        // Do we already have this extent? Should never happen
                        if (extentBlocks.TryGetValue(entryNo, out List <ushort> blocks))
                        {
                            extentBlocks.Remove(entryNo);
                        }
                        else
                        {
                            blocks = new List <ushort>();
                        }

                        // Attributes
                        if (hidden)
                        {
                            fInfo.Attributes |= FileAttributes.Hidden;
                        }

                        if (rdOnly)
                        {
                            fInfo.Attributes |= FileAttributes.ReadOnly;
                        }

                        if (system)
                        {
                            fInfo.Attributes |= FileAttributes.System;
                        }

                        // Supposedly there is a value in the directory entry telling how many blocks are designated in
                        // this entry. However some implementations tend to do whatever they wish, but none will ever
                        // allocate block 0 for a file because that's where the directory resides.
                        // There is also a field telling how many bytes are used in the last block, but its meaning is
                        // non-standard so we must ignore it.
                        foreach (ushort blk in entry.allocations.Where(blk => !blocks.Contains(blk) && blk != 0))
                        {
                            blocks.Add(blk);
                        }

                        // Save the file
                        fInfo.UID = (ulong)user;
                        extentBlocks.Add(entryNo, blocks);
                        fileExtents.Add(filename, extentBlocks);
                        _statCache.Add(filename, fInfo);

                        // Add the file to the directory listing
                        if (!_dirList.Contains(filename))
                        {
                            _dirList.Add(filename);
                        }

                        // Count entries 3 by 3 for timestamps
                        switch (dirCnt % 3)
                        {
                        case 0:
                            file1 = filename;

                            break;

                        case 1:
                            file2 = filename;

                            break;

                        case 2:
                            file3 = filename;

                            break;
                        }

                        dirCnt++;
                    }
                }

                // A password entry (or a file entry in PDOS, but this does not handle that case)
                else if ((directory[dOff] & 0x7F) >= 0x10 &&
                         (directory[dOff] & 0x7F) < 0x20)
                {
                    PasswordEntry entry = Marshal.ByteArrayToStructureLittleEndian <PasswordEntry>(directory, dOff, 32);

                    int user = entry.userNumber & 0x0F;

                    for (int i = 0; i < 8; i++)
                    {
                        entry.filename[i] &= 0x7F;
                    }

                    for (int i = 0; i < 3; i++)
                    {
                        entry.extension[i] &= 0x7F;
                    }

                    string filename  = Encoding.ASCII.GetString(entry.filename).Trim();
                    string extension = Encoding.ASCII.GetString(entry.extension).Trim();

                    // If user is != 0, append user to name to have identical filenames
                    if (user > 0)
                    {
                        filename = $"{user:X1}:{filename}";
                    }

                    if (!string.IsNullOrEmpty(extension))
                    {
                        filename = filename + "." + extension;
                    }

                    // Do not repeat passwords
                    if (_passwordCache.ContainsKey(filename))
                    {
                        _passwordCache.Remove(filename);
                    }

                    // Copy whole password entry
                    byte[] tmp = new byte[32];
                    Array.Copy(directory, dOff, tmp, 0, 32);
                    _passwordCache.Add(filename, tmp);

                    // Count entries 3 by 3 for timestamps
                    switch (dirCnt % 3)
                    {
                    case 0:
                        file1 = filename;

                        break;

                    case 1:
                        file2 = filename;

                        break;

                    case 2:
                        file3 = filename;

                        break;
                    }

                    dirCnt++;
                }

                // Volume label and password entry. Volume password is ignored.
                else
                {
                    switch (directory[dOff] & 0x7F)
                    {
                    case 0x20:
                        LabelEntry labelEntry =
                            Marshal.ByteArrayToStructureLittleEndian <LabelEntry>(directory, dOff, 32);

                        // The volume label defines if one of the fields in CP/M 3 timestamp is a creation or an
                        // access time
                        atime |= (labelEntry.flags & 0x40) == 0x40;

                        _label             = Encoding.ASCII.GetString(directory, dOff + 1, 11).Trim();
                        _labelCreationDate = new byte[4];
                        _labelUpdateDate   = new byte[4];
                        Array.Copy(directory, dOff + 24, _labelCreationDate, 0, 4);
                        Array.Copy(directory, dOff + 28, _labelUpdateDate, 0, 4);

                        // Count entries 3 by 3 for timestamps
                        switch (dirCnt % 3)
                        {
                        case 0:
                            file1 = null;

                            break;

                        case 1:
                            file2 = null;

                            break;

                        case 2:
                            file3 = null;

                            break;
                        }

                        dirCnt++;

                        break;

                    case 0x21:
                        if (directory[dOff + 10] == 0x00 &&
                            directory[dOff + 20] == 0x00 &&
                            directory[dOff + 30] == 0x00 &&
                            directory[dOff + 31] == 0x00)
                        {
                            DateEntry dateEntry =
                                Marshal.ByteArrayToStructureLittleEndian <DateEntry>(directory, dOff, 32);

                            FileEntryInfo fInfo;

                            // Entry contains timestamps for last 3 entries, whatever the kind they are.
                            if (!string.IsNullOrEmpty(file1))
                            {
                                if (_statCache.TryGetValue(file1, out fInfo))
                                {
                                    _statCache.Remove(file1);
                                }
                                else
                                {
                                    fInfo = new FileEntryInfo();
                                }

                                if (atime)
                                {
                                    fInfo.AccessTime = DateHandlers.CpmToDateTime(dateEntry.date1);
                                }
                                else
                                {
                                    fInfo.CreationTime = DateHandlers.CpmToDateTime(dateEntry.date1);
                                }

                                fInfo.LastWriteTime = DateHandlers.CpmToDateTime(dateEntry.date2);

                                _statCache.Add(file1, fInfo);
                            }

                            if (!string.IsNullOrEmpty(file2))
                            {
                                if (_statCache.TryGetValue(file2, out fInfo))
                                {
                                    _statCache.Remove(file2);
                                }
                                else
                                {
                                    fInfo = new FileEntryInfo();
                                }

                                if (atime)
                                {
                                    fInfo.AccessTime = DateHandlers.CpmToDateTime(dateEntry.date3);
                                }
                                else
                                {
                                    fInfo.CreationTime = DateHandlers.CpmToDateTime(dateEntry.date3);
                                }

                                fInfo.LastWriteTime = DateHandlers.CpmToDateTime(dateEntry.date4);

                                _statCache.Add(file2, fInfo);
                            }

                            if (!string.IsNullOrEmpty(file3))
                            {
                                if (_statCache.TryGetValue(file3, out fInfo))
                                {
                                    _statCache.Remove(file3);
                                }
                                else
                                {
                                    fInfo = new FileEntryInfo();
                                }

                                if (atime)
                                {
                                    fInfo.AccessTime = DateHandlers.CpmToDateTime(dateEntry.date5);
                                }
                                else
                                {
                                    fInfo.CreationTime = DateHandlers.CpmToDateTime(dateEntry.date5);
                                }

                                fInfo.LastWriteTime = DateHandlers.CpmToDateTime(dateEntry.date6);

                                _statCache.Add(file3, fInfo);
                            }

                            file1  = null;
                            file2  = null;
                            file3  = null;
                            dirCnt = 0;
                        }

                        // However, if this byte is 0, timestamp is in Z80DOS or DOS+ format
                        else if (directory[dOff + 1] == 0x00)
                        {
                            TrdPartyDateEntry trdPartyDateEntry =
                                Marshal.ByteArrayToStructureLittleEndian <TrdPartyDateEntry>(directory, dOff, 32);

                            FileEntryInfo fInfo;

                            // Entry contains timestamps for last 3 entries, whatever the kind they are.
                            if (!string.IsNullOrEmpty(file1))
                            {
                                if (_statCache.TryGetValue(file1, out fInfo))
                                {
                                    _statCache.Remove(file1);
                                }
                                else
                                {
                                    fInfo = new FileEntryInfo();
                                }

                                byte[] ctime = new byte[4];
                                ctime[0] = trdPartyDateEntry.create1[0];
                                ctime[1] = trdPartyDateEntry.create1[1];

                                fInfo.AccessTime    = DateHandlers.CpmToDateTime(trdPartyDateEntry.access1);
                                fInfo.CreationTime  = DateHandlers.CpmToDateTime(ctime);
                                fInfo.LastWriteTime = DateHandlers.CpmToDateTime(trdPartyDateEntry.modify1);

                                _statCache.Add(file1, fInfo);
                            }

                            if (!string.IsNullOrEmpty(file2))
                            {
                                if (_statCache.TryGetValue(file2, out fInfo))
                                {
                                    _statCache.Remove(file2);
                                }
                                else
                                {
                                    fInfo = new FileEntryInfo();
                                }

                                byte[] ctime = new byte[4];
                                ctime[0] = trdPartyDateEntry.create2[0];
                                ctime[1] = trdPartyDateEntry.create2[1];

                                fInfo.AccessTime    = DateHandlers.CpmToDateTime(trdPartyDateEntry.access2);
                                fInfo.CreationTime  = DateHandlers.CpmToDateTime(ctime);
                                fInfo.LastWriteTime = DateHandlers.CpmToDateTime(trdPartyDateEntry.modify2);

                                _statCache.Add(file2, fInfo);
                            }

                            if (!string.IsNullOrEmpty(file3))
                            {
                                if (_statCache.TryGetValue(file1, out fInfo))
                                {
                                    _statCache.Remove(file3);
                                }
                                else
                                {
                                    fInfo = new FileEntryInfo();
                                }

                                byte[] ctime = new byte[4];
                                ctime[0] = trdPartyDateEntry.create3[0];
                                ctime[1] = trdPartyDateEntry.create3[1];

                                fInfo.AccessTime    = DateHandlers.CpmToDateTime(trdPartyDateEntry.access3);
                                fInfo.CreationTime  = DateHandlers.CpmToDateTime(ctime);
                                fInfo.LastWriteTime = DateHandlers.CpmToDateTime(trdPartyDateEntry.modify3);

                                _statCache.Add(file3, fInfo);
                            }

                            file1  = null;
                            file2  = null;
                            file3  = null;
                            dirCnt = 0;
                        }

                        break;
                    }
                }
            }

            // Cache all files. As CP/M maximum volume size is 8 Mib
            // this should not be a problem
            AaruConsole.DebugWriteLine("CP/M Plugin", "Reading files.");
            long usedBlocks = 0;

            _fileCache = new Dictionary <string, byte[]>();

            foreach (string filename in _dirList)
            {
                var fileMs = new MemoryStream();

                if (_statCache.TryGetValue(filename, out FileEntryInfo fInfo))
                {
                    _statCache.Remove(filename);
                }

                fInfo.Blocks = 0;

                if (fileExtents.TryGetValue(filename, out Dictionary <int, List <ushort> > extents))
                {
                    for (int ex = 0; ex < extents.Count; ex++)
                    {
                        if (!extents.TryGetValue(ex, out List <ushort> alBlks))
                        {
                            continue;
                        }

                        foreach (ushort alBlk in alBlks)
                        {
                            allocationBlocks.TryGetValue(alBlk, out byte[] blk);
                            fileMs.Write(blk, 0, blk.Length);
                            fInfo.Blocks++;
                        }
                    }
                }

                // If you insist to call CP/M "extent based"
                fInfo.Attributes |= FileAttributes.Extents;
                fInfo.BlockSize   = blockSize;
                fInfo.Length      = fileMs.Length;
                _cpmStat.Files++;
                usedBlocks += fInfo.Blocks;

                _statCache.Add(filename, fInfo);
                _fileCache.Add(filename, fileMs.ToArray());
            }

            _decodedPasswordCache = new Dictionary <string, byte[]>();

            // For each stored password, store a decoded version of it
            if (_passwordCache.Count > 0)
            {
                foreach (KeyValuePair <string, byte[]> kvp in _passwordCache)
                {
                    byte[] tmp = new byte[8];
                    Array.Copy(kvp.Value, 16, tmp, 0, 8);

                    for (int t = 0; t < 8; t++)
                    {
                        tmp[t] ^= kvp.Value[13];
                    }

                    _decodedPasswordCache.Add(kvp.Key, tmp);
                }
            }

            // Generate statfs.
            _cpmStat.Blocks         = (ulong)(_dpb.dsm + 1);
            _cpmStat.FilenameLength = 11;
            _cpmStat.Files          = (ulong)_fileCache.Count;
            _cpmStat.FreeBlocks     = _cpmStat.Blocks - (ulong)usedBlocks;
            _cpmStat.PluginId       = Id;
            _cpmStat.Type           = "CP/M filesystem";

            // Generate XML info
            XmlFsType = new FileSystemType
            {
                Clusters              = _cpmStat.Blocks,
                ClusterSize           = (uint)blockSize,
                Files                 = (ulong)_fileCache.Count,
                FilesSpecified        = true,
                FreeClusters          = _cpmStat.FreeBlocks,
                FreeClustersSpecified = true,
                Type = "CP/M filesystem"
            };

            if (_labelCreationDate != null)
            {
                XmlFsType.CreationDate          = DateHandlers.CpmToDateTime(_labelCreationDate);
                XmlFsType.CreationDateSpecified = true;
            }

            if (_labelUpdateDate != null)
            {
                XmlFsType.ModificationDate          = DateHandlers.CpmToDateTime(_labelUpdateDate);
                XmlFsType.ModificationDateSpecified = true;
            }

            if (!string.IsNullOrEmpty(_label))
            {
                XmlFsType.VolumeName = _label;
            }

            _mounted = true;

            return(Errno.NoError);
        }
 public HttpResponseMessage DeleteEntries([FromUri] DateEntry dateEntry)
 {
     _diaryRepository.DeleteEntries(dateEntry);
     return(new HttpResponseMessage(HttpStatusCode.NoContent));
 }
Example #13
0
 private bool IsWeekend(DateEntry entry)
 {
     return(entry.Date.DayOfWeek == DayOfWeek.Saturday || entry.Date.DayOfWeek == DayOfWeek.Sunday);
 }