vfs.pas

Переключить прокрутку окна
Загрузить этот исходный код

{
    VFS – модуль для создания реализаций файловых систем.

    Copyright © 2017 Малик Разработчик

    Это свободная программа: вы можете перераспространять её и/или
    изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она может быть полезна,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <http://www.gnu.org/licenses/>.
}

unit VFS;

{$MODE DELPHI,EXTENDEDSYNTAX ON}

interface

uses
    Lang, IOStream;

{$ASMMODE INTEL,CALLING REGISTER,INLINE ON,GOTO ON}
{$H+,I-,J-,M-,Q-,R-,T-}

type
    FileAttributes = class;
    FileEnumerator = class;
    VirtualFileSystemReadOnly = interface;
    VirtualFileSystemReadWrite = interface;

    { Время в формате Utils.DateTime }
    FileAttributes = class(RefCountInterfacedObject)
    public
        const FLAG_READ_ONLY = $0001;
        const FLAG_HIDDEN = $0002;
        const FLAG_DIRECTORY = $0010;

    public
        constructor create();
        procedure assignAttributes(flags: int;
                creationTime, lastWriteTime, lastAccessTime: long); virtual;
    strict private
        fieldFlags: int;
        fieldCreationTime: long;
        fieldLastWriteTime: long;
        fieldLastAccessTime: long;
        function getFlag(index: int): boolean;
        procedure setFlag(index: int; value: boolean);
    protected
        procedure setFlags(flags: int); virtual;
        procedure setCreationTime(creationTime: int64); virtual;
        procedure setLastWriteTime(lastWriteTime: int64); virtual;
        procedure setLastAccessTime(lastAccessTime: int64); virtual;
    published
        property readOnly: boolean index 0
                read getFlag
                write setFlag
                stored false;
        property hidden: boolean index 1
                read getFlag
                write setFlag
                stored false;
        property directory: boolean index 4
                read getFlag
                write setFlag
                stored false;
        property flags: int
                read fieldFlags
                write setFlags
                default 0;
        property creationTime: int64
                read fieldCreationTime.native
                write setCreationTime
                default 0;
        property lastWriteTime: int64
                read fieldLastWriteTime.native
                write setLastWriteTime
                default 0;
        property lastAccessTime: int64
                read fieldLastAccessTime.native
                write setLastAccessTime
                default 0;
    end;

    FileEnumerator = class(FileAttributes, Connection)
    public
        constructor create();
        procedure close(); virtual; abstract;
        function findNext(): boolean; virtual; abstract;
        procedure assignAttributes(flags: int; creationTime, lastWriteTime, lastAccessTime: long;
                size: long; const name: UnicodeString); overload; virtual;
    strict private
        fieldSize: long;
        fieldName: UnicodeString;
    published
        property size: int64
                read fieldSize.native
                write fieldSize.native
                default 0;
        property name: UnicodeString
                read fieldName
                write fieldName
                stored true;
    end;

    VirtualFileSystemReadOnly = interface(_Interface)
            ['{CBE47A87-8409-49EC-8DC6-43E05AEFEB2E}']
        procedure readAttributes(const fileOrDirName: UnicodeString; attrDst: FileAttributes);
        function fileNameCorrect(const fileOrDirName: UnicodeString): boolean;
        function fileNameCaseSensitive(): boolean;
        function fileNameMaximumLength(): int;
        function findFirst(): FileEnumerator; overload;
        function findFirst(const pathOrFileName: UnicodeString): FileEnumerator; overload;
        function openFileForRead(const fileName: UnicodeString): InputStream;
    end;

    VirtualFileSystemReadWrite = interface(VirtualFileSystemReadOnly)
            ['{CBE47A87-8409-49EC-8DC6-43E05AEFEB2F}']
        procedure writeAttributes(const fileOrDirName: UnicodeString; attrSrc: FileAttributes);
        procedure move(const oldFileOrDirName, newFileOrDirName: UnicodeString);
        procedure deleteDirectory(const dirName: UnicodeString);
        procedure createDirectory(const dirName: UnicodeString);
        procedure deleteFile(const fileName: UnicodeString);
        function createFile(const fileName: UnicodeString): OutputStream;
        function openFileForAppending(const fileName: UnicodeString): OutputStream;
        function openFileForReadWrite(const fileName: UnicodeString): InputOutputStream;
    end;

implementation

{ FileAttributes }

constructor FileAttributes.create();
begin
    inherited create();
end;

procedure FileAttributes.assignAttributes(flags: int;
        creationTime, lastWriteTime, lastAccessTime: long);
begin
    setFlags(flags);
    setCreationTime(creationTime);
    setLastWriteTime(lastWriteTime);
    setLastAccessTime(lastAccessTime);
end;

function FileAttributes.getFlag(index: int): boolean;
begin
    if (index >= 0) and (index < 32) then begin
        result := (fieldFlags shr index) and 1 <> 0;
        exit;
    end;
    result := false;
end;

procedure FileAttributes.setFlag(index: int; value: boolean);
begin
    if (index >= 0) and (index < 32) then begin
        if value = true then begin
            fieldFlags := fieldFlags or (1 shl index);
        end else begin
            fieldFlags := fieldFlags and not (1 shl index);
        end;
    end;
end;

procedure FileAttributes.setFlags(flags: int);
begin
    self.fieldFlags := flags;
end;

procedure FileAttributes.setCreationTime(creationTime: int64);
begin
    self.fieldCreationTime := creationTime;
end;

procedure FileAttributes.setLastWriteTime(lastWriteTime: int64);
begin
    self.fieldLastWriteTime := lastWriteTime;
end;

procedure FileAttributes.setLastAccessTime(lastAccessTime: int64);
begin
    self.fieldLastAccessTime := lastAccessTime;
end;

{ FileEnumeration }

constructor FileEnumerator.create();
begin
    inherited create();
end;

procedure FileEnumerator.assignAttributes(flags: int;
        creationTime, lastWriteTime, lastAccessTime: long; size: long; const name: UnicodeString);
begin
    assignAttributes(flags, creationTime, lastWriteTime, lastAccessTime);
    self.fieldSize := size;
    self.fieldName := name;
end;

end.