Właśnie skończyłem pracę nad kolejną wersją biblioteki; Prace końcowe trwały trochę czasu, bo kilka ostatnich tygodni, ale wszystkie założenia zostały zrealizowane;
1. Konwertery wartości
Przede wszystkim przystosowałem konwertery (funkcje) natywnych danych na łańcuchy i wice wersa, aby obsługiwały nowy format zapisu liczb całkowitych w systemach innych niż dziesiętny; Dzięki temu nowym standardem są znaki minusa przed prefiksami, a nie tak jak poprzednio, czyli ~U2;
2. Ładowanie i zapisywanie drzew
Kolejną bardzo ważną rzeczą jest nowy sposób parsowania źródła tekstowego i generowanie wyjścia w tej formie; Nowa wersja biblioteki posiada klasy, które korzystają z dodatkowych list, przechowujących elementy referencjonowane; Dzięki temu wejście można parsować linia po linii, bez konieczności ładowania całego pliku do pomocniczej listy (z czego i tak nie skorzystałem, głównie ze względu na jeden kod ładujący drzewa z różnych źródeł); To samo tyczy się generowania wyjscia tekstowego - wyjście generowane jest linia po linii i od razu sformatowane, a nie tak jak wcześniej, że linie definicji były przesuwane na koniec listy już po wstępnej serializacji;
Wykorzystywanie pomocniczych list dla obiektów elementów referencjonowanych nieco uprościło kod, a także go przyspieszyło, więc uważam to za bardzo ważną zmianę;
3. Drzewa dołączane
Tutaj też jest kilka zmian - na lepsze; Tak jak poprzednio, możliwe jest ładowanie dowolnego pliku bez możliwości obsługi linkowania; Wcześniej była to opcja domyślna, teraz już nie jest; Co więcej, każdy plik może zostać załadowany osobno i bez liknowania zewnętrznych drzew, bez względu na to czy plik faktycznie jest samodzielny, czy jest głównym czy linkowanych plikiem systemu konfiguracji; Dzięki temu API jest bezpieczniejsze dla aplikacji wykorzystującej bibliotekę;
Kolejna i najważniejsza rzecz jeśli chodzi o linkowanie to kompletne zabezpieczenie przed zapętleniem dowiązań; W nowej wersji API nie będzie możliwe dołączenie jednego pliku wielokrotnie (w kilku miejscach drzewa), tworząc wiele identycznych gałęzi (de facto pochodzących z tego samego pliku); Zabezpieczenie to dotyczy także blokady linkowania "samego siebie", co również mogło by rekurencyjnie zapętlić praser i spowodować przepełnienie pamięci; Natomiast sama blokada nie usuwa deklaracji linków z drzew, dzięki temu zawartość pliku i drzewa nie zmieni się po wykryciu kolizji; Element linku w drzewie pozostanie, a jedynie zostanie zignorowany;
Ostatnia rzecz jeśli chodzi o linkowanie kolejnych drzew to użycie dodatkowej listy drzew, zamiast rekurencyjnego ich ładowania; W nowej wersji parser przyjmuje listę drzew i jeśli aktualnie ładowane drzewo zawiera linki - są one dodawane do listy, a sam parser nie ładuje tych drzew od razu; Dzięki temu wszystkie pliki systemu konfiguracji ładowane są liniowo (nie rekurencyjnie) bezpośrednio w metodzie LoadFromFile
, co sprawia, że w końcu rzucane przez parsery wyjątki będą wydostawać się poza metodę LoadFromFile
; To pozwoli aplikacji używającej biblioteki wyłapywać wyjątki i stosownie na nie reagować;
4. Obsługiwane źródła
Do tej pory biblioteka umożliwiała załadowanie drzewa (lub pełnego systemu konfiguracji) z plików dyskowych, bezpośrednio z list TStrings
oraz ze strumieni TStream
, a także z kompilowanych zasobów (wkompilowanych plików .res) na podstawie nazwy zasobu lub identyfikatora liczbowego; Nowością jest możliwość załadowania pojedynczego drzewa z zasobów Lazarusa, czyli z wkompilowanych plików .lrs na podstawie nazwy zasobu;
Niestety nie udało mi się ogarnąć metody TLazarusResourceStream.CreateFromID
(czyli odpowiednika TResourceStream.CreateFromID
), bo nie mam zielonego pojęcia jak to działa; Zasób w pliku .lrs jest tekstowym skryptem, w którym nie można podać liczby jako identyfikatora zasobu; Otrzymywałem wyjątki SIGSEGV
przy próbie rozgryzienia tej metody, niestety na próżno; Próżno też szukać instrukcji w dokumentacji, bo opis tej metody jest obskórny... Dlatego też póki co nie będzie takiej możliwości, ale w przyszłości może się to zmienić;
Pozostałe zmiany
Zmian i ulepszeń jest więcej, ale są to małe pierdółki jak formatowanie kodu, nazewnictwo, reorganizacja kolejności deklaracji i definicji klas itd.; Wszystkich zmian nie ma sensu wypisywać, bo te pozostałe mają zasięg lokalny;
Nowe API nie będzie kompatybilne z poprzednim, tak samo jak nowy format nie będzie kompatybilny z poprzednim; W API zmieniły się nieco instrukcje ładowania drzew (zostały wydzielone z konstruktorów do metod LoadFrom*
), a także lekko zmieniło się nazewnictwo klas i niektórych metod; Co do samego formatu - nieco zmieniła się składnia tekstowych plików (rozwinięte frazy kluczowe, nowy zapis deklaracji linków do plików dołączanych itd.), a także budowa plików binarnych (nagłówek pliku oraz zapis głównego węzła drzewa);
Funkcjonalność samego formatu praktycznie nie zmieniła się - inny jest tylko zapis pewnych elementów; Pozostało tylko wszystko porządnie przetestować, aby mieć 100% pewności co do niezawodności i słabych punktów biblioteki; Przede mną jeszcze dużo pracy, bo co prawda biblioteka już prawie gotowa, ale trzeba jeszcze przygotować specyfikację dla nowej wersji formatu, a także dokumentację i tutorial dla nowego API;
Jeszcze miesiąc-dwa i będzie gotowe.