IPB
ЛогинПароль:

> Реализовать вектор в Ada 95 с быстрым доступом
сообщение
Сообщение #1


Большевик–концептуал
***

Группа: Пользователи
Сообщений: 194
Пол: Мужской
Реальное имя: Иван Левашев
Jabber: bu_gen@octagram.name
Skype: i.levashew
QQ: 3152538431
WeChat
Ада: Сторонник
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик
Turbo Pascal: Установлен

Репутация: -  1  +


Работа выполняется в GNAT -gnat95.

За основу программного интерфейса берётся Vector из библиотеки контейнеров. В GNAT явно указано, что то, что выше private, имеет происхождение из ISO стандарта Ada, и общедоступен. У нас будет солянка. Производный от общедоступного продукт можно лицензировать под Апаче. Расписывать, какой метод повторяет то, что есть в стандарте, а какой — нет, можно заскучать. Я предлагаю ограничиться пометкой, как в GNAT, что нечто, но не всё, имеет происхождение из ISO стандарта Ada, но в отличие от GNAT, не расписывать.


Реализовать нужно как минимум добавление и определение количества элементов.

Также нужно реализовать по аналогии с Fast_Strings быстрый доступ к элементам.

При разработке необходимо учесть «любовь» транслятора к избыточному копированию. Учёт этого обстоятельства заключается в том, что реализуется копирование при записи. Вектор по своей природе содержит ссылки, это нормально, но, как правило, структура, на которую сделана ссылка, уникальна. Придётся уникальностью пожертвовать.

В отличие от TList<>, IList<> и TArray<> в Delphi, и аналогично Ada 2005+ контейнерам, значения типа Vector считаются независимыми после копирования. Так что для чтения можно разделять структуры данных, но и только. Перед любыми изменяющими операциями выполняется публично доступная процедура Unique, приводящая вектор к состоянию уникальности содержимого, если счётчик ссылок не 1.

Структура в динамической памяти не должна быть tagged. Массив, из которого структура состоит, должен быть из Storage_Element, но с выравниванием, как у Element. Впоследствии, при выделении элементов используется специальный выделитель памяти, который при выделении возвращает заранее известный адрес, а при освобождении — ничего не делает. С его помощью инициализируются и финализируются элементы в векторе.

Под быстрым доступом имеется в виду возможность закрепить на стеке структуру Vector_View, посредством которой можно обозревать содержимое на чтение. Для этого используется дискриминант неограниченного указателя на массив элементов. И тогда это закрепление добавляет ссылку на время своего существования. В Fixed_Strings это достигалось копированием Unbounded_String внутрь себя. В данном проекте Vector предполагает наличие внутри себя замков на запись, и тогда класть копию Vector внутри себя не очень хорошо. Придётся сделать ещё раз Initialize/Finalize для подсчёта ссылок.

Для доступа на запись структура Vector_Edit. Аналогично String_Edit, забирает на время своего существования содержимое исходного вектора, ведь редактировать можно только уникальное содержимое. А если не забирать, уникальным оно не будет. В Finalize гипотетически может обнаружиться, что в том векторе, откуда забирали содержимое, снова что-то есть. Значит, уничтожить и заменить своим.

В Fast_Strings String_View — это функция, возвращающая Ada 2012 ссылку, а String_Edit — структура, производящая манипуляции над собой и целью в Initialize и Finalize. В Ada 95 нельзя из функции вернуть limited. Позволить этим структурам быть копируемыми тоже нельзя. Поэтому и View, и Edit будут устроены как Edit.

Такой вектор должен будет стать фундаментом для аналога Unbounded_Wide_Wide_String.



Куда складывать, напишу позже.


--------------------
If you want to get to the top, you have to start at the bottom
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Большевик–концептуал
***

Группа: Пользователи
Сообщений: 194
Пол: Мужской
Реальное имя: Иван Левашев
Jabber: bu_gen@octagram.name
Skype: i.levashew
QQ: 3152538431
WeChat
Ада: Сторонник
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик
Turbo Pascal: Установлен

Репутация: -  1  +


Публикация в

https://osdn.net/projects/paf/scm/hg/Ada95FL/

Новое хранилище в пустой директории создаётся командой hg init .
Или из TortoiseHg.

Потом hg add добавляются нужные файлы или, что аналогично, проставляются галочки у файлов в TortoiseHg. Игнорируемые артифакты сборки добавляются по маскам или по поддиректориям в .hgignore (пункт Игнорировать контекстного меню у лишнего файла). В директории, которые нужны для успешной сборки, добавляется пустой файл .hgignore, иначе TortoiseHg директории при клонировании не создаст.

В такой директории можно выполнить

Код
touch .hgignore
hg add .hgignore


--------------------
If you want to get to the top, you have to start at the bottom
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 27
Пол: Мужской
Реальное имя: Сергей Дюков
Skype: sergey.dukov54
Ада: Разработчик
Компонентный Паскаль: Сторонник

Репутация: -  0  +



Первоначальная реализация векторов байт на севере.

