суббота, сентября 23, 2006

Счастливы вместе

Речь снова о TurboDelphi. Описаный ранее трюк с подключением пакетов перестает работать после установки вышедшего не так давно патча. Установка в среду пакета dclusr становится невозможной, а если он был ранее установлен то последующая его пересборка приведет к тому, что пакет из среды будет удален. Но есть решение: установить данный пакет до установки патча, код загрузки с прямым указанием загружаемых пакетов заменить на чтение списка пакетов из файла. После чего установить патч и не изменять dclusr.

четверг, сентября 21, 2006

Кодировки в XML-RPC

Неоднократно встречал в сети недовольные высказывания относительно того, что спецификация XML-RPC никак не регламентирует использование различных кодировок, в частности Unicode (и это, якобы, является минусом протокола). Но я считаю, что авторы этих высказываний (как и авторы библиотек включивших поддержку Unicode) не до конца понимают сути XML-RPC. Дело в том, что пакеты XML-RPC это лишь транспорт для данных приложения/сервиса и в каком виде данные должны предоставляться дело именно взаимодействующих сущностей, но ни как не протокола. На самом деле проблемы нет, как таковой. Ни что не мешает сервису предъявлять требования к передаче строк в кодировке, скажем UTF-8, если в том есть необходимость, а клиенту останется только "соответствовать". Такое требование затрагивает лишь данные, но не формат самого пакета. Таким образом и цель достигается, и происходит все в рамках спецификации. Выходит, что эта проблема "не в клозетах, а в головах" (c) Почти Булгаков :)

 

P.S.

Ну, а если вспомнить, что спецификация XML говорит об использовании UTF-8 во всяком случае, когда кодировка не может быть определена (не указаны Encoding и ByteOrder), то все становится просто и понятно, ведь пакеты XML-RPC не содержат ни того ни другого ;)

100 лет вместе с Turbo!

Позавчера получил CD c TurboDelphi 2006 Explorer! Спасибо Borland'у за бесплатную лицензию на 100 лет :) Правда в версии Explorer есть ограничение, а именно невозможность установки в среду сторонних компонентов. Но "ничего нет невозможного, для врача, для неотложного" (c) Розенбаум :), поэтому рецепт в студию: открываем пакет dclusr.dpk (это стандартный пакет пользовательских компонент и его установка допустима) и добавляем в него новый модуль инициализационная часть которого содержит код для загрузки необходимых пакетов:

Initialization

  LoadPackage('package_1.bpl');

  LoadPackage('package_1.bpl');

  LoadPackage('package_1.bpl');

Но это еще не все! Для успешности данной операции необходимо, чтоб загружаемые пакеты могли саморегистрироваться (в отличие от обычного способа, когда регистрацией занимается среда) т.е. в инициализационной части модуля/модулей необходимо вызвать процедуру Register. Теперь все :) При запуске среды будет загружен dclusr.bpl, который, в свою очередь, загрузит нужные нам пакеты.

пятница, сентября 15, 2006

Багафича, даже две...

На оператор класса Implicit (другие не пробовал) не действует директива Inline. Все условия для Inline соблюдены, но тело оператора не разворачивается в код :( И еще об Implicit: не удается добиться работоспособности данного оператора при декларировании с типами Double и TDateTime. Типы по описанию не идентичные, но компилятор, так, видимо, не считает... Поэтому, если описать неявное преобразование в Double, будет допустимо присваивание значения типа TDateTime, но при этом, разумеется, будет вызван метод Implicit для типа Double. Если же описать неявное преобразование для них обоих, будет потеряна всякая возможность присваивания значений данных типов. Такое вот, хреновое лето...

среда, сентября 06, 2006

Advanced Records ("class-like")

Замечательная возможность BDS 2006! Работа с записями превращается в сказку, в смысле элегантности использования при грамотном проектировании. Использование свойств, методов и модификаторов видимости позволяет абстрагироваться от внутренней структуры записи, а применение директивы inline уменьшает/сводит на нет, какие бы то нибыло накладные расходы. В результате получаем работу с абстракцией и имеем при этом "чистый код"! Наличие конструкторов (пусть и параметризированных) облегчает использование advanced records в коде т.к. избавляет от необходимости объявлять переменные. Огромным плюсом является и тот факт, что даже при "конструировании" запись остается статической переменной, что в свою очередь снижает (опять же) накладные расходы и стимулирует к использованию advanced records в качестве перечислителей (enumerators). О перечислителях немного позже ;)

Небольшой пример:

    // Структура для хранения данных о регионе
TData = Record

Public

{$REGION ' Определение вложенных членов '}

Type

// Массив прямоугольников и указатель на него
TRects = Array [0 .. MaxInt Div SizeOf(TRect) - 1] Of TRect;
PRects = ^TRects;

{$ENDREGION}

Strict Private

FBuffer : TByteDynArray;

Function GetPRect(AIndex : Cardinal) : PRect; Inline;

{$REGION ' Методы доступа к значениям свойств '}

Function GetBuffer : Pointer; Inline;
Function GetBufferSize : Integer; Inline;
Function GetHeader : PRgnDataHeader; Inline;
Function GetRects : PRects; Inline;
Function GetRectCount : Integer; Inline;
Procedure SetRectCount(Const Value : Integer); Inline;

{$ENDREGION}

Public

{$REGION ' Поддержка оператора for-in-do '}

Function GetEnumerator : TRectEnumerator; Inline;

{$ENDREGION}

Constructor Create(ARegion : HRGN); Overload;
Constructor Create(ARegion : TRegion); Overload;

Procedure UpdateHeader(ARecalculateBounds : Boolean = False);
Procedure RecalculateBounds;

Function TakeFrom(ARegion : TRegion{$IFDEF LASTERROR_SUPPORT}; Out ALastError : Longword{$ENDIF}) : Boolean; Overload;

{$IFDEF LASTERROR_SUPPORT}

Function TakeFrom(ARegion : TRegion) : Boolean; Overload; Inline;

{$ENDIF}

Function TakeFrom(ARegion : HRGN{$IFDEF LASTERROR_SUPPORT}; Out ALastError : Longword{$ENDIF}) : Boolean; Overload;

{$IFDEF LASTERROR_SUPPORT}

Function TakeFrom(ARegion : HRGN) : Boolean; Overload; Inline;

{$ENDIF}

Function TakeFrom(Const ARects : Array Of TRect) : Boolean; Overload;
Function TakeFrom(Const ABuffer : TByteDynArray) : Boolean; Overload;

Property Buffer : Pointer Read GetBuffer;
Property BufferSize : Integer Read GetBufferSize;
Property Header : PRgnDataHeader Read GetHeader;
Property Rects : PRects Read GetRects;
Property RectCount : Integer Read GetRectCount Write SetRectCount;

End;

Turbo возвращается!

Сегодня стала доступна для скачивания TurboDelphi! Ура, товарищи! Уже заказал CD, поглядим через пару неделек :)