суббота, сентября 23, 2006
Счастливы вместе
четверг, сентября 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
Багафича, даже две...
среда, сентября 13, 2006
среда, сентября 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;