<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ars Longa, Vita Brevis &#187; Vladimir</title>
	<atom:link href="http://blog.sjinks.pro/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sjinks.pro</link>
	<description>Quod scripsi, scripsi</description>
	<lastBuildDate>Mon, 06 Feb 2012 17:56:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Исправление проблемы обхода хранителя экрана в X11</title>
		<link>http://blog.sjinks.pro/security/960-fix-bypass-screensaver-locker/</link>
		<comments>http://blog.sjinks.pro/security/960-fix-bypass-screensaver-locker/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 12:18:51 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[безопасность]]></category>
		<category><![CDATA[уязвимость]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=960</guid>
		<description><![CDATA[Программистов всё больше, а профессионалов всё меньше В X.Org Server 1.11 обнаружена уязвимость, позволяющая через манипуляции с клавиатурой обойти режим блокировки экрана и получить доступ к заблокированному рабочему окружению пользователя. Подробности либо по ссылке выше, либо на OpenNet. Исправление: в файле /usr/share/X11/xkb/compat/xfree86 закомментировать следующие строки: interpret XF86_Ungrab { action = Private(type=0x86, data=&#34;Ungrab&#34;); }; interpret XF86_ClearGrab [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/960-fix-bypass-screensaver-locker/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Программистов всё больше, а профессионалов всё меньше</em></h2>
<p>В X.Org Server 1.11 <a href="http://gu1.aeroxteam.fr/2012/01/19/bypass-screensaver-locker-program-xorg-111-and-up/">обнаружена уязвимость</a>, позволяющая через манипуляции с клавиатурой обойти режим блокировки экрана и получить доступ к заблокированному рабочему окружению пользователя.</p>
<p>Подробности либо по ссылке выше, либо на <a href="http://www.opennet.ru/opennews/art.shtml?num=32844">OpenNet</a>.<span id="more-960"></span></p>
<p>Исправление: в файле <code>/usr/share/X11/xkb/compat/xfree86</code> закомментировать следующие строки:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9602">
        <div class="code text" id="p960code2">
&nbsp; &nbsp; interpret XF86_Ungrab {<br />
&nbsp; &nbsp; &nbsp; &nbsp; action = Private(type=0x86, data=&quot;Ungrab&quot;);<br />
&nbsp; &nbsp; };<br />
&nbsp; &nbsp; interpret XF86_ClearGrab {<br />
&nbsp; &nbsp; &nbsp; &nbsp; action = Private(type=0x86, data=&quot;ClsGrb&quot;);<br />
&nbsp; &nbsp; };
        </div>
    </div>
</div>

<p>После чего перезапустить X Server.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/960-fix-bypass-screensaver-locker/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/960-fix-bypass-screensaver-locker/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Автоматическое добавление ссылки на источник при копировании текста с сайта</title>
		<link>http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/</link>
		<comments>http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 03:42:35 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=958</guid>
		<description><![CDATA[Навязчивое добавление ссылки на оригинал при копировании текста с сайта Идея: когда пользователь выделяет часть текста и копирует её в буфер обмена (например, чтобы выложить на своём сайте), автоматически добавлять к выделению ссылку на источник. Реализация: var source_link = &#039;&#60;p&#62;Подробнее: &#60;a href=&#34;&#039; + location.href + &#039;&#34;&#62;&#039; + location.href + &#039;&#60;/a&#62;&#60;/p&#62;&#039;; jQuery( function($) { if (window.getSelection) [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Навязчивое добавление ссылки на оригинал при копировании текста с сайта</em></h2>
<p><strong>Идея:</strong> когда пользователь выделяет часть текста и копирует её в буфер обмена (например, чтобы выложить на своём сайте), автоматически добавлять к выделению ссылку на источник.<span id="more-958"></span></p>
<p><strong>Реализация:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9584">
        <div class="code javascript" id="p958code4">
<span class="kw2">var</span> source_link <span class="sy0">=</span> <span class="st0">'&lt;p&gt;Подробнее: &lt;a href=&quot;'</span> <span class="sy0">+</span> location.<span class="me1">href</span> <span class="sy0">+</span> <span class="st0">'&quot;&gt;'</span> <span class="sy0">+</span> location.<span class="me1">href</span> <span class="sy0">+</span> <span class="st0">'&lt;/a&gt;&lt;/p&gt;'</span><span class="sy0">;</span><br />
jQuery<span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>$<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">getSelection</span><span class="br0">&#41;</span> $<span class="br0">&#40;</span><span class="st0">'#content div.post'</span><span class="br0">&#41;</span>.<span class="me1">bind</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'copy'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> selection <span class="sy0">=</span> window.<span class="me1">getSelection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> range <span class="sy0">=</span> selection.<span class="me1">getRangeAt</span><span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> magic_div <span class="sy0">=</span> $<span class="br0">&#40;</span><span class="st0">'&lt;div&gt;'</span><span class="br0">&#41;</span>.<span class="me1">css</span><span class="br0">&#40;</span><span class="br0">&#123;</span> overflow <span class="sy0">:</span> <span class="st0">'hidden'</span><span class="sy0">,</span> width<span class="sy0">:</span> <span class="st0">'1px'</span><span class="sy0">,</span> height <span class="sy0">:</span> <span class="st0">'1px'</span><span class="sy0">,</span> position <span class="sy0">:</span> <span class="st0">'absolute'</span><span class="sy0">,</span> top<span class="sy0">:</span> <span class="st0">'-10000px'</span><span class="sy0">,</span> left <span class="sy0">:</span> <span class="st0">'-10000px'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; magic_div.<span class="me1">append</span><span class="br0">&#40;</span>range.<span class="me1">cloneContents</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> source_link<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span><span class="st0">'body'</span><span class="br0">&#41;</span>.<span class="me1">append</span><span class="br0">&#40;</span>magic_div<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> cloned_range <span class="sy0">=</span> range.<span class="me1">cloneRange</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">removeAllRanges</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> new_range <span class="sy0">=</span> document.<span class="me1">createRange</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_range.<span class="me1">selectNode</span><span class="br0">&#40;</span>magic_div.<span class="me1">get</span><span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">addRange</span><span class="br0">&#40;</span>new_range<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; window.<span class="me1">setTimeout</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">removeAllRanges</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selection.<span class="me1">addRange</span><span class="br0">&#40;</span>cloned_range<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; magic_div.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">,</span> 0<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p><strong>Настраиваемые параметры</strong>:</p>
<ul>
<li><code>source_link</code> — текст, который будет добавляться к копируемому фрагменту. В данном примере задаётся статически, но при желании генерацию ссылки можно усложнить (например, при копировании с текста с домашней страницы можно возвращать ссылку на статью, из которой взята данная цитата). Для этого в строке <code>magic_div.append(range.cloneContents(), source_link);</code> вместо <code>source_link</code> нужно использовать свою функцию, возвращающую <a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a> для вставки в копируемый фрагмент.</li>
<li><code>'#content div.post'</code> — выражение, задающее один или более контейнер с текстом, при копировании которого нужно добавлять ссылку на оригинал. Идея в том, что добавлять ссылку на статью при копировании, скажем, части текста одного из комментариев к статье было бы нелогично. С помощью данного выражения можно задать требуемые защищаемые объекты.</li>
</ul>
<p><strong>Возможные улучшения:</strong> проверка длины копируемого текста. Например, если пользователь копирует меньше 20 слов, не добавлять ссылку. Получить выделенный текст можно через <code>range.cloneContents().textContent</code>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/javascript/958-link-to-source-on-copy-clipboard/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Qt, libfcgi и многопоточность</title>
		<link>http://blog.sjinks.pro/c-cpp/qt/956-qt-libfcgi-multithreading/</link>
		<comments>http://blog.sjinks.pro/c-cpp/qt/956-qt-libfcgi-multithreading/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 17:31:00 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Qt]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[потоки]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=956</guid>
		<description><![CDATA[Предотвращение блокирования событий при использовании libfcgi в многопоточном режиме Для создания приложений FastCGI на C/C++ есть библиотека libfcgi. Не буду вдаваться в дискуссию, зачем нужны приложения FastCGI на C/C++/подставить нужный язык, когда Python/PHP/Perl/подставить нужное гораздо удобнее. Отмечу лишь, что по работе понадобилось написать FastCGI-приложение на Qt (в основном из-за наличия нескольких высокопроизводительных библиотек, написанных на [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/c-cpp/qt/956-qt-libfcgi-multithreading/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Предотвращение блокирования событий при использовании libfcgi в многопоточном режиме</em></h2>
<p>Для создания приложений <a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">FastCGI</a> на <a href="http://blog.sjinks.pro/tag/cpp/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  C/C++">C/C++</a> есть библиотека <a href="http://www.fastcgi.com/devkit/doc/overview.html">libfcgi</a>. Не буду вдаваться в дискуссию, зачем нужны приложения FastCGI на C/C++/подставить нужный язык, когда Python/<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>/Perl/подставить нужное гораздо удобнее. Отмечу лишь, что по работе понадобилось написать FastCGI-приложение на <a href="http://blog.sjinks.pro/tag/qt/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Qt">Qt</a> (в основном из-за наличия нескольких высокопроизводительных библиотек, написанных на <a href="http://blog.sjinks.pro/tag/qt/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Qt">Qt</a>, но не суть).</p>
<p>Строго говоря, libfcgi, хотя и является официальной библиотекой от создателей протокола, не лучший вариант для поддержки FastCGI — API, предоставляемое библиотекой, сильно ограничено (в плане функциональности) и недостаточно гибко.<span id="more-956"></span></p>
<p>Грубо говоря, приложение, использующее libfcgi, может работать в двух режимах:</p>
<ol>
<li>Последовательная обработка запросов: приложение получило запрос, обработало его, отправило результат, получило следующий запрос. Схема хороша, если обработка запроса тривиальна и/или не занимает много времени. Скорее всего, под большой нагрузкой масштабируется плохо, ибо чем длиннее очередь запросов, тем дольши придётся ждать клиенту.</li>
<li><a href="http://www.fastcgi.com/devkit/examples/threaded.c">Многопоточная</a> обработка запросов: приложение создаёт определённое количество потоков, каждый из которых будет обрабатывать свой запрос. При средних нагрузках эта схема работает лучше (если один поток занят, свободный поток займётся выполнением запроса). Но в предельном случае (когда все <a href="http://blog.sjinks.pro/tag/threads/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  потоки">потоки</a> заняты) имеем те же проблемы, что и в первом варианте. Схему можно немного изменить, создавая <a href="http://blog.sjinks.pro/tag/threads/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  потоки">потоки</a> по мере необходимости, но всё равно плодить <a href="http://blog.sjinks.pro/tag/threads/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  потоки">потоки</a> до бесконечности нельзя.</li>
</ol>
<p>Использование потоков не всегда уместно/хорошо: многопоточные программы, как правило, сложнее для разработки и отладки; кроме того, потоки потребляют системные ресурсы (например, память для стека) и при большом количестве потоков эти издержки могут быть существенными (например, для <a href="http://blog.sjinks.pro/tag/linux/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Linux">Linux</a>/IA-32 размер стека для потока по умолчанию составляет 2 мегабайта).</p>
<p>К сожалению, при использовании libfcgi отказаться от потоков очень трудно — дело в том, что библиотека использует блокирующие операции при работе с сокетами.</p>
<p>В общем случае алгоритм работы с libfcgi следующий:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p9569">
        <div class="code c" id="p956code9">
<span class="coMULTI">/* Инициализация */</span><br />
FCGX_Init<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw4">int</span> socket <span class="sy0">=</span> FCGX_OpenSocket<span class="br0">&#40;</span><span class="st0">&quot;:9001&quot;</span><span class="sy0">,</span> 256<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="coMULTI">/* ... */</span><br />
<br />
<span class="co1">// Собственно работа</span><br />
<span class="kw1">while</span> <span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; FCGX_Request<span class="sy0">*</span> req <span class="sy0">=</span> new FCGX_Request<span class="sy0">;</span><br />
&nbsp; &nbsp; FCGX_InitRequest<span class="br0">&#40;</span>req<span class="sy0">,</span> socket<span class="sy0">,</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw4">int</span> rc <span class="sy0">=</span> FCGX_Accept_r<span class="br0">&#40;</span>req<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>rc <span class="sy0">&gt;=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* Здесь создаём и запускаем поток, отвечающий за обработку запроса */</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>В случае с Qt и использованием рабочего цикла внутри основной программы имеется неприятный подводный камень: из-за того, что <code>FCGX_Accept_r()</code> использует блокирующие вызовы при работе с сокетом, основная программа может очень долго не увидеть сообщения, посылаемые, например, потоком.</p>
<p>Поэтому перед вызовом <code>FCGX_Accept_r()</code> имеет смысл проверять, имеются ли запросы на соединение.<br />
Решение в лоб:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95610">
        <div class="code cpp" id="p956code10">
<span class="co2">#include &lt;QtCore/QCoreApplication&gt;</span><br />
<span class="co2">#include &lt;sys/select.h&gt;</span><br />
<br />
<span class="coMULTI">/* ... */</span><br />
<br />
<span class="kw4">int</span> rc<span class="sy4">;</span><br />
<span class="kw1">do</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; QCoreApplication<span class="sy4">::</span><span class="me2">processEvents</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; <span class="kw4">struct</span> timeval tv <span class="sy1">=</span> <span class="br0">&#123;</span> 0, 500 <span class="br0">&#125;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; fd_set r<span class="sy4">;</span><br />
&nbsp; &nbsp; FD_ZERO<span class="br0">&#40;</span><span class="sy3">&amp;</span>r<span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; FD_SET<span class="br0">&#40;</span>socket, <span class="sy3">&amp;</span>r<span class="br0">&#41;</span><span class="sy4">;</span><br />
<br />
&nbsp; &nbsp; rc <span class="sy1">=</span> <span class="sy4">::</span><span class="me2">select</span><span class="br0">&#40;</span>socket<span class="sy2">+</span>1, <span class="sy3">&amp;</span>r, 0, 0, <span class="sy3">&amp;</span>tv<span class="br0">&#41;</span><span class="sy4">;</span><br />
<span class="br0">&#125;</span> <span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy3">!</span>rc<span class="br0">&#41;</span><span class="sy4">;</span><br />
<br />
FCGX_Request<span class="sy2">*</span> req <span class="sy1">=</span> <span class="kw3">new</span> FCGX_Request<span class="sy4">;</span><br />
FCGX_InitRequest<span class="br0">&#40;</span>req, socket, 0<span class="br0">&#41;</span><span class="sy4">;</span><br />
<span class="kw4">int</span> sock <span class="sy1">=</span> FCGX_Accept_r<span class="br0">&#40;</span>req<span class="br0">&#41;</span><span class="sy4">;</span><br />
<span class="coMULTI">/* ... */</span>
        </div>
    </div>
</div>

<p>Но более корректно будет использовать <code>QSocketNotifier</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95611">
        <div class="code cpp-qt" id="p956code11">
<span class="co1">// core.h</span><br />
<span class="co2">#include &lt;QtCore/QObject&gt;</span><br />
<br />
<span class="kw2">class</span> QSocketNotifier<span class="sy0">;</span><br />
<br />
<span class="kw2">class</span> Core <span class="sy0">:</span> <span class="kw2">public</span> <span class="kw5">QObject</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">Q_OBJECT</span><br />
<span class="kw2">public</span><span class="sy0">:</span><br />
&nbsp; &nbsp; <span class="kw2">explicit</span> Core<span class="br0">&#40;</span><span class="kw5">QObject</span> <span class="sy0">*</span>parent <span class="sy0">=</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">void</span> run<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw2">private</span><span class="sy0">:</span><br />
&nbsp; &nbsp; <span class="kw5">QSocketNotifier</span><span class="sy0">*</span> m_notifier<span class="sy0">;</span><br />
<br />
<span class="kw2">private</span> <span class="kw2">slots</span><span class="sy0">:</span><br />
&nbsp; &nbsp; <span class="kw4">void</span> connectionPending<span class="br0">&#40;</span><span class="kw4">int</span> socket<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><span class="sy0">;</span><br />
<br />
<span class="co1">// core.cpp</span><br />
<br />
Core<span class="sy0">::</span><span class="me2">Core</span><span class="br0">&#40;</span><span class="kw5">QObject</span> <span class="sy0">*</span>parent<span class="br0">&#41;</span> <span class="sy0">:</span> <span class="kw5">QObject</span><span class="br0">&#40;</span>parent<span class="br0">&#41;</span><span class="sy0">,</span> m_notifier<span class="br0">&#40;</span>0<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; FCGX_Init<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> sock <span class="sy0">=</span> FCGX_OpenSocket<span class="br0">&#40;</span><span class="st0">&quot;:9001&quot;</span><span class="sy0">,</span> 256<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; this<span class="sy0">-&gt;</span><span class="me3">m_notifier</span> <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw5">QSocketNotifier</span><span class="br0">&#40;</span>sock<span class="sy0">,</span> <span class="kw5">QSocketNotifier</span><span class="sy0">::</span><span class="me2">Read</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QObject</span><span class="sy0">::</span><span class="kw2">connect</span><span class="br0">&#40;</span>this<span class="sy0">-&gt;</span><span class="me3">m_notifier</span><span class="sy0">,</span> SIGNAL<span class="br0">&#40;</span>activated<span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="kw1">this</span><span class="sy0">,</span> SLOT<span class="br0">&#40;</span>connectionPending<span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> Core<span class="sy0">::</span><span class="me2">connectionPending</span><span class="br0">&#40;</span><span class="kw4">int</span> socket<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw5">QSocketNotifier</span><span class="sy0">*</span> notifier <span class="sy0">=</span> qobject_cast<span class="sy0">&lt;</span><span class="kw5">QSocketNotifier</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>this<span class="sy0">-&gt;</span><span class="me3">sender</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; Q_CHECK_PTR<span class="br0">&#40;</span>notifier<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; notifier<span class="sy0">-&gt;</span><span class="me3">setEnabled</span><span class="br0">&#40;</span><span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; FCGX_Request<span class="sy0">*</span> req <span class="sy0">=</span> <span class="kw1">new</span> FCGX_Request<span class="sy0">;</span><br />
&nbsp; &nbsp; FCGX_InitRequest<span class="br0">&#40;</span>req<span class="sy0">,</span> socket<span class="sy0">,</span> 0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> s <span class="sy0">=</span> FCGX_Accept_r<span class="br0">&#40;</span>req<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>s <span class="sy0">&gt;=</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* Здесь создаём и запускаем поток */</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; notifier<span class="sy0">-&gt;</span><span class="me3">setEnabled</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>В качестве альтернативы созданию потоков можно предложить использовать очередь запросов.</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95612">
        <div class="code cpp" id="p956code12">
<span class="co2">#include &lt;QtCore/QMutex&gt;</span><br />
<span class="co2">#include &lt;QtCore/QMutexLocker&gt;</span><br />
<span class="co2">#include &lt;QtCore/QQueue&gt;</span><br />
<span class="co2">#include &lt;QtCore/QWaitCondition&gt;</span><br />
<br />
<span class="kw2">class</span> Queue <span class="br0">&#123;</span><br />
<span class="kw2">public</span><span class="sy4">:</span><br />
&nbsp; &nbsp; <span class="kw4">void</span> addToQueue<span class="br0">&#40;</span>FCGX_Request<span class="sy2">*</span> r, <span class="kw4">bool</span> broadcast <span class="sy1">=</span> <span class="kw2">false</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; QMutexLocker locker<span class="br0">&#40;</span><span class="sy3">&amp;</span>this<span class="sy2">-</span><span class="sy1">&gt;</span>mx<span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; this<span class="sy2">-</span><span class="sy1">&gt;</span>queue.<span class="me1">enqueue</span><span class="br0">&#40;</span>r<span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>broadcast<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this<span class="sy2">-</span><span class="sy1">&gt;</span>cv.<span class="me1">wakeAll</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this<span class="sy2">-</span><span class="sy1">&gt;</span>cv.<span class="me1">wakeOne</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; FCGX_Request<span class="sy2">*</span> getFromQueue<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; this<span class="sy2">-</span><span class="sy1">&gt;</span>mx.<span class="me1">lock</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>this<span class="sy2">-</span><span class="sy1">&gt;</span>queue.<span class="me1">isEmpty</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this<span class="sy2">-</span><span class="sy1">&gt;</span>cv.<span class="me1">wait</span><span class="br0">&#40;</span><span class="sy3">&amp;</span>this<span class="sy2">-</span><span class="sy1">&gt;</span>mx<span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; FCGX_Request<span class="sy2">*</span> result <span class="sy1">=</span> this<span class="sy2">-</span><span class="sy1">&gt;</span>queue.<span class="me1">dequeue</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; this<span class="sy2">-</span><span class="sy1">&gt;</span>mx.<span class="me1">unlock</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> result<span class="sy4">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="kw2">private</span><span class="sy4">:</span><br />
&nbsp; &nbsp; QMutex mx<span class="sy4">;</span><br />
&nbsp; &nbsp; QWaitCondition cv<span class="sy4">;</span><br />
&nbsp; &nbsp; QQueue<span class="sy1">&lt;</span>FCGX_Request<span class="sy2">*</span><span class="sy1">&gt;</span> queue<span class="sy4">;</span><br />
<span class="br0">&#125;</span><span class="sy4">;</span>
        </div>
    </div>
</div>

<p>Но это уже совсем другая история.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/c-cpp/qt/956-qt-libfcgi-multithreading/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/c-cpp/qt/956-qt-libfcgi-multithreading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Обход плагина WP Hashcash</title>
		<link>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/</link>
		<comments>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 05:43:11 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Плагины WordPress]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[плагин]]></category>
		<category><![CDATA[спам]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=955</guid>
		<description><![CDATA[Не так страшен JavaScript, как его малюют… WP Hashcash — очередной плагин WordPress для борьбы со спамом. Принцип работы основывается на том, что спам-боты не умеют исполнять JavaScript. Идея в том, что если пользователь открыл сайт из браузера, браузер выполнит некоторый хитрый код JavaScript, и реузльтат работы этого скрипта будет передан назад на сервер в качестве доказательства [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/955-bypass-wp-hashcash/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Не так страшен <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>, как его малюют…</em></h2>
<p><a href="http://wordpress-plugins.feifei.us/hashcash/">WP Hashcash</a> — очередной <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> для борьбы со спамом. Принцип работы основывается на том, что <a href="http://blog.sjinks.pro/tag/spam/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  спам">спам</a>-боты не умеют исполнять JavaScript. Идея в том, что если пользователь открыл сайт из браузера, браузер выполнит некоторый хитрый код JavaScript, и реузльтат работы этого скрипта будет передан назад на сервер в качестве доказательства «человечности» комментатора.<span id="more-955"></span></p>
<p>Недостаток этого подхода заключается в том, что используемый JavaScript является довольно-таки простым; как следствие, его можно «понять» даже из <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>-скрипта.</p>
<p>Пример кода JavaScript, генерируемого плагином:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95519">
        <div class="code javascript" id="p955code19">
<span class="kw2">function</span> wphc<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> wphc_data <span class="sy0">=</span> <span class="br0">&#91;</span>1850500665<span class="sy0">,</span>1666021931<span class="sy0">,</span>1699898495<span class="sy0">,</span>1648446524<span class="sy0">,</span>2035770162<span class="sy0">,</span>1980447546<span class="sy0">,</span>2018932269<span class="sy0">,</span>956464429<span class="sy0">,</span>890644332<span class="sy0">,</span>956447103<span class="sy0">,</span>890644332<span class="sy0">,</span>973224063<span class="sy0">,</span>890579818<span class="sy0">,</span>761213796<span class="sy0">,</span>1850368808<span class="sy0">,</span>1615687680<span class="sy0">,</span>1750492719<span class="sy0">,</span>756628087<span class="br0">&#93;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>wphc_data.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">=</span>wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">^</span><span class="nu0">220336991</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> a <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span>wphc_data.<span class="me1">length</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i<span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> i<span class="sy0">&lt;</span>wphc_data.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> String.<span class="me1">fromCharCode</span><span class="br0">&#40;</span>wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>8 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>16 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> wphc_data<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">&gt;&gt;&gt;</span>24 <span class="sy0">&amp;</span> 0xFF<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">eval</span><span class="br0">&#40;</span>a.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Такой JavaScript весьма похож на PHP <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Как следствие, идея обхода плагина заключается в том, чтобы преобразовать JavaScript в PHP и выполнить получившийся PHP-код.</p>
<p>Итак:</p>
<ol>
<li>В PHP нет ключевого слова <code>var</code> (строго говоря, оно там есть, только имеет другое назначение).</li>
<li>В PHP несколько другой синтаксис объявления массива</li>
<li>Идентификаторы в PHP начинаются с доллара</li>
<li>Операция сдвига выглядит как <code>&gt;&gt;</code>, а не <code>&gt;&gt;&gt;</code>.</li>
<li>В PHP нет классов Array, String, но никто не мешает их написать <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ol>
<p>Наша задача состоит в преобразовании кода, приведённого выше, в нечто подобное:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95520">
        <div class="code php" id="p955code20">
<span class="kw2">function</span> wphc<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$wphc_data</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span>1850500665<span class="sy0">,</span>1666021931<span class="sy0">,</span>1699898495<span class="sy0">,</span>1648446524<span class="sy0">,</span>2035770162<span class="sy0">,</span>1980447546<span class="sy0">,</span>2018932269<span class="sy0">,</span>956464429<span class="sy0">,</span>890644332<span class="sy0">,</span>956447103<span class="sy0">,</span>890644332<span class="sy0">,</span>973224063<span class="sy0">,</span>890579818<span class="sy0">,</span>761213796<span class="sy0">,</span>1850368808<span class="sy0">,</span>1615687680<span class="sy0">,</span>1750492719<span class="sy0">,</span>756628087<span class="br0">&#41;</span><span class="sy0">;</span> <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span>count<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">=</span><span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span>^<span class="nu0">220336991</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&lt;</span>count<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> <span class="sy0">=</span> fromCharCode<span class="br0">&#40;</span><span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>8 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>16 <span class="sy0">&amp;</span> 0xFF<span class="sy0">,</span> <span class="re0">$wphc_data</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="sy0">&gt;&gt;</span>24 <span class="sy0">&amp;</span> 0xFF<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw3">join</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="sy0">,</span> <span class="re0">$a</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Это достигается таким набором правил <code>str_replace()</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95521">
        <div class="code php" id="p955code21">
<span class="re0">$x</span> <span class="sy0">=</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'wphc_data'</span> &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$wphc_data'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'var $'</span> &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'var '</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'$'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'];'</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">');'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'= ['</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'= array('</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'new Array($wphc_data.length)'</span> <span class="sy0">=&gt;</span> <span class="st_h">'array()'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'$wphc_data.length'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'count($wphc_data)'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">' i&lt;'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">' $i&lt;'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'[i]'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'[$i]'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'i++'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$i++'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'&gt;&gt;&gt;'</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'&gt;&gt;'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'a[$i] ='</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">'$a[$i] ='</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'String.'</span> &nbsp; &nbsp;<span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st_h">'eval'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;a.join('')&quot;</span> <span class="sy0">=&gt;</span> <span class="st_h">'join(&quot;&quot;, $a)'</span><span class="sy0">,</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="kw3">array_keys</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="kw3">array_values</span><span class="br0">&#40;</span><span class="re0">$x</span><span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="re0">$s</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>При желании правила можно попытаться оптимизировать, но мне было лень — скрипт ломался на коленке за 10 минут.</p>
<p>Реализация функции <code>fromCharCode</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95522">
        <div class="code php" id="p955code22">
<span class="kw2">function</span> fromCharCode<span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="sy0">,</span> <span class="re0">$c</span><span class="sy0">,</span> <span class="re0">$d</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$b</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="kw3">chr</span><span class="br0">&#40;</span><span class="re0">$d</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>После замены результат нужно вычислить при помощи <code>eval()</code>. После чего получим такой результат:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95523">
        <div class="code javascript" id="p955code23">
<span class="kw2">function</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="kw1">return</span> 43448 <span class="sy0">*</span> 43448 <span class="sy0">+</span> <span class="nu0">75878</span><span class="sy0">;</span> <span class="br0">&#125;</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Как можно заметить, этот код является одновременно и PHP-кодом, и JavaScript-кодом.</p>
<p>Следующий шаг —</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p95524">
        <div class="code php" id="p955code24">
<span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'wphc_compute();'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">eval</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> wphc_compute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Результатом выполнения будет число 1887804582.</p>
<p>Как видим, для обхода такой простой защиты не нужен даже интерпретатор JavaScript <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/955-bypass-wp-hashcash/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/955-bypass-wp-hashcash/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Уважаемый Дмитрий</title>
		<link>http://blog.sjinks.pro/uncategorized/951-mr-president/</link>
		<comments>http://blog.sjinks.pro/uncategorized/951-mr-president/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 22:05:46 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Всё подряд]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=951</guid>
		<description><![CDATA[Приколы от Google Translate Идём на Google Translate Выбираем перевод с русского на анлийский Вводим фразу Уважаемый Дмитрий Наслаждаемся переводом Говорят, что это аж с 2010 года тянется. © 2012 Ars Longa, Vita Brevis. Все права защищены. Перепубликация материалов без разрешения автора запрещена. При использовании материалов блога наличие активной не закрытой от индексирования ссылки на источник [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/uncategorized/951-mr-president/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Приколы от <a href="http://blog.sjinks.pro/tag/google/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Google">Google</a> Translate</em></h2>
<ol>
<li>Идём на <a href="http://translate.google.com/?hl=en#ru|en|">Google Translate</a></li>
<li>Выбираем перевод с русского на анлийский</li>
<li>Вводим фразу <em>Уважаемый Дмитрий</em></li>
<li>Наслаждаемся переводом <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ol>
<p><span id="more-951"></span><br />
<a href="http://static.sjinks.info/wp-content/uploads/2011/12/mr-president.png"><img src="http://static.sjinks.info/wp-content/uploads/2011/12/mr-president.png" alt="Dear Dmitry or Mr President?" title="Приколы от Google Translate" width="676" height="415" class="alignnone size-full wp-image-952" /></a></p>
<p><a href="http://www.polit.ru/news/2010/10/24/19/">Говорят</a>, что это аж с 2010 года тянется.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/uncategorized/951-mr-president/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/uncategorized/951-mr-president/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>SQLMon для Yii</title>
		<link>http://blog.sjinks.pro/php/yii/947-sqlmon-for-yii/</link>
		<comments>http://blog.sjinks.pro/php/yii/947-sqlmon-for-yii/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 15:02:18 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQLMon]]></category>
		<category><![CDATA[лог]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=947</guid>
		<description><![CDATA[Расширение для анализа производительности SQL-запросов для Yii Одной из вещей, которых мне очень не хватало при разработке сайтов на Yii — нормального отображения всех запросов к базе данных, что дало бы возможность их последующего анализа. Ситуацию частично исправило расширение под названием Yii DB profiler. Но остались некоторые неудобства: Отображение запросов в порядке убывания времени выполнения — в принципе, это [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/yii/947-sqlmon-for-yii/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Расширение для анализа производительности SQL-запросов для <a href="http://blog.sjinks.pro/tag/yii/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Yii">Yii</a></em></h2>
<p>Одной из вещей, которых мне очень не хватало при разработке сайтов на Yii — нормального отображения всех запросов к базе данных, что дало бы возможность их последующего анализа.</p>
<p>Ситуацию частично исправило расширение под названием <a href="http://rmcreative.ru/blog/post/yii-db-profiler">Yii DB profiler</a>. Но остались некоторые неудобства:</p>
<ul>
<li>Отображение запросов в порядке убывания времени выполнения — в принципе, это дело вкуса: при таком порядке сразу видны проблемные запросы. С другой стороны, лично мне более привычен хронологический порядок — так чётче прослеживается логика работы;</li>
<li>Prepared statements. Это просто здорово, но если повторять запрос в phpMyAdmin (например, если интересует план выполнения запроса), бывает очень муторно заменять все связанные значения. Например, для запросов вида
          
<div class="codebox">
    <div class="the_code" style="" id="p94729">
        <div class="code mysql" id="p947code29">
<span class="kw1">SELECT</span> <span class="st0">'t'</span>.<span class="st0">&quot;object<span class="es1">_</span>id&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c0&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;ymd&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c1&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;black&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c2&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;brown&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c3&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;yellow&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c4&quot;</span><span class="sy2">,</span> <br />
<span class="st0">'t'</span>.<span class="st0">&quot;neutral&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c5&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;white&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c6&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;unknown&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c7&quot;</span><span class="sy2">,</span> <span class="st0">'t'</span>.<span class="st0">&quot;error&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t0<span class="es1">_</span>c8&quot;</span><span class="sy2">,</span> <span class="st0">'object'</span>.<span class="st0">&quot;object&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t1<span class="es1">_</span>c2&quot;</span><span class="sy2">,</span><br />
<span class="st0">'object'</span>.<span class="st0">&quot;id&quot;</span> <span class="kw1">AS</span> <span class="st0">&quot;t1<span class="es1">_</span>c0&quot;</span><br />
<span class="kw1">FROM</span> <span class="st0">'dnsbl<span class="es1">_</span>summary'</span> <span class="st0">'t'</span> <br />
<span class="kw13">LEFT</span> <span class="kw1">OUTER</span> <span class="kw1">JOIN</span> <span class="st0">'objects'</span> <span class="st0">'object'</span> <span class="kw1">ON</span> <span class="br0">&#40;</span><span class="st0">'t'</span>.<span class="st0">&quot;object<span class="es1">_</span>id&quot;</span><span class="sy1">=</span><span class="st0">'object'</span>.<span class="st0">&quot;id&quot;</span><span class="br0">&#41;</span> <br />
<span class="kw1">WHERE</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>black <span class="sy1">&gt;</span> 0<span class="br0">&#41;</span> <span class="kw10">OR</span> <span class="br0">&#40;</span>brown <span class="sy1">&gt;</span> 0<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <br />
<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>ymd<span class="sy1">=</span>:ycp0<span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>black<span class="sy1">&gt;</span>:ycp1<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>brown<span class="sy1">=</span>:ycp2<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>yellow<span class="sy1">=</span>:ycp3<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <br />
<span class="br0">&#40;</span>neutral<span class="sy1">&gt;</span>:ycp4<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>white<span class="sy1">&gt;</span>:ycp5<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>unknown<span class="sy1">=</span>:ycp6<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>black<span class="sy1">&gt;</span>:ycp7<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <br />
<span class="br0">&#40;</span>error<span class="sy1">=</span>:ycp8<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw10">AND</span> <span class="br0">&#40;</span>object.enabled <span class="sy1">=</span> 1<span class="br0">&#41;</span><br />
<span class="kw1">LIMIT</span> <span class="nu0">50</span>
        </div>
    </div>
</div>

заменять все <code>:ycpXXX</code> на их значения немного муторно. В общем случае здесь вряд ли можно что-то сделать — заполнители параметров могут быть любыми (и даже позиционными), поэтому тупое использование <code>str_replace</code> может наделать делов.
</li>
</ul>
<p>Лично мне список запросов нужен обычно только для двух вещей:</p>
<ol>
<li>Оценка работы механизмов кэширования;</li>
<li>Оценка плана выполнения запроса, составленная оптимизатором.</li>
</ol>
<p>Первое обычно не критично (зачастую достаточно посмотреть на количество запросов), а вот второе позволяет выявить многие будущие проблемы с производительностью заранее.</p>
<p>В результате, взяв за основу <a href="http://blog.sjinks.pro/tag/plugin/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  плагин">плагин</a> <a href="http://rmcreative.ru/">Александра</a>, я портировал <a href="http://blog.sjinks.pro/tag/sqlmon/">SQLMon</a> на Yii.<br />
<span id="more-947"></span></p>
<p>В результате получилось расширение, позволяющее получать планы выполнения запросов в реальном времени.</p>
<p>Поддерживаются MySQL и SQLite, в планах поддержка PgSQL (там не всё просто, ибо Postgres <em>выполняет</em> запрос, что может привести к интересным последствиям при использовании <code>INSERT</code>/<code>UPDATE</code>/<code>DELETE</code>; как следствие, придётся использовать <a href="http://blog.sjinks.pro/php/932-pdo-nested-transactions/">вложенные транзакции</a>).</p>
<p>Вывод результатов осуществляется либо при помощи виджета:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94730">
        <div class="code php" id="p947code30">
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">widget</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'ext.sqlmon.components.SQLMon'</span><br />
&nbsp; &nbsp; <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'explain'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать план выполнения запроса</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'backtrace'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать трассу вызовов</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dsn'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать DSN соединения (может быть полезно при использовании нескольких БД)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cssFile'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">null</span><span class="sy0">,</span> <span class="co1">// Эстеты могут задать свой файл стилей </span><br />
&nbsp; &nbsp; <span class="br0">&#41;</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Либо при помощи Log Route:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94731">
        <div class="code php" id="p947code31">
<span class="kw1">return</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'components'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'log'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'routes'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'class'</span> <span class="sy0">=&gt;</span> <span class="st_h">'ext.sqlmon.components.SQLMonLogRoute'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'showExplain'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать план выполнения</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'showDsn'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать DSN соединения</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'showBacktrace'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать трассу вызовов</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'class'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="st_h">'ext.sqlmon.components.SQLMonFileLogRoute'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'logFile'</span> <span class="sy0">=&gt;</span> <span class="st_h">'sqlmon.log'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'showExplain'</span> &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать план выполнения</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'showDsn'</span> &nbsp; &nbsp; &nbsp; <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать DSN соединения</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'showBacktrace'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="co1">// Показывать трассу вызовов</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p><code>SQLMonLogRoute</code> наследуется от <code>CWebLogRoute</code>, но, как и <code>CProfileLogRoute</code>, отказывается выдавать данные для AJAX-запросов.</p>
<p><code>SQLMonFileLogRoute</code> наследуется от <code>CFileLogRoute</code> и, как следствие, воспринимает все параметры конфигурации последнего.</p>
<p>Для того, чтобы протоколирование нормально работало, сообщения от <a href="http://blog.sjinks.pro/tag/sqlmon/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SQLMon">SQLMon</a> попадают в общий протокол и, как следствие, видны при использовании <code>CWebLogRoute</code> (в этом случае выдаётся минимум информации).</p>
<p>Результаты работы выглядят примерно так (пример приведён для SQLite):</p>
<p><a href="http://static.sjinks.info/wp-content/uploads/2011/11/sqlmon-yii.png"><img src="http://static.sjinks.info/wp-content/uploads/2011/11/sqlmon-yii-300x283.png" alt="Пример выдачи SQLMon" title="SQLMon в Yii" width="300" height="283" class="alignnone size-medium wp-image-948" /></a></p>
<p>Реализовано всё через собственный класс PDO, поэтому для использования SQLMon нужно в файл конфигурации добавить такие строки:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94732">
        <div class="code php" id="p947code32">
<br />
<span class="kw1">return</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st_h">'import'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ext.sqlmon.components.*'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
<br />
&nbsp; &nbsp; <span class="st_h">'components'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'db'</span> <span class="sy0">=&gt;</span> <span class="kw1">array</span><span class="br0">&#40;</span><br />
<span class="co1">// ...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdoClass'</span> <span class="sy0">=&gt;</span> <span class="st_h">'SQLMonPDO'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Реализация просмотра выполнения плана выполнения запроса осуществляется при помощи класса-наследника от <code>PDOStatement</code> и переопределения метода <code>PDO::prepare()</code>.</p>
<p>Планы на будущее:</p>
<ul>
<li>поддержка PostgreSQL;</li>
<li>возможность расширения классов <code>SQLMonPDO</code> и <code>SQLMonPDOStatement</code> (возможно, придётся позаимствовать некоторые идеи из Kohana);</li>
<li>наследование <code>SQLMon_Explainer_Base</code> от <code>CComponent</code>, что даст дополнительные плюшки для расширяемости;</li>
<li>более красивая реализация функции SQLMon::arr2pre(), что позволит рисовать красивые ASCII-таблички;</li>
<li>возможная поддержка FireBug;</li>
<li>протоколирование в <a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a>-файл;</li>
<li>информация профайлера MySQL (нужность пока под большим вопросом);</li>
<li>рефакторинг, написание документации</li>
</ul>
<p><strong><a href='http://static.sjinks.info/wp-content/uploads/2011/11/sqlmon-0.1.zip'>SQLMon 0.1 for Yii</a></strong> — скачать бесплатно без регистрации без смс <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/php/yii/947-sqlmon-for-yii/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/php/yii/947-sqlmon-for-yii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML Parser для Qt</title>
		<link>http://blog.sjinks.pro/c-cpp/qt/942-html-parser-qt/</link>
		<comments>http://blog.sjinks.pro/c-cpp/qt/942-html-parser-qt/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 08:03:07 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Qt]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=942</guid>
		<description><![CDATA[Использование libxml2 для разбора документов HTML в Qt XML — это, конечно, хорошо, но очень часто требуется разбирать документы HTML, которые могут и не быть валидными. В Qt есть множество классов для работы с XML, но они не подходят для HTML, так как ошибки в HTML для них фатальны. Ниже приведён вариант парсера для HTML, основанный на [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/c-cpp/qt/942-html-parser-qt/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Использование libxml2 для разбора документов <a href="http://blog.sjinks.pro/tag/html/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTML">HTML</a> в <a href="http://blog.sjinks.pro/tag/qt/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Qt">Qt</a></em></h2>
<p><a href="http://blog.sjinks.pro/tag/xml/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XML">XML</a> — это, конечно, хорошо, но очень часто требуется разбирать документы HTML, которые могут и не быть валидными.</p>
<p>В Qt есть множество классов для работы с XML, но они не подходят для HTML, так как ошибки в HTML для них фатальны.</p>
<p>Ниже приведён вариант парсера для HTML, основанный на библиотеке libxml2.<span id="more-942"></span></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94237">
        <div class="code cpp-qt" id="p942code37">
<span class="co2">#ifndef LIBXML2READER_H</span><br />
<span class="co2">#define LIBXML2READER_H</span><br />
<br />
<span class="co2">#include &lt;QtXml/QXmlReader&gt;</span><br />
<span class="co2">#include &lt;libxml/xmlstring.h&gt;</span><br />
<br />
<span class="kw2">class</span> LibXml2ReaderPrivate<span class="sy0">;</span><br />
<br />
<span class="kw2">class</span> LibXml2Reader <span class="sy0">:</span> <span class="kw2">public</span> <span class="kw5">QXmlReader</span> <span class="br0">&#123;</span><br />
<span class="kw2">public</span><span class="sy0">:</span><br />
&nbsp; &nbsp; LibXml2Reader<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> ~LibXml2Reader<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">bool</span> feature<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span> name<span class="sy0">,</span> <span class="kw4">bool</span><span class="sy0">*</span> ok <span class="sy0">=</span> 0<span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setFeature<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span> name<span class="sy0">,</span> <span class="kw4">bool</span> value<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">bool</span> hasFeature<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span> name<span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span><span class="sy0">*</span> property<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span> name<span class="sy0">,</span> <span class="kw4">bool</span><span class="sy0">*</span> ok <span class="sy0">=</span> 0<span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setProperty<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span> name<span class="sy0">,</span> <span class="kw4">void</span><span class="sy0">*</span> value<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">bool</span> hasProperty<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span> name<span class="br0">&#41;</span> const<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setEntityResolver<span class="br0">&#40;</span><span class="kw5">QXmlEntityResolver</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw5">QXmlEntityResolver</span><span class="sy0">*</span> entityResolver<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setDTDHandler<span class="br0">&#40;</span><span class="kw5">QXmlDTDHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw5">QXmlDTDHandler</span><span class="sy0">*</span> DTDHandler<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setContentHandler<span class="br0">&#40;</span><span class="kw5">QXmlContentHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw5">QXmlContentHandler</span><span class="sy0">*</span> contentHandler<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setErrorHandler<span class="br0">&#40;</span><span class="kw5">QXmlErrorHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw5">QXmlErrorHandler</span><span class="sy0">*</span> errorHandler<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setLexicalHandler<span class="br0">&#40;</span><span class="kw5">QXmlLexicalHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw5">QXmlLexicalHandler</span><span class="sy0">*</span> lexicalHandler<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">void</span> setDeclHandler<span class="br0">&#40;</span><span class="kw5">QXmlDeclHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw5">QXmlDeclHandler</span><span class="sy0">*</span> declHandler<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">bool</span> parse<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QXmlInputSource</span><span class="sy0">&amp;</span> input<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">bool</span> parse<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QXmlInputSource</span><span class="sy0">*</span> input<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<br />
<span class="kw2">private</span><span class="sy0">:</span><br />
&nbsp; &nbsp; Q_DISABLE_COPY<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><br />
&nbsp; &nbsp; Q_DECLARE_PRIVATE<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><br />
&nbsp; &nbsp; QScopedPointer<span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">&gt;</span> d_ptr<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">friend</span> <span class="kw2">class</span> LibXml2ReaderLocator<span class="sy0">;</span><br />
<span class="br0">&#125;</span><span class="sy0">;</span><br />
<br />
<span class="co2">#endif // LIBXML2READER_H</span>
        </div>
    </div>
</div>

          
<div class="codebox">
    <div class="the_code" style="" id="p94238">
        <div class="code cpp-qt" id="p942code38">
<span class="co2">#include &quot;libxml2reader.h&quot;</span><br />
<span class="co2">#include &lt;cstring&gt;</span><br />
<span class="co2">#include &lt;libxml/tree.h&gt;</span><br />
<span class="co2">#include &lt;libxml/parser.h&gt;</span><br />
<span class="co2">#include &lt;libxml/HTMLparser.h&gt;</span><br />
<br />
<span class="kw2">class</span> LibXml2ReaderLocator <span class="sy0">:</span> <span class="kw2">public</span> <span class="kw5">QXmlLocator</span> <span class="br0">&#123;</span><br />
<span class="kw2">public</span><span class="sy0">:</span><br />
&nbsp; &nbsp; LibXml2ReaderLocator<span class="br0">&#40;</span>LibXml2Reader<span class="sy0">*</span> r<span class="br0">&#41;</span> <span class="sy0">:</span> reader<span class="br0">&#40;</span>r<span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">int</span> columnNumber<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">virtual</span> <span class="kw4">int</span> lineNumber<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> const<span class="sy0">;</span><br />
<span class="kw2">private</span><span class="sy0">:</span><br />
&nbsp; &nbsp; LibXml2Reader<span class="sy0">*</span> reader<span class="sy0">;</span><br />
<span class="br0">&#125;</span><span class="sy0">;</span><br />
<br />
<span class="kw2">class</span> LibXml2ReaderPrivate <span class="br0">&#123;</span><br />
<span class="kw2">public</span><span class="sy0">:</span><br />
&nbsp; &nbsp; ~LibXml2ReaderPrivate<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
<span class="kw2">private</span><span class="sy0">:</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="br0">&#40;</span>LibXml2Reader<span class="sy0">*</span> reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> startDocument<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> endDocument<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> startElement<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> name<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">**</span> attrs<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> endElement<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> name<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> comment<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> value<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> cdataBlock<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> value<span class="sy0">,</span> <span class="kw4">int</span> len<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> processingInstruction<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> target<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> data<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> characters<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> ch<span class="sy0">,</span> <span class="kw4">int</span> len<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> ignorableWhitespace<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> ch<span class="sy0">,</span> <span class="kw4">int</span> len<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">void</span> internalSubset<span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> name<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> publicId<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> systemId<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw4">void</span> parse<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QXmlInputSource</span><span class="sy0">*</span> input<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; QScopedPointer<span class="sy0">&lt;</span>LibXml2ReaderLocator<span class="sy0">&gt;</span> locator<span class="sy0">;</span><br />
&nbsp; &nbsp; Q_DECLARE_PUBLIC<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><br />
&nbsp; &nbsp; LibXml2Reader<span class="sy0">*</span> q_ptr<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw5">QXmlEntityResolver</span><span class="sy0">*</span> entityresolver<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QXmlDTDHandler</span><span class="sy0">*</span> &nbsp; &nbsp; dtdhandler<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QXmlContentHandler</span><span class="sy0">*</span> contenthandler<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QXmlErrorHandler</span><span class="sy0">*</span> &nbsp; errorhandler<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QXmlLexicalHandler</span><span class="sy0">*</span> lexicalhandler<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QXmlDeclHandler</span><span class="sy0">*</span> &nbsp; &nbsp;declhandler<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; xmlParserCtxt<span class="sy0">*</span> context<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">friend</span> <span class="kw2">class</span> LibXml2ReaderLocator<span class="sy0">;</span><br />
<span class="br0">&#125;</span><span class="sy0">;</span><br />
<br />
LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">LibXml2ReaderPrivate</span><span class="br0">&#40;</span>LibXml2Reader<span class="sy0">*</span> reader<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="sy0">:</span> q_ptr<span class="br0">&#40;</span>reader<span class="br0">&#41;</span><span class="sy0">,</span> entityresolver<span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">,</span> dtdhandler<span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">,</span> contenthandler<span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">,</span> errorhandler<span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">,</span> lexicalhandler<span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">,</span> declhandler<span class="br0">&#40;</span>0<span class="br0">&#41;</span><span class="sy0">,</span> context<span class="br0">&#40;</span>0<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; this<span class="sy0">-&gt;</span><span class="me3">locator</span>.<span class="me1">reset</span><span class="br0">&#40;</span><span class="kw1">new</span> LibXml2ReaderLocator<span class="br0">&#40;</span>reader<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">parse</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QXmlInputSource</span><span class="sy0">*</span> input<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; htmlSAXHandler handler<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QByteArray</span> arr <span class="sy0">=</span> input<span class="sy0">-&gt;</span><span class="me3">data</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">toLocal8Bit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*</span> data <span class="sy0">=</span> arr.<span class="me1">data</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; std<span class="sy0">::</span><span class="kw3">memset</span><span class="br0">&#40;</span><span class="sy0">&amp;</span>handler<span class="sy0">,</span> 0<span class="sy0">,</span> <span class="kw3">sizeof</span><span class="br0">&#40;</span>handler<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">startDocument</span> &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">startDocument</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">endDocument</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">endDocument</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">startElement</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">startElement</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">endElement</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">endElement</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">comment</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">comment</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">cdataBlock</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">cdataBlock</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">processingInstruction</span> <span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">processingInstruction</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">characters</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">characters</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">ignorableWhitespace</span> &nbsp; <span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">ignorableWhitespace</span><span class="sy0">;</span><br />
&nbsp; &nbsp; handler.<span class="me1">internalSubset</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">=</span> <span class="sy0">&amp;</span>LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">internalSubset</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; this<span class="sy0">-&gt;</span><span class="me3">context</span> <span class="sy0">=</span> htmlCreatePushParserCtxt<span class="br0">&#40;</span><span class="sy0">&amp;</span>handler<span class="sy0">,</span> <span class="kw1">this</span><span class="sy0">,</span> data<span class="sy0">,</span> xmlStrlen<span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> xmlChar<span class="sy0">*&gt;</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="sy0">,</span> XML_CHAR_ENCODING_NONE<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; htmlParseChunk<span class="br0">&#40;</span>this<span class="sy0">-&gt;</span><span class="me3">context</span><span class="sy0">,</span> <span class="kw2">NULL</span><span class="sy0">,</span> 0<span class="sy0">,</span> 1<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; htmlFreeParserCtxt<span class="br0">&#40;</span>this<span class="sy0">-&gt;</span><span class="me3">context</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; xmlCleanupParser<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">startDocument</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">startDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">endDocument</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">endDocument</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">startElement</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> name<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">**</span> attrs<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QXmlAttributes</span> a<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>attrs<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>attrs<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*</span> name &nbsp;<span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>attrs<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*</span> value <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>attrs<span class="br0">&#91;</span>i<span class="sy0">+</span>1<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i <span class="sy0">+=</span> <span class="nu0">2</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a.<span class="me1">append</span><span class="br0">&#40;</span>name<span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="sy0">,</span> value ? value <span class="sy0">:</span> name<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QString</span> uri <span class="sy0">=</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QString</span> localName <span class="sy0">=</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QString</span> qName <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">startElement</span><span class="br0">&#40;</span>uri<span class="sy0">,</span> localName<span class="sy0">,</span> qName<span class="sy0">,</span> a<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">endElement</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> name<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">endElement</span><span class="br0">&#40;</span><span class="kw5">QString</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="kw5">QString</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="kw5">QString</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">comment</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> value<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="sy0">-&gt;</span><span class="me3">comment</span><span class="br0">&#40;</span><span class="kw5">QString</span><span class="sy0">::</span><span class="me2">fromLocal8Bit</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">cdataBlock</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> value<span class="sy0">,</span> <span class="kw4">int</span> len<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="sy0">-&gt;</span><span class="me3">startCDATA</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QByteArray</span> arr<span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span><span class="sy0">,</span> len<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">characters</span><span class="br0">&#40;</span>arr<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="sy0">-&gt;</span><span class="me3">endCDATA</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">processingInstruction</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> target<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> data<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">processingInstruction</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>target<span class="br0">&#41;</span><span class="sy0">,</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">characters</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> ch<span class="sy0">,</span> <span class="kw4">int</span> len<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">characters</span><span class="br0">&#40;</span><span class="kw5">QString</span><span class="sy0">::</span><span class="me2">fromLocal8Bit</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>ch<span class="br0">&#41;</span><span class="sy0">,</span> len<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">ignorableWhitespace</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> ch<span class="sy0">,</span> <span class="kw4">int</span> len<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">ignorableWhitespace</span><span class="br0">&#40;</span><span class="kw5">QString</span><span class="sy0">::</span><span class="me2">fromLocal8Bit</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>ch<span class="br0">&#41;</span><span class="sy0">,</span> len<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2ReaderPrivate<span class="sy0">::</span><span class="me2">internalSubset</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span> c<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> name<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> publicId<span class="sy0">,</span> <span class="kw4">const</span> xmlChar<span class="sy0">*</span> systemId<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; LibXml2ReaderPrivate<span class="sy0">*</span> r <span class="sy0">=</span> <span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span>LibXml2ReaderPrivate<span class="sy0">*&gt;</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QString</span> n<span class="br0">&#40;</span><span class="kw5">QString</span><span class="sy0">::</span><span class="me2">fromLocal8Bit</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QString</span> p<span class="br0">&#40;</span><span class="kw5">QString</span><span class="sy0">::</span><span class="me2">fromLocal8Bit</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>publicId<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw5">QString</span> s<span class="br0">&#40;</span><span class="kw5">QString</span><span class="sy0">::</span><span class="me2">fromLocal8Bit</span><span class="br0">&#40;</span><span class="kw2">reinterpret_cast</span><span class="sy0">&lt;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy0">*&gt;</span><span class="br0">&#40;</span>systemId<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="sy0">-&gt;</span><span class="me3">startDTD</span><span class="br0">&#40;</span>n<span class="sy0">,</span> p<span class="sy0">,</span> s<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; r<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="sy0">-&gt;</span><span class="me3">endDTD</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
<span class="br0">&#125;</span><br />
<br />
LibXml2Reader<span class="sy0">::</span><span class="me2">LibXml2Reader</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="sy0">:</span> d_ptr<span class="br0">&#40;</span><span class="kw1">new</span> LibXml2ReaderPrivate<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="br0">&#125;</span><br />
<br />
LibXml2Reader<span class="sy0">::</span><span class="me2">~LibXml2Reader</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">bool</span> LibXml2Reader<span class="sy0">::</span><span class="me2">feature</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;,</span> <span class="kw4">bool</span><span class="sy0">*</span> ok<span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>ok<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">*</span>ok <span class="sy0">=</span> false<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> false<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setFeature</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;,</span> <span class="kw4">bool</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">bool</span> LibXml2Reader<span class="sy0">::</span><span class="me2">hasFeature</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> false<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">property</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;,</span> <span class="kw4">bool</span><span class="sy0">*</span> ok<span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>ok<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">*</span>ok <span class="sy0">=</span> false<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setProperty</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;,</span> <span class="kw4">void</span><span class="sy0">*</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">bool</span> LibXml2Reader<span class="sy0">::</span><span class="me2">hasProperty</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QString</span><span class="sy0">&amp;</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> false<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setEntityResolver</span><span class="br0">&#40;</span><span class="kw5">QXmlEntityResolver</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">entityresolver</span> <span class="sy0">=</span> handler<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw5">QXmlEntityResolver</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">entityResolver</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> LibXml2ReaderPrivate<span class="sy0">*</span> d <span class="sy0">=</span> this<span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="sy0">-&gt;</span><span class="me3">entityresolver</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setDTDHandler</span><span class="br0">&#40;</span><span class="kw5">QXmlDTDHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">dtdhandler</span> <span class="sy0">=</span> handler<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw5">QXmlDTDHandler</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">DTDHandler</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> LibXml2ReaderPrivate<span class="sy0">*</span> d <span class="sy0">=</span> this<span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="sy0">-&gt;</span><span class="me3">dtdhandler</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setContentHandler</span><span class="br0">&#40;</span><span class="kw5">QXmlContentHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">contenthandler</span> <span class="sy0">=</span> handler<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw5">QXmlContentHandler</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">contentHandler</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> LibXml2ReaderPrivate<span class="sy0">*</span> d <span class="sy0">=</span> this<span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setErrorHandler</span><span class="br0">&#40;</span><span class="kw5">QXmlErrorHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">errorhandler</span> <span class="sy0">=</span> handler<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw5">QXmlErrorHandler</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">errorHandler</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> LibXml2ReaderPrivate<span class="sy0">*</span> d <span class="sy0">=</span> this<span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="sy0">-&gt;</span><span class="me3">errorhandler</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setLexicalHandler</span><span class="br0">&#40;</span><span class="kw5">QXmlLexicalHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span> <span class="sy0">=</span> handler<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw5">QXmlLexicalHandler</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">lexicalHandler</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> LibXml2ReaderPrivate<span class="sy0">*</span> d <span class="sy0">=</span> this<span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="sy0">-&gt;</span><span class="me3">lexicalhandler</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> LibXml2Reader<span class="sy0">::</span><span class="me2">setDeclHandler</span><span class="br0">&#40;</span><span class="kw5">QXmlDeclHandler</span><span class="sy0">*</span> handler<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">declhandler</span> <span class="sy0">=</span> handler<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw5">QXmlDeclHandler</span><span class="sy0">*</span> LibXml2Reader<span class="sy0">::</span><span class="me2">declHandler</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">const</span> LibXml2ReaderPrivate<span class="sy0">*</span> d <span class="sy0">=</span> this<span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="sy0">-&gt;</span><span class="me3">declhandler</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">bool</span> LibXml2Reader<span class="sy0">::</span><span class="me2">parse</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QXmlInputSource</span><span class="sy0">&amp;</span> input<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> this<span class="sy0">-&gt;</span><span class="me3">parse</span><span class="br0">&#40;</span><span class="sy0">&amp;</span>input<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">bool</span> LibXml2Reader<span class="sy0">::</span><span class="me2">parse</span><span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw5">QXmlInputSource</span><span class="sy0">*</span> input<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; Q_D<span class="br0">&#40;</span>LibXml2Reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>d<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">contenthandler</span><span class="sy0">-&gt;</span><span class="me3">setDocumentLocator</span><span class="br0">&#40;</span>d<span class="sy0">-&gt;</span><span class="me3">locator</span>.<span class="me1">data</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; d<span class="sy0">-&gt;</span><span class="me3">parse</span><span class="br0">&#40;</span>input<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> true<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">int</span> LibXml2ReaderLocator<span class="sy0">::</span><span class="me2">columnNumber</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> this<span class="sy0">-&gt;</span><span class="me3">reader</span><span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me3">context</span><span class="sy0">-&gt;</span><span class="me3">input</span><span class="sy0">-&gt;</span><span class="me3">col</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">int</span> LibXml2ReaderLocator<span class="sy0">::</span><span class="me2">lineNumber</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> <span class="kw4">const</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> this<span class="sy0">-&gt;</span><span class="me3">reader</span><span class="sy0">-&gt;</span><span class="me3">d_func</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me3">context</span><span class="sy0">-&gt;</span><span class="me3">input</span><span class="sy0">-&gt;</span><span class="me3">line</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span>
        </div>
    </div>
</div>

<p>Использование:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94239">
        <div class="code cpp-qt" id="p942code39">
&nbsp; &nbsp; <span class="kw5">QByteArray</span> data<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QXmlInputSource</span> src<span class="sy0">;</span><br />
&nbsp; &nbsp; LibXml2Reader reader<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw5">QDomDocument</span> doc<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="coMULTI">/* здесь читаем данные в data */</span><br />
<br />
&nbsp; &nbsp; src.<span class="me1">setData</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; doc.<span class="me1">setContent</span><span class="br0">&#40;</span><span class="sy0">&amp;</span>src<span class="sy0">,</span> <span class="sy0">&amp;</span>reader<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="coMULTI">/* doc будет содержать дерево DOM, построенное из документа HTML */</span>
        </div>
    </div>
</div>

<p>В файл проекта нужно будет добавить две строки:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94240">
        <div class="code text" id="p942code40">
INCLUDEPATH += /usr/include/libxml2<br />
LIBS &nbsp; &nbsp; &nbsp; &nbsp;+= -lxml2
        </div>
    </div>
</div>

<p>В <code>INCLUDEPATH</code> помещается путь к заголовочным файлам libxml2, в <code>LIBS</code> — опции компилятора для подключения библиотеки libxml2.</p>
<p>Скачать:</p>
<ul>
<li><a href='http://static.sjinks.info/wp-content/uploads/2011/09/libxml2reader.h'>libxml2reader.h</a></li>
<li><a href='http://static.sjinks.info/wp-content/uploads/2011/09/libxml2reader.cpp'>libxml2reader.cpp</a></li>
</ul>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/c-cpp/qt/942-html-parser-qt/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/c-cpp/qt/942-html-parser-qt/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Linux, консоль и деванагари</title>
		<link>http://blog.sjinks.pro/uncategorized/941-linux-console-devanagari/</link>
		<comments>http://blog.sjinks.pro/uncategorized/941-linux-console-devanagari/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 15:51:08 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Всё подряд]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[ошибка]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=941</guid>
		<description><![CDATA[В то время, когда наши корабли бороздят просторы Вселенной… Недавно отлаживал небольшой скрипт, транслитерирующий текст, записанный в системе IAST или ITRANS, на деванагари. Так как на домашней машине стоит Linux, то логично, что скрипт отлаживался в Linux — в терминале. И тут меня ожидал огромный сюрприз… В качестве теста брался отрывок из Брихадараньяка-упанишады, выглядящий следующим образом (в [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/uncategorized/941-linux-console-devanagari/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>В то время, когда наши корабли бороздят просторы Вселенной…</em></h2>
<p>Недавно отлаживал небольшой скрипт, транслитерирующий текст, записанный в системе <abbr title="International Alphabet of Sanskrit Transliteration">IAST</abbr> или ITRANS, на деванагари. Так как на домашней машине стоит <a href="http://blog.sjinks.pro/tag/linux/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Linux">Linux</a>, то логично, что скрипт отлаживался в <a href="http://blog.sjinks.pro/tag/linux/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Linux">Linux</a> — в терминале.</p>
<p>И тут меня ожидал огромный сюрприз…<span id="more-941"></span></p>
<p>В качестве теста брался отрывок из <a href="http://ru.wikipedia.org/wiki/%D0%91%D1%80%D0%B8%D1%85%D0%B0%D0%B4%D0%B0%D1%80%D0%B0%D0%BD%D1%8C%D1%8F%D0%BA%D0%B0-%D1%83%D0%BF%D0%B0%D0%BD%D0%B8%D1%88%D0%B0%D0%B4%D0%B0">Брихадараньяка-упанишады</a>, выглядящий следующим образом (в IAST):</p>
<pre style="font-size: 15px">
pūrṇamadaḥ pūrṇamidam pūrṇāt pūrṇamudacyate
pūrṇasya pūrṇamādāya pūrṇamevāvaśiṣyate
</pre>
<p>По-русски это примерно так:</p>
<blockquote>
    То — бесконечность, и это — бесконечность. Бесконечность исходит из бесконечности,<br />
    Обретая бесконечность бесконечного, она остается лишь бесконечностью.<br />
</blockquote>
<p>На деванагари результат должен выглядеть так:</p>
<pre style="font-size: 15px">
पूर्णमदः पूर्णमिदम् पूर्णात् पूर्णमुदच्यते
पूर्णस्य पूर्णमादाय पूर्णमेवावशिष्यते
</pre>
<p>Как оказалось, если взять результат, сохранить в файл, а потом вывести на экран (например, командой <code>cat</code>), то получится полный бред:</p>
<pre style="font-size: 15px">
परणमदः परणमिदम परणात परणमदचयत
परणसय परणमादाय परणमवावशिषयत
</pre>
<p>В IAST это будет</p>
<pre style="font-size: 15px">
paraṇamadaḥ paraṇamidama paraṇāta paraṇamadacayata
paraṇasaya paraṇamādāya paraṇamavāvaśiṣayata
</pre>
<p>Что в корне отличается от того, что было в оригинале.</p>
<p>Тут нужно сделать парочку лирических отступлений: </p>
<ol>
<li>В деванагари есть такая особенность, что символы согласных звуков «по умолчанию» содержат гласный <code>a</code>. То есть <code>क</code> — это <code>ka</code>, а не <code>k</code>. Отсутствие этого <code>a</code> обозначается специальным подстрочным символом (символ <dfn>вирама</dfn> или <dfn>халант</dfn>). Например, комбинация, соответствующая звуку <code>k</code> будет записываться как <code>क्</code>.</li>
<li>Вторая особенность — гласные звуки имеют два варианта написания: гласный после гласной (или сам по себе) и после согласной записываются по-разному (во втором случае обычно используются диакритические знаки). Например, u — ku: उ — कु. </li>
</ol>
<p>Возвращаясь к примеру: если сравнить первое слово того, что должно быть и того, что получилось:</p>
<pre style="font-size: 15px">
पूर्णमदः — पू र् ण म दः — pū r ṇa ma daḥ
परणमदः — प र ण म दः — pa ra ṇa ma daḥ
</pre>
<p>Можно заметить одну особенность: терминал «обрезает» надстрочные и подстрочные символы (причём обрезает наглухо — при копировании копируется не исходный вариант, а обрезанный). Например, в पू подстрочный символ обозначает гласный ū (лирическое отступление №2), если подстрочный символ «обрезать», то останется просто प, который в соответствии с лирическим отступлением №1 будет pa.</p>
<pre style="font-size: 15px">
क	ka	=&gt;	क	ka
का	kā	=&gt;	का	kā
कि	ki	=&gt;	कि	ki
की	kī	=&gt;	की	kī
कु	ku	=&gt;	क	ka
कू	kū	=&gt;	क	ka
कृ	kṛ	=&gt;	क	ka
कॄ	kṝ	=&gt;	क	ka
कॢ	kḷ	=&gt;	क	ka
कॣ	kḹ	=&gt;	क	ka
के	ke	=&gt;	क	ka
कै	kai	=&gt;	क	ka
को	ko	=&gt;	को	ko
कौ	kau	=&gt;	कौ	kau
कँ	kam̐	=&gt;	क	ka
कं	kaṁ	=&gt;	क	ka
कः	kaḥ	=&gt;	कः	kaḥ
क्	k	=&gt;	क	ka
</pre>
<p>Видим, что в терминале очень не везёт гласным u, ū, ṛ, ṝ, ḷ, ḹ, e и дифтонгу ai — они тихо превращаются в <code>a</code>. Вирама также погибает смертью храбрых, в результате чего к согласным добавляется звук <code>a</code>. Анусвара (ṃ) и чандрабинду (m̐) обрезаются.</p>
<p>Какой можно сделать вывод? Индийские тексты в терминале нечитаемы. Вообще. И это в век повсеместного <a href="http://blog.sjinks.pro/tag/unicode/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Unicode">Unicode</a> и UTF-8! Честно говоря, в Linux достаточно проблем с <a href="http://blog.sjinks.pro/tag/unicode/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Unicode">Unicode</a>: <a href="https://bugs.launchpad.net/ubuntu/+source/apport/+bug/349081">apport не воспринимает русские символы</a>, <a href="https://bugs.launchpad.net/command-not-found/+bug/841914">command-not-found вылетает с ошибкой на не английских символах</a>, <a href="https://bugs.launchpad.net/inkscape/+bug/421199">Inkscape некорректно отображает деванагари</a>, те же проблемы в <a href="https://bugs.launchpad.net/ubuntu/+source/libreoffice/+bug/806211">LibreOffice</a>… Грустно…</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/uncategorized/941-linux-console-devanagari/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/uncategorized/941-linux-console-devanagari/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Установка Skype на Ubuntu Oneiric Ocelot AMD64</title>
		<link>http://blog.sjinks.pro/linux/940-skype-ubuntu-oneiric-ocelot-amd64/</link>
		<comments>http://blog.sjinks.pro/linux/940-skype-ubuntu-oneiric-ocelot-amd64/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 01:48:21 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[64 bit]]></category>
		<category><![CDATA[Oneiric Ocelot]]></category>
		<category><![CDATA[Skype]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=940</guid>
		<description><![CDATA[И так идут за годом год… Прошло два года… Единственное изменение — в текущей бете Oneiric Ocelot в репозитории partner Skype нет. Вообще. Skype из Natty Narwhal не прижился: проблема с зависимостями: ia32-libs зависит от lib32v4l-0, который зависит от libv4l-0 версии 0.8.3-2, при том, что в репозитории есть только 0.8.5-3ubuntu1. Понятно, что проблему с зависимостями в конце концов исправят, [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/linux/940-skype-ubuntu-oneiric-ocelot-amd64/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>И так идут за годом год…</em></h2>
<p><a href="http://blog.sjinks.pro/linux/614-bringing-skype-back-in-ubuntu-karmic-koala-64-bit/">Прошло два года</a>… Единственное изменение — в текущей бете <a href="http://blog.sjinks.pro/tag/oneiric-ocelot/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Oneiric Ocelot">Oneiric Ocelot</a> в репозитории partner <a href="http://blog.sjinks.pro/tag/skype/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Skype">Skype</a> нет. Вообще.</p>
<p>Skype из <a href="http://blog.sjinks.pro/tag/natty-narwhal/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Natty Narwhal">Natty Narwhal</a> не прижился: проблема с зависимостями: <code>ia32-libs</code> зависит от <code>lib32v4l-0</code>, который зависит от <code>libv4l-0</code> версии 0.8.3-2, при том, что в репозитории есть только 0.8.5-3<a href="http://blog.sjinks.pro/tag/ubuntu/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Ubuntu">ubuntu</a>1. Понятно, что проблему с зависимостями в конце концов исправят, но без Skype плохо.<span id="more-940"></span></p>
<p>Решение пока такое:</p>
<ol>
<li>Если <a href="https://lists.ubuntu.com/archives/ubuntu-devel-announce/2011-August/000886.html">поддержка multiarch</a> не включена, включить:
          
<div class="codebox">
    <div class="the_code" style="" id="p94046">
        <div class="code bash" id="p940code46">
<span class="kw3">echo</span> foreign-architecture i386 <span class="sy0">&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>dpkg<span class="sy0">/</span>dpkg.cfg.d<span class="sy0">/</span>multiarch<br />
<span class="kw2">apt-get</span> update
        </div>
    </div>
</div>

</li>
<li>Установить статическую сборку Skype (<a href="http://www.skype.com/intl/ru/get-skype/on-your-computer/linux/downloading.static">отсюда</a>) — .deb-пакет всё равно не установится из-за проблем с зависимостями.</li>
<li>Доставить недостающие 32-битные пакеты:
          
<div class="codebox">
    <div class="the_code" style="" id="p94047">
        <div class="code bash" id="p940code47">
<span class="kw2">apt-get</span> <span class="kw2">install</span> libxv1:i386 libxss1:i386
        </div>
    </div>
</div>

</li>
<li>Возможно потребуются дополнительные пакеты. Узнать просто: нужно запустить Skype из консоли. Если чего-то не хватает, система пожалуется:
<p><strong>skype: error while loading shared libraries: libXv.so.1: cannot open shared object file: No such file or directory</strong></p>
<p>Нужно найти, какому пакету принадлежит библиотека:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94048">
        <div class="code bash" id="p940code48">
$ <span class="kw2">dpkg</span> <span class="re5">-S</span> libXv.so<br />
libxv1: <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>x86_64-linux-gnu<span class="sy0">/</span>libXv.so.1.0.0
        </div>
    </div>
</div>

<p>И устаносить 32-битную версию этого пакета:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94049">
        <div class="code bash" id="p940code49">
<span class="kw2">apt-get</span> <span class="kw2">install</span> libxv1:i386
        </div>
    </div>
</div>

</li>
</ol>
<p>После этого Skype должен заработать.</p>
<p><strong>UPDATE 2011-12-20:</strong> рекомендованный ныне способ:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p94050">
        <div class="code bash" id="p940code50">
<span class="kw3">echo</span> foreign-architecture i386 <span class="sy0">&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>dpkg<span class="sy0">/</span>dpkg.cfg.d<span class="sy0">/</span>multiarch<br />
<span class="kw2">aptitude</span> update<br />
<span class="kw2">aptitude</span> <span class="kw2">install</span> skype:i386 <span class="re5">--without-recommends</span>
        </div>
    </div>
</div>

<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/linux/940-skype-ubuntu-oneiric-ocelot-amd64/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/linux/940-skype-ubuntu-oneiric-ocelot-amd64/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>nspluginwrapper: no appropriate viewer found for /usr/lib/flashplugin-installer/libflashplayer.so</title>
		<link>http://blog.sjinks.pro/linux/939-nspluginwrapper-no-appropriate-viewer-found/</link>
		<comments>http://blog.sjinks.pro/linux/939-nspluginwrapper-no-appropriate-viewer-found/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 23:34:06 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[64 bit]]></category>
		<category><![CDATA[Natty Narwhal]]></category>
		<category><![CDATA[Oneiric Ocelot]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[ошибка]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=939</guid>
		<description><![CDATA[Исправление ошибки установки Flash Player в Ubuntu 11.10/AMD64 При обновлении Ubuntu Natty Narwhal до текущей альфы Oneiric Ocelot на архитектуре AMD64 возникает неприятная ошибка при обновлении пакета flashplugin-installer (Flash Player): package flashplugin-installer 10.3.183.4ubuntu3 failed to install/upgrade: nspluginwrapper: no appropriate viewer found for /usr/lib/flashplugin-installer/libflashplayer.so Лечение довольно простое: Необходимо включить поддержку multiarch, если она еще не включена: [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/linux/939-nspluginwrapper-no-appropriate-viewer-found/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Исправление ошибки установки Flash Player в <a href="http://blog.sjinks.pro/tag/ubuntu/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Ubuntu">Ubuntu</a> 11.10/AMD64</em></h2>
<p>При обновлении Ubuntu <a href="http://blog.sjinks.pro/tag/natty-narwhal/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Natty Narwhal">Natty Narwhal</a> до текущей альфы <a href="http://blog.sjinks.pro/tag/oneiric-ocelot/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Oneiric Ocelot">Oneiric Ocelot</a> на архитектуре AMD64 возникает неприятная <a href="http://blog.sjinks.pro/tag/bug/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  ошибка">ошибка</a> при обновлении пакета flashplugin-installer (Flash Player):</p>
<p><strong><br />
package flashplugin-installer 10.3.183.4ubuntu3 failed to install/upgrade:<br />
nspluginwrapper: no appropriate viewer found for /usr/lib/flashplugin-installer/libflashplayer.so<br />
</strong><span id="more-939"></span></p>
<p>Лечение довольно простое:</p>
<ol>
<li>Необходимо <a href="https://lists.ubuntu.com/archives/ubuntu-devel-announce/2011-August/000886.html">включить поддержку multiarch</a>, если она еще не включена:
          
<div class="codebox">
    <div class="the_code" style="" id="p93953">
        <div class="code bash" id="p939code53">
<span class="kw3">echo</span> foreign-architecture i386 <span class="sy0">&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>dpkg<span class="sy0">/</span>dpkg.cfg.d<span class="sy0">/</span>multiarch<br />
<span class="kw2">apt-get</span> update
        </div>
    </div>
</div>

Это позволит устанавливать пакеты для архитектуры i386 на AMD64.
</li>
<li>Затем нужно установить пакеты <code>libnss3:i386</code> и <code>libcurl3:i386</code>:
          
<div class="codebox">
    <div class="the_code" style="" id="p93954">
        <div class="code bash" id="p939code54">
<span class="kw2">aptitude</span> <span class="kw2">install</span> libnss3:i386 libcurl3:i386
        </div>
    </div>
</div>

В зависимостях подтянутся пакеты <code>libnspr4:i386</code> и <code>libsqlite3-0:i386</code>.
</li>
</ol>
<p>После этого можно спокойно (пере)установить пакет <code>flashplugin-installer</code> — всё будет работать.</p>
<p>С отчётом об ошибке и комментариями пользователей можно ознакомиться <a href="https://bugs.launchpad.net/ubuntu/+source/flashplugin-nonfree/+bug/762968">здесь</a>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/linux/939-nspluginwrapper-no-appropriate-viewer-found/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/linux/939-nspluginwrapper-no-appropriate-viewer-found/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

