Анализ возможностей платформы. Классификация грамматик по Хомскому. Способы задания языков. Разработка алгоритмов выполнения файловых операций на основе спроектированных интерфейсов. Криптосистема с открытым ключом. Свойства электронной цифровой подписи.
Чтобы понять какие задачи должны решать файловые менеджеры как группа программного обеспечения (ПО), рассмотрим типовые возможности ОС. Главные задачи, решаемые ОС - это арбитраж ресурсов вычислительной системы (ВС) и предоставление готовых функций для поиска ресурсов и организации работы с ними. Набор функций различных ОС представляет практически одинаковые функциональные возможности управления тем или иным ресурсом. Среди главных задач решаемых файловыми менеджерами: абстрагирование от разнотипных представлений данных и выполнение типовых операций над абстрактной структурой каталогов и файлов. Помимо присутствия ПО в составе ВС, можно выделить следующие особенности: наличие развитой и расширяемой системы драйверов, наличие собственного байт-кода, возможность блокировки не подписанного цифровой подписью кода, выполнение прикладного ПО, поддержка устройств графического вывода, устройств позиционирования, например, мышь и пр.Лексема Тип if Ключевое слово else Ключевое слово do Ключевое слово while Ключевое слово for Ключевое слово break Ключевое слово continue Ключевое слово function Ключевое слово return Ключевое слово var Ключевое слово true Ключевое слово, идентификатор false Ключевое слово, идентификатор null Ключевое слово, идентификатор undefined Ключевое слово, идентификатор new Зарезервированное слово Оператор - это литерал, определяющий операцию обработки данных, например, сложение или вычитание. Конвертация из разных типов в логический тип данных происходит следующим образом: «null», «undefined», числовой - «0», строковый, если длина строки равна 0, становятся «false», все остальные значения переходят в «true». Для переменных логического и числового типа можно использовать операторы всех типов в любой комбинации, в этом случае результатом работы операторов будут переменные числового типа. В случае, если один из операндов оператора « » имеет строковый тип, то будет выполнена операция конкатенация между операндом строкового типа и строковым представлением операнда любого другого типа.В классе есть метод для создания нового массива (Recreate), с полным удалением предыдущего и метод для увеличения или уменьшения размера массива (Resize) с сохранением информации в неизменяемой зоне. Дочерними классами относительно базового будут являться классы для разделения пространства экрана между двумя объектами и класс, реализующий методы вывода информации на экран, в пределах ограниченного пространства. В классе содержаться метод для определения количества элементов (NUMBERCONTROL), методы для запуска (Show) и остановки (Hide) формы. Так же есть абстрактные виртуальные методы, которые являются моделью данных, которые будут в списке, среди этих методов есть методы определяющие общее количество строк (COUNTROW) и столбцов (COUNTCOLOUMN), методы, возвращающие строковое представления ячейки таблицы (Source) и информации о ячейке (SOURCEINFO). Класс содержит методы для открытия нового файла (Open), закрытия текущего (Close), удаления текущего (Delete), методы для получения или установки указателя на позицию внутри файла, для чтения информации о файле, содержащемся в каталоге или для чтения набора байт из файла (Read), для записи массива в файл (Write) и для сброса данных кешированых операции на жесткий диск (Flush).Языком над алфавитом - называют некоторое счетное подмножество цепочек конечной длины из множества всех цепочек над этим алфавитом. Язык включает в себя язык Конкатенацией (объединением) языков и называют язык , состоящий из всевозможных сцеплений цепочек языков и : . Существуют три основных способа задания языка: - перечисление всех допустимых цепочек языка (способ формальный, на практике нереализуем, т.к. в общем случае множество цепочек языка бесконечно и перечислить их невозможно). Грамматика языка программирования содержит правила двух типов: первые (определяющие синтаксические конструкции языка) легко поддаются формальному описанию; вторые (определяющие семантические ограничения языка) обычно излагаются в неформальном виде.Электронная цифровая подпись (ЭЦП)-реквизит электронного документа, предназначенный для защиты данного электронного документа от подделки, полученный в результате криптографического преобразования информации с использованием закрытого ключа электронной цифровой подписи и позволяющий идентифицировать владельца сертификата ключа подписи, а также установить отсутствие искажения информации в электронном документе. Функция вычисления подписи на основе документа и секретного ключа пользователя вычисляет собственно подпись. Функция проверки подписи проверяет, соответствует ли данная подпись данному документу и открытому ключу пользователя. Поскольку подписываемые документы - переменной (и достаточно большой) длины, в схемах ЭЦП зачастую подпись ставится не на сам документ, а на него хэш-значение. злоумышленник может попытаться подобрать документ к данной подписи, чтобы подпись к нему подходила.В том числе будет приведено экономическое обоснование необходимости разработки, расчет затрат на
Введение
Файловые менеджеры являются неотъемлемой частью программной инфраструктуры любой операционной системы (ОС). Чтобы понять какие задачи должны решать файловые менеджеры как группа программного обеспечения (ПО), рассмотрим типовые возможности ОС.
Главные задачи, решаемые ОС - это арбитраж ресурсов вычислительной системы (ВС) и предоставление готовых функций для поиска ресурсов и организации работы с ними. Набор функций различных ОС представляет практически одинаковые функциональные возможности управления тем или иным ресурсом. Данный уровень ПО называется системным и решает задачу абстрагирования управления различными однотипными ресурсами.
Файловые менеджеры классифицируются как системное ПО. Среди главных задач решаемых файловыми менеджерами: абстрагирование от разнотипных представлений данных и выполнение типовых операций над абстрактной структурой каталогов и файлов.
Несмотря на схожесть возможностей различных ОС в управлении ресурсами, те или иные ОС могут представлять меньшие возможности по сравнению с другими аналогами. Современным примером платформы с сокращенной функциональностью является UEFI BIOS. Данную платформу не принято классифицировать как ОС, однако она решает все основные задачи, решаемые ОС.
Особенность платформы в том, что за ее реализацию отвечают производители ВС и данная платформа представлена в виде системного ПО встроенного в ВС. В UEFI BIOS существуют механизмы загрузки полноценной ОС, а также есть интерфейс между драйверами среды UEFI BIOS и ОС. Помимо присутствия ПО в составе ВС, можно выделить следующие особенности: наличие развитой и расширяемой системы драйверов, наличие собственного байт-кода, возможность блокировки не подписанного цифровой подписью кода, выполнение прикладного ПО, поддержка устройств графического вывода, устройств позиционирования, например, мышь и пр.
Таким образом, для выполнения программ предназначенных для работы в среде UEFI BIOS в общем случае не требуется стороннее ПО. Это дает возможность выполнения программ не требовательных к производительности в коммерческих целях без затрат на покупку сопутствующего ПО.
Поскольку платформа UEFI BIOS является более простой, разрабатывается и тестируется производителем ВС, то надежность такого ПО значительно выше, чем у полноценных ОС. В данном контексте интересной идей представляется создание файлового менеджера для платформы UEFI BIOS. Такое приложение могло бы стать удобным инструментом резервного копирования данных после отказа ОС или при отсутствии таковой.
Помимо резервного копирования файловые менеджеры нужны для восстановления системы и данных. Восстановление работоспособности системы иногда можно достичь заменой одного или нескольких поврежденных файлов. Поэтому подобная задача не ставит серьезных требований к быстродействию файловых операций, следовательно, решение этой задачи возможно при использовании не оптимизированных драйверов, в том числе и драйверов файловых систем платформы UEFI BIOS.
Резервное копирование и восстановление работоспособности системы не единственное применение подобного файлового менеджера. Не смотря на распространение различных облачных сервисов хранения данных необходимость в файловом менеджере, который можно запустить вне ОС, достаточно большая. Практически у любого пользователя есть на домашнем компьютере такие файлы, которые возможно и не желательно терять при восстановлении системы. В этом случае файловый менеджер на платформе UEFI BIOS будет очень полезен.
Резервное копирование и восстановление работоспособности системы в простейшем представлении можно свести к проверке наличия по определенному пути определенных файлов с определенными свойствами. Если знать путь до директории с резервными файлами и путь до восстанавливаемой директории можно провести восстановление по заранее определенным правилам в автоматическом режиме.
Автоматический режим увеличивает сложность решаемых задач, а совокупности с ручным режимом, можно решать еще и не стандартные задачи.
Помимо описанных способов применения, такое ПО можно использовать для синхронизации содержимого на различных носителях.
Целью данного дипломного проекта является разработка файлового менеджера для платформы UEFI BIOS, который должен обеспечит выполнение файловых операций в ручном и автоматическом режиме.
Вывод
В данном разделе проведен обзор не многочисленной литературы по данной тематике. Кратно изложены основные особенности платформы UEFI BIOS и представлен обзор аналогов файлового менеджера для других платформ.
2 Разработка расширенного технического задания
В данном разделе конкретизируется цель проекта, с учетом обзора аналогов. Формируются общие требования к концепции интерфейса. Разрабатываются требования к языку написания пользовательских сценариев.
2.1 Цель дипломного проекта
Целью дипломного проектирования является создание файлового менеджера для платформы UEFI BIOS, представляющего пользовательский интерфейс со следующими основными возможностями: - перечисление логических томов, каталогов и файлов;
- перемещение, копирование, удаление каталогов и файлов;
- поиск каталогов и файлов по маске, дате и времени создания и изменения, размеру;
- возможность выполнения пользовательских сценариев;
- реализация интерфейсов в приложении для выполнения файловых операции на виртуальных логических томах, например, FTP-сервер.
Проект должен быть реализован на платформе UEFI BIOS, при помощи объектно-ориентированного программирования (ООП).
2.2 Требования к пользовательскому интерфейсу
Пользовательский интерфейс должен быть простым и понятным. Интерфейс должен перенимать базовые принципы прототипа: деление экрана на две части с разными списками каталогов, выполнение операций между активным списком источником и пассивным назначением. Изза сложности разработки приложений на данной платформе допустим мало функциональный интерфейс.
2.3 Поддержка пользовательских сценариев
Для компенсации малого функционала интерфейса, в файловом менеджере необходимо реализовать поддержку пользовательских сценариев. Для ускорения и упрощения работ разработку можно сделать на основе проекта TINYJS. Проект TINYJS - это интерпретатор ограниченной реализации языка Java Script с открытым исходным кодом. Интерпретатор должен поддерживать файлы сценария в кодировке UTF-16 LE.
Требования к языку написания сценариев сформулированы далее.
Прежде чем начать описывать конструкции языка необходимо ввести некоторые понятия и дать и их описание. Лексема - это неделимая лексическая единица, корректная с точки зрения грамматики конкретного языка. Лексемы разделены пробелами или прочими символами форматирования. Символы форматирования текста не влияют на порядок или результата работы сценария. Ключевое слово - это лексема, являющийся его частью синтаксиса. Эти слова являются частью синтаксиса языка. Зарезервированное слово - это лексема, которая корректна с точки зрения грамматики и являются частью синтаксиса языка. Эти слова нельзя использовать в сценарии. Их поддержка может быть реализована в будущем.
Идентификаторы - это лексема, являющаяся наименованием, некоторого объекта в исходном тексте сценария. Нельзя задавать имена идентификаторов одинаковые с ключевыми и зарезервированными словами. Задаваемые имена идентификаторов должны состоять из символов латинского алфавита, символа подчеркивания и цифр, причем имя не должно начинаться с цифр. Все идентификаторы сценариев чувствительны к регистру, то есть идентификаторы «id» и «Id» семантически различны.
Пример правильных имен идентификаторов - A, A0, _A0
Далее в таблице 2.1 приведен список ключевых и зарезервированных слов.
Таблица 2.1 - Список ключевых и зарезервированных слов
Лексема Тип if Ключевое слово else Ключевое слово do Ключевое слово while Ключевое слово for Ключевое слово break Ключевое слово continue Ключевое слово function Ключевое слово return Ключевое слово var Ключевое слово true Ключевое слово, идентификатор false Ключевое слово, идентификатор null Ключевое слово, идентификатор undefined Ключевое слово, идентификатор new Зарезервированное слово
Литерал - это лексема, описывающая отдельный элемент множества данных и содержащаяся непосредственно в программном коде.
Переменная - это элемент данных, значение которого может меняться на любое из соответствующего множества во время выполнения сценария. Представлением переменной в программном коде является идентификатор.
Оператор - это литерал, определяющий операцию обработки данных, например, сложение или вычитание.
Тип данных - это множество данных одинаковых по форме представления, но разных по значению.
Базовые типы данных делятся на: - специальные (null, undefined);
- скалярные (логический, числовой, строковый);
- составные (массивы, объекты).
Для специальных типов данных названия типов и единственное литеральное значение одинаковы. Переменные с типом null можно охарактеризовать как не содержащие данные. Переменные имеют тип undefined только после создания, до инициализации.
Логический тип данных может иметь только два литеральных значения «true» и «false», «истина» и «ложь» соответственно. Конвертация из разных типов в логический тип данных происходит следующим образом: «null», «undefined», числовой - «0», строковый, если длина строки равна 0, становятся «false», все остальные значения переходят в «true».
Числовой тип данных состоит из множества целых чисел от минус 2147483648 до 2147483647. Литералом данного типа является строковое представление числа в десятичной системе счисления из данного диапазона. Например, «-123434». Конвертация в числовой тип происходит по следующим правилам: - «null» соответствует «0»;
- строка конвертируется, если является представлением целого числа в десятичной системе счисления, в само число, иначе интерпретатор не корректно завершит работу.
- «boolean» конвертируется в «0», если «false», в «1», если «true».
- все остальные значения приводят к не корректной работе интерпретатора.
Строковый тип предназначен для хранения данных в виде последовательности символов. Строковые литералы задаются путем заключения последовательности символов в одинарные или двойные кавычки, причем вложенные кавычки другого типа будут являться частью строковых данных. Но нельзя начинать и заканчивать строку кавычками разного типа. Для записи литерала в нескольких строках программного кода необходимо в конце строки добавлять обратный слеш.
В нутрии литерала строкового типа можно использовать специальные управляющие символы: «
» перенос позиции печати в потоке ввода/вывода на следующую строку и «
» возврат позиции печати на начало текущей строки. В случае «
» дальнейший вывод затрет те данные, которые уже есть в этой строке. Пример многострочного строкового литерала
“text string 1 ‘name text’ \ text strung 2
”
Скалярные типы данных являются базовыми типами и используются повсеместно, поэтому имеется большое количество операций, которые можно выполнить над ними. Операторы можно разделить на несколько групп. Операторы каждой группы представлены в отдельных таблицах с номерами (2.2) - (2.6)
Таблица 2.2 - Арифметические операторы
Оператор Приоритет Количество операндов Операция
- 1 1 Унарный минус
- 2 2 Вычитание
2 2 Сложение
* 2 2 Умножение
/ 2 2 Деление
% 2 2 Остаток от деления
- 1 1 Декремент
1 1 Инкремент
Таблица 2.3 - Бинарные операторы
Оператор Приоритет Количество операндов Операция
& 7 2 Поразрядное «И»
| 9 2 Поразрядное «ИЛИ»
^ 8 2 Поразрядное исключающее «И»
<< 4 2 Поразрядный сдвиг влево с учетом знака
>> 4 2 Поразрядный сдвиг вправо с учетом знака
Таблица 2.4 - Операторы присваивания
Оператор Приоритет Количество операндов Операция
= 13 2 Присваивание
=, -= 13 2 Составные операторы присваивания. Между первым и вторым операндом выполняется соответствующая операция, а затем результат присваивается первому операнду.
Таблица 2.5 - Логические операторы
Оператор Приоритет Количество операндов Операция
! 1 1 Логическое отрицание
< 5 2 Меньше, чем > 5 2 Больше, чем <= 5 2 Меньше или равно >= 5 2 Больше или равно == 6 2 Равенство
!= 6 2 Неравенство
=== 6 2 Строгое соответствие
!== 6 2 Строгое несоответствие
&& 10 2 Логическое «И»
|| 11 2 Логическое «ИЛИ»
Приоритет определяет последовательность выполнения операторов.
Перед выполнением операции над переменной логического типа она всегда конвертируются в переменную числового типа.
Для переменных логического и числового типа можно использовать операторы всех типов в любой комбинации, в этом случае результатом работы операторов будут переменные числового типа.
Переменные со строковым типом данных можно использовать в логических операторах и операторах « », « =», «=». В случае, если один из операндов оператора « » имеет строковый тип, то будет выполнена операция конкатенация между операндом строкового типа и строковым представлением операнда любого другого типа.
Оператор строгого соответствия отличается от оператора равенства тем, что сравнивает не только представление числа, но и тип.
Примеры работы операторов равенства и строгого соответствия -
В исходные коды могут быть включены комментарий, текстовые дополнения, которые не влияют процесс выполнения сценария. Комментарии могут быть однострочными и многострочными.
Пример однострочного комментария - //Этот текст будет проигнорирован интерпретатором.
Пример многострочного комментария - /* Этот текст будет проигнорирован интерпретатором*/
Главной конструкцией языка являются инструкции. Сценарий состоит из последовательности инструкций, разделенных между собой символом «;». Инструкция - это грамматически верная семантически завершенная синтаксическая конструкция, выполняющая, при помощи операторов, одно законченное действие.
Выражение - это сложная инструкция, состоящая из нескольких операторов, которая может быть вычислена в одно значение.
Объявление переменных - это процесс создания объекта переменной и привязка объекта к идентификатору, используемому в сценарии. Различные типы переменных объявляются одинаково. Тип переменной задается динамически, то есть определяется данными, содержащимися в переменной.
Пример инструкции для объявления переменной «a» var a; //переменная создана, но не проинициализирована a = 5; //переменной присвоено значение пять var b = 5; //переменная создана и инициализирована значением пять
После присваивания значения пять, переменная имеет числовой тип. После инициализации переменной можно присвоить значение другого типа, в этом случае переменная сменит тип, но так делать не рекомендуется, чтобы не усложнять сценарий.
Пример переопределения переменной - var a = 5; //переменная создана и инициализирована значением пять a = false; //переменная вновь инициализирована логическим значением «ложь»
Операторный блок - это объединение одной или нескольких инструкций в один логический блок, путем заключения их в фигурные скобки «{ }». Такая конструкция может рассматриваться как один оператор, называемый составным оператором.
Пример операторного блока
{ a = b 5;
b = (a 5) % 3; }
Функции традиционно используются для реализации структурного подхода в программировании. Декларирование функции с помощью ключевого слова function - это классический способ определения функции.
Пример основной способ объявления функции function f0(x, y) { return x y; };
После слова «function» идет название идентификатора функции, потом в круглых скобках перечисляются через запятую параметры функции и, наконец, в операторном блоке находиться тело функции.
Ключевое слово «return» определяет точку выхода из функции. Следующее за словом «return» значение возвращается функцией. Если после «return» следует «;», то возвращается значение «undefined». Тело функции может не содержать слова «return», в этом случае функция вернет «undefined» и завершится когда выполниться вся последовательность инструкции в операторном блоке.
Еще один способ описания функции, с помощью литерала функции. Такая функция называется лямбда-функция.
Пример объявления лямбда-функции - var f1 = function(x, y) { return x y; };
Отличие этого метода в том, что к функции нужно обращаться через переменную. Эту функцию можно передать в качестве параметра в другую функцию.
Подобного результата можно добиться, используя первый метод объявления.
Пример объявления функции - function f0(x, y) { return x y; };
var f1 = f0;
После присваивания одна и та же функция становиться доступна через два идентификатора: «f0», «f1».
Вызов функции осуществляется при помощи оператора круглых скобок «( )». В скобках указывается список параметров, передаваемых в функцию. Количество параметров передаваемых в функцию должно совпадать с количество в описании функции.
Пример вызова функции f0(5);
f1(5);
В любом сценарии существует две области видимости переменных: локальная и глобальная. Переменные принадлежащие глобальной области видимости, могут использоваться в любом месте сценария. Локальная область допускает использование принадлежащих ей переменных только ее в пределах. Локальную область видимости создает только тело функции.
Пример локальных и глобальных переменных - var global = 1; //Объявление глобальной переменной function func(x, y)
{ var local = x y; //Объявление локальной переменной global /= local;
return local;
};
//Далее доступна только переменная global
Одной из главных конструкций является условное ветвление. Она позволяет реализовать различную обработку данных, в зависимости от значения самих данных. Для определения пути дальнейшего выполнения кода используется логическое значение.
Пример условного ветвления - if (a < 5) {
//Обработка при a < 5
} else {
//Обработка при a >= 5
}
В случае если выражение, передаваемое оператору «if», вычисляется в «true», будет выполнен первый блок операторов, иначе - второй. Предложение «else» может быть опущено, если не требуется выполнять каких либо действий при вычислении логического условия в «false».
Конструкции циклов также поддерживаются интерпретатором. Они позволяют проводить многократное выполнение наборов инструкций при условии истинности некоторого утверждения.
Пример цикла «for» for (var i = 0; i < 5; i ) { var j = i; //Тело цикла выполниться пять раз }
Цикл «for» выполняется до тех пор, пока выражение, указанное как условие, вычисляется в «true». Инициализирующее выражение вычисляется единственный раз - при начале исполнения оператора «for». Оно обычно используется для присваивания начальных данных переменным, используемым в выражении условия цикла. Выражение условие цикла вычисляется каждый раз перед выполнением тела цикла. Тело цикла может ни разу не выполниться, если на первом же проходе выражение условия вычисляется в «false». Обновляющее выражение вычисляется после каждого прохода цикла.
Конструкция «while» - это самый простой из операторов цикла. Тело цикла выполняется, пока значением выражения - условия является «true».
Пример цикла «while» - var i = 0;
while (i < 5) { var j = i; //Тело цикла выполниться пять раз i ;
}
В противоположность предыдущему оператору, тело «do...while» выполняется, пока выражение условия цикла вычисляется в «false».
Пример цикла « do...while » - var i = 0;
do { var j = i; //Тело цикла выполниться пять раз i ;
} while (i >= 5)
В теле цикла можно использовать два ключевых слова для управления циклами конструкции. Первый оператор «break» прерывает выполнение цикла. Второй «continue» прерывает исполнение текущей итерации цикла и переходит к следующей. Составные типы данных - это типы, состоящие из комбинации простых типов. Примером таких типов являются массивы.
Массивы представлены как набор пар «ключ - значение». Как ключи, так и значения могут быть разного типа данных. В данной реализации объекты полностью аналогичны массивам.
Литеральное представление определяется перечислением значений в квадратных скобках «[ ]», при этом ключи будут иметь возрастающий от нуля индекс.
Пример объявления массива и добавления значений в массив
//Объявление массива var arr = [1, , “text”, [1, 2, 3], function(x, y) { return x y;}, true];
arr[“lenght”] = 6;
//Получение элементов из массива: var n0 = arr[0]; //n0 станет числовой переменной со значением 1 var n1 = arr[1]; //n1 станет undefined var n2 = arr.lenght; //n2 станет числовой переменной со значением 6 var n3 = arr[“lenght”] //аналогично предыдущей строчке
Таблица 2.6 - Специальные операторы
Оператор Приоритет Количество операндов Операция
. 0 1 Доступ к свойству объекта
[ ] 0 1 Доступ к элементу массива
( ) 0 Группировка операций или вызов функций
, 14 2 Последовательное вычисление выраженийВ данном разделе поставлена цель, разработаны подробные требования к программе, пользовательскому интерфейсу и языку описания пользовательских сценариев.
3 Разработка программного обеспечения
В данном разделе разрабатывается структура программы, программные интерфейсы, алгоритмы файловых операций, а так же поддержка пользовательских сценариев.
Структурно файловые менеджеры можно разделить на блок пользовательского интерфейса и блок работы с файловой системой. Предполагается, что функции обработки событий интерфейса включают в себя вызов функций блока работы с файловой системой. Нужно отметить, что перед разработкой блоков, в них целесообразно выделить общую часть. В частности представления данных используемых в обоих блоках должны быть одинаковыми, это необходимо для организации эффективного интерфейса между блоками.
3.1 Разработка структуры программы
В общем виде программа должна иметь модульное строение, чтобы обеспечить возможность дальнейшего развития программы. Модульность обеспечивается с помощью программных интерфейсов. Каждый модуль должен реализовывать заданный интерфейс, с собственными особенностями. Такой подход позволит по частям расширять возможности программы. В свою очередь постепенное развитие программы позволит, в конечном счете, написать более качественное программное обеспечение.
При разработке структурной схемы необходимо учитывать закладываемую модульность. На рисунке 3.1 представлена структурная схема программы.
Рисунок 3.5 - Структура программы
На схеме представлены три блока обеспечивающие взаимодействие с ресурсами системы, это блоки доступа к файловой системе и консоли, а так же блок ввода данных с клавиатуры. Главная цель этих блоков - это обеспечение единообразного доступа к данному типу ресурса.
Блок ввода данных обеспечивает генерацию событий, которые меняют состояние системы и как следствие информацию, выводимую в консоль с помощью блока доступа к консоли. В процессе работы системы так же меняется содержимое внешних носителей информации через блок доступа к файловой системе.
Определившись с взаимодействием с внешними ресурсами можно перейти к рассмотрению самой системы.
После ввода данных и генерации события в блоке дешифрации определяется тип события, если данное событие является системным (например, смена активного элемента или запуск интерпретатора пользовательских сценариев), то вызова обработчика отдельного элемента не происходит, происходит вызов специального системного обработчика.
Блоки выбора активного элемента интерфейса и блок разбора исходного текста пользовательского сценария активируются только в случае специального системного события. Активный элемент выбирается из списка, сформированного в блоке формирования списка активных элементов интерфейса.
Если событие не является системным, то оно передается на обработку текущему активному элементу в блок обработки события активным элементом интерфейса. Данный блок может выполнять различные не стандартизированные операции, именно этот блок обеспечивает расширяемость программы.
После выполнения обработчика события, при условии изменения состояния, происходит вывод представления нового состояния программы в консоль. Поскольку элементы предполагают визуальное присутствие, то необходимо расположить эти элементы в консоли с помощью блока расчета размера элемента интерфейса и представление, сформированное в блоке формирования внешнего вида элемента вывести в расчетное место в консоли.
Для реализации поддержки интерпретатора пользовательских сценариев необходимы, помимо блока разбора пользовательских сценариев, еще блоки формирования списка переменных и блок вызова встроенные функций и объектов.
Определившись с общей структурой проекта можно приступить к разработке программных интерфейсов.
3.2 Разработка программных интерфейсов
На данном этапе необходимо выделить и разработать общую базовую часть для структурных блоков. Поскольку на платформе UEFI BIOS нет библиотек, то базовой частью будут выступать средства работы с массивами. Возможность удобного управления данными является важным фактором, влияющим на скорость разработки.
В данном пункте описана разработка программных интерфейсов для работы с данными.
Платформа UEFI BIOS имеет реализацию собственного менеджера памяти. Память можно выделять как страницами виртуальной памяти, удобно для реализации собственного менеджера памяти, так и для выделения буфера заданного размера. Предпосылок для написания собственного менеджера памяти нет, так как приложения данной группы не требовательны к ним, а существующий удовлетворяет всем требования программы.
При использовании ООП необходимо объединить в одном классе данные и способы их обработки. В качестве данных будут выступать указатель на данные, количество элементов массива и размер одного элемента массива. В базовом классе будет в качестве элемента выступать байт. Среди способов обработки данных базового класса целесообразно выделить основные: - произвольный побайтовый доступ к данным и доступ к указателю на данные;
- копирование данных в объект;
- перемещение данных внутри объекта;
- частичное и полное сравнение данных объекта с другим объектном или его частью;
- нахождение индекса первого, последнего, следующего и предыдущего частичного и полного вхождения данных внешнего объекта в данные текущего объекта;
- нахождение количество частичного и полного вхождения данных внешнего объекта в данные текущего объекта;
Следующим в иерархии будет класс, расширяющий возможности базового класса в сторону динамического изменения размера. Важными данными этого объекта будет размер шага выделения памяти. Данный параметр описывает, сколько элементов будет дополнительно резервироваться в памяти при каждом новом выделении. Данный класс добавляет к функциональности базового несколько новых методов: - создание нового массива вместо старого с заданными параметрами;
- расширение массива на заданное количество элементов;
- добавление и удаление заданного количества элементов в произвольное место массива;
- включение или исключение частично или полностью в объект данных из внешнего объекта или во внешний объект в заданное место.
Для удобства программиста необходимо наследовать от классов работы с байтовыми массивами шаблоны реализующие функционал базового класса для произвольного типа элемента массива.
На рисунке 3.2 изображена схема наследования классов работы с данными.
Рисунок 3.6 - Схема наследования классов работы с данными
Базовым классом является FIXBYTEARRAY, его наследуют все остальные классы. Далее более подробно рассматриваются отдельные классы.
На рисунке 3.3 представлен класс FIXBYTEARRAY.
Рисунок 3.7 - Класс FIXBYTEARRAY
Основными данными класса являются: размер одного элемента массива (size_item), размер всего массива (size_byte) и указатель на массив (pointer). Так как данные сокрыты внутри класса, то для доступа к этим данным, введены одноименные методы, возвращающие значения соответствующих переменных.
Класс содержит несколько конструкторов: конструктор по умолчанию, копирующий конструктор и конструктор для инициализации существующим массивом.
Для удобства использования класса переопределен оператор обращения к элементам массива (operator[]). Так же реализован широкий набор перегруженных методов копирования данных (Copy) из другого массива, методы обмена данными (Replace) между массивами, методы сравнения содержимого массивов (Compire, Equal).
В классе присутствуют методы для нахождения индекса первого (INDEXFIRSTOF), следующего (INDEXNEXTOF), последнего (INDEXLASTOF), предыдущего (INDEXPREVIOUSOF) вхождения массива или под массива. Так же есть методы для подсчета количества вхождений (QUANTITYINCLUDEOF) массива или подмассива.
Метод определения вхождения индексов (CHECKSEGMENT) в заданном диапазоне в массив и коррекция индексов (CORRECTSEGMENT) для заданного диапазона.
На рисунке 3.4 представлен класс BYTEARRAY.
Рисунок 3.8 - Класс BYTEARRAY
В данном классе объявлены дополнительные данные: использованный размер массива (use_size) и шаг выделения памяти (step). Использованный размер определяет, сколько памяти из выделенной используется, а шаг выделения памяти определяет, с каким шагом будет увеличиваться или уменьшаться вся выделенная память для этого массива. Так как данные сокрыты внутри класса, то для доступа к этим данным, введены одноименные методы, возвращающие значения соответствующих переменных.
Класс содержит основные типы конструкторов по умолчанию и копирующий. Прочие конструкторы позволяют задать начальный размер массива и шаг, а также инициализировать выделенную память из другого массива.
В классе есть метод для создания нового массива (Recreate), с полным удалением предыдущего и метод для увеличения или уменьшения размера массива (Resize) с сохранением информации в неизменяемой зоне.
Так же есть методы для добавления (Add) и удаления (Delete) из заданного места определенного количества элементов или одного элемента в конце.
Класс содержит перегруженные методы с большим количеством настроек для вставки (Insert) в определенное место данных из массива или подмассива. В результате подобной вставки размер массива увеличиться или останется неизменным. Есть так же обратный метод извлечения подмассива и другой массив (Extract), с последующим сокращением массива.
Шаблоны классов Array и FIXARRAY переопределяют только оператор обращения к элементу массива и конструкторы под определенный тип.
На этом разработка программных интерфейсов работы с данными можно завершить. Функциональности разработанных классов достаточно для дальнейшей разработки.
В данном пункте описана разработка программных интерфейсов для работы с консолью. Возможности платформы UEFI BIOS позволяют использовать консольный вывод для информации. Функционал работы с консолью в UEFI BIOS является сопоставимым по уровню абстракции с функционалом современных ОС.
Разработка пользовательского интерфейса является наиболее трудоемкой в связи со сложностью организации, требованием масштабирования приложения и отсутствием готовых библиотек.
При разработке интерфейса необходимо соблюдать не официальные стандарты интерфейсов файлового менеджера. Они четко представлены в прототипе. Для первого этапа реализации жесткое следование стандарту не обязательно, но в то же время соблюдение общей концепции необходимо в дальнейшем для простой адаптации реализации под стандарт.
Таким образом, с учетом выше перечисленных замечаний можно сформулировать требования к интерфейсу программы для первого этапа: - разделение экрана на две рабочие области с одинаковыми возможностями;
- возможность выбора одной функциональной области для просмотра дерева каталогов;
- отображение в функциональных областях структуры выбранного каталога или перечисление логических томов.
В качестве базового класса для объектов описания интерфейса, целесообразно использовать класс, имеющий свойства размерности, положения, функции связи с родительским объектом и функции обработки событий, например, получение и снятие фокуса, обновление состояния объекта, универсальный обработчик проектируемых в будущем событий. Дочерними классами относительно базового будут являться классы для разделения пространства экрана между двумя объектами и класс, реализующий методы вывода информации на экран, в пределах ограниченного пространства.
Класс, разделяющий экран на две части должен реализовывать методы присоединения дочерних объектов и методы изменения правил разделения. Класс должен содержать данные описывающие положение линии разделения (вертикально, горизонтально) и соотношение размеров дочерних объектов. Соотношение можно описать числом, максимальное значение, которого определяет полное заполнение первым дочерним объектом всего допустимого пространства, а ноль - заполнение вторым дочерним объектом. Все остальные значения - промежуточные состояния.
Класс, реализующий методы вывода информации на экран, должен иметь все сопутствующие этому методы: вывод символа или строки, настройка атрибутов цвета выводимой информации, положение курсора и его видимость.
Таким образом, все классы разделяющие пространство и классы, реализующие определенные правила вывода, будут наследоваться от соответствующих базовых классов.
Далее от объекта управляющего пространством, целесообразно наследовать класс являющийся основой окна. Такой класс должен реализовывать модель поведения для встраиваемой иерархии других объектов. Для данного класса нужно реализовать возможности смены активного элемента, который получает информацию о событиях передаваемых окну.
Классы визуальных элементов наследуются от другого потомка базового класса. Такие объекты должны реагировать на события, меняя внутренне состояние и отражая изменения в отведенной области экрана. Основным классом данного типа должен стать класс, реализующий вывод рамки по периметру объекта. От него должен наследоваться класс для вывода списка элементов, который будет базовым для класса расширяющего возможности до множественного выделения объектов, которые будут реализовывать получение данных из различных источников.
Далее на рисунке 3.5 представлена схема наследования классов пользовательского интерфейса.
Рисунок 3.9 - Схема наследования классов пользовательского интерфейса
Базовым классом является Control, его наследуют все остальные классы. Рассмотрим подробнее содержимое классов.
На рисунке 3.6 представлен класс Control.
Рисунок 3.10 - Класс Control
Класс содержит данные о положении и размере видимой обрасти на экране (window), указатель на родительский контейнер, к которому прикреплен элемент и флаг (parent), определяющий активность класса (focus).
Класс содержит конструктор по умолчанию, копирующий конструктор и конструктор привязки к контейнеру. Так же привязку к контейнеру и отсоединение можно осуществить с помощью методов определенных в классе (Connect, Disconnect).
В классе есть методы для определения находиться ли объект в фокусе (ISFOCUS). А с помощью определенных виртуальных методов можно выполнить определенные действия во время получения и возвращения фокуса (TAKEFOCUS, RETURNFOCUS). В классе так же есть метод для выполнения обработки событий поступающих в класс (HANDLEEVENT).
Оставшиеся методы позволяют обновить размер элемента в соответствии с размером предоставляемым контейнером (Update), а так же получить этот размер без обновления размеров элемента (GETWINDOW) и получить размер всего имеющегося пространства для печати (GETDISPLAY).
На рисунке 3.7 представлен класс Container.
Рисунок 3.11 - Класс Container
Класс содержит данные о первом и втором элементе привязанных к контейнеру (first, second), данные о положении оси (axis) и пропорций (ratio) разделения пространства между ними. В классе есть методы для настройки и получения данных (Separator, Ratio).
Среди конструкторов класса есть конструктор по умолчанию, копирующий конструктор задания оси разделения и привязки к базовому элементу.
В классе есть методы для привязки (Attach) и отсоединения (Detach) к определенному месту элемента, метод расчета размера присоединенного элемента (Rate), метод определения наличия связи между текущим контейнером и элементом (Detect).
Так же есть метод позволяющий обновить дочерние элементы (Update).
На рисунке 3.8 представлен класс Form.
Рисунок 3.12 - Класс Form
Класс содержит список указатели на элементы формы (control), количество элементов (number), индекс активного элемента (index), и признак повторения командного цикла (run).
Конструкторы класса бывают по умолчанию, копирующие и конструктор задания положения оси разделителя.
В классе содержаться метод для определения количества элементов (NUMBERCONTROL), методы для запуска (Show) и остановки (Hide) формы.
Класс содержит методы для чтения кодов клавиш нажатых на клавиатуре.
Среди метод работы с фокусом есть метод для получения указателя на активный элемент (GETFOCUS), метод получения текущего размера доступной обрасти окна (GETWINDOW), индекс активного элемента (GETINDEX), метод перехода фокуса к следующему (NEXTFOCUS) или предыдущему (PREVIOUSFOCUS) элементу из списка и метод инициализации списка элементов (LINKCONTROL).
На рисунке 3.9 представлен класс Splitter.
Рисунок 3.13 - Класс Splitter
Класс является законченной реализацией абстрактного базового класса контейнера.
На рисунке 3.10 представлен класс Canvas.
Рисунок 3.14 - Класс Canvas
Класс содержит данные о стандартном цвете (standart), цвете фокуса (focus), положении курсора (position) и его видимости (visible). Класс содержит соответствующие методы работы с данными класса (STANDARTCOLOR, FOCUSCOLOR, ACTIVECOLOR, POSITIONCURSOR, VISIBLECURSOR).
В классе присутствует метод позволяющий обновить размер элемента в соответствии с размером предоставляемым контейнером (Update).
Перед вызовом метода рисования (Draw) в прямоугольнике текста необходимо предварительно сохранить параметры вывода (BEGINDRAW), активировать требуемые параметры (FONTDRAW), а после восстановить старые параметры (ENDDRAW).
На рисунке 3.11 представлен класс Panel.
Рисунок 3.15 - Класс Panel
Класс дополняет базовый класс рамкой, которая рисуется согласно данным класса (border), которые можно получить (Border). Так же есть метод, рассчитывающий новый сокращенный размер (SIZECONTENT) и переопределенный метод для обновления (Update), который теперь вызывает методы рисования (DRAWCONTENT, DRAWUPTEXT, DRAWDOWNTEXT, DRAWFRAME).
На рисунке 3.12 представлен класс LISTBOX.
Рисунок 3.16 - Класс LISTBOX
Класс содержит данные о индексе текущего (target_next) и текущего (target_last) активного элемента списка, индекс первого выводимого элемента списка (draw_item), а так же методы, которые возвращают эти значения (Target, LASTTARGET, FIRSTVISIBLE).
Класс содержит конструкторы аналогичные базовому классу.
Так же есть абстрактные виртуальные методы, которые являются моделью данных, которые будут в списке, среди этих методов есть методы определяющие общее количество строк (COUNTROW) и столбцов (COUNTCOLOUMN), методы, возвращающие строковое представления ячейки таблицы (Source) и информации о ячейке (SOURCEINFO).
В классе есть методы определяющие размеры списка данных (SIZELIST) и размеры информации о текущих данных (SIZEINFO).
Класс содержит несколько методов обрабатывающих навигацию по элементам списка: переход к следующему (NEXTTARGET) или предыдущему элементу списка (PREVIOUSTARGET), а так же переход к следующей (NEXTPAGETARGET) или предыдущей (PREVIOUSPAGETARGET) странице списка элементов.
Класс содержит аналогичные базовому методы для работы с фокусом (TAKEFOCUS, RETURNFOCUS, HANDLEEVENT).
Для отрисовки списка присутствуют методы: определения атрибутов элемента списка (FONTRECORD), метод рисования списка (DRAWCONTENT), метод рисования элемента списка (DRAWTARGET), метод рисования активного элемента списка (DRAWTARGET), метод рисования информации об элементе списка (DRAWRECORDINFO), а так же метод обновления состояния списка (CHANGECONTENT).
На рисунке 3.13 представлен класс LISTSELECTBOX.
Рисунок 3.17 - Класс LISTSELECTBOX
Конструкторы данного класса аналогичны базовому классу с одним исключением, к параметрам, определявшим атрибуты, добавляется еще один описывающий атрибут выделенного элемента.
В классе содержаться данные о количестве выделенных элементов (is_select), списке элементов с флагом выделения (select_list) и цвете выделения (select). Так же есть методы, которые позволяют получать и изменять эти данные (SELECTCOLOR, ISSELECT, Select, CLEARSELECT).
Остальные методы наследуются от базового и имеют такой же функционал.
На рисунке 3.14 представлен класс LISTFILEBOX.
Рисунок 3.18 - Класс LISTFILEBOX
В классе содержаться данные о списке файлов (folder) и об иерархической структуре первого видимого файла (visible_position) и первого целевого файла (target_position).
В классе есть методы для привязки источника списка файлов (VIEWFOLDER), входа в выбранную директорию (Enter) и выхода из директории (Exit). Так же методы для сохранения контекста текущей директории (SAVECONTEXTFOLDER) перед открытием новой и восстановление контекста родительской директории после закрытия предыдущей (RESTORECONTEXTFOLDER). Остальные методы наследуются от базового класса и имеют подобную функциональность
Вы можете ЗАГРУЗИТЬ и ПОВЫСИТЬ уникальность своей работы