platform.independent.filesystem.pas

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

{
    platform.independent.filesystem — основной модуль для разработки классов
    файловых систем.

    Copyright © 2021, 2026 Малик Разработчик

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

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

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

unit platform.independent.filesystem;

    {$MODE DELPHI}

interface

    {%region} uses
        pascalx.lang,
        pascalx.io;
    {%endregion}

    {$TYPEINFO ON}
    {$CALLING REGISTER}

    const UNIT_NAME = 'platform.independent.filesystem';

    {%region} type
        Attributes                     = interface;
        FileSystem                     = interface;
        RequiredAttributes             = class;
        ObjectAttributes               = class;
        ObjectEnumeration              = class;
        InvalidObjectNameException     = class;
        ObjectNameTooLongException     = class;
        FileSystemException            = class;
        FileSystemNotAttachedException = class;
        FileSystemReadOnlyException    = class;
        FileSystemFullException        = class;
        ObjectOperationException       = class;
        ObjectReadAttributesException  = class;
        ObjectWriteAttributesException = class;
        ObjectNotFoundException        = class;
        DirectoryOperationException    = class;
        DirectoryCreationException     = class;
        DirectoryDeletionException     = class;
        DirectoryNotFoundException     = class;
        FileOperationException         = class;
        FileCreationException          = class;
        FileDeletionException          = class;
        FileOpeningException           = class;
        FileNotFoundException          = class;
        MoveOperationException         = class;

        Attributes = interface(RefCountInterface) ['{EF1E7852-B2E5-4336-8EED-64C136AD6A62}']
            procedure setBooleanAttribute(const attributeId: AnsiString; attributeValue: boolean);
            procedure setLongAttribute(const attributeId: AnsiString; attributeValue: long);
            procedure setStringAttribute(const attributeId: AnsiString; const attributeValue: UnicodeString);
            function isSupportedAttributeId(const attributeId: AnsiString): boolean;
            function getBooleanAttribute(const attributeId: AnsiString): boolean;
            function getLongAttribute(const attributeId: AnsiString): long;
            function getStringAttribute(const attributeId: AnsiString): UnicodeString;
            function displayName(const attributeId: AnsiString): UnicodeString;
            function getSupportedAttributeIds(): AnsiString_Array1d;
        end;

        FileSystem = interface(RawInterface) ['{EF1E7852-B2E5-4336-8EED-64C136AD6A63}']
            procedure changeCurrentDirectory(const directoryPath: UnicodeString);
            procedure readAttributes(const objectName: UnicodeString; objectAttr: ObjectAttributes);
            procedure writeAttributes(const objectName: UnicodeString; objectAttr: ObjectAttributes);
            procedure move(const objectOldName, objectNewName: UnicodeString);
            procedure deleteFile(const fileName: UnicodeString);
            procedure deleteDirectory(const directoryName: UnicodeString);
            procedure createDirectory(const directoryName: UnicodeString);
            function isAttached(): boolean;
            function isReadOnly(): boolean;
            function isObjectNameCaseSensitive(): boolean;
            function isObjectExists(const objectName: UnicodeString): boolean;
            function isObjectNameValid(const objectName: UnicodeString): boolean;
            function isInternalNameFull(const internalName: UnicodeString): boolean;
            function isInternalNameValid(const internalName: UnicodeString): boolean;
            function getObjectNameMaximumLength(): int;
            function totalSize(): long;
            function usedSize(): long;
            function availableSize(): long;
            function getCurrentDirectory(): UnicodeString;
            function toInternalName(const objectName: UnicodeString): UnicodeString;
            function toObjectName(const internalName: UnicodeString): UnicodeString;
            function findFirst(const objectPath: UnicodeString): ObjectEnumeration;
            function createFile(const fileName: UnicodeString): ByteWriter;
            function rewriteFile(const fileName: UnicodeString): ByteWriter;
            function openFileForAppend(const fileName: UnicodeString): ByteWriter;
            function openFileForRead(const fileName: UnicodeString): ByteReader;
            function openFile(const fileName: UnicodeString): ByteStream;
            function newAttributes(): Attributes;
            property currentDirectory: UnicodeString read getCurrentDirectory;
        end;

        RequiredAttributes = class(RefCountObject)
        public const
            B_DIRECTORY        = AnsiString('bDirectory');
            B_READ_ONLY        = AnsiString('bReadOnly');
            L_LAST_ACCESS_TIME = AnsiString('lLastAccessTime');
            L_LAST_WRITE_TIME  = AnsiString('lLastWriteTime');
        end;

        ObjectAttributes = class(&Object, Attributes)
        private
            class function getAttributeId(index: int): AnsiString; static;
        private
            fldSource: Attributes;
            procedure setBooleanAttribute(index: int; value: boolean); overload;
            procedure setLongAttribute(index: int; value: long); overload;
            function getBooleanAttribute(index: int): boolean; overload;
            function getLongAttribute(index: int): long; overload;
        public
            constructor create(source: Attributes); overload;
            constructor create(source: FileSystem); overload;
            procedure setBooleanAttribute(const attributeId: AnsiString; attributeValue: boolean); virtual; overload;
            procedure setLongAttribute(const attributeId: AnsiString; attributeValue: long); virtual; overload;
            procedure setStringAttribute(const attributeId: AnsiString; const attributeValue: UnicodeString); virtual;
            function isSupportedAttributeId(const attributeId: AnsiString): boolean; virtual;
            function getBooleanAttribute(const attributeId: AnsiString): boolean; virtual; overload;
            function getLongAttribute(const attributeId: AnsiString): long; virtual; overload;
            function getStringAttribute(const attributeId: AnsiString): UnicodeString; virtual;
            function displayName(const attributeId: AnsiString): UnicodeString; virtual;
            function getSupportedAttributeIds(): AnsiString_Array1d; virtual;
        published
            property directory: boolean index 1 read getBooleanAttribute write setBooleanAttribute;
            property readOnly: boolean index 2 read getBooleanAttribute write setBooleanAttribute;
            property lastAccessTime: long index 11 read getLongAttribute write setLongAttribute;
            property lastWriteTime: long index 12 read getLongAttribute write setLongAttribute;
        end;

        ObjectEnumeration = class abstract(ObjectAttributes)
        private
            fldSize: long;
            fldName: UnicodeString;
        public
            constructor create(source: Attributes);
            procedure close(); virtual;
            function findNext(): boolean; virtual; abstract;
        published
            property size: long read fldSize write fldSize;
            property name: UnicodeString read fldName write fldName;
        end;

        InvalidObjectNameException = class(IllegalArgumentException);

        ObjectNameTooLongException = class(InvalidObjectNameException);

        FileSystemException = class abstract(IOException);

        FileSystemNotAttachedException = class(FileSystemException);

        FileSystemReadOnlyException = class(FileSystemException);

        FileSystemFullException = class(FileSystemException);

        ObjectOperationException = class abstract(FileSystemException);

        ObjectReadAttributesException = class(ObjectOperationException);

        ObjectWriteAttributesException = class(ObjectOperationException);

        ObjectNotFoundException = class(ObjectOperationException);

        DirectoryOperationException = class(ObjectOperationException);

        DirectoryCreationException = class(DirectoryOperationException);

        DirectoryDeletionException = class(DirectoryOperationException);

        DirectoryNotFoundException = class(ObjectNotFoundException);

        FileOperationException = class(ObjectOperationException);

        FileCreationException = class(FileOperationException);

        FileDeletionException = class(FileOperationException);

        FileOpeningException = class(FileOperationException);

        FileNotFoundException = class(ObjectNotFoundException);

        MoveOperationException = class(ObjectOperationException);
    {%endregion}

implementation

    {$R *.res}

    {$CALLING REGISTER}

    {%region  ObjectAttributes }
        class function ObjectAttributes.getAttributeId(index: int): AnsiString;
        begin
            case index of
             1: result := RequiredAttributes.B_DIRECTORY;
             2: result := RequiredAttributes.B_READ_ONLY;
            11: result := RequiredAttributes.L_LAST_ACCESS_TIME;
            12: result := RequiredAttributes.L_LAST_WRITE_TIME;
            else
                result := '';
            end;
        end;

        procedure ObjectAttributes.setBooleanAttribute(index: int; value: boolean);
        begin
            setBooleanAttribute(getAttributeId(index), value);
        end;

        procedure ObjectAttributes.setLongAttribute(index: int; value: long);
        begin
            setLongAttribute(getAttributeId(index), value);
        end;

        function ObjectAttributes.getBooleanAttribute(index: int): boolean;
        begin
            result := getBooleanAttribute(getAttributeId(index));
        end;

        function ObjectAttributes.getLongAttribute(index: int): long;
        begin
            result := getLongAttribute(getAttributeId(index));
        end;

        constructor ObjectAttributes.create(source: Attributes);
        begin
            inherited create();
            fldSource := source;
        end;

        constructor ObjectAttributes.create(source: FileSystem);
        begin
            inherited create();
            if source <> nil then fldSource := source.newAttributes();
        end;

        procedure ObjectAttributes.setBooleanAttribute(const attributeId: AnsiString; attributeValue: boolean);
        begin
            fldSource.setBooleanAttribute(attributeId, attributeValue);
        end;

        procedure ObjectAttributes.setLongAttribute(const attributeId: AnsiString; attributeValue: long);
        begin
            fldSource.setLongAttribute(attributeId, attributeValue);
        end;

        procedure ObjectAttributes.setStringAttribute(const attributeId: AnsiString; const attributeValue: UnicodeString);
        begin
            fldSource.setStringAttribute(attributeId, attributeValue);
        end;

        function ObjectAttributes.isSupportedAttributeId(const attributeId: AnsiString): boolean;
        begin
            result := fldSource.isSupportedAttributeId(attributeId);
        end;

        function ObjectAttributes.getBooleanAttribute(const attributeId: AnsiString): boolean;
        begin
            result := fldSource.getBooleanAttribute(attributeId);
        end;

        function ObjectAttributes.getLongAttribute(const attributeId: AnsiString): long;
        begin
            result := fldSource.getLongAttribute(attributeId);
        end;

        function ObjectAttributes.getStringAttribute(const attributeId: AnsiString): UnicodeString;
        begin
            result := fldSource.getStringAttribute(attributeId);
        end;

        function ObjectAttributes.displayName(const attributeId: AnsiString): UnicodeString;
        begin
            result := fldSource.displayName(attributeId);
        end;

        function ObjectAttributes.getSupportedAttributeIds(): AnsiString_Array1d;
        begin
            result := fldSource.getSupportedAttributeIds();
        end;
    {%endregion}

    {%region  ObjectEnumeration }
        constructor ObjectEnumeration.create(source: Attributes);
        begin
            inherited create(source);
        end;

        procedure ObjectEnumeration.close();
        begin
            destroy;
        end;
    {%endregion}

    {%region} initialization
        Lang.registerInterfaces([
            typeInfo(Attributes),
            typeInfo(FileSystem)
        ]);
    {%endregion}

end.