Miranda IM со встроенным ядром XML парсерa

Последняя, двадцать первая, альфа сборка Miranda IM знаменовалась появлением встроенного в ядро XML парсерa. До этого каждый плагин, зачастую, использовал свой парсер. Так, к примеру, в плагине протокола MSN был встроен XML парсер ezXML, в плагине протокола Jabber был встроен свой парсер, ну а плагин Variables, кажется, использовал парсер Libxml.

Наличие кучи различных парсеров, с различным API, нужда в парсере во многих плагинах и вызвала появление XML парсера непосредственно в ядре Miranda IM. Необходимость в этом парсере была понятна давно, но требовалось выбрать либо готовый парсер с GNU/GPL совместимой лицензией, либо написать его с нуля. Так же проблемой стало то, что ядро Miranda IM было написано на С, и поиск парсера написаного на С был более сложным.

Долгие поиски подходяшего парсера, и неторопливость, в виду не критичной необходимости, растянула процесс на долгие месяцы. Наконец, 31 июля 2008 года, был сделан первый шаг. Ядро было переведено на С++ и был выбран парсер. Основой для парсера стала разработка др. Франка Вандер Бергена. Это лёгкий, быстрый парсер написанный на C++. Однако после интеграции этого парсера в ядро, над ним была проведена громадная работа. Было создано API для работы с парсером плагинами, а так же были внесены некоторые изменения в сам парсер.

API для работы с парсером вполне обычное и код с его использование выглядит примерно так:

static void InviteUser(CJabberProto* ppro, TCHAR *room, TCHAR *pUser, TCHAR *text)
{
int iqId = ppro->SerialNext();
XmlNode m( _T(«message»));
m.addAttr( «to», room );
m.addAttrID( iqId );
XmlNode x = m.addChild( «x» );
x.addAttr( «xmlns», _T(«http://jabber.org/protocol/muc#user»));
XmlNode i = x.addChild( «invite» ); i.addAttr( «to», pUser );
if ( text[0] != 0 )
i.addChild( «reason», text );
ppro->m_ThreadInfo->send( m );
}
Посмотреть какие функции вам доступны можно в файле исходных кодов API. При обновлении кода в протоколе Jabber было добавлена интересная обёртка вокруг этого API. Добавленная Ghazan’ом обёртка упростила разработку, сократив время на написание кода. Обёртка основана на перегрузке оператора побитового сдвига, и код с её использованием выглядит так:

static void InviteUser(CJabberProto* ppro, TCHAR *room, TCHAR *pUser, TCHAR *text)
{
ppro->m_ThreadInfo->send(
XmlNode(_T(«message»))
<< XATTR(_T(«to»), room)
<< XATTRID(ppro->SerialNext())
<< XCHILD(_T(«x»))
<< XATTR(_T(«xmlns»), _T(«http://jabber.org/protocol/muc#user»))
<< XCHILD(_T(«invite»)) << XATTR( _T(«to»), pUser)
<< (( text[0] != 0 ) ? XCHILD( _T(«reason»), text ) : NULL )
);
}
Как видно новое API, используемое в Jabber, слегка непривычное и в то же время довольно логичное. Кроме этого API, недавно, Nullbie добавил в Jabber возможность использования XPath выражений. Пример использования Xpath в Jabber можно посмотреть, к примеру, здесь. Если вы захотите поближе ознакомится с API для работы с XML в плагине Jabber посмотрете на следущие файлы: jabber_xml.cpp и jabber_xml.h.

Изначально, после добавления в ядро парсера и создания API парсера для плагинов, весь код работы c XML плагина Jabber был переписан. Был убран встроенный в Jabber парсер, и вся работа с XML была заменена на вызовы встроенного в ядро парсера. Чуть позже, после добавления в Jabber своего API для работы с XML, снова весь код работы с XML был переписан на новое API. К сожалению, все эти маштабные изменения привели к некоторой нестабильности плагина Jabber. Но баги связаные с этим довольно быстро фиксятся, поэтому если вы нашли какой нибудь баг, не стесняясь пишите в багтрекер.

Плагин протокола Jabber на данный момент единственный плагин использующий парсер в ядре. Возможно, вскоре, остальные плагины использующий XML подтянутся и перейдут на встроенный в ядро парсер. Надеюсь, если вы соберётесь писать плагин для Miranda IM и вам понадобится работа с XML, вы учтёте наличие встроенного в ядро парсера XML.

Добавить комментарий