Реализованы различные методы добавления байт в вектор.
Вьювер реализован с помощью функции "To_Array".
Функциональность типа "редактора" я не совсем понял. По всей видимости, функциональность редактирования нужно реализовывать за счёт введения новых процедур работы с самим вектором.

Проект я только откомпилировал, но не проверял. На создание тестера у меня не хватает воображения. Помогите мне с этим вопросом. Напишите исходник тестера, а я его соберу и пропущу через отладчик.

Нужно ли реализовывать процедуры чтения из потока и записи в поток?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Большевик–концептуал
***

Группа: Пользователи
Сообщений: 194
Пол: Мужской
Реальное имя: Иван Левашев
Jabber: bu_gen@octagram.name
Skype: i.levashew
QQ: 3152538431
WeChat
Ада: Сторонник
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик
Turbo Pascal: Установлен

Репутация: -  1  +


Цитата(Sergey Dukov @ 14.09.2019 5:24) *
Функциональность типа "редактора" я не совсем понял. По всей видимости, функциональность редактирования нужно реализовывать за счёт введения новых процедур работы с самим вектором.


Нет, это Limited_Controlled с access discriminant, указывающим на вектор. В Initialize он переносит данные к себе и требует уникальности, в Finalize переносит обратно.

Цитата(Sergey Dukov @ 14.09.2019 5:24) *
Проект я только откомпилировал, но не проверял. На создание тестера у меня не хватает воображения. Помогите мне с этим вопросом. Напишите исходник тестера, а я его соберу и пропущу через отладчик.


С этим до сих пор завал sad.gif

Цитата(Sergey Dukov @ 14.09.2019 5:24) *
Нужно ли реализовывать процедуры чтения из потока и записи в поток?


Нет. Предполагается, что если вектор инстанциировать для октетов и открыть на чтение или редактирование, то чтение/запись можно делать обычными массивными функциями.


--------------------
If you want to get to the top, you have to start at the bottom
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Новичок
*

Группа: Пользователи
Сообщений: 27
Пол: Мужской
Реальное имя: Сергей Дюков
Skype: sergey.dukov54
Ада: Разработчик
Компонентный Паскаль: Сторонник

Репутация: -  0  +



Я реализовал преобразование UTF-8 в UTF-32. И, поневоле, пришлось создать простенький тестер для этой функциональности. Преобразование происходит правильно, но возникла проблема с удалением массивов из памяти. Попробовал исправить ошибки при размещении массивов в памяти, но это не помогло.

Вообще-то я с самого начала принял неправильный подход к построению реализации векторов октетов. Я лишь посмотрел, и то не совсем внимательно, приватную часть спецификации пакета от AdaCore и сделал почти всё по своему. Тип вектора я наследовал от Limited_Controlled, а не от Controlled. Испугался того, что во втором случае деструктор объекта может вызываться несколько раз. Не посмотрел как эта проблема решается стандартным способом. Далее начал городить свой огород исходя из меры своей распущенности, даже не подсматривая реализацию AdaCore. Ничего хорошего из этого не получилось.

При обнаружении проблем я решил посмотреть, а как всё устроено в Unbounded_String? Оказалась там всё гораздо проще чем в векторах. Нет ничего лишнего, привнесённого из контейнеров. Можно сказать -- просто и элегантно! Я решил взять за основу Unbounded_String, а не Vectors.

Сейчас разрабатываю проект "Unbouded_Array". Функциональность "Vector_View" здесь реализуется через массивы "Array_Of_Byte_Type" или "String", полученные с помощью функций "To_Constant_Array" или "To_Constant_String". Тут надо помнить, что это не копии, а ссылки на данные в объекте "Unbounded_Array_Type". Функциональность "Vector_Edit" здесь реализуется за счёт подобных массивов, но полученных с помощью фукций "Get_Array_Variable" и "Get_String_Variable". При вызове этих функций исходный объект "Unbounded_Array_Type" блокируется на изменение. Всякая дальнейшая попытка изменить объект, включая вызов деструктура, вызывает исключение "Buffer_Locked". Снятие блокировки обеспечивается вызовом процедуры "Unlock_Change".

Проблему, затрагивающуюся в теме "Поддержка 32битного Юникода для Ada 95", я уже обдумывал до появления этой темы. Пакет "XmlAda" совместим с АДА95, потому что в нём не применяются типы "Wide_Wide_***", "Wide_***", а типы "UTF8String", "UTF16**String и "UTF32**String" просто алиасы типа "String". Исходя из подобной идеи, я для каждой процедуры, работающей с "Array_Of_Byte_Type", ввёл альтернативную для "String". Думаю ввести в струкру "Referenced_Buffer" для объекта "Unbounded_Array_Type" признаки "UTF32" и "BOM" (вернее "BE"). А также, за счёт манипуляции с указателями, обеспечить работу с массивами 32-х кодов UTF32.

Сейчас, всё что я наваял, опубликую на сервере OSDN.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 11.05.2024 21:05
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name