<?xml version="1.0" encoding="Windows-1251"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
 <description>
  <title-info>
   <genre>comp_programming</genre>
   <author>
    <first-name>Bob</first-name>
    <last-name>Swart</last-name>
    <nickname>Dr.Bob</nickname>
    <home-page>http://www.drbob42.com</home-page>
   </author>
   <book-title>Интернет решения от доктора Боба</book-title>
   <date>2000</date>
   <coverpage>
    <image l:href="#image001.png"/>
    <image l:href="#image003.jpg"/></coverpage>
   <lang>ru</lang>
   <src-lang>en</src-lang>
   <translator>
    <first-name>Анатолий </first-name>
    <last-name>Подгорецкий</last-name>
    <home-page>http://nps.vnet.ee</home-page>
   </translator>
  </title-info>
  <document-info>
   <author>
    <nickname>honorato bonafe</nickname>
   </author>
   <program-used>FB Editor v2.0</program-used>
   <date value="2009-11-13">13 November 2009</date>
   <id>898985EA-F90F-4744-B05C-B526D88210C2</id>
   <version>1.0</version>
   <history>
    <p>1.0 doc-&gt;fb2</p>
   </history>
  </document-info>
 </description>
 <body>
  <section>
   <title>
    <p>Введение</p>
   </title>
   <section>
    <p id="AutBody_0DocRoot">Следующие главы были сделаны доступными в OnLine, как небольшие заметки, статьи и "белые книги".</p>
    <p><strong>От переводчика:</strong> данные заметки были доступны только как статьи в Интернете на странице доктора Боба, с моей стороны было сделано преобразование в формат Word 97, как английского варианта, так и перевод его на русский язык.</p>
    <subtitle>Форматы кодирования файлов Интернет</subtitle>
    <p>Рассматриваются форматы кодирования файлов Интернет, такие как uuencode/decode, xxencode/decode, Base64 encode/decode, сосредоточенные в едином компоненте TBUUCode (часть пакета DrBob42 для Delphi и C++Builder). Также рассмотрены основы HTML (HyperText Markup Language) и CGI (Common Gateway Interface).</p>
    <subtitle>HTML и CGI/WinCGI "трудный путь"</subtitle>
    <p>В данной главе показывается, как опубликовать вашу базу данных в Интернете путем (1) генерации статических страниц из таблиц базы данных, (2) написания CGI/WinCGI приложений для выполнения запросов к базе данных без использования Delphi Web Modules.</p>
    <subtitle>Microsoft WinInet</subtitle>
    <p>В данной главе приводятся детальные примеры использования WinInet.DLL (только для Win32 разработчиков) с помощью протоколов HTTP и FTP, примеры DrBobFTP и другие магические инструменты Веб-мастера.</p>
    <subtitle>Delphi ActiveForms (intranet)</subtitle>
    <p>Показывает, чем активные формы (<strong><emphasis>ActiveForms</emphasis></strong>) отличаются от обычных ActiveX. Как сделать ActiveForms, затем как использовать их, как распространять и как преобразовать существующие формы в активные формы. Также подробно рассмотрены вопросы безопасности и уменьшение размеров файлов (с помощью использования пакетов), как распространять BDE и использование активных форм для создания n-tier приложений.</p>
    <subtitle>Delphi Web Modules (internet)</subtitle>
    <p>Краткое введение в CGI, WinCGI и ISAPI/NSAPI, с помощью Web Modules, WebDispatcher и WebAction компонент. Генерация HTML с помощью PageProducer, DataSetTableProducer и QueryTablePoducer, включая методы сохранения текущего состояния с помощью куки (<strong><emphasis>cookie</emphasis></strong>) и "невидимых" полей.</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042044">1. Форматы кодирования файлов Интернет</p>
    </title>
    <p>Форматы файлов Интернет можно разделить на несколько групп. Во первых форматы передачи файлов по FTP, для чего очень давно была разработана схема uuencode/decode, замененная затем на xxencode/decode. В дальнейшем произошел отказ в пользу Base64 и MIME, которая сейчас используется большинством почтовых программ. Второй тип Интернет форматов это HTML, который со всеми его версиями (часто специфичными для конкретного браузера) и улучшениями сам в себе. Третий тип Интернет форматов это больше интерфейс или протокол связи: CGI, который может быть или стандартный CGI (консольный, или Windows CGI или WinCGI.).</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042045">1.1. Передача файлов через Интернет</p>
    </title>
    <section>
     <p>Дельфи имеет сильный набор средств для написания новых компонентов и для иллюстрации мы напишем кодирование с помощью uuencode/uudecode, xxencode/xxdecode и Base64. Мы напишем достаточно мощный компонент, который реализует данные алгоритмы. Новый компонент реализует uuencode и uudecode алгоритмы, которые могут быть использованы для передачи файлов через Интернет (ранее использовались для передачи файлов между Unix системами).</p>
     <p>Для более утонченного способа передачи файлов смотри главу об WinInet и FTP компонентах. Эти алгоритмы кодирования файлов д в основном используются для передачи файлов в почте и группах новостей</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042046">1.1.1. UUEncode и UUDecode</p>
     </title>
     <p>Необходимость кодирования файлов при передаче является то, что в файле могут находиться любые двоичные данные, для этого файл преобразовывается в "читаемую" или "печатаемую" форму в набор из 64 символов: [`!"#$%&amp;'()*+,-./0123456789:;&lt;=?@ABC…XYZ[\]^_], чтобы кодированный файл прошел через различные сети и почтовые шлюзы. Эти 64 печатных символа представлены в следующей таблице.</p>
     <table>
      <tr align="left">
       <th colspan="8" align="left" valign="top">Набор символов UEncode</th>
      </tr>
      <tr align="left">
       <td align="left" valign="top">0 ` </td>
       <td align="left" valign="top">8 ( </td>
       <td align="left" valign="top">16 0 </td>
       <td align="left" valign="top">24 8 </td>
       <td align="left" valign="top">32 @ </td>
       <td align="left" valign="top">40 H </td>
       <td align="left" valign="top">48 P </td>
       <td align="left" valign="top">56 X</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">1 ! </td>
       <td align="left" valign="top">9 ) </td>
       <td align="left" valign="top">17 1 </td>
       <td align="left" valign="top">25 9 </td>
       <td align="left" valign="top">33 A </td>
       <td align="left" valign="top">41 I </td>
       <td align="left" valign="top">49 Q </td>
       <td align="left" valign="top">57 Y</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">2 " </td>
       <td align="left" valign="top">10 * </td>
       <td align="left" valign="top">18 2 </td>
       <td align="left" valign="top">26 : </td>
       <td align="left" valign="top">34 B </td>
       <td align="left" valign="top">42 J </td>
       <td align="left" valign="top">50 R </td>
       <td align="left" valign="top">58 Z</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">3 # </td>
       <td align="left" valign="top">11 + </td>
       <td align="left" valign="top">19 3 </td>
       <td align="left" valign="top">27 ; </td>
       <td align="left" valign="top">35 C </td>
       <td align="left" valign="top">43 K </td>
       <td align="left" valign="top">51 S </td>
       <td align="left" valign="top">59 [ </td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">4 $ </td>
       <td align="left" valign="top">12 , </td>
       <td align="left" valign="top">20 4 </td>
       <td align="left" valign="top">28 &lt; </td>
       <td align="left" valign="top">36 D </td>
       <td align="left" valign="top">44 L </td>
       <td align="left" valign="top">52 T </td>
       <td align="left" valign="top">60 \</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">5 % </td>
       <td align="left" valign="top">13 – </td>
       <td align="left" valign="top">21 5 </td>
       <td align="left" valign="top">29 = </td>
       <td align="left" valign="top">37 E </td>
       <td align="left" valign="top">45 M </td>
       <td align="left" valign="top">53 U </td>
       <td align="left" valign="top">61 ]</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">6 &amp; </td>
       <td align="left" valign="top">14 . </td>
       <td align="left" valign="top">22 6 </td>
       <td align="left" valign="top">30 &gt; </td>
       <td align="left" valign="top">38 F </td>
       <td align="left" valign="top">46 N </td>
       <td align="left" valign="top">54 V </td>
       <td align="left" valign="top">62 ^</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">7 '</td>
       <td align="left" valign="top">15 /</td>
       <td align="left" valign="top">23 7</td>
       <td align="left" valign="top">31 ?</td>
       <td align="left" valign="top">39 G</td>
       <td align="left" valign="top">47 O</td>
       <td align="left" valign="top">55 W</td>
       <td align="left" valign="top">63 _</td>
      </tr>
     </table>
     <p>Алгоритм выдает файл состоящий из строки заголовка, за ней несколько кодированных строк и в конце завершающая строка.</p>
     <p>Любые строки до строки заголовка или после завершающей строки игнорируются (так как они не содержат специальных ключевых слов "begin" или "end", которые однозначно определяют заголовок и завершающую строку).</p>
     <p>Строка заголовка начинается с ключевого слова "begin", за который следует режим файла (четыре восьмеричных цифры) и имя файла, разделенные пробелом.</p>
     <p>Завершающая строка начинается с ключевого слова "end"</p>
     <p>Кодированные строки располагаются между заголовком и завершающей строкой, и могут содержать максимум 61 символ, первый символ указывает размер строки и максимум 60 символов сама строка.</p>
     <p>Первый символ строки содержит длину строки из набора символов UUEncode, для получения подлинной длины строки из кода символов вычитается 32 ($20).</p>
     <p>Строки данных могут содержать максимум 60 символов, это означает, что первый символ строки (длина) может быть 'M' (60 символ набора символов UUEncode).</p>
     <p>Действительные данные группируются по четыре байта.</p>
     <p>Три символа из входного фала (3 * 8 = 24 бита) кодируются в четыре символа, так что каждый из них содержит только 6 бит, то есть значения от 0 до 63.</p>
     <p>Результат затем используется как индекс в таблицу набора символов UUEncode.</p>
     <p>Так как каждый кодированный символ представляет из себя простой символ таблицы ASCII начинающийся с позиции 33 и до позиции 64 + 32 = 96, то мы можем просто прибавить ASCII значение символа пробела, что бы получить требуемый UUкодированный символ.</p>
     <p>Алгоритм преобразовывает три двоичных символа (Triplet) в четыре (Kwartet) UUкодированных символа и может быть реализован в Паскале следующим образом.</p>
     <p><code><strong>procedure</strong> Triplet2Kwartet(<strong>const</strong> Triplet: TTriplet; <strong>var</strong> Kwartet: TKwartet);</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   Kwartet[0] := (Triplet[0]  <strong>SHR</strong> 2);</code></p>
     <p><code>   Kwartet[1] := ((Triplet[0] <strong>SHL</strong> 4) <strong>AND</strong> $30) +</code></p>
     <p><code>                 ((Triplet[1] <strong>SHR</strong> 4) <strong>AND</strong> $0F);</code></p>
     <p><code>   Kwartet[2] := ((Triplet[1] <strong>SHL</strong> 2) <strong>AND</strong> $3C) +</code></p>
     <p><code>                 ((Triplet[2] <strong>SHR</strong> 6) <strong>AND</strong> $03);</code></p>
     <p><code>   Kwartet[3] := (Triplet[2] <strong>AND</strong> $3F);</code></p>
     <p><code>   <strong>for</strong> i:=0 <strong>to</strong> 3 <strong>do</strong></code></p>
     <p><code>     <strong>if</strong> Kwartet[i] = 0 <strong>then</strong></code></p>
     <p><code>       Kwartet[i] := $40 + Ord(SP)</code></p>
     <p><code>     <strong>else</strong> Inc(Kwartet[i], Ord(SP))</code></p>
     <p><code> <strong>end</strong> <emphasis>{Triplet2Kwartet}</emphasis>;</code></p>
     <p>Данная процедура состоит из из двух частей: в первой части 24 бита (3 * 8) из триплета преобразовываются в 24 бита (4 * 6) квартета. Во второй части алгоритма, мы добавляем ASCII код символа пробела к каждому квартету. ASCII код символа пробела закодирован как Ord(SP), где SP определен как символ пробела или #32. Заметим, что для случая когда квартет равен 0, то мы не добавляем значение #32, поскольку многие почтовые программы имеют проблемы с этим символом, просто в этом случае добавляем код со значением 64 ($40), в результате получаем вместо пробела код обратного апострофа, который нейтрален к алгоритму декодирования, одинаково работающий как для пробела так и для апострофа.</p>
     <p>Говоря о декодировании, реализация его в Паскале преобразования квартетов обратно в триплеты следующая:</p>
     <p><code><strong>procedure</strong> Kwartet2Triplet(<strong>const</strong> Kwartet: TKwartet; <strong>var</strong> Triplet: TTriplet);</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   Triplet[0] :=  ((Kwartet[0] - Ord(SP)) <strong>SHL</strong> 2) +</code></p>
     <p><code>                 (((Kwartet[1] - Ord(SP)) <strong>AND</strong> $30) <strong>SHR</strong> 4);</code></p>
     <p><code>   Triplet[1] := (((Kwartet[1] - Ord(SP)) <strong>AND</strong> $0F) <strong>SHL</strong> 4) +</code></p>
     <p><code>                 (((Kwartet[2] - Ord(SP)) <strong>AND</strong> $3C) <strong>SHR</strong> 2);</code></p>
     <p><code>   Triplet[2] := (((Kwartet[2] - Ord(SP)) <strong>AND</strong> $03) <strong>SHL</strong> 6) +</code></p>
     <p><code>                  ((Kwartet[3] - Ord(SP)) <strong>AND</strong> $3F)</code></p>
     <p><code> <strong>end</strong> <emphasis>{Kwartet2Triplet}</emphasis>;</code></p>
     <p>Если размер триплета в файле менее 3 байт (4 байта в квартете), то производится добавление структуры нулями при кодировании и декодировании.</p>
    </section>
    <section>
     <title>
      <p>1.1.2. XXEncode и XXDecode</p>
     </title>
     <p>UUкодирование было наиболее популярным форматом 64 битного кодирования. Ограничение состояло в том, что набор символов не мог транслироваться между наборами ASCII и EBCDIC (IBM мейнфреймы). XXencode очень похож на UUEncode, просто используется другой набор символов, что более удобно между различными типами систем, например как указано выше между EBCDIC и ASCII.</p>
     <table>
      <tr align="left">
       <th colspan="8" align="left" valign="top">Набор символов XXEncode</th>
      </tr>
      <tr align="left">
       <td align="left" valign="top">0 + </td>
       <td align="left" valign="top">8 6 </td>
       <td align="left" valign="top">16 E </td>
       <td align="left" valign="top">24 M </td>
       <td align="left" valign="top">32 U </td>
       <td align="left" valign="top">40 c </td>
       <td align="left" valign="top">48 k </td>
       <td align="left" valign="top">56 s</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">1 – </td>
       <td align="left" valign="top">9 7 </td>
       <td align="left" valign="top">17 F </td>
       <td align="left" valign="top">25 N </td>
       <td align="left" valign="top">33 V </td>
       <td align="left" valign="top">41 d </td>
       <td align="left" valign="top">49 l </td>
       <td align="left" valign="top">57 t</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">2 0 </td>
       <td align="left" valign="top">10 8 </td>
       <td align="left" valign="top">18 G </td>
       <td align="left" valign="top">26 O </td>
       <td align="left" valign="top">34 W </td>
       <td align="left" valign="top">42 e </td>
       <td align="left" valign="top">50 m </td>
       <td align="left" valign="top">58 u</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">3 1 </td>
       <td align="left" valign="top">11 9 </td>
       <td align="left" valign="top">19 H </td>
       <td align="left" valign="top">27 P </td>
       <td align="left" valign="top">35 X </td>
       <td align="left" valign="top">43 f </td>
       <td align="left" valign="top">51 n </td>
       <td align="left" valign="top">59 v</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">4 2 </td>
       <td align="left" valign="top">12 A </td>
       <td align="left" valign="top">20 I </td>
       <td align="left" valign="top">28 Q </td>
       <td align="left" valign="top">36 Y </td>
       <td align="left" valign="top">44 g </td>
       <td align="left" valign="top">52 o </td>
       <td align="left" valign="top">60 w</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">5 3 </td>
       <td align="left" valign="top">13 B  </td>
       <td align="left" valign="top">21 J </td>
       <td align="left" valign="top">29 R </td>
       <td align="left" valign="top">37 Z </td>
       <td align="left" valign="top">45 h </td>
       <td align="left" valign="top">53 p </td>
       <td align="left" valign="top">61 x</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">6 4 </td>
       <td align="left" valign="top">14 C </td>
       <td align="left" valign="top">22 K </td>
       <td align="left" valign="top">30 S </td>
       <td align="left" valign="top">38 a </td>
       <td align="left" valign="top">46 i </td>
       <td align="left" valign="top">54 q </td>
       <td align="left" valign="top">62 y</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">7 5</td>
       <td align="left" valign="top">15 D</td>
       <td align="left" valign="top">23 L</td>
       <td align="left" valign="top">31 T</td>
       <td align="left" valign="top">39 b</td>
       <td align="left" valign="top">47 j</td>
       <td align="left" valign="top">55 r</td>
       <td align="left" valign="top">63 z</td>
      </tr>
     </table>
     <p>Заметим что если для UUEncodeиспользуется подмножество набора символов ASCII (32..96), то для XXEncode это не так.</p>
     <p>Для преобразования процедур Triplet2Kwartet и Kwartet2Triplet для поддержки мы вводим дополнительный массив из 64 символов.</p>
     <p>Нам также необходимо модифицировать процедуры Triplet2Kwartet и Kwartet2Triplet следующим образом.</p>
     <p><code><strong>const</strong></code></p>
     <p><code>   XX: <strong>Array</strong>[0..63] <strong>of</strong> Char =</code></p>
     <p><code>      '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';</code></p>
     <empty-line/>
     <p><code> <strong>procedure</strong> Triplet2Kwartet(<strong>const</strong> Triplet: TTriplet; <strong>var</strong> Kwartet: TKwartet);</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   Kwartet[0] := (Triplet[0] <strong>SHR</strong> 2);</code></p>
     <p><code>   Kwartet[1] := ((Triplet[0] <strong>SHL</strong> 4) <strong>AND</strong> $30) +</code></p>
     <p><code>                 ((Triplet[1] <strong>SHR</strong> 4) <strong>AND</strong> $0F);</code></p>
     <p><code>   Kwartet[2] := ((Triplet[1] <strong>SHL</strong> 2) <strong>AND</strong> $3C) +</code></p>
     <p><code>                 ((Triplet[2] <strong>SHR</strong> 6) <strong>AND</strong> $03);</code></p>
     <p><code>   Kwartet[3] := (Triplet[2] <strong>AND</strong> $3F);</code></p>
     <p><code>   <strong>for</strong> i:=0 <strong>to</strong> 3 <strong>do</strong></code></p>
     <p><code>     <strong>if</strong> Kwartet[i] = 0 <strong>then </strong>Kwartet[i] := $40 + Ord(SP)</code></p>
     <p><code>     <strong>else</strong> Inc(Kwartet[i],Ord(SP));</code></p>
     <p><code>   <strong>if</strong> XXCode <strong>then</strong></code></p>
     <p><code>     <strong>for</strong> i:=0 <strong>to</strong> 3 <strong>do </strong>Kwartet[i] := Ord(XX[(Kwartet[i] - Ord(SP)) <strong>mod</strong> $40])</code></p>
     <p><code> <strong>end</strong> <emphasis>{Triplet2Kwartet}</emphasis>;</code></p>
     <p>Последние несколько строк новые для процедуры Triplet2Kwartet и мы используем набор символов XXencode для возврата правильно закодированных символов. Помните, что UUEncode возвращает индекс кодированного символа, после чего мы к нему добавляем код #32, так что если XXencode используется после преобразования в UUEncode, то мы должны вычесть 32 и использовать результат как индекс в таблицу символов XXencode.</p>
     <p>То же самое относится и к процедуре Kwartet2Triplet, где мы должны преобразовать XXencode символы перед использованием алгоритма UUdecode (заметим, что мы теперь не передаем Kwartet как const).</p>
     <p><code><strong>procedure</strong> Kwartet2Triplet(Kwartet: TKwartet; <strong>var</strong> Triplet: TTriplet);</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   <strong>if</strong> XXCode <strong>then</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>for</strong> i:=0 <strong>to</strong> 3 <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       <strong>case</strong> Chr(Kwartet[i]) <strong>of</strong></code></p>
     <p><code>             '+': Kwartet[i] := 0 + Ord(SP);</code></p>
     <p><code>             '-': Kwartet[i] := 1 + Ord(SP);</code></p>
     <p><code>        '0'..'9': Kwartet[i] := 2 + Kwartet[i]</code></p>
     <p><code>                                  - Ord('0') + Ord(SP);</code></p>
     <p><code>        'A'..'Z': Kwartet[i] := 12 + Kwartet[i]</code></p>
     <p><code>                                   - Ord('A') + Ord(SP);</code></p>
     <p><code>        'a'..'z': Kwartet[i] := 38 + Kwartet[i]</code></p>
     <p><code>                                   - Ord('a') + Ord(SP)</code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <p><code>   Triplet[0] :=  ((Kwartet[0] - Ord(SP)) <strong>SHL</strong> 2) +</code></p>
     <p><code>                 (((Kwartet[1] - Ord(SP)) <strong>AND</strong> $30) <strong>SHR</strong> 4);</code></p>
     <p><code>   Triplet[1] := (((Kwartet[1] - Ord(SP)) <strong>AND</strong> $0F) <strong>SHL</strong> 4) +</code></p>
     <p><code>                 (((Kwartet[2] - Ord(SP)) <strong>AND</strong> $3C) <strong>SHR</strong> 2);</code></p>
     <p><code>   Triplet[2] := (((Kwartet[2] - Ord(SP)) <strong>AND</strong> $03) <strong>SHL</strong> 6) +</code></p>
     <p><code>                  ((Kwartet[3] - Ord(SP)) <strong>AND</strong> $3F)</code></p>
     <p><code> <strong>end</strong> {Kwartet2Triplet};</code></p>
     <p>Заметим, что в новой версии этих процедур используется глобальная переменная XXCode логического типа для определения типа кодирования.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042048">1.1.3. Base64</p>
     </title>
     <p>Алгоритм кодирования Base64 отличается от алгоритмов UUencode и XXencode тем, что в нем не используется первый символ как индикатор длины. Общее то что используется алгоритм преобразования триплетов в квартеты с помощью 64 байтной таблицы преобразования.</p>
     <table>
      <tr align="left">
       <th colspan="8" align="left" valign="top">Набор символов Base64</th>
      </tr>
      <tr align="left">
       <td align="left" valign="top">0 A </td>
       <td align="left" valign="top">8 I </td>
       <td align="left" valign="top">16 Q </td>
       <td align="left" valign="top">24 Y </td>
       <td align="left" valign="top">32 g </td>
       <td align="left" valign="top">40 o </td>
       <td align="left" valign="top">48 w </td>
       <td align="left" valign="top">56 4</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">1 B </td>
       <td align="left" valign="top">9 J </td>
       <td align="left" valign="top">17 R </td>
       <td align="left" valign="top">25 Z </td>
       <td align="left" valign="top">33 h </td>
       <td align="left" valign="top">41 p </td>
       <td align="left" valign="top">49 x </td>
       <td align="left" valign="top">57 5</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">2 C </td>
       <td align="left" valign="top">10 K </td>
       <td align="left" valign="top">18 S </td>
       <td align="left" valign="top">26 a </td>
       <td align="left" valign="top">34 I </td>
       <td align="left" valign="top">42 q </td>
       <td align="left" valign="top">50 y </td>
       <td align="left" valign="top">58 6</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">3 D </td>
       <td align="left" valign="top">11 L </td>
       <td align="left" valign="top">19 T </td>
       <td align="left" valign="top">27 b </td>
       <td align="left" valign="top">35 j </td>
       <td align="left" valign="top">43 r </td>
       <td align="left" valign="top">51 z </td>
       <td align="left" valign="top">59 7</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">4 E </td>
       <td align="left" valign="top">12 M </td>
       <td align="left" valign="top">20 U </td>
       <td align="left" valign="top">28 c </td>
       <td align="left" valign="top">36 k </td>
       <td align="left" valign="top">44 s </td>
       <td align="left" valign="top">52 0 </td>
       <td align="left" valign="top">60 8</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">5 F </td>
       <td align="left" valign="top">13 N </td>
       <td align="left" valign="top">21 V </td>
       <td align="left" valign="top">29 d </td>
       <td align="left" valign="top">37 l </td>
       <td align="left" valign="top">45 t </td>
       <td align="left" valign="top">53 1 </td>
       <td align="left" valign="top">61 9</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">6 G </td>
       <td align="left" valign="top">14 O </td>
       <td align="left" valign="top">22 W </td>
       <td align="left" valign="top">30 e </td>
       <td align="left" valign="top">38 m </td>
       <td align="left" valign="top">46 u </td>
       <td align="left" valign="top">54 2 </td>
       <td align="left" valign="top">62 +</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">7 H</td>
       <td align="left" valign="top">15 P</td>
       <td align="left" valign="top">23 X</td>
       <td align="left" valign="top">31 f</td>
       <td align="left" valign="top">39 n</td>
       <td align="left" valign="top">47 v</td>
       <td align="left" valign="top">55 3</td>
       <td align="left" valign="top">63 /</td>
      </tr>
     </table>
     <p>Подобно набору символов XXencode, набор символов Base64 не является подмножеством набора символов ASCII.</p>
     <p>Это означает, что мы должны добавить массив преобразования в набор символов Base64 и также преобразовать процедуры Triplet2Kwartet и Kwartet2Triplet для поддержки данного алгоритма:</p>
     <p><code> const</code></p>
     <p><code>   B64: Array[0..63] of Char =</code></p>
     <p><code>      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';</code></p>
     <empty-line/>
     <p><code> procedure Triplet2Kwartet(Const Triplet: TTriplet; var Kwartet: TKwartet);</code></p>
     <p><code> var</code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> begin</code></p>
     <p><code>   Kwartet[0] := (Triplet[0] SHR 2);</code></p>
     <p><code>   Kwartet[1] := ((Triplet[0] SHL 4) AND $30) +</code></p>
     <p><code>                 ((Triplet[1] SHR 4) AND $0F);</code></p>
     <p><code>   Kwartet[2] := ((Triplet[1] SHL 2) AND $3C) +</code></p>
     <p><code>                 ((Triplet[2] SHR 6) AND $03);</code></p>
     <p><code>   Kwartet[3] := (Triplet[2] AND $3F);</code></p>
     <p><code>   for i:=0 to 3 do</code></p>
     <p><code>     if Kwartet[i] = 0 then Kwartet[i] := $40 + Ord(SP)</code></p>
     <p><code>     else Inc(Kwartet[i],Ord(SP));</code></p>
     <p><code>   if Base64 then</code></p>
     <p><code>     for i:=0 to 3 do</code></p>
     <p><code>       Kwartet[i] := Ord(B64[(Kwartet[i] - Ord(SP)) mod $40])</code></p>
     <p><code>   else</code></p>
     <p><code>     if XXCode then</code></p>
     <p><code>       for i:=0 to 3 do</code></p>
     <p><code>         Kwartet[i] := Ord(XX[(Kwartet[i] - Ord(SP)) mod $40])</code></p>
     <p><code> end <emphasis>{Triplet2Kwartet}</emphasis>;</code></p>
     <empty-line/>
     <p><code> procedure Kwartet2Triplet(Kwartet: TKwartet; var Triplet: TTriplet);</code></p>
     <p><code> var</code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> begin</code></p>
     <p><code>   if Base64 then</code></p>
     <p><code>   begin</code></p>
     <p><code>     for i:=0 to 3 do</code></p>
     <p><code>     begin</code></p>
     <p><code>       case Chr(Kwartet[i]) of</code></p>
     <p><code>        'A'..'Z': Kwartet[i] := 0 + Kwartet[i]</code></p>
     <p><code>                                  - Ord('A') + Ord(SP);</code></p>
     <p><code>        'a'..'z': Kwartet[i] := 26+ Kwartet[i]</code></p>
     <p><code>                                  - Ord('a') + Ord(SP);</code></p>
     <p><code>        '0'..'9': Kwartet[i] := 52+ Kwartet[i]</code></p>
     <p><code>                                  - Ord('0') + Ord(SP);</code></p>
     <p><code>             '+': Kwartet[i] := 62+ Ord(SP);</code></p>
     <p><code>             '/': Kwartet[i] := 63+ Ord(SP);</code></p>
     <p><code>       end</code></p>
     <p><code>     end</code></p>
     <p><code>   end</code></p>
     <p><code>   else</code></p>
     <p><code>   if XXCode then</code></p>
     <p><code>   begin</code></p>
     <p><code>     for i:=0 to 3 do</code></p>
     <p><code>     begin</code></p>
     <p><code>       case Chr(Kwartet[i]) of</code></p>
     <p><code>             '+': Kwartet[i] := 0 + Ord(SP);</code></p>
     <p><code>             '-': Kwartet[i] := 1 + Ord(SP);</code></p>
     <p><code>        '0'..'9': Kwartet[i] := 2 + Kwartet[i]</code></p>
     <p><code>                                  - Ord('0') + Ord(SP);</code></p>
     <p><code>        'A'..'Z': Kwartet[i] := 12 + Kwartet[i]</code></p>
     <p><code>                                   - Ord('A') + Ord(SP);</code></p>
     <p><code>        'a'..'z': Kwartet[i] := 38 + Kwartet[i]</code></p>
     <p><code>                                   - Ord('a') + Ord(SP)</code></p>
     <p><code>       end</code></p>
     <p><code>     end</code></p>
     <p><code>   end;</code></p>
     <p><code>   Triplet[0] :=  ((Kwartet[0] - Ord(SP)) SHL 2) +</code></p>
     <p><code>                 (((Kwartet[1] - Ord(SP)) AND $30) SHR 4);</code></p>
     <p><code>   Triplet[1] := (((Kwartet[1] - Ord(SP)) AND $0F) SHL 4) +</code></p>
     <p><code>                 (((Kwartet[2] - Ord(SP)) AND $3C) SHR 2);</code></p>
     <p><code>   Triplet[2] := (((Kwartet[2] - Ord(SP)) AND $03) SHL 6) +</code></p>
     <p><code>                  ((Kwartet[3] - Ord(SP)) AND $3F)</code></p>
     <p><code> <strong>end</strong> {Kwartet2Triplet};</code></p>
     <p>Заметим, что в новой версии появилась новая глобальная переменная, которая используется для определения формата кодирования.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042049">1.1.4. MIME</p>
     </title>
     <p>MIME означает Multipurpose Internet Mail Extensions (Расширение форматов Интернет почты), в котором международным стандартом является кодирование Base64. Данное расширение было разработано для многоязычной поддержки и преобразования символов между системами (такими как IBM мейнфреймы, системы на базе UNIX, Macintosh и IBM PC).</p>
     <p>MIME алгоритм кодирования базируется на RFC1341 как MIME Base64. Подобно UUencode, назначение MIME кодировать двоичные файлы так, что бы они смогли пройти через различные почтовые системы, и MIME использует для этого алгоритм кодирования Base64, плюс набор специальных ключевых слов и опций, которые используются для более детализированной информации о содержимом MIME.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042050">1.1.5. TBUUCode компонент</p>
     </title>
     <p>Определение интерфейса компонента TUUCode, базируется на ранее приведенных и объясненных процедур Triplet2Kwartet и Kwartet2Triplet, заметим, что ниже приведенный код использует условное компилирование в зависимости от версий Delphi и C++Builder.</p>
     <p><code><strong>unit</strong> UUCode;</code></p>
     <p><code> <strong>interface</strong></code></p>
     <p><code> <strong>uses</strong></code></p>
     <p><code> <emphasis>{$IFDEF WIN32}</emphasis></code></p>
     <p><code>   Windows,</code></p>
     <p><code> <emphasis>{$ELSE}</emphasis></code></p>
     <p><code>   WinTypes, WinProcs,</code></p>
     <p><code> <emphasis>{$ENDIF}</emphasis></code></p>
     <p><code>   SysUtils, Messages, Classes, Graphics, Controls, Forms;</code></p>
     <empty-line/>
     <p><code> <emphasis>{$IFNDEF WIN32}</emphasis></code></p>
     <p><code> <strong>type</strong></code></p>
     <p><code>   ShortString = <strong>String</strong>;</code></p>
     <p><code> <emphasis>{$ENDIF}</emphasis></code></p>
     <empty-line/>
     <p><code> <strong>type</strong></code></p>
     <p><code>   EUUCode = <strong>class</strong>(Exception);</code></p>
     <empty-line/>
     <p><code>   TAlgorithm = (filecopy, uuencode, uudecode, xxencode, xxdecode, Base64encode, Base64decode);</code></p>
     <p><code>   TUnixCRLF = (CRLF, LF);</code></p>
     <empty-line/>
     <p><code>   TProgressEvent = <strong>procedure</strong>(Percent:Word) <strong>of Object</strong>;</code></p>
     <empty-line/>
     <p><code>   TBUUCode = <strong>class</strong>(TComponent)</code></p>
     <p><code>   <strong>public</strong></code></p>
     <p><code>   <emphasis>{ Public class declarations (override) }</emphasis></code></p>
     <p><code>     <strong>constructor</strong> Create(AOwner: TComponent); <strong>override</strong>;</code></p>
     <empty-line/>
     <p><code>   <strong>private</strong></code></p>
     <p><code>   <emphasis>{ Private field declarations }</emphasis></code></p>
     <p><code>     FAbout: ShortString;</code></p>
     <p><code>     FActive: Boolean;</code></p>
     <p><code>     FAlgorithm: TAlgorithm;</code></p>
     <p><code>     FFileMode: Word;</code></p>
     <p><code>     FHeaders: Boolean;</code></p>
     <p><code>     FInputFileName: TFileName;</code></p>
     <p><code>     FOutputFileName: TFileName;</code></p>
     <p><code>     FOnProgress: TProgressEvent;</code></p>
     <p><code>     FUnixCRLF: TUnixCRLF;</code></p>
     <p><code>   <emphasis>{ Dummy method to get read-only About property }</emphasis></code></p>
     <p><code>     <strong>procedure</strong> Dummy(Ignore: ShortString);</code></p>
     <empty-line/>
     <p><code>   <strong>protected</strong></code></p>
     <p><code>   <emphasis>{ Protected Activate method }</emphasis></code></p>
     <p><code>     <strong>procedure</strong> Activate(GoActive: Boolean);</code></p>
     <empty-line/>
     <p><code>   <strong>public</strong></code></p>
     <p><code>   <emphasis>{ Public UUCode interface declaration }</emphasis></code></p>
     <p><code>     <strong>procedure</strong> UUCode;</code></p>
     <empty-line/>
     <p><code>   <strong>published</strong></code></p>
     <p><code>   <emphasis>{ Published design declarations }</emphasis></code></p>
     <p><code>     <strong>property</strong> About: ShortString <strong>read</strong> FAbout <strong>write</strong> Dummy;</code></p>
     <p><code>     <strong>property</strong> Active: Boolean <strong>read</strong> FActive <strong>write</strong> Activate;</code></p>
     <p><code>     <strong>property</strong> Algorithm: TAlgorithm <strong>read</strong> Falgorithm <strong>write</strong> FAlgorithm;</code></p>
     <p><code>     <strong>property</strong> FileMode: Word <strong>read</strong> FFileMode <strong>write</strong> FFileMode;</code></p>
     <p><code>     <strong>property</strong> Headers: Boolean <strong>read</strong> FHeaders <strong>write</strong> FHeaders;</code></p>
     <p><code>     <strong>property</strong> InputFile: TFileName <strong>read</strong> FInputFileName <strong>write</strong> FInputFileName;</code></p>
     <p><code>     <strong>property</strong> OutputFile: TFileName <strong>read</strong> FOutputFileName <strong>write</strong> FOutputFileName;</code></p>
     <p><code>     <strong>property</strong> UnixCRLF: TUnixCRLF <strong>read</strong> FUnixCRLF <strong>write</strong> FUnixCRLF;</code></p>
     <empty-line/>
     <p><code>   <strong>published</strong></code></p>
     <p><code>   <emphasis>{ Published Event property }</emphasis></code></p>
     <p><code>     <strong>property</strong> OnProgress: TProgressEvent <strong>read</strong> FOnProgress <strong>write</strong> FOnProgress;</code></p>
     <p><code>   <strong>end</strong> {TUUCode};</code></p>
     <empty-line/>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042051">1.1.6. Свойства</p>
     </title>
     <p>TUUCode компонент имеет восемь опубликованных свойств (мы здесь опустим описание обработчиков событий):</p>
     <p>Свойство <strong>About</strong> содержит информацию о правах и версии.</p>
     <p>Свойство <strong>Active</strong> может использоваться для вызова преобразования UUCode во время разработки (design time), подобно свойству Active у TTables и Tquery компонент.</p>
     <p>Свойство <strong>Algorithm</strong> содержит информацию об алгоритме кодирования для метода UUCode. Реализованы следующие алгоритмы:</p>
     <p>· filecopy – простое копирование файла InputFile в файл OutputFile</p>
     <p>· uuencode – копирование файла с помощью алгоритма uuencode из файла InputFile и генерация файла OutputFile</p>
     <p>· uudecode – копирование файла с помощью алгоритма uudecode из файла InputFile (и генерация файла OutputFile, если не используется Headers)</p>
     <p>· xxencode – копирование файла с помощью алгоритма xxencode из файла InputFile и генерация файла OutputFile</p>
     <p>· xxdecode – копирование файла с помощью алгоритма xxdecode из файла InputFile (и генерация файла OutputFile, если не используется Headers)</p>
     <p>· Base64encode – копирование файла с помощью алгоритма Base64 encode InputFile и генерация файла OutputFile</p>
     <p>· Base64decode – копирование файла с помощью алгоритма Base64 decode InputFile (и генерация файла OutputFile, если не используется Headers)</p>
     <p>Свойство <strong>FileMode</strong> содержит шестнадцатеричное значение режима файла (обычно 0644 или 0755). Заметим, что режим задается с помощью десятичных цифр.</p>
     <p>Свойство <strong>Headers</strong> может быть использовано для указания должны или нет использоваться заголовки begin-end в алгоритме кодирования или ожидаются в алгоритме декодирования. Значение по умолчанию True.</p>
     <p>Свойство <strong>InputFile</strong> содержит имя входного файла для кодирования/декодирования.</p>
     <p>Свойство <strong>OutputFile</strong> содержит имя выходного файла, в который будет записан результат кодирования. Заметим, что свойство OutputFile игнорируется при декодировании, если входной файл имеет заголовки, которые определяют имя файла для декодирования.</p>
     <p>Свойство <strong>UnixCRLF</strong> используется для указания разделителей строк специфичных для Unix систем, только Line Feed (перевод строки) или DOS/Windows, где используется пара Carriage Return/Line Feed (возврат каретки/ перевод строки). По умолчанию CRLF, но как минимум вы имеете возможность кодировать и декодировать файлы для Unix систем.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042052">1.1.7. Методы</p>
     </title>
     <p>Компонент TUUCode имеет три метода; один public конструктор, один protected метод и один public метод:</p>
     <p>Конструктор <strong>Create</strong> используется для создания компонента и инициализации свойств ао умолчанию (default) для Active, FileMode, Headers и About.</p>
     <p>Метод <strong>Activate</strong> используется для вызова метода UUCode во время разработки, когда вы изменяете состояние свойства в True. При необходимости вы можете вызвать этот метод напрямую, так как это проще вызова метода UUCode.</p>
     <p>Метод <strong>UUCode</strong> это метод, в котором в действительности производится кодирование/декодирование входного файла (InputFile), базируясь на состоянии других свойств компонента TUUCode.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042053">1.1.8. События</p>
     </title>
     <p>Компонент TUUCode имеет только одно такое свойство:</p>
     <p>Событие <strong>OnProgress</strong> может использоваться как callback функция, позволяющая компоненту TUUCode выдавать текущий процент обработки входного файла. Использовать эту информацию вы можете с компонентами 16-битным TGauge или 32-битным TprogressBar, для примера показывая прогресс выполнения кодирования/декодирования от 0 до 100%.</p>
     <p>Кодирование/декодирование больших документов может занимать значительное время даже при использовании быстрой машины и быстрых дисков. Поэтому приятно иметь такую возможность показывать процесс выполнения. Для реализации вам нужно создать обработчик события.</p>
     <p>Обработчик состоит из двух частей, сигнализатора и обработчика события. Сигнализатор должен быть уверен, что компонент в состоянии принять сообщение определенного типа и сгенерировать событие. Обработчик события с другой стороны начинает работать только при поступлении события.</p>
     <p>Сигнализатор типично виртуальный или динамический метод самого класса (подобно методу Click) или сообщению Windows, такому как оповещение (notification) или callback сообщения. Обработчик события типично присваивается свойству, такому как OnClick, OnChange или OnProgress. Если обработчик события опубликован, то конечный пользователь компонента может написать любой код для обработки события.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042054">1.1.9. Обработчики событий</p>
     </title>
     <p>Обработчики события методы объекта. Это означает, что они должны быть методами класса, а не обычной процедурой или функцией (первый параметр должен быть Self). Для наиболее употребимых обработчиков предназначен следующий тип:</p>
     <p><code>TNotifyEvent = <strong>procedure</strong>(sender: TObject) <strong>of object</strong>;</code></p>
     <p>Тип TNotifyEvent для обработчиков, в которые передается только один параметр sender. Эти события просто оповещают компонент о возникновении специфического события у объекта sender. Например, OnClick, типа TNotifyEvent, указывает органу, что произошло событие click у конкретного органа. Если бы параметр Sender отсутствовал, то мы бы знали только, то, что произошло определенное событие, но не знали бы у какого органа. Обычно нам требуется знать, у какого конкретно органа произошло данное событие, что бы мы могли работать с этим органом или его данными..</p>
     <p>Как было указано ранее, Обработчики событий присваиваются свойствам типа событие (event), и они появляются как отдельная закладка в инспекторе объектов (Object Inspector), для различения их от обычных свойств. Основой для помещения этого свойства на закладку события является то, что они должны быть типа "procedure/function of Object". Фраза "of Object" обязательна, иначе мы получим сообщение об ошибке "cannot publish property".</p>
     <p>Компоненту TUUCode требуется событие типа TProgressEvent. Данному событию реально не требуется параметр sender (это всегда можно добавить позже), но ему необходим процент выполнения операции, для цели опишем следующий прототип:</p>
     <p><code>TProgressEvent = <strong>procedure</strong>(percent: Word) <strong>of object</strong>;</code></p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042055">1.1.10. Сигнализаторы событий</p>
     </title>
     <p>Сигнализаторы событий требуются для указания обработчику события, что возникло указанное событие, что бы обработчик события смог бы выполнить свои действия. Сигнализаторы обычно виртуальные или динамические методы класса (подобно методу Click) или сообщения Windows, такие как callback ил notification сообщения.</p>
     <p>В случае с компонентом TUUCode, сигнализатор интегрирован непосредственно в метод UUCode. После кодирования каждой строки, вызывается обработчик события назначенный OnProgress, реализация этого следующая:</p>
     <p><code><strong>if</strong> Assigned(FOnProgress) <strong>then </strong>FOnProgress(trunc((100.0 * Size) / OutputBufSize))</code></p>
     <p>Где Size это текущий размер или позиция в выходном буфере, и OutputBufSize это размер выходного файла. Size увеличивается от нуля до OutputBufSize, что означает, что обработчик события FOnProgress вызывается с аргументом от 0 до 100.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042056">1.1.11. Регистрация компонента</p>
     </title>
     <p>При регистрации компонента TUUCode, полезно добавить редактор свойства FileName (InputFile), что обеспечит дополнительный комфорт для конечного пользователя. Редактор этого свойства реализован в модуле UUReg, который регистрирует компонент TUUCode в палитре компонентов Дельфи.</p>
     <p><code><strong>unit</strong> UUReg;</code></p>
     <p><code> <strong>interface</strong></code></p>
     <p><code> <emphasis>{$IFDEF WIN32}</emphasis></code></p>
     <p><code>   <emphasis>{$R UUCODE.D32}</emphasis></code></p>
     <p><code> <emphasis>{$ELSE}</emphasis></code></p>
     <p><code>   <emphasis>{$R UUCODE.D16}</emphasis></code></p>
     <p><code> <emphasis>{$ENDIF}</emphasis></code></p>
     <p><code> <strong>uses</strong></code></p>
     <p><code>   DsgnIntf;</code></p>
     <p><code> <strong>type</strong></code></p>
     <p><code>   TFileNameProperty = <strong>class</strong>(TStringProperty)</code></p>
     <p><code>   <strong>public</strong></code></p>
     <p><code>     <strong>function</strong> GetAttributes: TPropertyAttributes; <strong>override</strong>;</code></p>
     <p><code>     <strong>procedure</strong> Edit; <strong>override</strong>;</code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <empty-line/>
     <p><code> <strong>procedure</strong> Register;</code></p>
     <empty-line/>
     <p><code> <strong>implementation</strong></code></p>
     <p><code> <strong>uses</strong></code></p>
     <p><code>   UUCode, Classes, Dialogs, Forms, SysUtils;</code></p>
     <empty-line/>
     <p><code>   <strong>function</strong> TFileNameProperty.GetAttributes: TPropertyAttributes;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Result := [paDialog]</code></p>
     <p><code>   <strong>end</strong> <emphasis>{GetAttributes}</emphasis>;</code></p>
     <empty-line/>
     <p><code>   <strong>procedure</strong> TFileNameProperty.Edit;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>with</strong> TOpenDialog.Create(Application) <strong>do</strong></code></p>
     <p><code>     <strong>try</strong></code></p>
     <p><code>       Title := GetName; <emphasis>{ name of property as OpenDialog caption }</emphasis></code></p>
     <p><code>       Filename := GetValue;</code></p>
     <p><code>       Filter := 'All Files (*.*)|*.*';</code></p>
     <p><code>       HelpContext := 0;</code></p>
     <p><code>       Options := Options +</code></p>
     <p><code>                 [ofShowHelp, ofPathMustExist, ofFileMustExist];</code></p>
     <p><code>       <strong>if</strong> Execute <strong>then</strong> SetValue(Filename);</code></p>
     <p><code>     <strong>finally</strong></code></p>
     <p><code>       Free</code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong> <emphasis>{Edit}</emphasis>;</code></p>
     <empty-line/>
     <p><code>   <strong>procedure</strong> Register;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <emphasis>{ component }</emphasis></code></p>
     <p><code>     RegisterComponents('DrBob42', [TUUCode]);</code></p>
     <p><code>     <emphasis>{ property editor }</emphasis></code></p>
     <p><code>     RegisterPropertyEditor(TypeInfo(TFilename), nil,</code></p>
     <p><code>                           'InputFile', TFilenameProperty);</code></p>
     <p><code>   <strong>end</strong> <emphasis>{Register}</emphasis>;</code></p>
     <p><code> end.</code></p>
     <p>Если вы желаете использовать компонент TUUCode в составе, какого либо пакета, то вы должны поместить компонент UUCode в пакет времени выполнения (runtime package), и модуль UUReg в пакет разработки (design-time), который требует пакет времени выполнения. В действительности, для использования пакетов вы можете использовать UUCode Wizard из следующей главы в пакет времени разработки и сделать его доступным в IDE Delphi для всех пользователей!</p>
    </section>
    <section>
     <title>
      <p>1.1.12. UUCode Example Wizard</p>
     </title>
     <p>Для показа прогресса 16-битный пример использует TGauge компонент, в то же время 32-битная версия использует Windows 95 Progress Control.</p>
     <image l:href="#Any2FbImgLoader0"/>
     <p>рис. 1.1. 16-битная версия примера UUCode</p>
     <image l:href="#Any2FbImgLoader1"/>
     <p>рис. 1.2. 32-битная версия примера UUCode</p>
     <p>Во время исполнения программы могут возникнуть два исключения. Если входной файл пуст и во время кодирования, если выходной файл пуст. Для 16 битной версии может возникнуть третье исключение, если входной или выходной файл больше 65000 байт (16-битная версия данного компонента может обрабатывать входные и выходные файлы до 64 килобайт). На практике это означает, не может быть более 48 килобайт. 32-битная версия не имеет такого ограничения).</p>
    </section>
    <section>
     <title>
      <p>1.1.13. Заключение</p>
     </title>
     <p>В этой главе мы рассмотрели uuencode/uudecode, xxencode/xxdecode, и Base64 алгоритмы кодирования/декодирования. Мы также разработали простой VCL компонент, который поддерживает эти алгоритмы в дополнение к простому копированию. Свойства, методы и события делают данный компонент пригодным для построения Интернет приложений нуждающихся в подобном преобразовании.</p>
     <p>Компонент TBUUCode сейчас часть пакета "DrBob42 component package for Delphi and C++Builder".</p>
    </section>
   </section>
   <section>
    <title>
     <p>1.2. HTML</p>
    </title>
    <p>Аббревиатура HTML означает HyperText Mark-up Language (язык разметки гипертекстовых документов), который является базовым для построения статических страниц. HTML страница является простым текстовым ASCII файлом с HTML-тегами между "&lt;" и "&gt;" (часто парами). Браузеры, такие как Netscape Navigator и Internet Explorer просто интерпретируют HTML коды на данных страницах для показа заголовков, жирного и наклонного текста, изображений и также фреймов и таблиц. Следующая таблица приводит несколько основных HTML тегов, которые будут рассмотрены далее в этой главе.</p>
    <table>
     <tr align="left">
      <th align="left" valign="top">HTML tag </th>
      <th align="left" valign="top">text effect</th>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;HTML&gt;…&lt;/HTML&gt; </td>
      <td align="left" valign="top">Ограничивает HTML страницу</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;HEADER&gt;…&lt;/HEADER&gt; </td>
      <td align="left" valign="top">Секция заголовков</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;TITLE&gt;…&lt;/TITLE&gt; </td>
      <td align="left" valign="top">Заголовок документа</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;BODY&gt;…&lt;/BODY&gt; </td>
      <td align="left" valign="top">Секция содержимого страницы</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;H1&gt;…&lt;/H1&gt; </td>
      <td align="left" valign="top">Заголовок (возможные уровни 1..6)</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;B&gt;…&lt;/B&gt; </td>
      <td align="left" valign="top">Жирный текст</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;I&gt;…&lt;/I&gt; </td>
      <td align="left" valign="top">Наклонный текст</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;BR&gt; </td>
      <td align="left" valign="top">Разрыв строки</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;HR&gt; </td>
      <td align="left" valign="top">Горизонтальная черта</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;P&gt;</td>
      <td align="left" valign="top">Абзац</td>
     </tr>
     <tr align="left">
      <td align="left" valign="top">&lt;A HREF="URL"&gt;….&lt;/A&gt;</td>
      <td align="left" valign="top">Ссылка на другую страницу или URL</td>
     </tr>
    </table>
    <p>HTML страница всегда начинается тегом &lt;HTML&gt; и заканчивается тегом &lt;/HTML&gt;.</p>
    <p>Содержимое страницы размещается между тегами &lt;BODY&gt; и &lt;/BODY&gt;. Множественные разрывы строк и пробелы/табуляции игнорируются и заменяются на один пробел, это причина, по которой требуется специальный тег разрыва строки &lt;BR&gt; и &lt;P&gt;. Простая HTML страница с одним заголовком и ссылкой выглядит так.</p>
    <p><code>&lt;HTML&gt;</code></p>
    <p><code>&lt;BODY&gt;</code></p>
    <p><code>&lt;H1&gt;Hello, world!&lt;/H1&gt;</code></p>
    <p><code>&lt;P&gt;</code></p>
    <p><code>&lt;HR</code></p>
    <p><code>&lt;ADDRESS&gt;</code></p>
    <p><code>&lt;A HREF=http://www.drbob42.com&gt;Dr.Bob's Delphi Clinic&lt;/A&gt;</code></p>
    <p><code>&lt;/ADDRESS&gt;</code></p>
    <p><code>&lt;/BODY&gt;</code></p>
    <p><code>&lt;/HTML&gt;</code></p>
    <p>Примечание: тег &lt;ADDRESS&gt;, который мы можем использовать для помещения адресной информации и ссылки на домашнюю страницу или e-mail адрес. Эта информация будет отображена наклонным шрифтом. Тег &lt;A&gt; часть основы HTML; данная форма используется для указания гипер-ссылки, в данном случае на другую страницу (мою домашнюю страницу) по адресу http://www.drbob42.com. Для данной простой HTML страницы, браузер (такой как Netscape Navigator) покажет одну страницу с заголовком и с ссылкой.</p>
    <p>Для освоения HTML я могу рекомендовать хорошую книгу "Netscape &amp; HTML Explorer".</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042060">1.3. CGI</p>
    </title>
    <section>
     <p>Аббревиатура CGI означает Common Gateway Interface, и является связевым протоколом между формой в Web браузере (клиент) и приложением запущенным на Web сервере (сервер). Приложение обычно называется CGI скрипт, но мы можем использовать Дельфи для написания CGI приложений без скриптов.</p>
     <p>Имеется два типа CGI: стандартное или консольное CGI приложение и позже появилась версия для Windows называемая WinCGI.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042061">1.3.1. Консольное CGI приложение</p>
     </title>
     <p>Стандартное или консольное CGI приложение взаимодействует с формой на клиенте с помощью переменных среды (управляющая информация), стандартным входом (данные формы) и стандартным выводом (возвращаемая динамическая HTML страница).</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042062">1.3.2. WinCGI</p>
     </title>
     <p>Приложение WinCGI взаимодействует с формой на клиенте с помощью Windows.INI файла вместо переменных среды. Windows.INI файл содержит управляющую информацию, иногда данные формы и имена входного, данных и выходного файлов.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042063">1.3.3. Delphi и CGI</p>
     </title>
     <p>В данной главе я расскажу, как написать простое Дельфи CGI приложение, без использования Web Modules или других Client/Server модулей.</p>
     <p>Во первых аббревиатура CGI означает Common Gateway Interface, и это только имя для передачи информации от клиента серверу. На клиентской стороне это реализуется с помощью формы, содержащей только теги. На серверной стороне</p>
     <p>На сервере запускается CGI приложение, которое иногда называется CGI скрипт (для примера на Unix машинах, где Perl используется для исполнения CGI скриптов).</p>
     <p>В данной главе я сконцентрирую внимание на написание CGI приложения для Windows NT web сервера, и использовании 32-битной Дельфи (например Delphi 2.x или 3.x) для данной задачи, данный код может быть также без проблем откомпилирован в C++Builder.</p>
     <p>Стандартное CGI приложение получает данные через стандартный вход и должно выдать ответ через стандартный вывод. (например сгенерированную HTML страницу). Это означает необходимость написания консольного приложения. Если даже нет входных данных мы все равно можем использовать CGI приложение для генерации динамических HTML страниц (например для выдачи данных их таблицы).</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042064">1.3.4. Динамический вывод</p>
     </title>
     <p>Для начала посмотрим на стандартное "hello world" CGI приложение. Единственное, что оно должно сделать, это вернуть HTML страницу со строкой "hello, world". Перед тем как мы начнем делать это – обратим внимание на следующее: CGI приложение должно сообщить миру какой (MIME) формат оно выдает. В нашем случае это "text/html", которое мы должны указать как: <emphasis>content-type: text/html</emphasis> , и затем одну пустую строку.</p>
     <p>Вот код нашего первого "Hello, world!" CGI приложения:</p>
     <p><code> <strong>program</strong> CGI1;</code></p>
     <p><code> <emphasis>{$APPTYPE CONSOLE}</emphasis></code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   writeln('content-type: text/html');</code></p>
     <p><code>   writeln;</code></p>
     <p><code>   writeln('&lt;HTML');</code></p>
     <p><code>   writeln('&lt;BODY');</code></p>
     <p><code>   writeln('Hello, world!');</code></p>
     <p><code>   writeln('&lt;/BODY');</code></p>
     <p><code>   writeln('&lt;/HTML')</code></p>
     <p><code> end.</code></p>
     <p>Если вы откомпилируете данную программу в Дельфи 2 или 3 и затем запустите ее из web браузера подключенного к web серверу, где оно записано в исполнимом виде в исполняемом каталоге таком как cgi-bin, то вы увидите текст "Hello, world!" на странице.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042065">1.3.5. CGI ввод</p>
     </title>
     <p>Теперь, мы знаем как создавать CGI приложение, которое может генерировать динамическую HTML страницу (или в действительности почти статическую). Но как насчет ввода<emphasis>?</emphasis> Здесь более чем одно действие: мы должны проверять переменную DOS 'CONTENT LENGTH' что бы знать как много символов мы можем прочитать со стандартного ввода (если мы попытаемся читать больше чем есть, то мы повиснем навсегда). Конечно, это широко известный факт. Я написал компонент <strong>TBDosEnvironment</strong> чтобы вы могли иметь доступ до переменных среды DOS:</p>
     <p><code> <strong>unit</strong> DrBobDOS;</code></p>
     <p><code> <strong>interface</strong></code></p>
     <p><code> <strong>uses</strong></code></p>
     <p><code>   SysUtils, WinTypes, WinProcs, Classes;</code></p>
     <empty-line/>
     <p><code> <strong>type</strong></code></p>
     <p><code>   TBDosEnvironment = <strong>class</strong>(TComponent)</code></p>
     <p><code>   <strong>public</strong></code></p>
     <p><code>   <emphasis>{ Public class declarations (override) }</emphasis></code></p>
     <p><code>     <strong>constructor</strong> Create(AOwner: TComponent); <strong>override</strong>;</code></p>
     <p><code>     <strong>destructor</strong> Destroy; <strong>override</strong>;</code></p>
     <empty-line/>
     <p><code>   <strong>private</strong></code></p>
     <p><code>   <emphasis>{ Private field declarations }</emphasis></code></p>
     <p><code>     FDosEnvList: TStringList;</code></p>
     <p><code>     <strong>procedure</strong> DoNothing(<strong>const</strong> Value: TStringList);</code></p>
     <empty-line/>
     <p><code>   <strong>protected</strong></code></p>
     <p><code>   <emphasis>{ Protected method declarations }</emphasis></code></p>
     <p><code>     Dummy: Word;</code></p>
     <p><code>     <strong>function</strong> GetDosEnvCount: Word;</code></p>
     <empty-line/>
     <p><code>   <strong>public</strong></code></p>
     <p><code>   <emphasis>{ Public interface declarations }</emphasis></code></p>
     <p><code>     <strong>function</strong> GetDosEnvStr(<strong>const</strong> Name: <strong>String</strong>): <strong>String</strong>;</code></p>
     <p><code>     <emphasis>{ This function is a modified version of the GetEnvVar function thatappears in the WinDos unit that comes with Delphi. This function's interface uses Pascal strings instead of null-terminated strings.</emphasis></code></p>
     <p><code><emphasis>     }</emphasis></code></p>
     <empty-line/>
     <p><code>   <strong>published</strong></code></p>
     <p><code>   <emphasis>{ Published design declarations }</emphasis></code></p>
     <p><code>     <strong>property</strong> DosEnvCount: Word <strong>read</strong> GetDosEnvCount <strong>write</strong> Dummy;</code></p>
     <p><code>     <strong>property</strong> DosEnvList: TStringList <strong>read</strong> FDosEnvList <strong>write</strong> DoNothing;</code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <empty-line/>
     <p><code> <strong>implementation</strong></code></p>
     <empty-line/>
     <p><code>   <strong>constructor</strong> TBDosEnvironment.Create(AOwner: TComponent);</code></p>
     <p><code>   <strong>var</strong></code></p>
     <p><code>     P: PChar;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>inherited</strong> Create(AOwner);</code></p>
     <p><code>     FDosEnvList := TStringList.Create;</code></p>
     <p><code>   <emphasis>{$IFDEF WIN32}</emphasis></code></p>
     <p><code>     P := GetEnvironmentStrings;</code></p>
     <p><code>   <emphasis>{$ELSE}</emphasis></code></p>
     <p><code>     P := GetDosEnvironment;</code></p>
     <p><code>   <emphasis>{$ENDIF}</emphasis></code></p>
     <p><code>     <strong>while</strong> P^ &lt;&gt; #0 <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       FDosEnvList.Add(StrPas(P));</code></p>
     <p><code>       Inc(P, StrLen(P)+1) <emphasis>{ Fast Jump to Next Var }</emphasis></code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>   <strong>end</strong> <emphasis>{Create}</emphasis>;</code></p>
     <empty-line/>
     <p><code>   <strong>destructor</strong> TBDosEnvironment.Destroy;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     FDosEnvList.Free;</code></p>
     <p><code>     FDosEnvList := <strong>nil</strong>;</code></p>
     <p><code>     <strong>inherited</strong> Destroy</code></p>
     <p><code>   <strong>end</strong> <emphasis>{Destroy}</emphasis>;</code></p>
     <empty-line/>
     <p><code>   <strong>procedure</strong> TBDosEnvironment.DoNothing(<strong>const</strong> Value: StringList);</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>   <strong>end</strong> <emphasis>{DoNothing}</emphasis>;</code></p>
     <empty-line/>
     <p><code>   <strong>function</strong> TBDosEnvironment.GetDosEnvCount: Word;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>if</strong> Assigned(FDosEnvList) <strong>then </strong></code></p>
     <p><code>       Result := FDosEnvList.Count</code></p>
     <p><code>     <strong>else</strong></code></p>
     <p><code>       Result := 0;</code></p>
     <p><code>   <strong>end</strong> <emphasis>{GetDosEnvCount}</emphasis>;</code></p>
     <empty-line/>
     <p><code>   <strong>function</strong> TBDosEnvironment.GetDosEnvStr(<strong>const</strong> Name: <strong>String</strong>): <strong>String</strong>;</code></p>
     <p><code>   <strong>var</strong></code></p>
     <p><code>     i: Integer;</code></p>
     <p><code>     Tmp: <strong>String</strong>;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     i := 0;</code></p>
     <p><code>     Result := '';</code></p>
     <p><code>     <strong>if</strong> Assigned(FDosEnvList) <strong>then while</strong> i &lt; FDosEnvList.Count <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Tmp := FDosEnvList[i];</code></p>
     <p><code>       Inc(i);</code></p>
     <p><code>       <strong>if</strong> Pos(Name,Tmp) = 1 <strong>then</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         Delete(Tmp,1,Length(Name));</code></p>
     <p><code>         <strong>if</strong> Tmp[1] = '=' <strong>then</strong></code></p>
     <p><code>         <strong>begin</strong></code></p>
     <p><code>           Delete(Tmp,1,1);</code></p>
     <p><code>           Result := Tmp;</code></p>
     <p><code>           i := FDosEnvList.Count <emphasis>{ end while-loop }</emphasis></code></p>
     <p><code>         <strong>end</strong></code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong> <emphasis>{GetDosEnvStr}</emphasis>;</code></p>
     <p><code> <strong>end</strong>.</code></p>
     <p>Здесь список переменных среды (предоставленный Deepak Shenoy), которые доступны для CGI программ. Даже ISAPI программы могут использовать эти переменные:</p>
     <table>
      <tr align="left">
       <th align="left" valign="top">Environment Variable </th>
       <th align="left" valign="top">Purpose/Meaning/Value</th>
      </tr>
      <tr align="left">
       <td align="left" valign="top">GATEWAY_INTERFACE </td>
       <td align="left" valign="top">Версия CGI для которой скомпилирован web сервер</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">SERVER_NAME </td>
       <td align="left" valign="top">IP адрес сервера или имя.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">SERVER_PORT </td>
       <td align="left" valign="top">Порт на сервере, которые принимает HTTP запросы.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">SERVER_PROTOCOL </td>
       <td align="left" valign="top">Имя и версия протокола, используемая для обработки запросов.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">SERVER_SOFTWARE </td>
       <td align="left" valign="top">Имя (и обычно версия) программного обеспечения сервера.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">AUTH_TYPE </td>
       <td align="left" valign="top">Схема проверки прав используемая сервером (NULL, BASIC)</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">CONTENT_FILE </td>
       <td align="left" valign="top">Файл используемый для передачи данных CGI программе (только Windows HTTPd/WinCGI).</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">CONTENT_LENGTH </td>
       <td align="left" valign="top">Количество байтов переданное на стандартный вход (STDIN) как содержимое POST запроса.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">CONTENT_TYPE </td>
       <td align="left" valign="top">Тип данных переданных на сервер.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">OUTPUT_FILE </td>
       <td align="left" valign="top">Имя файла для результата (только Windows HTTPd/WinCGI).</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">PATH_INFO </td>
       <td align="left" valign="top">Дополнительный, относительный путь переданный на сервер после имени скрипта, но до данных запроса.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">PATH_TRANSLATED </td>
       <td align="left" valign="top">Та же самая информация, но преобразованная из относительного пути в абсолютный.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">QUERY_STRING </td>
       <td align="left" valign="top">Данные переданные как часть URL, все после символа ? в URL.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">REMOTE_ADDR </td>
       <td align="left" valign="top">Адрес IP или имя сервера конечного пользователя.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">REMOTE_USER </td>
       <td align="left" valign="top">Имя пользователя, если используется схема проверки прав.</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">REQUEST_LINE </td>
       <td align="left" valign="top">Полный HTTP запрос представляемый сервером (зависит от сервера).</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">REQUEST_METHOD </td>
       <td align="left" valign="top">Указывает метод передачи данных, как часть URL (GET) или через стандартный ввод STDIN (POST).</td>
      </tr>
      <tr align="left">
       <td align="left" valign="top">SCRIPT_NAME</td>
       <td align="left" valign="top">Имя запущенного скрипта.</td>
      </tr>
     </table>
     <p>Немного еще дополнительной, но важной информации. Немного об переменных среды, которые особо важны для обработки запроса, и небольшое описание по обработке стандартных CGI приложений:</p>
     <p>REQUEST_METHOD – указывает, как посланы данные, как POST или как GET метод.</p>
     <p>QUERY_STRING – если используется GET</p>
     <p>CONTENT_LENGTH – если мы используем POST, то мы должны прочитать "CONTENT_LENGTH" символов со стандартного ввода (которые оканчиваются "Query", подобно QUERY_STRING при использовании метода GET).</p>
     <p>Во всех случаях стандартное CGI приложение должно писать свой вывод на стандартный выход, если мы используем консольное приложение.</p>
     <p>Теперь с помощью компонента TBDosEnvironment мы создадим приложение, которое примет все три переменных среды, описанных выше и получит необходимые данные. После этого мы напишем код генерирующий вывод.</p>
     <p><emphasis>Правда просто?</emphasis> Для другого очень маленького (39 Кб) стандартного CGI приложения, проверьте Search Engine на моем web сайте. Краткий исходный код будет опубликован в одной из статей в The Delphi Magazine, но я могу сказать, что базовый протокол CGI связи не более сложный, чем представленный здесь.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042066">1.3.6. Input Queries</p>
     </title>
     <p>Сейчас мы попробуем прочитать запрос в стандартном CGI приложении с помощью 32-битной версии Дельфи (Delphi 2.x или 3.x).</p>
     <p>Обычно это двух ступенчатый процесс. Первый шаг создание HTML и специальный CGI Form-тегов, второй шаг получение данных внутри CGI приложения на сервере.</p>
     <p>HTML CGI форма определяется с помощью тегов &lt;FORM&gt;…&lt;/FORM&gt;. Открывающий тег также содержит имя метода (GET or POST) и действие, которое является URLом CGI приложения на web сервере. Например:</p>
     <p><code>&lt;FORM ACTION=http://www.drbob42.com/cgi-bin/debug.exe METHOD=POST&gt;</code></p>
     <p><code>…</code></p>
     <p><code>&lt;/FORM</code></p>
     <p>Данная HTML CGI форма посылает свои данные методом POST на мой web сервер, и выполняет программу debug.exe (из каталога cgi-bin). В данный момент мы пока не знакомы с концепцией различий между методами POST и GET (Я всегда использую метод POST). Мы заметим, что здесь пока нет ничего что бы посылать на сервер методом POST, это позже. Мы должны указать поля ввода внутри CGI формы. Для этого мы поместим некоторое количество наиболее стандартных Windows органов управления, все они предопределены, подобно editbox, memo, listbox, drop-down combobox, radiobuttons, checkboxes и конечно клавиши "action" (reset или submit).</p>
     <p>Простой editbox это поля ввода типа "text", которое обязано иметь имя и необязательно размер и ширину в пикселях, и может иметь значение:</p>
     <p><code>&lt;INPUT TYPE=text NAME=login SIZE=8&gt;</code></p>
     <p>Результатом этой фразы будет нарисован editbox в котором можно ввести до восьми символов, и которое будет послано нашему CGI приложению как "login=xxxxxxxx", где xxxxxxxx данные введенные на форме в окошке подобному этому</p>
     <image l:href="#Any2FbImgLoader2"/>
     <p>Стандартное CGI приложение обязано проверить переменную среды REQUEST-METHOD для определения метода передачи данных. В случае POST, мы должны проверить CONTENT-LENGTH для определения количества символов, которые необходимо прочесть со стандартного ввода. Стандартный ввод содержит данные (такие как "login-xxxxxxxx") для нашего CGI приложения.</p>
     <p>Вместо написания сложного стартового кода для каждого CGI приложения, я написал модуль DrBobCGI для выполнения всех необходимых стартовых процедур и извлечения входных данных и доступных затем через вызов единственной функции, называемой "Value". Так для выше приведенного примера мы можем вызвать "Value('login')" для получения строки 'xxxxxxxx'.</p>
     <p><code><strong>unit</strong> DrBobCGI;</code></p>
     <p><code> {$I-}</code></p>
     <p><code> <strong>interface</strong></code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   ContentLength: Integer = 0;</code></p>
     <empty-line/>
     <p><code>   <strong>function</strong> Value(<strong>const</strong> Field: ShortString): ShortString;</code></p>
     <p><code>   <emphasis>{ use this function to get the CGI inputquery values }</emphasis></code></p>
     <empty-line/>
     <p><code> <strong>implementation</strong></code></p>
     <p><code> <strong>uses</strong></code></p>
     <p><code>   SysUtils, Windows;</code></p>
     <empty-line/>
     <p><code> <strong>var</strong></code></p>
     <p><code>   Data: <strong>String</strong> = '';</code></p>
     <empty-line/>
     <p><code>   <strong>function</strong> Value(<strong>const</strong> Field: ShortString): ShortString;</code></p>
     <p><code>   <strong>var</strong></code></p>
     <p><code>     i: Integer;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Result := '';</code></p>
     <p><code>     i := Pos(Field+'=',Data);</code></p>
     <p><code>     <strong>if</strong> i &gt; 0 <strong>then</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Inc(i,Length(Field)+1);</code></p>
     <p><code>       <strong>while</strong> Data[i] &lt;&gt; '&amp;' <strong>do</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         Result := Result + Data[i];</code></p>
     <p><code>         Inc(i)</code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong> <emphasis>{Value}</emphasis>;</code></p>
     <empty-line/>
     <p><code> <strong>var</strong></code></p>
     <p><code>   P: PChar;</code></p>
     <p><code>   i: Integer;</code></p>
     <p><code>   Str: ShortString;</code></p>
     <empty-line/>
     <p><code> <strong>type</strong></code></p>
     <p><code>   TRequestMethod = (Unknown,Get,Post);</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   RequestMethod: TRequestMethod = Unknown;</code></p>
     <empty-line/>
     <p><code> initialization</code></p>
     <p><code>   P := GetEnvironmentStrings;</code></p>
     <p><code>   <strong>while</strong> P^ &lt;&gt; #0 <strong>do</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Str := StrPas(P);</code></p>
     <p><code>     <strong>if</strong> Pos('REQUEST_METHOD=',Str) &gt; 0 <strong>then</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Delete(Str,1,Pos('=',Str));</code></p>
     <p><code>       <strong>if</strong> Str = 'POST' <strong>then</strong> RequestMethod := Post</code></p>
     <p><code>       <strong>else</strong></code></p>
     <p><code>         <strong>if</strong> Str = 'GET' <strong>then</strong> RequestMethod := Get</code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>     <strong>if</strong> Pos('CONTENT_LENGTH=',Str) = 1 <strong>then</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Delete(Str,1,Pos('=',Str));</code></p>
     <p><code>       ContentLength := StrToInt(Str)</code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>     <strong>if</strong> Pos('QUERY_STRING=',Str) &gt; 0 <strong>then</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Delete(Str,1,Pos('=',Str));</code></p>
     <p><code>       SetLength(Data,Length(Str)+1);</code></p>
     <p><code>       Data := Str</code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>     Inc(P, StrLen(P)+1)</code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <p><code>   <strong>if</strong> RequestMethod = Post <strong>then</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     SetLength(Data,ContentLength+1);</code></p>
     <p><code>     <strong>for</strong> i:=1 <strong>to</strong> ContentLength <strong>do read</strong>(Data[i]);</code></p>
     <p><code>     Data[ContentLength+1] := '&amp;';</code></p>
     <p><code>   { if IOResult &lt;&gt; 0 then { skip }</code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <p><code>   i := 0;</code></p>
     <p><code>   <strong>while</strong> i &lt; Length(Data) <strong>do</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Inc(i);</code></p>
     <p><code>     <strong>if</strong> Data[i] = '+' <strong>then</strong> Data[i] := ' ';</code></p>
     <p><code>     <strong>if</strong> (Data[i] = '%') <strong>then</strong> <emphasis>{ special code }</emphasis></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Str := '$00';</code></p>
     <p><code>       Str[2] := Data[i+1];</code></p>
     <p><code>       Str[3] := Data[i+2];</code></p>
     <p><code>       Delete(Data,i+1,2);</code></p>
     <p><code>       Data[i] := Chr(StrToInt(Str))</code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <p><code>   <strong>if</strong> i &gt; 0 <strong>then</strong> Data[i+1] := '&amp;'</code></p>
     <p><code>            <strong>else</strong> Data := '&amp;'</code></p>
     <p><code> <strong>finalization</strong></code></p>
     <p><code>   Data := ''</code></p>
     <p><code> end.</code></p>
     <p>Я написал кучу CGI приложений за последний год и все они используют модуль DrBobCGI. Теперь реальное пример: стандартное CGI приложение – гостевая книга (guestbook), в которой запрашивается ваше имя и небольшой комментарий, написанное с помощью всего нескольких строк на Дельфи.</p>
     <p>Вначале CGI форма:</p>
     <p><code>&lt;HTML&gt;</code></p>
     <p><code>&lt;BODY&gt;</code></p>
     <p><code>&lt;H2&gt;Dr.Bob's Guestbook&lt;/H2&gt;</code></p>
     <p><code>&lt;FORM ACTION=http://www.drbob42.com/cgi-bin/guest.exe</code></p>
     <p><code>  METHOD=POST&gt; </code></p>
     <p><code>  Name: &lt;INPUT TYPE=text NAME=name&gt;&lt;BR&gt;</code></p>
     <p><code>  Comments: &lt;TEXTAREA COLS=42 LINES=4 NAME=comments&gt;</code></p>
     <p><code>  &lt;P&gt;</code></p>
     <p><code>  &lt;INPUT TYPE=SUBMIT VALUE="Send Comments <strong>to</strong> Dr.Bob"&gt;</code></p>
     <p><code>  &lt;/FORM&gt;</code></p>
     <p><code>  &lt;/BODY&gt;</code></p>
     <p><code>  &lt;/HTML&gt;</code></p>
     <p>Теперь консольное приложение:</p>
     <p><code> program CGI;</code></p>
     <p><code> <emphasis>{$I-}</emphasis></code></p>
     <p><code> <emphasis>{$APPTYPE CONSOLE}</emphasis></code></p>
     <p><code> uses</code></p>
     <p><code>   DrBobCGI;</code></p>
     <p><code> var</code></p>
     <p><code>   guest: Text;</code></p>
     <p><code>   Str: String;</code></p>
     <p><code> begin</code></p>
     <p><code>   Assign(guest,'book.htm'); // assuming that's the guestbook</code></p>
     <p><code>   Append(guest);</code></p>
     <p><code>   if IOResult &lt;&gt; 0 then // open new guestbook</code></p>
     <p><code>   begin</code></p>
     <p><code>     Rewrite(guest);</code></p>
     <p><code>     writeln(guest,'&lt;HTML&gt;');</code></p>
     <p><code>     writeln(guest,'&lt;BODY&gt;')</code></p>
     <p><code>   end;</code></p>
     <p><code>   writeln(guest,'Date: ',DateTimeToStr(Now),'&lt;BR&gt;');</code></p>
     <p><code>   writeln(guest,'Name: ',Value('name'),'&lt;BR&gt;');</code></p>
     <p><code>   writeln(guest,'Comments: ',Value('comments'),'&lt;HR&gt;');</code></p>
     <p><code>   reset(guest);</code></p>
     <p><code>   while not eof(guest) do // now output guestbook itself</code></p>
     <p><code>   begin</code></p>
     <p><code>     readln(guest,Str);</code></p>
     <p><code>     writeln(Str)</code></p>
     <p><code>   end;</code></p>
     <p><code>   close(guest);</code></p>
     <p><code>   writeln('&lt;/BODY&gt;');</code></p>
     <p><code>   writeln('&lt;/HTML&gt;')</code></p>
     <empty-line/>
     <image l:href="#Any2FbImgLoader3"/>
     <subtitle>Вопрос:</subtitle>
     <p>У меня на форме две "submit" клавиши, одна на переход на предыдущую страницу, другая переход на следующую страницу. Как определить какая из них была нажата, чтобы я мог выполнить соответствующее действие.</p>
     <subtitle>Доктор Боб отвечает:</subtitle>
     <empty-line/>
     <p>Вы должны назначить уникальное значение для каждой кнопки "type=submit", ниже приведен соответствующий код:</p>
     <empty-line/>
     <p><code>&lt;HTML&gt;</code></p>
     <p><code>&lt;BODY&gt;</code></p>
     <p><code>Edit the information and press the SAVE button&lt;BR&gt;</code></p>
     <p><code>To Delete information, press the DELETE button&lt;BR&gt;</code></p>
     <p><code>&lt;P&gt;</code></p>
     <p><code>&lt;FORM METHOD=POST ACTION=http://www.drbob42.com/cgi-bin/debug.exe&gt;</code></p>
     <p><code>&lt;HR&gt;</code></p>
     <p><code>&lt;input type=text name=name&gt;</code></p>
     <p><code>&lt;P&gt;</code></p>
     <p><code>&lt;input type=reset  value="RESET"&gt;</code></p>
     <p><code>&lt;input type=submit name=action value="SAVE"&gt;</code></p>
     <p><code>&lt;input type=submit name=action value="DELETE"&gt;</code></p>
     <p><code>&lt;/FORM&gt;</code></p>
     <p><code>&lt;/BODY&gt;</code></p>
     <p><code>&lt;/HTML&gt;</code></p>
     <p>Вы должны получить "Action=SAVE" или "Action=DELETE" после нажатия одной из этих кнопок.</p>
    </section>
   </section>
  </section>
  <section>
   <title>
    <p id="AutBody_0_toc485042067">2. html и CGI/WinCGI "трудный путь"</p>
   </title>
   <section>
    <p>В данной главе показывается, как опубликовать вашу базу данных в Интернете путем (1) генерации статических страниц из таблиц базы данных, (2) написания CGI/WinCGI приложений для выполнения запросов к базе данных без использования Delphi Web Modules.</p>
   </section>
   <section>
    <title>
     <p>2.1. HTML– страницы</p>
    </title>
    <section>
     <p>Допустим, вы имеете базу данных с продуктами. Бумажная реклама очень накладна. Но реклама в web это что-то новое и за приемлемую цену. Хорошо было бы иметь вашу базу опубликованной в Интернете, не так ли? Но организация своего собственного сайта на NT Web Server, работающего с инструментом типа IntraBuilder или WebHub стоит больших денег, включая время ни эксперименты и настройку. В данной главе мы покажем быстрый путь и простой путь публикации вашей базы данных на web: просто генерируя статические HTML страницы, базируясь на записях в таблице. <emphasis>Накладно?</emphasis> Нет. Сложно<emphasis>?</emphasis> Я так не думаю. Позвольте указать простой путь на небольшой базе данных.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm1">2.1.1. Delphi и HTML</p>
     </title>
     <p>Мой главный инструмент разработчики это Дельфи, и мы напишем Delphi Database HTML Expert в данной главе. Дельфи позволяет подсоединяться практически к базе данных любого формата. С помощью BDE к Парадоксу и dBASE, с помощью ODBC например к Access, и с помощью SQL Links к большим DBMS типа InterBase, Oracle, Sybase и Informix. Также, вы можете купить дополнительные продукты типа Apollo для связи с таблицами Clipper и FoxPro. В этой главе мы будем использовать базы формата Парадокс. Парадокс имеет достаточно развитый формат, что решает многие проблемы при преобразовании полей, типов и значения из базы в HTML.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm2">2.1.2. Basic HTML</p>
     </title>
     <p>Ввод будет преобразовываться в формат базы данных, а вывод в формат HTML-страниц.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm3">2.1.3. Преобразование полей</p>
     </title>
     <p>HTML страница может содержать только простой ASCII текст. Конечно, здесь могут быть и другие вещи встроенный в текст, обычно картинки в .GIF или .JPEG формат. Таблица базы данных содержит поля, у которых есть значения, которые можно преобразовать в строки символов. Дельфи даже имеет встроенное свойство "AsString" для всех основных классов наследованных от TField. Свойство AsString в действительно преобразующие свойство. Для TStringField, AsString может использоваться для чтения значения из поля как строка. Для TBCDField, TCurrencyField, TDateField, TDateTimeField, TFloatField, TIntegerField, TSmallintField, TTimeField, и TWordField, свойство AsString преобразует тип в строку при чтении из поля. Для TBooleanField, свойство AsString возвращает 'T' или 'F'. Для TMemoField, TGraphicField, TBlobField, TBytesField или TVarBytesField, свойство AsString должно использоваться только для чтения из поля. Это возвращает строковое выражение '(Memo)', '(Graphic)', '(Blob)', '(Bytes)' или '(Var Bytes)' соответственно. Так как мемо поля могут содержать важную текстовую информацию, я решил игнорировать все кроме TMemoField, и при работе с TMemoField мы можем использовать метод SaveToStream для чтения данных из поля, как мы увидим это позже. Так что мы можем разделить их на две группы: те у которых мы можем использовать свойство AsString, и те у которых нет. Мы можем определить третий тип (неизвестный – unknown), и использовать следующие определения для таблиц не более 255 полей:</p>
     <p><code>const</code></p>
     <p><code>  MaxField = 255;</code></p>
     <p><code>  sf_UnKnown = 0;</code></p>
     <p><code>  sf_String  = 1;</code></p>
     <p><code>  sf_Memo    = 2;</code></p>
     <empty-line/>
     <p><code>var</code></p>
     <p><code>  FieldTypes: Array[0..Pred(MaxField)] of Byte; <emphasis>{ default unknowns }</emphasis></code></p>
     <p>Мы должны просмотреть структуру таблицы для получения информации об типах полей:</p>
     <p><code> <strong>with</strong> TTable.Create(<strong>nil</strong>) <strong>do</strong></code></p>
     <p><code> <strong>try</strong></code></p>
     <p><code>   DatabaseName := ADatabase;</code></p>
     <p><code>   TableName := ATable;</code></p>
     <p><code>   Active := True;</code></p>
     <p><code>   keys := -1; { no key in table }</code></p>
     <p><code>   <strong>for</strong> i:=0 <strong>to</strong> Pred(FieldDefs.Count) <strong>do</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>if</strong> Fields[i].IsIndexField <strong>then</strong> keys := i;</code></p>
     <p><code>     FieldTypes[i] := sf_String; { default }</code></p>
     <p><code>     <strong>if</strong> (FieldDefs[i].FieldClass = TMemoField) <strong>then</strong></code></p>
     <p><code>       FieldTypes[i] := sf_Memo</code></p>
     <p><code>     <strong>else</strong></code></p>
     <p><code>       <strong>if</strong> (FieldDefs[i].FieldClass = TGraphicField) <strong>or</strong></code></p>
     <p><code>          (FieldDefs[i].FieldClass = TBlobField) <strong>or</strong></code></p>
     <p><code>          (FieldDefs[i].FieldClass = TBytesField) <strong>or</strong></code></p>
     <p><code>          (FieldDefs[i].FieldClass = TVarBytesField) <strong>then</strong></code></p>
     <p><code>         FieldTypes[i] := sf_UnKnown { ignore }</code></p>
     <p><code>   <strong>end</strong></code></p>
     <p><code> <strong>finally</strong></code></p>
     <p><code>   Free</code></p>
     <p><code> <strong>end</strong>;</code></p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm4">2.1.4. Записи</p>
     </title>
     <p>После анализа полей таблицы, мы можем пройтись по всей таблице и получить значения полей. Для каждой записи в таблице мы сгенерируем HTML-страницу. Мы можем использовать имена полей как заголовки, используя тег &lt;H2&gt; для ключевых полей и тег &lt;H3&gt; для не ключевых полей. Код просматривает всю таблицу т преобразовывает поля в текст и выводит их в HTML-файл:</p>
     <p><code><strong>while not</strong> Eof <strong>do</strong></code></p>
     <p><code><strong>begin</strong></code></p>
     <p><code>  Inc(RecNr);</code></p>
     <p><code>  System.Assign(f,FileName+'/'+PageNr(RecNr));</code></p>
     <p><code>  System.Rewrite(f);</code></p>
     <p><code>  writeln(f,'&lt;HTML&gt;');</code></p>
     <p><code>  writeln(f,'&lt;HEADER&gt;');</code></p>
     <p><code>  writeln(f,'&lt;TITLE&gt;');</code></p>
     <p><code>  writeln(f,Format('%s %d/%d',[ATable,RecNr,RecordCount]));</code></p>
     <p><code>  writeln(f,'&lt;/TITLE&gt;');</code></p>
     <p><code>  writeln(f,'&lt;/HEADER&gt;');</code></p>
     <p><code>  writeln(f,'&lt;BODY&gt;');</code></p>
     <p><code>  <emphasis>{ print fields }</emphasis></code></p>
     <p><code>  <strong>for</strong> i:=0 <strong>to</strong> Pred(FieldCount) <strong>do</strong> </code></p>
     <p><code>    <strong>if</strong> FieldTypes[i] &gt; sf_UnKnown <strong>then</strong></code></p>
     <p><code>    <strong>begin</strong></code></p>
     <p><code>      <strong>if</strong> (keys &gt;= i) <strong>then</strong> writeln(f,'&lt;H2&gt;')</code></p>
     <p><code>                     <strong>else</strong> writeln(f,'&lt;H3&gt;');</code></p>
     <p><code>      writeln(f,FieldDefs[i].Name,':');</code></p>
     <p><code>      <strong>if</strong> (keys &gt;= i) <strong>then</strong> writeln(f,'&lt;/B&gt;&lt;BR&gt;') <emphasis>{ &lt;/H2&gt; }</emphasis></code></p>
     <p><code>                     <strong>else</strong> writeln(f,'&lt;/B&gt;&lt;BR&gt;'); <emphasis>{ &lt;/H3&gt; }</emphasis></code></p>
     <p><code>      <strong>if</strong> FieldTypes[i] = sf_Memo <strong>then</strong></code></p>
     <p><code>        writeMemo(f,Fields[i])</code></p>
     <p><code>      <strong>else</strong> writeln(f,Fields[i].AsString);</code></p>
     <p><code>      <strong>if</strong> (keys = i) <strong>then</strong> writeln(f,'&lt;HR&gt;');</code></p>
     <p><code>    <strong>end</strong>;</code></p>
     <p><code>    writeln(f,'&lt;/BODY&gt;');</code></p>
     <p><code>    writeln(f,'&lt;/HTML&gt;');</code></p>
     <p><code>    System.Close(f);</code></p>
     <p><code>    Next</code></p>
     <p><code>  <strong>end</strong>;</code></p>
     <p>Заметим, что я использую здесь одно недокументированное свойство HTML: для окончания заголовка вы можете написать &lt;/B&gt;, но вы должны использовать &lt;BR&gt; для разрыва строки. Таким образом, вы можете иметь заголовки, и текст, начинающийся правее и ниже заголовка. Пожалуйста, учтите, что это недокументированное свойство и вы должны заменить его раскомментировав &lt;/H2&gt; и &lt;/H3&gt; если вы не желаете жить на угле &lt;юмор&gt;. Следующий листинг показывает как получить информацию из мемо поля базы данных и поместить его в текстовый файл. И наконец после этого мы отформатируем немного, помня что HTML игнорирует множественные переводы строки и пробелы.</p>
     <p><code> <strong>procedure</strong> WriteStream(<strong>var</strong> f: Text; <strong>var</strong> Stream: TMemoryStream);</code></p>
     <p><code> <strong>const</strong></code></p>
     <p><code>   LF = #10;</code></p>
     <p><code>   BufSize = 8192; { bigger memos are chopped off!! }</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   Buffer: <strong>Array</strong>[0..Pred(BufSize)] <strong>of</strong> Char;</code></p>
     <p><code>   i: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   Stream.Seek(0,0);</code></p>
     <p><code>   <strong>if</strong> Stream.Size &gt; 0 <strong>then</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Stream.<strong>Read</strong>(Buffer,Stream.Size);</code></p>
     <p><code>     <strong>for</strong> i:=0 <strong>to</strong> Pred(Pred(Stream.Size)) <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       <emphasis>{ empty line converted to &lt;P&gt; break }</emphasis></code></p>
     <p><code>       <strong>if</strong> (Buffer[i] = LF) <strong>and</strong> (Buffer[i+1] = LF) <strong>then</strong> writeln(f,'&lt;P&gt;');</code></p>
     <p><code>       <emphasis>{ strip multiple spaces (are ignored anyway) }</emphasis></code></p>
     <p><code>       <strong>if not</strong> ((Buffer[i] = ' ') <strong>and</strong> (Buffer[i+1] = ' ')) <strong>then write</strong>(f,Buffer[i]);</code></p>
     <p><code>       <emphasis>{ start new sentence on a new line (but only in HTML doc itself }</emphasis></code></p>
     <p><code>       <strong>if</strong> (Buffer[i] = '.') <strong>and</strong> (Buffer[i+1] = ' ') <strong>then</strong> writeln(f)</code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>     writeln(f,Buffer[Pred(Stream.Size)])</code></p>
     <p><code>   <strong>end</strong></code></p>
     <p><code>   <strong>else</strong> writeln(f,' ') <emphasis>{ empty memo }</emphasis></code></p>
     <p><code> <strong>end</strong> <emphasis>{WriteStream}</emphasis>;</code></p>
     <p><code> <strong>procedure</strong> WriteMemo(<strong>var</strong> f: Text; Field: TField);</code></p>
     <p><code> <strong>var</strong> Stream: TMemoryStream;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   Stream := TMemoryStream.Create;</code></p>
     <p><code>  (Field AS TMemoField).SaveToStream(Stream);</code></p>
     <p><code>   WriteStream(f,Stream);</code></p>
     <p><code>   Stream.Free</code></p>
     <p><code> <strong>end</strong> {WriteMemo};</code></p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm5">2.1.5. Страницы</p>
     </title>
     <p>Теперь у нас есть метод преобразования записей в HTML страницы, нам также нужен путь уникальной идентификации каждой записи. Допустим, что база данных не не содержит более 100,000 записей (Если таблица содержит свыше 100,000 записей, то конвертирование их в HTML страницы наверно не очень хорошая идея), Я думаю что подойдет схема где каждая запись помещается в файл с именем "pag#####.htm", где ##### номер записи в базе данных. Для уменьшения конфликта имен, каждая таблица должна размещаться в своем собственном каталоге (например, BIOLIFE.HTM каталог для BIOLIFE.DB таблиц, так что мы будем иметь BIOLIFE.HTM/PAG00001.HTM для первой записи из BIOLIFE.DB таблицы).</p>
     <p><code> <strong>const</strong></code></p>
     <p><code>   FirstPage = 'pag00001.htm';</code></p>
     <p><code>   LastPage: TPageName = 'pag%.5d.htm'; <emphasis>{ format }</emphasis></code></p>
     <empty-line/>
     <p><code>   <strong>function</strong> PageNr(Nr: Word): TPageName;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Result := Format('pag%.5d.htm',[Nr])</code></p>
     <p><code>   <strong>end</strong> <emphasis>{PageNr}</emphasis>;</code></p>
     <p>Кроме первой страницы PAG00001.HTM, нам также необходимо знать имя последней страницы, и функцию, которая нам даст номер текущей страницы для номера записи.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm6">2.1.6. HTML "Живые" клавиши</p>
     </title>
     <p>Неплохо также иметь путь для навигации по записям таблицы, для этого я использую IMAGE MAP, встроенный в HTML-страницу и работающий даже если браузер загружает локальный файл. HTML-синтаксис для отображения картинки следующий:</p>
     <p><code>&lt;IMG SRC="image.gif"&gt;</code></p>
     <image l:href="#Any2FbImgLoader4"/>
     <p>где image.gif это файл типа .GIF или .JPEG. Мы можем вставить опцию USEMAP в тег, для указания имени карты образа, например:</p>
     <p><code>&lt;IMG SRC="image.gif" USEMAP="#map"&gt;</code></p>
     <p>Внутри страницы мы можем ссылаться на "#map", а в действительности на картинку. Image map ничего более чем список координат и ссылок. Переход на ссылку произойдет, мы щелкнем мышкой в указанных координатах. HTML-синтаксис карты образа, the image map выглядит как навигационная панель размером 25x125 пикселей:</p>
     <p><code>&lt;MAP NAME="map"&gt;</code></p>
     <p><code>&lt;AREA SHAPE="rect" COORDS="51,0,75,25" HREF="next"&gt;</code></p>
     <p><code>&lt;AREA SHAPE="rect" COORDS="76,0,100,25" HREF="last"&gt;</code></p>
     <p><code>&lt;AREA SHAPE="rect" COORDS="101,0,125,25"HREF="this"&gt;</code></p>
     <p><code>&lt;/MAP&gt;</code></p>
     <p>Таким образом, мы можем свой навигатор по базе данных. Для этого нам необходимо иметь три картинки: одна для первой записи (клавиши первая и предыдущая запрещены), одна для последней записи (клавиши следующая и последняя запись запрещены) и одна для записей в середине таблицы (все клавиши разрешены). В каждой ситуации я назначаю ссылку для одной из клавиш на другую страницу. Это обеспечивает сильную обратную связь между нажатиями на клавиши. Конечно, клавиши не могут быть надавлены, но мы имеем очень быстрый ответ по сравнению с Java или CGI-приложениями (все что происходит это только прыжок на другую страницу).</p>
     <p>NAVIGATL.GIF:</p>
     <image l:href="#Any2FbImgLoader5"/>
     <empty-line/>
     <p>NAVIGAT.GIF:</p>
     <image l:href="#Any2FbImgLoader4"/>
     <empty-line/>
     <p>NAVIGATR.GIF:</p>
     <image l:href="#Any2FbImgLoader6"/>
     <p>Вот код на Дельфи, который генерирует корректный образ и карту для каждой записи:</p>
     <p><code>  <strong>if</strong> (RecNr = 1) <strong>then</strong> <emphasis>{ first record }</emphasis></code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    writeln(f,'&lt;IMG SRC="../images/navigatl.gif" '+</code></p>
     <p><code>               'ALIGN=RIGHT USEMAP="#map" BORDER="0"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;MAP NAME="map"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="51,0,75,25"  HREF="'+</code></p>
     <p><code>                PageNr(2)+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="76,0,100,25" HREF="'+</code></p>
     <p><code>                LastPage+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="101,0,125,25"HREF="'+</code></p>
     <p><code>                PageNr(RecNr)+'"&gt;');</code></p>
     <p><code>  <strong>end</strong></code></p>
     <p><code>  <strong>else</strong></code></p>
     <p><code>  <strong>if</strong> (RecNr = RecordCount) <strong>then</strong> <emphasis>{ last record }</emphasis></code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    writeln(f,'&lt;IMG SRC="../images/navigatr.gif" '+</code></p>
     <p><code>               'ALIGN=RIGHT USEMAP="#map" BORDER="0"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;MAP NAME="map"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="0,0,25,25"   HREF="'+</code></p>
     <p><code>                FirstPage+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="26,0,50,25"  HREF="'+</code></p>
     <p><code>                PageNr(RecNr-1)+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="101,0,125,25"HREF="'+</code></p>
     <p><code>                PageNr(RecNr)+'"&gt;');</code></p>
     <p><code>  <strong>end</strong></code></p>
     <p><code>  <strong>else</strong> <emphasis>{ middle record }</emphasis></code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    writeln(f,'&lt;IMG SRC="../images/navigat.gif" '+</code></p>
     <p><code>              'ALIGN=RIGHT USEMAP="#map" BORDER="0"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;MAP NAME="map"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="0,0,25,25"   HREF="'+</code></p>
     <p><code>                FirstPage+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="26,0,50,25"  HREF="'+</code></p>
     <p><code>                PageNr(RecNr-1)+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="51,0,75,25"  HREF="'+</code></p>
     <p><code>                PageNr(RecNr+1)+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="76,0,100,25" HREF="'+</code></p>
     <p><code>                LastPage+'"&gt;');</code></p>
     <p><code>    writeln(f,'&lt;AREA SHAPE="rect" COORDS="101,0,125,25"HREF="'+</code></p>
     <p><code>                PageNr(RecNr)+'"&gt;');</code></p>
     <p><code>  <strong>end</strong>;</code></p>
     <p><code>  writeln(f,'&lt;/MAP&gt;');</code></p>
     <p>Все три образа панели навигации хранятся в общем каталоге "../images" и дают мне шанс конвертировать множество таблиц в одно и тоже время для всех точек только с помощью этих трех образов. В действительности, в нашей локальной интрасети мы имеем порядка 23 таблиц преобразованных в 200 HTML страниц, и все они используют эти самые три образа.</p>
    </section>
    <section>
     <title>
      <p>2.1.7. Первый результат</p>
     </title>
     <p>После конвертирования базы BIOLIFE.DB, которая содержит много текстовых данных в мемо поле и одно поле, которое мы игнорируем (image field), мы получили следующий результат (обратите внимание на заголовок, который показывает запись 1 из 28):</p>
     <image l:href="#Any2FbImgLoader7"/>
    </section>
    <section>
     <title>
      <p>2.1.8. Расширенный HTML</p>
     </title>
     <section>
      <p>Конечно, не всегда таблица содержит только текстовые поля. Иногда данные из таблице удобнее представлять в виде таблицы (grid или таблице подобной структуре). Для этого я должен ввести вас в расширенные HTML свойства: фреймы и таблицы.</p>
     </section>
     <section>
      <title>
       <p>2.1.8.1. Фреймы</p>
      </title>
      <p>Фреймы это в действительности расширение HTML+, которое не поддерживается некоторыми web браузерами. Фреймы это свойство разделения вашей web страницы на две или более страниц. Основное свойство фреймом то, что каждый фрейм может иметь свое собственное имя и может переходить в другое местонахождение. Так, вы можете иметь индекс или таблицу оглавления с левой стороны, и например действительное содержимое с правой стороны. Для таблицы со многими записями вы можете иметь список ключей слева (главный индекс) и одну индивидуальную запись справа. Ключевое значение слева конечно ссылка на актуальную страницу с данными в правом фрейме. Как только мы щелкнем по ссылке в главном индексе (левый фрейм) в правом фрейме появятся данные относящиеся к этому ключу. Дополнительно к двум фреймам мы должны иметь главную специальную страницу, в которой определяем количество и относительные позиции (и размер) этих фреймов. Я использую для левого фрейма имя "Menu" и размер 32% от текущей ширины экрана, для правого фрейма имя "Main" и остаток ширины экрана. В HTML коде это выглядит следующим образом:</p>
      <p><code>&lt;HTML&gt;</code></p>
      <p><code>&lt;FRAMESET COLS="32%,*"&gt;</code></p>
      <p><code>&lt;FRAME SRC="pag00000.htm" NAME="Menu"&gt;</code></p>
      <p><code>&lt;FRAME SRC="pag00001.htm" NAME="Main"&gt;</code></p>
      <p><code>&lt;/FRAMESET&gt;</code></p>
      <p><code>&lt;/HTML&gt;</code></p>
      <p>Конечно, вы можете иметь более значимые имена для фреймов (например имена таблиц), но я оставлю это на совести читателя.</p>
     </section>
     <section>
      <title>
       <p>2.1.8.2. Таблицы</p>
      </title>
      <p>Использование фреймов для показа содержимого индекса и одной записи это одна из возможностей. Но имеется возможность отображать это и как таблицу. HTML 3.0 поддерживает ТАБЛИЦЫ, которое является одним из наиболее используемых свойств наших дней. Таблицы с рамками и без могут использоваться для всего, что вы не можете сделать нормальным путем (например, нет метода иметь множественные колонки в HTML странице, без использования таблиц). В нашем случае это может быть двух колоночная таблица с рамкой. В левой колонке мы просто отображаем название каждого поля, а правой колонке – значение этого поля. Подобно предыдущему текстовому решению, единственная вещь которую нужно изменить это коды заголовков в коды таблицы. &lt;TR&gt; начинает новую строку таблицы, заканчивая ее тегом &lt;/TR&gt;. Тег &lt;TD&gt; открывает новое поле , закачивающее тегом &lt;/TD&gt;. Для окончательно преобразования, мы должны написать специальную индексную HTML страницу как файл (файл g в нашем случае). Преобразованный листинг выглядит следующим образом:</p>
      <p><code><strong>if</strong> (keys &gt;= 0) <strong>then</strong></code></p>
      <p><code><strong>begin</strong></code></p>
      <p><code>  writeln(g,'&lt;TR&gt;');</code></p>
      <p><code>  write(g,'&lt;TD&gt;&lt;A HREF="../',FileName,'/',PageNr(RecNr), '"TARGET="Main"&gt;');</code></p>
      <p><code>  writeln(g,RecNr:3,'&lt;/A&gt;&lt;/TD&gt;')</code></p>
      <p><code><strong>end</strong>;</code></p>
      <p><code>  { print fields }</code></p>
      <p><code>writeln(f,'&lt;TABLE BORDER&gt;');</code></p>
      <p><code><strong>for</strong> i:=0 <strong>to</strong> Pred(FieldCount) <strong>do if</strong> FieldTypes[i] &gt; sf_UnKnown <strong>then</strong></code></p>
      <p><code><strong>begin</strong></code></p>
      <p><code>  writeln(f,'&lt;TR&gt;');</code></p>
      <p><code>  write(f,'&lt;TD&gt;&lt;B&gt;',FieldDefs[i].Name,'&lt;/B&gt;&lt;/TD&gt;&lt;TD&gt;');</code></p>
      <p><code>  <strong>if</strong> FieldTypes[i] = sf_Memo <strong>then</strong></code></p>
      <p><code>    writeMemo(f,Fields[i])</code></p>
      <p><code>  <strong>else</strong> writeln(f,Fields[i].AsString);</code></p>
      <p><code>  writeln(f,'&lt;/TD&gt;&lt;/TR&gt;');</code></p>
      <p><code>  <strong>if</strong> (keys &gt;= i) <strong>then</strong></code></p>
      <p><code>    writeln(g,'&lt;TD&gt;',Fields[i].AsString,'&lt;/TD&gt;')</code></p>
      <p><code><strong>end</strong>;</code></p>
      <p><code><strong>if</strong> (keys &gt;= 0) <strong>then</strong> writeln(g,'&lt;/TR&gt;');</code></p>
      <p><code>writeln(f,'&lt;/TABLE&gt;');</code></p>
     </section>
     <section>
      <title>
       <p>2.1.9. Последний вариант конвертора</p>
      </title>
      <p>Имея объединенные фреймы и таблицы в нашем конверторе, мы можем переходить от простой BIOLIFE.DB таблицы к более реалистичной таблицы продуктов, например PARTS.DB. Данная таблица имеет больше цифровых и меньше "memo" (или тестовых) данных, и поэтому выглядит лучше когда данные отображаются в табличном виде с простыми заголовками.</p>
      <image l:href="#Any2FbImgLoader8"/>
      <p>"Живые" HTML кнопки работают также как и ранее, и мы можем выбирать любую запись из фрейма с индексом. Заметим, что содержимое правого фрейма также содержит текущую позицию (и общее количество записей) в таблице, так как это тоже генерируется на лету.</p>
      <p>В данный момент мы уже имеем два пути для преобразования таблицы в HTML страницу, или с помощью простого текстового конвертора или с помощью более сложного конвертора фрейм /таблица, Я написал маленькую программу, которая использует оба метода. Это простое консольное приложение, которое нуждается только в имени таблицы как аргумент командной строки (таблица должна находиться в текущем каталоге). По умолчанию используется нормальный метод преобразования, тем не менее, если ввести более одного параметра, то будет использоваться метод преобразования во фреймы с таблицами (сам дополнительный параметр игнорируется).</p>
      <p><code> <strong>program</strong> BDE2HTML;</code></p>
      <p><code> <emphasis>{$IFDEF WIN32}</emphasis></code></p>
      <p><code> <emphasis>{$APPTYPE CONSOLE}</emphasis></code></p>
      <p><code> <strong>uses</strong></code></p>
      <p><code> <emphasis>{$ELSE}</emphasis></code></p>
      <p><code> <strong>uses</strong> WinCrt,</code></p>
      <p><code> <emphasis>{$ENDIF}</emphasis></code></p>
      <p><code>      Convert, HTables;</code></p>
      <p><code> <strong>begin</strong></code></p>
      <p><code>   <strong>case</strong> ParamCount <strong>of</strong></code></p>
      <p><code>       0: writeln('Usage: BDE2HTML tablename');</code></p>
      <p><code>       1: Convert.DatabaseHTML('',ParamStr(1));</code></p>
      <p><code>     <strong>else</strong> HTables.DatabaseHTML('',ParamStr(1))</code></p>
      <p><code>   <strong>end</strong></code></p>
      <p><code> <strong>end</strong>.</code></p>
     </section>
    </section>
    <section>
     <title>
      <p>2.1.10. Линейка прогресса</p>
     </title>
     <p>Конвертирование маленьких таблиц в небольшое количество страниц не занимает много времени, не более нескольких секунд. Но конвертирование больших таблиц в сотни или тысячи страниц может занять несколько минут. По этой причине я сделал небольшой прогресс индикатор к конвертору. Простая форма с компонентом TGauge. Мы устанавливаем MinValue и Value в 0, а MaxValue в количество записей в таблице, и после генерации страницы мы увеличиваем значение Value на единицу. Небольшие часики в левом верхнем углу показываю количество пройденного времени:</p>
     <image l:href="#Any2FbImgLoader9"/>
    </section>
    <section>
     <title>
      <p>2.1.11. Производительность</p>
     </title>
     <p>Единственная разница между реальным приложением обработки баз данных (например с использованием BDE) и браузером базы данных это производительность. Наше "приложение" не нуждается ни в каких других приложениях, кроме стандартного браузера. Посылка данных по сети и взаимодействие эмулируется с помощью щелчков по картинке-навигатору и перехода по гипер-ссылке. Ни BDE или ISAPI/NSAPI программы не могут выполнять подобную архитектуру. Конечно, мы имеем только статические страницы, поэтому здесь нет возможности делать динамические запросы или преобразование базы данных. Поэтому нам нет нужды разрабатывать другие вещи, как CGI скрипты. Но наши сгенерированные страницы могут "имитировать" Парадокс базу, даже не Unix Web сервере! И особенно для баз, в которых изменения очень редки, например раз в неделю, это превосходная схема быстрой и простой организации web сайта.</p>
    </section>
    <section>
     <title>
      <p>2.1.12. Заключение</p>
     </title>
     <p>В данной главе мы увидели быстрый и простой путь преобразование Дельфи таблиц в платформа независимые HTML страницы; или текстовые с заголовками или в виде фрейм/таблица. Мы изучили, как использовать HTML технологию, включая карты-картинки, для имитации "живых" клавиш и выполнения действия. Данная технология может быть применима, как в Интернет, так и в Интранет приложениях (как минимум для меня). И в результате хорошая производительность по сравнению с другими решениями (ограничением может быть нехватка места на сервере, если вы имеете действительно большое количество HTML страниц). Что еще осталось (как задание для читателя) это поддержка показа картинок из базы данных и запросы (например, для генерации master-detail HTML страниц).</p>
    </section>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042083">2.2. CGI/WinCGI приложения</p>
    </title>
    <section>
     <p>Допустим, вы имеете базу данных с продуктами. Бумажная реклама очень накладна. Но реклама в web это что-то новое и за приемлемую цену. Хорошо бы было иметь вашу базу опубликованной в Интернете, не так ли? Но организация своего собственного сайта на NT Web Server, работающего с инструментом типа IntraBuilder или WebHub стоит больших денег, включая время ни эксперименты и настройку. В данной главе мы покажем быстрый путь и простой путь публикации вашей базы данных на web: просто генерируя статические HTML страницы, базируясь на записях в таблице. <emphasis>Накладно?</emphasis> Нет. <emphasis>Сложно?</emphasis> Я так не думаю. Позвольте указать простой путь на небольшой базе данных.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042084">2.2.1.Дельфи и CGI</p>
     </title>
     <p id="AutBody_0_hlt484189220">В то время как H T ml это стандарт для гипертекстовых документов, CGI означает Common Gateway Interface, и реализует связевой интерфейс между клиентом (Web браузер) и сервером (Web сервером). Имеется, по крайней мере, две различных формы CGI, стандартный CGI и высокоуровневый, называемый WinCGI (Windows (NT) CGI). Первый использует переменные среды и стандартные потоки ввода/вывода, второй использует файл формата Windows INI (в которых указываются имена входного и выходного файлов) для связи между клиентом и сервером, на котором запущено CGI приложение. Дельфи 2 CGI приложения являются не визуальными приложениями, то есть консольными приложениями, где на входе информация (запрос) от клиента, а на выходе динамический HTML документ, сгенерированный на лету и отправляемый обратно на клиенту в Web браузер. Информация, введенная на клиенте посылается серверу и используется для генерации HTML страницы, может быть послана двумя путями: или с помощью переменных среды (стандартный CGI) или с помощью Windows INI файлов (WinCGI). В данной главе мы сфокусируем свое внимание только на стандартных CGI приложениях!</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm15">2.2.2. CGI Формы</p>
     </title>
     <p>Для начала мы должны определить, что хочет клиент, как выглядит клиентская сторона. Как можно послать серверу информацию для выполнения? Для этого мы должны использовать специальное расширение HTML, называемое FORMS. Подобно Дельфи формам, форма это место на котором располагаются органы управления, такие как edit box, listbox, combobox, button или multi-line text field. В отличии от Дельфи мы имеем не визуальную среду разработки формы с использованием HTML кодов. Для примера приведу часть файла DELBOOKS.HTM. Полный файл можно взять на http://members.aol.com/drbobnl/delbooks.htm.</p>
     <p><code>&lt;FORM ACTION="http://www.drbob42.com/cgi-bin/delbooks.exe" METHOD="POST"&gt;</code></p>
     <p><code>&lt;UL&gt;</code></p>
     <p><code>&lt;INPUT TYPE="radio" NAME="DELPHI" VALUE="0" CHECKED&gt;Delphi 1.0x or 2.0x&lt;BR&gt;</code></p>
     <p><code>&lt;INPUT TYPE="radio" NAME="DELPHI" VALUE="1"&gt;Delphi 1.0x only&lt;BR&gt;</code></p>
     <p><code>&lt;INPUT TYPE="radio" NAME="DELPHI" VALUE="2"&gt;Delphi 2.0x only</code></p>
     <p><code>&lt;P&gt;</code></p>
     <p><code>&lt;LI&gt;Level:</code></p>
     <p><code>&lt;BR&gt;&lt;SELECT NAME="Level"&gt;</code></p>
     <p><code>    &lt;OPTION VALUE=""&gt; don't care</code></p>
     <p><code>    &lt;OPTION VALUE="1"&gt; Beginning</code></p>
     <p><code>    &lt;OPTION VALUE="2"&gt; Intermediate</code></p>
     <p><code>    &lt;OPTION VALUE="3"&gt; Advanced</code></p>
     <p><code>    &lt;/SELECT&gt;</code></p>
     <p><code>&lt;P&gt;</code></p>
     <p><code>&lt;/UL&gt;</code></p>
     <p><code>&lt;HR&gt;</code></p>
     <p><code>&lt;P&gt;</code></p>
     <p><code>&lt;INPUT TYPE="RESET" VALUE="Reset Query"&gt;</code></p>
     <p><code>&lt;INPUT TYPE="SUBMIT" VALUE="Get Results"&gt;</code></p>
     <p><code>&lt;/FORM&gt;</code></p>
     <p>Данный код показывает на форме два типа органов управления: три радио кнопки (выбор между "Delphi 1.0x or 2.0x", "Delphi 1.0x only" и "Delphi 2.0x only"), и combobox с четырьмя значениями ("don't care", "Beginning", "Intermediate" и "Advanced"). Так же имеется две обычные кнопки, одна типа "RESET", для сброса введенной информации и одна типа "SUBMIT", для отправки введенной информации. Для выполнения запроса из Web браузера на Web сервер необходимо нажать кнопку типа SUBMIT (в нашем случае кнопку с текстом "Get Results"). Но как сервер узнает, какое CGI приложение запускать для обработки запроса? Для этого мы должны обратить внимание на параметр ACTION в теге FORM (первая строка кода). Параметр ACTION указывает точное местонахождение CGI приложения, в нашем случае это http://www.drbob42.com/cgi-bin/delbooks.exe (но ребята не пытайтесь запускать это у себя дома, так как это ссылка внутри моей Интрасети, а не Интернета).</p>
     <p>В действительности "официальная" DELBOOKS.HTM содержит гораздо больше органов управления. Она также доступна на http://members.aol.com/drbobnl/delbooks.htm. В Netscape Navigator :</p>
     <image l:href="#Any2FbImgLoader10"/>
     <p>Нажатие на клавишу "Get Result" посылает информацию на Web сервер, котрый запускает delbooks.exe приложение с информацией введенной на форме. В нашем случае это может быть DELPHI="2", LEVEL="3", TITLE="", AUTHOR="Bob_Swart", PUBLISHER="" и ISBN="" (символ подчеркивания здесь означает пробел). Delphi 2 CGI приложение delbooks.exe обрабатывает полученную информацию, выполняет запрос и генерирует динамическую HTML страницу, которую отправляет на стандартный вывод. Web затем отправляет ее клиенту в его Webбраузеру который отображает ее на экране.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042086">2.2.3. Переменные среды</p>
     </title>
     <p>Стандартное CGI приложение должно анализировать переменные среды для определения метода передачи и размера посылаемой информации через стандартный ввод. Для получения списка переменных среды я всегда использую простой компонент, который я написал очень давно и компилирую его с помощью директив условной компиляции, как в Дельфи 1, так и в Дельфи 2.</p>
     <p><code> <strong>unit</strong> TBDosEnv;</code></p>
     <p><code> <strong>interface</strong></code></p>
     <p><code> <strong>uses</strong></code></p>
     <p><code>   SysUtils, WinTypes, WinProcs, Classes;</code></p>
     <p><code> <strong>type</strong></code></p>
     <p><code>   TBDosEnvironment = <strong>class</strong>(TComponent)</code></p>
     <p><code>   <strong>public</strong></code></p>
     <p><code>   <emphasis>{ Public class declarations (override) }</emphasis></code></p>
     <p><code>     <strong>constructor</strong> Create(AOwner: TComponent); <strong>override</strong>;</code></p>
     <p><code>     <strong>destructor</strong> Destroy; <strong>override</strong>;</code></p>
     <p><code>   <strong>private</strong></code></p>
     <p><code>   <emphasis>{ Private field declarations }</emphasis></code></p>
     <p><code>     FDosEnvList: TStringList;</code></p>
     <p><code>   <strong>protected</strong></code></p>
     <p><code>   <emphasis>{ Protected method declarations }</emphasis></code></p>
     <p><code>     <strong>function</strong> GetDosEnvCount: Word;</code></p>
     <p><code>   <strong>public</strong></code></p>
     <p><code>   <emphasis>{ Public interface declarations }</emphasis></code></p>
     <p><code>     <strong>function</strong> GetDosEnvStr(<strong>Const</strong> Name: <strong>String</strong>): <strong>String</strong>;</code></p>
     <p><code>     <emphasis>{ This function is a modified version of the GetEnvVar function that</emphasis></code></p>
     <p><code><emphasis>       appears in the WinDos unit that comes with Delphi. This function's</emphasis></code></p>
     <p><code><emphasis>       interface uses Pascal strings instead of null-terminated strings.</emphasis></code></p>
     <p><code><emphasis>     }</emphasis></code></p>
     <p><code>     <strong>property</strong> DosEnvCount: Word <strong>read</strong> GetDosEnvCount;</code></p>
     <p><code>     <strong>property</strong> DosEnvList: TStringList <strong>read</strong> FDosEnvList;</code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <p><code> <strong>implementation</strong></code></p>
     <p><code>   <strong>constructor</strong> TBDosEnvironment.Create(AOwner: TComponent);</code></p>
     <p><code>   <strong>var</strong> P: PChar;</code></p>
     <p><code>       i: Integer;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>inherited</strong> Create(AOwner);</code></p>
     <p><code>     FDosEnvList := TStringList.Create;</code></p>
     <p><code>     <emphasis>{$IFDEF WIN32}</emphasis></code></p>
     <p><code>     P := GetEnvironmentStrings;</code></p>
     <p><code>     <emphasis>{$ELSE}</emphasis></code></p>
     <p><code>     P := GetDosEnvironment; <emphasis>{ Win API }</emphasis></code></p>
     <p><code>     <emphasis>{$ENDIF}</emphasis></code></p>
     <p><code>     i := 0;</code></p>
     <p><code>     <strong>while</strong> P^ &lt;&gt; #0 <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Inc(i);</code></p>
     <p><code>       FDosEnvList.Add(StrPas(P));</code></p>
     <p><code>       Inc(P, StrLen(P)+1) <emphasis>{ Fast Jump to Next Var }</emphasis></code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>   <strong>end</strong> <emphasis>{Create}</emphasis>;</code></p>
     <p><code>   <strong>destructor</strong> TBDosEnvironment.Destroy;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     FDosEnvList.Free;</code></p>
     <p><code>     FDosEnvList := <strong>nil</strong>;</code></p>
     <p><code>     <strong>inherited</strong> Destroy</code></p>
     <p><code>   <strong>end</strong> <emphasis>{Destroy}</emphasis>;</code></p>
     <p><code>   <strong>function</strong> TBDosEnvironment.GetDosEnvCount: Word;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Result := 0;</code></p>
     <p><code>     <strong>if</strong> Assigned(FDosEnvList) <strong>then</strong> Result := FDosEnvList.Count</code></p>
     <p><code>   <strong>end</strong> <emphasis>{GetDosEnvCount}</emphasis>;</code></p>
     <p><code>   <strong>function</strong> TBDosEnvironment.GetDosEnvStr(<strong>Const</strong> Name: <strong>String</strong>): <strong>String</strong>;</code></p>
     <p><code>   <strong>var</strong> i: Integer;</code></p>
     <p><code>       Tmp: <strong>String</strong>;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     i := 0;</code></p>
     <p><code>     Result := '';</code></p>
     <p><code>     <strong>if</strong> Assigned(FDosEnvList) <strong>then while</strong> i &lt;FDosEnvList.Count &gt;<strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Tmp := FDosEnvList[i];</code></p>
     <p><code>       Inc(i);</code></p>
     <p><code>       <strong>if</strong> Pos(Name,Tmp) = 1 <strong>then</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         Delete(Tmp,1,Length(Name));</code></p>
     <p><code>         <strong>if</strong> Tmp[1] = '=' <strong>then</strong></code></p>
     <p><code>         <strong>begin</strong></code></p>
     <p><code>           Delete(Tmp,1,1);</code></p>
     <p><code>           Result := Tmp;</code></p>
     <p><code>           i := FDosEnvList.Count <emphasis>{ end while-loop }</emphasis></code></p>
     <p><code>         <strong>end</strong></code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong> <emphasis>{GetDosEnvStr}</emphasis>;</code></p>
     <p><code> <strong>end</strong>.</code></p>
     <p>Данный компонент получает список переменных среды во время своего создания. Свойство DosEnvCount и DosEnvList является свойством только для чтения и поэтому лучше его создавать его в на ходу, а не бросать на форму, так как берется только 'свежий' список переменных среды, а не загружается из .DFM файла).</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm16">2.2.4. Анализ</p>
     </title>
     <p>Среди переменных среды есть переменная с именем REQUEST_METHOD. Она должна иметь значение POST для нашего примера (Я не люблю другие методы). Затем мы должны найти размер информации, которая передана нам. Для этого мы должны получить переменную CONTENT_LENGTH. Сама информация поступает к нам через стандартный ввод (без маркера конца файла, поэтому наша задача не пытаться читать больше, чем нам передано). Данные поступающие через стандартный ввод имеют следующую форму FIELD=VALUE и разделяется с помощью символа '&amp;'. Например: AUTHOR="Bob_Swart"&amp;. Поскольку мы имеем весь входной поток, как одну длинную строку, то мы можем быстро найти параметр AUTHOR с помощью следующей функции:</p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   Data: String;</code></p>
     <p><code>   <strong>function</strong> Value(Const Field: ShortString): ShortString;</code></p>
     <p><code>   <strong>var</strong> i: Integer;</code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     Result := '';</code></p>
     <p><code>     i := Pos(Field+'=',Data);</code></p>
     <p><code>     <strong>if</strong> i = 0 <strong>then</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       Inc(i,Length(Field)+1);</code></p>
     <p><code>       <strong>while</strong> Data[i] &lt;&gt; '&amp;' <strong>do</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         Result := Result + Data[i];</code></p>
     <p><code>         Inc(i)</code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>end</strong> <emphasis>{Value}</emphasis>;</code></p>
     <p>Следующий шаблон кода показывает как динамически создать переменную TBDosEnvironment, прочитать информацию со стандартного ввода и получить строку готовую для анализа переменных формы. </p>
     <p><code> {$APPTYPE CONSOLE}</code></p>
     <p><code> <strong>var</strong></code></p>
     <p><code>   Data: <strong>String</strong>;</code></p>
     <p><code>   ContentLength,i,j: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   writeln('HTTP/1.0 200 OK');</code></p>
     <p><code>   writeln('SERVER: Dr.Bob''s Intranet WebServer 1.0');</code></p>
     <p><code>   writeln('CONTENT-<strong>TYPE</strong>: TEXT/HTML');</code></p>
     <p><code>   writeln;</code></p>
     <p><code>   writeln('&lt;HTML&gt;');</code></p>
     <p><code>   writeln('&lt;BODY&gt;');</code></p>
     <p><code>   writeln('&lt;I&gt;Generated by Dr.Bob''s CGI-Expert on &lt;/I&gt;',DateTimeToStr(Now));</code></p>
     <p><code>   <strong>with</strong> TBDosEnvironment.Create(<strong>nil</strong>) <strong>do</strong></code></p>
     <p><code>   <strong>begin</strong></code></p>
     <p><code>     <strong>for</strong> i := 0 <strong>to</strong> Pred(DosEnvCount) <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       <strong>if</strong> Pos('REQUEST_METHOD',DosEnvList[i])  0 <strong>then</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         Data := DosEnvList[i];</code></p>
     <p><code>         Delete(Data,1,Pos('=',Data))</code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p><code>     <strong>if</strong> Data = 'POST' <strong>then</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       ContentLength := StrToInt(GetDosEnvStr('CONTENT_LENGTH'));</code></p>
     <p><code>       SetLength(Data,ContentLength+1);</code></p>
     <p><code>       j := 0;</code></p>
     <p><code>       <strong>for</strong> i:=1 <strong>to</strong> ContentLength <strong>do</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         Inc(j);</code></p>
     <p><code>         <strong>read</strong>(Data[j]);</code></p>
     <p><code>       <strong>end</strong>;</code></p>
     <p><code>       Data[j+1] := '&amp;';</code></p>
     <p><code>       { now call Value or ValueAsInteger to obtain individual values }</code></p>
     <p><code>     <strong>end</strong>;</code></p>
     <p>Заметим, что первые три "writeln" строки, посылаемые на стандартный вывод, необходимы для браузера, что бы сообщить ему, что содержимое страницы имеет тип TEXT/HTML.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm17">2.2.5. Базы данных</p>
     </title>
     <p>При написании CGI приложений, вам необходим, какой то путь для доступа к данным базы. Одним из простых решений будет использование BDE и помещение ваших данных в таблицы Парадокса или dBASE. Если по какой либо причине BDE не инсталлировано на вашем NT Web сервере (может быть ваш дружественный Internet Provider не предоставляет вам BDE), вы можете использовать технику старых дней, используйте вместо базы данных файл записей.. Все что вам нужно, определить тип TRecord и написать программу, которая конвертирует вашу базу данных в file of TRecord.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm18">2.2.6. Преобразование</p>
     </title>
     <p>Если вы посмотрите на список полей Парадокса, то вам не составит труда понять, что не все поля можно просто конвертировать в текстовый формат, например типа Memo обычно не помещаются в короткие строки (Short String). <emphasis>А как начет Blob?</emphasis> Для данного типа полей я составил небольшую таблицу конвертирования.</p>
     <table>
      <tr>
       <th>Paradox field type </th>
       <th>ObjectPascal conversion type</th>
      </tr>
      <tr>
       <td>TStringField (size) </td>
       <td>String[length]</td>
      </tr>
      <tr>
       <td>TIntegerField, TWordField, TSmallIntField </td>
       <td>Integer</td>
      </tr>
      <tr>
       <td>Currency </td>
       <td>Double</td>
      </tr>
      <tr>
       <td>Memo, Blob</td>
       <td>n/a (ignored)</td>
      </tr>
     </table>
     <p>Использую данную таблицу не трудно небольшую программу, которая берет на вход таблицу и создает программу определения записи на Паскале.</p>
     <p><code>{$APPTYPE CONSOLE}</code></p>
     <p><code> <strong>uses</strong> DB, DBTables;</code></p>
     <p><code> <strong>var</strong> i: Integer;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   <strong>if</strong> ParamCount = 1 <strong>then with</strong> TTable.Create(<strong>nil</strong>) <strong>do</strong></code></p>
     <p><code>   <strong>try</strong></code></p>
     <p><code>     TableName := ParamStr(1);</code></p>
     <p><code>     Active := True;</code></p>
     <p><code>     writeln('Type');</code></p>
     <p><code>     writeln('  TRecord = record');</code></p>
     <p><code>     <strong>for</strong> i:=0 <strong>to</strong> Pred(FieldDefs.Count) <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       <strong>if</strong> (FieldDefs[i].FieldClass = TStringField) <strong>then</strong></code></p>
     <p><code>         writeln(' ':4,FieldDefs[i].Name,': <strong>String</strong>[',FieldDefs[i].Size,'];')</code></p>
     <p><code>       <strong>else</strong></code></p>
     <p><code>       <strong>begin</strong></code></p>
     <p><code>         <strong>if</strong> (FieldDefs[i].FieldClass = TIntegerField) <strong>or</strong></code></p>
     <p><code>            (FieldDefs[i].FieldClass = TWordField) <strong>or</strong></code></p>
     <p><code>            (FieldDefs[i].FieldClass = TSmallintField) <strong>then</strong></code></p>
     <p><code>           writeln(' ':4,FieldDefs[i].Name,': Integer;')</code></p>
     <p><code>         <strong>else</strong></code></p>
     <p><code>           <strong>if</strong> (FieldDefs[i].FieldClass = TCurrencyField) <strong>then</strong></code></p>
     <p><code>             writeln(' ':4,FieldDefs[i].Name,': Double;')</code></p>
     <p><code>           <strong>else</strong></code></p>
     <p><code>             writeln('{ ':6,FieldDefs[i].Name,' }')</code></p>
     <p><code>       <strong>end</strong></code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>finally</strong></code></p>
     <p><code>     writeln('  <strong>end</strong>;');</code></p>
     <p><code>     Free</code></p>
     <p><code>   <strong>end</strong></code></p>
     <p><code>   <strong>else</strong></code></p>
     <p><code>     writeln('Usage: <strong>record</strong> tablename')</code></p>
     <p><code> <strong>end</strong>.</code></p>
     <p>Конечно, таблица трансляции и программа определения записи должны быть расширены, что включить и другие типы полей Парадокса, но для примера и этого достаточно.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm19">2.2.7. Записи</p>
     </title>
     <p>После осознания, что мы можем писать на Delphi 2 CGI приложения без использования BDE, мы решили сгенерировать тип записи для нашей таблицы delbooks.db и конвертировать ее записи в файл записей. Использую программ RECORD.EXE из предыдущей главы мы получили следующее определение записи.</p>
     <p><code>Type</code></p>
     <p><code>   TRecord = <strong>record</strong></code></p>
     <p><code>     ISBN: <strong>String</strong>[16];</code></p>
     <p><code>     Title: <strong>String</strong>[64];</code></p>
     <p><code>     Author: <strong>String</strong>[64];</code></p>
     <p><code>     Publisher: <strong>String</strong>[32];</code></p>
     <p><code>     Price: Double;</code></p>
     <p><code>     Code: <strong>String</strong>[7];</code></p>
     <p><code>     <emphasis>{ Comments }</emphasis></code></p>
     <p><code>     Level: Integer;</code></p>
     <p><code>     TechnicalContentsQuality: Integer;</code></p>
     <p><code>     QualityOfWriting: Integer;</code></p>
     <p><code>     ValueForMoney: Integer;</code></p>
     <p><code>     OverallAssessment: Integer;</code></p>
     <p><code>     <emphasis>{ Cover }</emphasis></code></p>
     <p><code>   <strong>end</strong>;</code></p>
     <p>Теперь нам осталось написать сам конвертор, который в цикле просматривает записи таблицы, помещает их в запись и записывает в файл.</p>
     <p><code>{$APPTYPE CONSOLE}</code></p>
     <p><code> <strong>uses</strong> DB, DBTables, SysUtils;</code></p>
     <empty-line/>
     <p><code> <strong>var</strong> i: Integer;</code></p>
     <p><code>     Rec: TRecord;</code></p>
     <p><code>     F: <strong>File of</strong> TRecord;</code></p>
     <p><code> <strong>begin</strong></code></p>
     <p><code>   <strong>if</strong> ParamCount = 1 <strong>then with</strong> TTable.Create(<strong>nil</strong>) <strong>do</strong></code></p>
     <p><code>   <strong>try</strong></code></p>
     <p><code>     System.Assign(f,ChangeFileExt(ParamStr(1),'.REC'));</code></p>
     <p><code>     Rewrite(f);</code></p>
     <p><code>     TableName := ParamStr(1);</code></p>
     <p><code>     Active := True;</code></p>
     <p><code>     First;</code></p>
     <p><code>     <strong>while not</strong> Eof <strong>do with</strong> Rec <strong>do</strong></code></p>
     <p><code>     <strong>begin</strong></code></p>
     <p><code>       ISBN := FieldByName('ISBN').AsString;</code></p>
     <p><code>       Title := FieldByName('Title').AsString;</code></p>
     <p><code>       Author := FieldByName('Author').AsString;</code></p>
     <p><code>       Publisher := FieldByName('Publisher').AsString;</code></p>
     <p><code>       Price := FieldByName('Price').AsFloat;</code></p>
     <p><code>       Code := FieldByName('Code').AsString;</code></p>
     <p><code>       Level := FieldByName('Level').AsInteger;</code></p>
     <p><code>       TechnicalContentsQuality :=</code></p>
     <p><code>          FieldByName('TechnicalContentsQuality').AsInteger;</code></p>
     <p><code>       QualityOfWriting := FieldByName('QualityOfWriting').AsInteger;</code></p>
     <p><code>       ValueForMoney := FieldByName('ValueForMoney').AsInteger;</code></p>
     <p><code>       OverallAssessment := FieldByName('OverallAssessment').AsInteger;</code></p>
     <p><code>       <strong>write</strong>(f,Rec);</code></p>
     <p><code>       Next</code></p>
     <p><code>     <strong>end</strong></code></p>
     <p><code>   <strong>finally</strong></code></p>
     <p><code>     System.Close(f);</code></p>
     <p><code>     Free</code></p>
     <p><code>   <strong>end</strong></code></p>
     <p><code>   <strong>else</strong></code></p>
     <p><code>     writeln('Usage: convert tablename')</code></p>
     <p><code><strong> end.</strong></code></p>
     <p>Данная программа может использоваться для полного преобразования таблицы delbooks.db в файл delbooks.rec с типом записи TRecord. Delphi 2 CGI приложение может просто открыть этот файл и читать любую запись без использования BDE. Конечно, преобразование записей не просто сделать, но для этого мы имеем всегда оригинальную базу и можем запускать периодически программу преобразования. Так как я добавляю всего несколько записей примерно раз в два месяца, то меня это не очень волнует.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm20">2.2.8. Производительность</p>
     </title>
     <p>Единственное различие между обычным CGI приложением, которое использует BDE для получения данных и нашим приложением без использования BDE это производительность. Кроме того, наше CGI всего лишь 70 KB, оно не нуждается в загрузке BDE, так что время загрузки еще меньше (в результате еще более высокая производительность). В действительности реальные CGI приложения, использующие BDE, часто используют ISAPI (Information Server API) или NSAPI (Netscape Server API) расширения для сохранения CGI приложения "все-время-в-полете (in the air)".</p>
     <p>Еще больше можно повысить производительность, если вместо файла записей использовать массив записей с предварительно инициализированными значениями! Вместо создания файла с записями, Я генерирую Паскаль код для этой цели. Таким образом, я могу генерировать исходный Паскаль код сразу с нужной информацией. Не нужды в файле записей. И сразу после компиляции я имею одиночное приложение на Дельфи 2, размером всего 77824 байта, которое содержит информацию об 44 книгах внутри самого себя.</p>
     <p>Книги внутри, разбор переменных среды, чтение стандартного ввода, генерация HTML страницы и отправка ее на стандартный вывод с динамическим формированием содержимого в зависимости от запроса на форме. Уверен, что единственный способ получить еще более быстрое приложение, это вернуться обратно к статическим страницам без запросов.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm21">2.2.9. Подсчет обращений</p>
     </title>
     <p>Код для подсчета обращений весьма прост. Для поля на форме, которое было выбрано, мы проходим через все записи и добавляем единичку в соответствующую запись при совпадении информации.</p>
     <p><code><strong>if</strong> DataRec.Author &lt;&gt; '' <strong>then</strong></code></p>
     <p><code><strong>begin</strong></code></p>
     <p><code><emphasis>{$IFDEF DEBUG}</emphasis></code></p>
     <p><code>  writeln('Author: ',DataRec.Author,'&lt;BR&gt;');</code></p>
     <p><code><emphasis>{$ENDIF}</emphasis></code></p>
     <p><code>  <strong>for</strong> i:=1 <strong>to</strong> Books16 <strong>do</strong></code></p>
     <p><code>    <strong>if</strong> Pos(DataRec.Author,Book16[i].Author) &lt;&gt; 0 <strong>then</strong></code></p>
     <p><code>      Inc(Result16[i]);</code></p>
     <p><code>  <strong>for</strong> i:=1 <strong>to</strong> Books32 <strong>do</strong></code></p>
     <p><code>    <strong>if</strong> Pos(DataRec.Author,Book32[i].Author) &lt;&gt; 0 <strong>then</strong></code></p>
     <p><code>Inc(Result32[i])</code></p>
     <p><code><strong>end</strong>;</code></p>
     <p>Заметим, что конструкция {$IFDEF DEBUG} может быть использована для вывода значения входного поля в стандартный вывод, так что мы можем использовать наше CGI приложение для отладки формы. Отладка вашего CGI приложения может оказать трудной задачей, поскольку вам нужен Web сервер и браузер для этого…</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm22">2.2.10. Результаты запроса</p>
     </title>
     <p>Теперь посмотрим на последнюю часть CGI приложения: часть, в которой генерируется HTML код. Здесь я использую другое свойство расширенного HTML, именованные таблицы, что бы вывод выглядел красивее. Для каждой записи, у которой счетчик более единицы, я выводу счетчик, название, автора, издательство, ISBN, уровень, техническое содержание, качество книги, стоимость и общее значение. Я также включаю ссылку из названия на другое место, где находится более подробное описание. С помощью этого великолепного свойства динамических HTML страниц: вы даже можете включать ссылки на статические страницы, так как результат запроса, часто стартовая точка для прыжка в другое место!</p>
     <p><code>writeln('&lt;HR&gt;');</code></p>
     <p><code>writeln('&lt;P&gt;');</code></p>
     <p><code>writeln('&lt;H3&gt;The following books have been found <strong>for</strong> you:&lt;/h3&gt;');</code></p>
     <p><code>writeln('&lt;TABLE BORDER&gt;');</code></p>
     <p><code>writeln('&lt;TR&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;Hits&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;Title&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;Author&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;Publisher&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;ISBN&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;Level&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;Con&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;Wri&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;Val&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;TH&gt;&lt;B&gt;Tot&lt;/B&gt;&lt;/TH&gt;');</code></p>
     <p><code>writeln('&lt;/TR&gt;');</code></p>
     <p>После того как заголовок написан, самое время выводить сами записи. Я не хочу сортировать их по рейтингу от 5 до 1, так что я просто иду по списку книг и печатаю каждую со своим рейтингом. Этот путь, потому что я знаю, что книги уже отсортированы по рейтингу в основной базе delbooks.db (которая отсортирована по уровню и рейтингу). Обычно книги в верху списка уже лучший ответ на заданный вопрос.</p>
     <p><code>  <strong>if</strong> DataRec.Delphi2 <strong>then</strong></code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    <strong>for</strong> Hits := 5 <strong>downto</strong> 1 <strong>do</strong></code></p>
     <p><code>    <strong>begin</strong></code></p>
     <p><code>      <strong>for</strong> i:=1 <strong>to</strong> Books32 <strong>do if</strong> Result32[i] = Hits <strong>then</strong></code></p>
     <p><code>      <strong>begin</strong></code></p>
     <p><code>        writeln('&lt;TR&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Roman[Hits],'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;&lt;A HREF="',root32,Book32[i].HREF,'"&gt;',Book32[i].Title,'&lt;/A&gt;&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book32[i].Author,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book32[i].Publisher,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book32[i].ISBN,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Level[Book32[i].Level],'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book32[i].TechnicalContentsQuality,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book32[i].QualityOfWriting,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book32[i].ValueForMoney,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;&lt;B&gt;',Book32[i].OverallAssessment,'&lt;/B&gt;&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;/TR&gt;')</code></p>
     <p><code>      <strong>end</strong></code></p>
     <p><code>    <strong>end</strong>;</code></p>
     <p><code>    <strong>if</strong> DataRec.Delphi1 <strong>then</strong> writeln('&lt;TR&gt;&lt;/TR&gt;')</code></p>
     <p><code>  <strong>end</strong>;</code></p>
     <empty-line/>
     <p><code>  <strong>if</strong> DataRec.Delphi1 <strong>then</strong></code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    <strong>for</strong> Hits := 5 <strong>downto</strong> 1 <strong>do</strong></code></p>
     <p><code>    <strong>begin</strong></code></p>
     <p><code>      <strong>for</strong> i:=1 <strong>to</strong> Books16 <strong>do if</strong> Result16[i] = Hits <strong>then</strong></code></p>
     <p><code>      <strong>begin</strong></code></p>
     <p><code>        writeln('&lt;TR&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Roman[Hits],'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;&lt;A HREF="',root16,Book16[i].HREF,'"&gt;',Book16[i].Title,'&lt;/A&gt;&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book16[i].Author,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book16[i].Publisher,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book16[i].ISBN,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Level[Book16[i].Level],'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book16[i].TechnicalContentsQuality,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book16[i].QualityOfWriting,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;',Book16[i].ValueForMoney,'&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;TD&gt;&lt;B&gt;',Book16[i].OverallAssessment,'&lt;/B&gt;&lt;/TD&gt;');</code></p>
     <p><code>        writeln('&lt;/TR&gt;')</code></p>
     <p><code>      <strong>end</strong></code></p>
     <p><code>    <strong>end</strong></code></p>
     <p><code>  <strong>end</strong>;</code></p>
     <empty-line/>
     <p><code>  writeln('&lt;/TABLE&gt;');</code></p>
     <p><code>  writeln('&lt;HR&gt;');</code></p>
     <p><code>  writeln('&lt;A HREF="http://www.drbob42.com"&gt;Dr.Bob''s Delphi Clinic&lt;/A&gt;');</code></p>
     <p><code>  writeln('&lt;/BODY&gt;');</code></p>
     <p><code>  writeln('&lt;/HTML&gt;');</code></p>
     <p><code>  writeln;</code></p>
     <p><code>  Free</code></p>
     <p><code><strong>end</strong></code></p>
    </section>
    <section>
     <title>
      <p id="AutBody_0bm23">2.2.11. Отладка CGI</p>
     </title>
     <p>Страницу HTML с результатом, сгенерированную по запросу мы модем увидеть выполнив CGI приложение. Для этого требуется (персональный) Web сервер. По этому я написал небольшую программу отладки, используя Delphi 2.01 и NetManage HTML control:</p>
     <image l:href="#Any2FbImgLoader11"/>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042095">2.2.12. Заключение</p>
     </title>
     <p>Я надеюсь, что я показал, как мы можем писать интерактивные Интернет (Интранет) CGI приложения с помощью Delphi 2 используя CGI, WinCGI и Delphi 3 ISAPI/NSAPI Web Modules. Лично я планирую делать многое с помощью Дельфи для Интернет и Интранет.</p>
    </section>
   </section>
  </section>
  <section>
   <title>
    <p id="AutBody_0_toc485042096">3. Microsoft WinInet</p>
   </title>
   <section>
    <p>Многое из того, что вы узнали, позволяет вам писать Интернет приложения с помощью Delphi. Особенно с помощью новых средств в Delphi 3 таких как ActiveForms и Web Modules. Но иногда мы хотим сделать, что еще быстрее и проще. Иногда мы просто хотим загрузить файл из Интернета. В терминах Интернета это означает, что мы хотим использовать FTP (file transfer protocol) клиента. И если вы верите мне, то вам не требуется ни какой FTP клиент, но если вы верите мне, то вы можете написать свой…</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042097">3.1. FTP</p>
    </title>
    <p>Как я сказал во введении, FTP означает File Transfer Protocol, который описан в RFC 959. Модель связи FTP может быть реализована с помощью сокетов, но это более низкоуровневое решение и если вы посмотрите спецификацию, то поймети, что написание программы FTP клиента с нуля не такая уж простая задача. С другой стороны, мы можем использовать NetManage TFTP компонент из Delphi 2.01 (и выше) и C++Builder. Я пробовал использовать этот компонент несколько раз, и нашел его просто глюкавым, особенно для файлов свыше 10 Kb. Я могу понять, почему Microsoft (первый разработчик Internet Solutions Pack) не захотела использовать его и продала затем NetManage, которая тоже не справилась с ним и продала далее фирме NetMasters. Проблема в том, что Internet Solutions Pack – хотя и бесплатный – основан на наборе с ограничениями ActiveX, и каждая компания которая использует его также имеет более лучшее решение (обычно не бесплатно). Поддержка и документация всегда отвратительная…</p>
    <p>Так что же, назад к низкоуровневому программированию? Ни в коем случае. Как всегда на помощь приходит <emphasis>Microsoft</emphasis></p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042098">3.2. WinInet</p>
    </title>
    <p>Некоторое время назад, Microsoft выпустила WinInet, который ни что иное как промежуточный слой между высоким и нижним уровнем программирования Internet API специально для Win32 программистов. WinInet Является интерфейсом высокого уровня для протоколов нижнего уровня, таких как HTTP и FTP. Использование его действительно просто, и хорошо, что модуль WinInet.PAS с API определениями уже включен в Delphi 2.x и выше!</p>
    <p>Имеется также большой документ, описывающий все детали WinInet API, который может быть найден на сайте Microsoft (но его местонахождение постоянно меняется, так что нужно использовать систему поиска, для загрузки последней версии документа).</p>
    <p>От переводчика: можно взять на моем сайте со страницы http://nps.vnet.ee/internet.html</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042099">3.3. DrBob FTP</p>
    </title>
    <p>WinInet использует не что, что они назвали Интернет хендл "<strong><emphasis>internet handle</emphasis></strong>" (очень похоже на windows handles), и все api функции или нуждаются или возвращают Интернет хендл. Например, что бы открыть новую WinInet сессию, нам нужно вызвать функцию InternetOpen, которая вернет Интернет хендл, который мы должны использовать до конца сессии (и передавать другим API функциям). Для освобождения хендла, мы всегда должны вызывать функцию InternetCloseHandle (после получения хендла мы можем его использовать, но мы обязаны написать блок try-finally, где должны освободить хендл в разделе finally).</p>
    <p>Для открытия удаленного файла (или URL) в Интернете, мы должны вызвать функцию InternetOpenURL, которая опять вернет нам хендл. Теперь, для загрузки удаленного файла (URL) на нашу локальную машину, нам осталось сделать только некоторое количество вызовов функции InternetReadFile, очень похожей на функцию BlockRead, которая копирует данные из удаленного файла в буфер данных. Мы можем использовать BlockWrite для записи из буфера в локальный файл, и все это с помощью всего лишь трех WinInet функций (четыре, если считать функцию InternetCloseHandle), мы можем написать простую, но очень быструю FTP программу следующим образом:</p>
    <p><code>  <strong>program</strong> DrBobFTP;</code></p>
    <p><code>  <emphasis>{$APPTYPE CONSOLE}</emphasis></code></p>
    <p><code><emphasis>  {$I+}</emphasis></code></p>
    <p><code>  <strong>uses</strong></code></p>
    <p><code>    Windows, WinInet;</code></p>
    <empty-line/>
    <p><code>    <strong>procedure</strong> CopyURL(<strong>const</strong> URL, OutputFile: String);</code></p>
    <p><code>    <strong>const</strong></code></p>
    <p><code>      BufferSize = 1024;</code></p>
    <p><code>    <strong>var</strong></code></p>
    <p><code>      hSession, hURL: HInternet;</code></p>
    <p><code>      Buffer: <strong>Array</strong>[0..Pred(BufferSize)] <strong>of</strong> Byte;</code></p>
    <p><code>      BufferLength: DWORD;</code></p>
    <p><code>      f: File;</code></p>
    <p><code>    <strong>begin</strong></code></p>
    <p><code>      hSession := InternetOpen('DrBob',INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);</code></p>
    <p><code>      <strong>try</strong></code></p>
    <p><code>        hURL := InternetOpenURL(hSession, PChar(URL), nil,0,0,0);</code></p>
    <p><code>        <strong>try</strong></code></p>
    <p><code>          Assign(f, OutputFile);</code></p>
    <p><code>          Rewrite(f,1);</code></p>
    <p><code>          <strong>repeat</strong></code></p>
    <p><code>            InternetReadFile(hURL, @Buffer, BufferSize, BufferLength);</code></p>
    <p><code>            write('.');</code></p>
    <p><code>            BlockWrite(f, Buffer, BufferLength)</code></p>
    <p><code>          <strong>until</strong> BufferLength = 0;</code></p>
    <p><code>          Close(f);</code></p>
    <p><code>          writeln('OK') { if we get here, we succeeded }</code></p>
    <p><code>        <strong>finally</strong></code></p>
    <p><code>          InternetCloseHandle(hURL)</code></p>
    <p><code>        <strong>end</strong></code></p>
    <p><code>      <strong>finally</strong></code></p>
    <p><code>        InternetCloseHandle(hSession)</code></p>
    <p><code>      <strong>end</strong></code></p>
    <p><code>    <strong>end</strong>;</code></p>
    <empty-line/>
    <p><code>  <strong>begin</strong></code></p>
    <p><code>    <strong>if</strong> ParamCount &lt;2 &gt;<strong>then</strong></code></p>
    <p><code>    <strong>begin</strong></code></p>
    <p><code>      writeln('Usage: DrBobFTP URL Filename');</code></p>
    <p><code>      writeln('Example: DrBobFTP http://www.drbob42.com/ftp/headconv.zip hc.zip')</code></p>
    <p><code>    <strong>end</strong></code></p>
    <p><code>    <strong>else</strong></code></p>
    <p><code>      CopyURL(ParamStr(1), ParamStr(2))</code></p>
    <p><code>  <strong>end</strong>.</code></p>
    <p>Конечно, для выполнения данной программы мы также обязаны иметь WinInet.DLL, которая также может быть найдена на Microsoft web сайте.</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042100">3.4. Web Magic</p>
    </title>
    <section>
     <p>Теперь вы уже знаете что, мы можем писать мощные Интернет приложения любого сорта с помощью Дельфи. Тем не менее, я как web мастер популярного web сайта, я очень часто чувствую нужду в приложениях поддержки; инструменте который бы мне помог обслуживать мой web сайт. Например, счетчики, гостевые книги, детектор мертвых ссылок, автоматический аплоадер (для публикации новых страниц) и даунлоадер (для автоматического получения файлов с сети).</p>
     <p>Поскольку не каждый использует Client/Server версию Delphi 3, мы используем только "голые кости" (bare bones) технологию, такую как мой модуль DrBobCGI или Microsoft WinInet DLL и модули импорта доступные бесплатно.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042101">3.4.1. Счетчик</p>
     </title>
     <p>Счетчик посещений это первое, в чем нуждается популярный web сайт. Меня всегда интересует количество людей посетивших мой сайт. Я всегда заинтересован знать количество людей каждый день. И я всегда заинтересован знать, как выходные и праздники влияют на посещения.</p>
     <p>Для отслеживания количества посетителей я просто создан однострочный файл, назвав его "counter", который содержит количество посещений. Единственная вещь, которая нам требуется, это простая CGI программа, которая читает этот файл, увеличивает на единичку и записывает обратно. Конечно, прекрасно при этом показывать посетителю эту информацию или в виде картинки или в виде простого текстового сообщения.</p>
     <p><code>  {$APPTYPE CONSOLE}</code></p>
     <p><code>  {$I-}</code></p>
     <p><code>  <strong>var</strong></code></p>
     <p><code>    f: Text;</code></p>
     <p><code>    i: Integer;</code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    System.Assign(f,'counter');</code></p>
     <p><code>    reset(f);</code></p>
     <p><code>    <strong>if</strong> IOResult = 0 <strong>then</strong> readln(f,i)</code></p>
     <p><code>                    <strong>else</strong> i := 0;</code></p>
     <p><code>    Inc(i);</code></p>
     <p><code>    rewrite(f);</code></p>
     <p><code>    writeln(f,i);</code></p>
     <p><code>    close(f);</code></p>
     <p><code>    <strong>if</strong> IOResult &lt;&gt; 0 <strong>then</strong> { skip };</code></p>
     <p><code>    writeln('Content-type: text/html');</code></p>
     <p><code>    writeln;</code></p>
     <p><code>    writeln('&lt;HTML&gt;');</code></p>
     <p><code>    writeln('&lt;BODY&gt;');</code></p>
     <p><code>    writeln('&lt;CENTER&gt;');</code></p>
     <p><code>    writeln('You are user &lt;B&gt;',i,'&lt;/B&gt; of Dr.Bob''s Delphi Clinic');</code></p>
     <p><code>    writeln('&lt;/CENTER&gt;');</code></p>
     <p><code>    writeln('&lt;/BODY&gt;');</code></p>
     <p><code>    writeln('&lt;/HTML&gt;')</code></p>
     <p><code>  <strong>end</strong>.</code></p>
     <p>Вышеприведенная программа показывает текущее значение в виде текстового сообщения, которое выводится в отдельном фрейме:</p>
     <p><code>&lt;HTML&gt;</code></p>
     <p><code>&lt;FRAMESET ROWS="64,*"&gt;</code></p>
     <p><code>&lt;FRAME SRC=http://www.drbob42.com/cgi-bin/hitcount.exe? NAME="Head"&gt;</code></p>
     <p><code>&lt;FRAME SRC="guest.htm"NAME="Main"&gt;</code></p>
     <p><code>&lt;/FRAMESET&gt;</code></p>
     <p><code>&lt;/HTML&gt;</code></p>
     <p>Это очень простое CGI приложение. Оно даже не получает ввода, просто преобразовывает удаленный файл на web сервере и возвращает динамическую страницу. Позвольте теперь сделать фокус на более сложном CGI приложении – таком которое требует ввода данных – например гостевой книге.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042102">3.4.2. Гостевая книга</p>
     </title>
     <p>Подлинный CGI пример: приложение – гостевая книга (в котором спрашиваем имя и небольшой комментарий), всего лишь несколько строк на Дельфи.</p>
     <p>Сначала CGI форма:</p>
     <p><code>  &lt;HTML&gt;</code></p>
     <p><code>  &lt;BODY&gt;</code></p>
     <p><code>  &lt;H2&gt;Dr.Bob's Guestbook&lt;/H2&gt;</code></p>
     <p><code>  &lt;FORM ACTION="http://www.drbob42.com/cgi-bin/guest.exe" METHOD=POST</code></p>
     <p><code>  Name: &lt;INPUT TYPE=text NAME=name&lt;BR&gt;</code></p>
     <p><code>  Comments: &lt;TEXTAREA COLS=42 LINES=4 NAME=comments&gt;</code></p>
     <p><code>  &lt;P&gt;</code></p>
     <p><code>  &lt;INPUT TYPE=SUBMIT VALUE="Send Comments <strong>to</strong> Dr.Bob"&gt;</code></p>
     <p><code>  &lt;/FORM&gt;</code></p>
     <p><code>  &lt;/BODY&gt;</code></p>
     <p><code>  &lt;/HTML&gt;</code></p>
     <p>Теперь консольное (Дельфи) приложение:</p>
     <p><code>  <strong>program</strong> CGI;</code></p>
     <p><code>  <emphasis>{$I-}</emphasis></code></p>
     <p><code>  <emphasis>{$APPTYPE CONSOLE}</emphasis></code></p>
     <p><code>  <strong>uses</strong></code></p>
     <p><code>    DrBobCGI;</code></p>
     <p><code>  <strong>var</strong></code></p>
     <p><code>    guest: Text;</code></p>
     <p><code>    Str: <strong>String</strong>;</code></p>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    Assign(guest,'guest'); // assuming that's the guestbook</code></p>
     <p><code>    Append(guest);</code></p>
     <p><code>    <strong>if</strong> IOResult &lt;&gt; 0 <strong>then</strong> // open new guestbook</code></p>
     <p><code>    <strong>begin</strong></code></p>
     <p><code>      Rewrite(guest);</code></p>
     <p><code>      writeln(guest,'&lt;HTML');</code></p>
     <p><code>      writeln(guest,'&lt;BODY')</code></p>
     <p><code>    <strong>end</strong>;</code></p>
     <p><code>    writeln(guest,'Date: ',DateTimeToStr(Now),'&lt;BR');</code></p>
     <p><code>    writeln(guest,'Name: ',Value('name'),'&lt;BR');</code></p>
     <p><code>    writeln(guest,'Comments: ',Value('comments'),'&lt;HR');</code></p>
     <p><code>    reset(guest);</code></p>
     <p><code>    writeln('Content-type: text/html');</code></p>
     <p><code>    writeln;</code></p>
     <p><code>    <strong>while not</strong> eof(guest) <strong>do</strong> // now output guestbook itself</code></p>
     <p><code>    <strong>begin</strong></code></p>
     <p><code>      readln(guest,Str);</code></p>
     <p><code>      writeln(Str)</code></p>
     <p><code>    <strong>end</strong>;</code></p>
     <p><code>    close(guest);</code></p>
     <p><code>    writeln('&lt;/BODY');</code></p>
     <p><code>    writeln('&lt;/HTML')</code></p>
     <p><code>  <strong>end</strong>.</code></p>
     <image l:href="#Any2FbImgLoader3"/>
     <p>Примечание, для того, что бы упростить, мы не используем базу данных для хранения комментариев. Иначе это потребовало установки BDE на web сервере.</p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042103">3.4.3. Детектор мертвых ссылок</p>
     </title>
     <p>Любой серьезный web сайт и его web мастер должны всегда следить за актуальность ссылок. И если обнаружится мертвая ссылка (например другой web сайт прекратил существование), но нет никаких оправданий для внутренних мертвых ссылок. И поэтому я написал простую программу, назвав ее HTMLINKS, которая может сканировать .HTM файлы на их присутствие на локальной машине. (что бы потом загрузить их на сервер). HTM файлы из текущего каталога и всех подкаталогов рекурсивно читаются и проверяются на тег <emphasis>"&lt;A HREF="</emphasis> или <emphasis>"&lt;FRAME SRC="</emphasis> . Если страница локальная, то есть без префикса "http://", то файл открывается с использованием относительно пути. Если страница не находится, то мы имеем внутреннюю мертвую ссылку, которая должна быть исправлена!!</p>
     <p>Заметим, что программа игнорирует все "file://", "ftp://", "mailto:", "news:" and ".exe?" значения если они встретятся внутри "HREF" части. Конечно, вы свободны в расширить HTMLINKS для проверки и этих случаев, можно также реализовать проверку и внешних ссылок. Для информации я написал и детектор внешних мертвых ссылок в статье для The Delphi Magazine, подробности можно найти на моем web сайте. Для анализа мертвых локальных ссылок код следующий:</p>
     <p><code>  {$APPTYPE CONSOLE}</code></p>
     <p><code>  {$I-,H+}</code></p>
     <p><code>  <strong>uses</strong></code></p>
     <p><code>    SysUtils;</code></p>
     <p><code>  <strong>var</strong></code></p>
     <p><code>    Path: <strong>String</strong>;</code></p>
     <empty-line/>
     <p><code>    <strong>procedure</strong> CheckHTML(<strong>const</strong> Path: <strong>String</strong>);</code></p>
     <p><code>    <strong>var</strong></code></p>
     <p><code>      SRec: TSearchRec;</code></p>
     <p><code>      Str: <strong>String</strong>;</code></p>
     <p><code>      f: Text;</code></p>
     <p><code>    <strong>begin</strong></code></p>
     <p><code>      <strong>if</strong> FindFirst('*.htm', faArchive, SRec) = 0 <strong>then</strong></code></p>
     <p><code>      <strong>repeat</strong></code></p>
     <p><code>        Assign(f,SRec.<strong>Name</strong>);</code></p>
     <p><code>        Reset(f);</code></p>
     <p><code>        <strong>if</strong> IOResult = 0 <strong>then</strong> { no error }</code></p>
     <p><code>        <strong>while not</strong> eof(f) <strong>do</strong></code></p>
     <p><code>        <strong>begin</strong></code></p>
     <p><code>          readln(f,Str);</code></p>
     <p><code>          <strong>while</strong> (Pos('&lt;A HREF="',Str)  0) <strong>or</strong></code></p>
     <p><code>                (Pos('FRAME SRC="',Str)  0) <strong>do</strong></code></p>
     <p><code>          <strong>begin</strong></code></p>
     <p><code>            <strong>if</strong> Pos('&lt;A HREF="',Str)  0 <strong>then</strong></code></p>
     <p><code>              Delete(Str,1,Pos('HREF="',Str)+8-3)</code></p>
     <p><code>            <strong>else</strong></code></p>
     <p><code>              Delete(Str,1,Pos('FRAME SRC="',Str)+10);</code></p>
     <p><code>            <strong>if</strong> (Pos('#',Str) &lt;&gt; 1) <strong>and</strong></code></p>
     <p><code>               (Pos('http://',Str) &lt;&gt; 1) <strong>and</strong></code></p>
     <p><code>               (Pos('mailto:',Str) &lt;&gt; 1) <strong>and</strong></code></p>
     <p><code>               (Pos('news:',Str) &lt;&gt; 1) <strong>and</strong></code></p>
     <p><code>               (Pos('ftp://',Str) &lt;&gt; 1) <strong>and</strong></code></p>
     <p><code>               (Pos('.exe?',Str) = 0) <strong>then</strong> { skip external links &amp; exe }</code></p>
     <p><code>            <strong>begin</strong></code></p>
     <p><code>              <strong>if</strong> Pos('file:///',Str) = 1 <strong>then</strong> Delete(Str,1,8);</code></p>
     <p><code>              <strong>if</strong> (Pos('#',Str)  0) <strong>and</strong></code></p>
     <p><code>                 (Pos('#',Str) &lt; Pos('"',Str)) <strong>then</strong> Str[Pos('#',Str)] := '"';</code></p>
     <p><code>              <strong>if not</strong> FileExists(Copy(Str,1,Pos('"',Str)-1)) <strong>then</strong></code></p>
     <p><code>                writeln(Path,'\',SRec.Name,': [',Copy(Str,1,Pos('"',Str)-1),']')</code></p>
     <p><code>            <strong>end</strong></code></p>
     <p><code>          <strong>end</strong></code></p>
     <p><code>        <strong>end</strong>;</code></p>
     <p><code>        Close(f);</code></p>
     <p><code>        <strong>if</strong> IOResult &lt;&gt; 0 <strong>then</strong> { skip }</code></p>
     <p><code>      <strong>until</strong> FindNext(SRec) &lt;&gt; 0;</code></p>
     <p><code>      FindClose(SRec);</code></p>
     <p><code>      // check sub-directories recursively</code></p>
     <p><code>      <strong>if</strong> FindFirst('*.*', faDirectory, SRec) = 0 <strong>then</strong></code></p>
     <p><code>      <strong>repeat</strong></code></p>
     <p><code>        <strong>if</strong> ((SRec.Attr <strong>AND</strong> faDirectory) = faDirectory) <strong>and</strong></code></p>
     <p><code>            (SRec.<strong>Name</strong>[1] &lt;&gt; '.') <strong>then</strong></code></p>
     <p><code>        <strong>begin</strong></code></p>
     <p><code>          ChDir(SRec.<strong>Name</strong>);</code></p>
     <p><code>          CheckHTML(Path+'\'+SRec.<strong>Name</strong>);</code></p>
     <p><code>          ChDir('..')</code></p>
     <p><code>        <strong>end</strong></code></p>
     <p><code>      <strong>until</strong> FindNext(SRec) &lt;&gt; 0;</code></p>
     <p><code>      FindClose(SRec)</code></p>
     <p><code>    <strong>end</strong> {CheckHTML};</code></p>
     <empty-line/>
     <p><code>  <strong>begin</strong></code></p>
     <p><code>    writeln('HTMLinks 4.0 (c) 1997-2000 by Bob Swart (aka Dr.Bob - www.drbob42.com)');</code></p>
     <p><code>    writeln;</code></p>
     <p><code>    FileMode := $40;</code></p>
     <p><code>    GetDir(0,Path);</code></p>
     <p><code>    CheckHTML(Path)</code></p>
     <p><code>  <strong>end</strong>.</code></p>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042104">3.4.4. FTP Upload/Download</p>
     </title>
     <section>
      <p>Иногда вам просто нужно загружать файлы из Интернета. В терминах Интернета, это означает, что вам нужно использовать FTP клиента. И если вы не желаете, подобно мне использовать настоящего FTP клиента, то просто напишите, как и я своего собственного клиента…</p>
     </section>
     <section>
      <title>
       <p id="AutBody_0_toc485042105">3.4.4.1. FTP</p>
      </title>
      <p>Как я сказал во введении, FTP означает File Transfer Protocol, который описан в which RFC 959. Модель связи FTP может быть реализована с помощью сокетов, но это более низкоуровневое решение и если вы посмотрите спецификацию, то поймети, что написание программы FTP клиента с нуля не такая уж простая задача. С другой стороны, мы можем использовать NetManage TFTP компонент из Delphi 2.01 (и выше) и C++Builder. Я пробовал использовать этот компонент несколько раз, и нашел его просто глюкавым, особенно для файлов свыше 10 Kb. Я могу понять, почему Microsoft (первый разработчик Internet Solutions Pack) не захотела использовать его и продала затем NetManage, которая тоже не справилась с ним и продала далее фирме NetMasters. Проблема в том, что Internet Solutions Pack – хотя и бесплатный – основан на наборе с ограничениями ActiveX, и каждая компания которая использует его также имеет более лучшее решение (обычно не бесплатно). Поддержка и документация всегда отвратительная…</p>
      <p>Так что же, назад к низкоуровневому программированию? Ни в коем случае. Как всегда на помощь приходит <emphasis>Microsoft</emphasis></p>
     </section>
     <section>
      <title>
       <p id="AutBody_0_toc485042106">3.4.4.2. WinInet</p>
      </title>
      <p>Некоторое время назад, Microsoft выпустила WinInet, который ни что иное, как промежуточный слой между высоким и нижним уровнем программирования Internet API специально для Win32 программистов. WinInet Является интерфейсом высокого уровня для протоколов нижнего уровня, таких как HTTP и FTP. Использование его действительно просто, и хорошо, что модуль WinInet.PAS с API определениями уже включен в Delphi 2.x и выше!</p>
      <p>Имеется также большой документ, описывающий все детали WinInet API, который может быть найден на сайте Microsoft (но его местонахождение постоянно меняется, так что нужно использовать систему поиска, для загрузки последней версии документа).</p>
      <p>От переводчика: можно взять на моем сайте со страницы http://nps.vnet.ee/internet.html</p>
     </section>
     <section>
      <title>
       <p id="AutBody_0_toc485042107">3.4.4.3. DrBob FTP</p>
      </title>
      <p>WinInet использует не что, что они назвали Интернет хендл "<strong><emphasis>internet handle</emphasis></strong>" (очень похоже на windows handles), и все api функции или нуждаются или возвращают Интернет хендл. Например, что бы открыть новую WinInet сессию, нам нужно вызвать функцию InternetOpen, которая вернет Интернет хендл, который мы должны использовать до конца сессии (и передавать другим API функциям). Для освобождения хендла, мы всегда должны вызывать функцию InternetCloseHandle (после получения хендла мы можем его использовать, но мы обязаны написать блок try-finally, где должны освободить хендл в разделе finally).</p>
      <p>Для открытия удаленного файла (или URL) в Интернете, мы должны вызвать функцию InternetOpenURL, которая опять вернет нам хендл. Теперь, для загрузки удаленного файла (URL) на нашу локальную машину, нам осталось сделать только некоторое количество вызовов функции InternetReadFile, очень похожей на функцию BlockRead, которая копирует данные из удаленного файла в буфер данных. Мы можем использовать BlockWrite для записи из буфера в локальный файл, и все это с помощью всего лишь трех WinInet функций (четыре, если считать функцию InternetCloseHandle), мы можем написать простую, но очень быструю FTP программу следующим образом:</p>
      <p><code><strong>program</strong> DrBobFTP;</code></p>
      <p><code>  <emphasis>{$APPTYPE CONSOLE}</emphasis></code></p>
      <p><code><emphasis>  {$I+}</emphasis></code></p>
      <p><code>  <strong>uses</strong></code></p>
      <p><code>    Windows, WinInet;</code></p>
      <empty-line/>
      <p><code>    <strong>procedure</strong> CopyURL(<strong>const</strong> URL, OutputFile: String);</code></p>
      <p><code>    <strong>const</strong></code></p>
      <p><code>      BufferSize = 1024;</code></p>
      <p><code>    <strong>var</strong></code></p>
      <p><code>      hSession, hURL: HInternet;</code></p>
      <p><code>      Buffer: <strong>Array</strong>[0..Pred(BufferSize)] <strong>of</strong> Byte;</code></p>
      <p><code>      BufferLength: DWORD;</code></p>
      <p><code>      f: File;</code></p>
      <p><code>    <strong>begin</strong></code></p>
      <p><code>      hSession := InternetOpen('DrBob',INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);</code></p>
      <p><code>      <strong>try</strong></code></p>
      <p><code>        hURL := InternetOpenURL(hSession, PChar(URL), nil,0,0,0);</code></p>
      <p><code>        <strong>try</strong></code></p>
      <p><code>          Assign(f, OutputFile);</code></p>
      <p><code>          Rewrite(f,1);</code></p>
      <p><code>          <strong>repeat</strong></code></p>
      <p><code>            InternetReadFile(hURL, @Buffer, BufferSize, BufferLength);</code></p>
      <p><code>            write('.');</code></p>
      <p><code>            BlockWrite(f, Buffer, BufferLength)</code></p>
      <p><code>          <strong>until</strong> BufferLength = 0;</code></p>
      <p><code>          Close(f);</code></p>
      <p><code>          writeln('OK') { if we get here, we succeeded }</code></p>
      <p><code>        <strong>finally</strong></code></p>
      <p><code>          InternetCloseHandle(hURL)</code></p>
      <p><code>        <strong>end</strong></code></p>
      <p><code>      <strong>finally</strong></code></p>
      <p><code>        InternetCloseHandle(hSession)</code></p>
      <p><code>      <strong>end</strong></code></p>
      <p><code>    <strong>end</strong>;</code></p>
      <empty-line/>
      <p><code>  <strong>begin</strong></code></p>
      <p><code>    <strong>if</strong> ParamCount &lt;2 &gt;<strong>then</strong></code></p>
      <p><code>    <strong>begin</strong></code></p>
      <p><code>      writeln('Usage: DrBobFTP URL Filename');</code></p>
      <p><code>      writeln('Example: DrBobFTP http://www.drbob42.com/ftp/headconv.zip hc.zip')</code></p>
      <p><code>    <strong>end</strong></code></p>
      <p><code>    <strong>else</strong></code></p>
      <p><code>      CopyURL(ParamStr(1), ParamStr(2))</code></p>
      <p><code>  <strong>end</strong>.</code></p>
      <p>Конечно, для выполнения данной программы мы также обязаны иметь WinInet.DLL, которая также может быть найдена на Microsoft web сайте.</p>
     </section>
     <section>
      <title>
       <p id="AutBody_0_toc485042108">3.4.4.4.Улучшения?</p>
      </title>
      <p>Если вы читали документацию по WinInet, вы заметили что, там есть функция FindFile, так что вы можете сделать обзор удаленных файлов. И базируясь на этой информации, вы можете написать своего web робота, который может загрузить часть a web сайта (например, те файлы, которые изменились после последнего посещения данного сайта). Все автоматически и без GUI (зато быстро). Для информации, Я работал над подобным сортом инструментария, названного мной RobotBob, который наложил свой глаз на Борландовский web сайт, помогая мне отслеживать новости и события по Борландовским средствам разработки…</p>
     </section>
    </section>
    <section>
     <title>
      <p id="AutBody_0_toc485042109">3.4.5. HTML подсветка синтаксиса</p>
     </title>
     <p>И последний инструмент, который я использую ежедневно, это программа HTMLHIGH, используемая для подсветки синтаксиса внутри фрагментов &lt;PRE…&lt;/PRE&gt; HTML страниц. Версию, работающую из командной строки можно найти на CD-ROM прилагаемой к моей книге. В данный момент я работаю над версией user-friendly Wizard и хочу написать об этом отдельную статью.</p>
    </section>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042110">3.5. Улучшения?</p>
    </title>
    <p>Если вы читали документацию по WinInet, вы заметили что, там есть функция FindFile, так что вы можете сделать обзор удаленных файлов. И базируясь на этой информации, вы можете написать своего web робота, который может загрузить часть web сайта (например, те файлы, которые изменились после последнего посещения данного сайта). Все автоматически и без GUI (зато быстро).</p>
   </section>
  </section>
  <section>
   <title>
    <p id="AutBody_0_toc485042111">4. Delphi ActiveForms (intranet)</p>
   </title>
   <section>
    <p>С помощью JBuilder возможно разрабатывать 100% pure Java апплеты, приложения., но мы не должны забывать и о том, что с помощью Дельфи так же можно создавать интересные Интранет решения используя такие вещи как <strong>ActiveForms</strong> и Web Modules…</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042112">4.1. ActiveForms</p>
    </title>
    <p>Дельфи 2.x не может создавать ActiveX органы управления. В Дельфи 3 это было исправлено и названо One-Step-ActiveX. Вначале показалось, что это было изумительное свойство Дельфи 3. Но после детального ознакомления, оказалось, что можете включать только компоненты наследники от TWinControl внутрь ActiveX, и вы не можете делать ActiveX органы, которые могут подключать другие компоненты, такие как TTable и TQuery компоненты, котрые подключаются к TDataSource, и все другие data-aware компоненты). На практике это означает, что изумительное нововведение оказалось в действительности пшиком, не позволяя делать серьезные Интернет приложения.</p>
    <p>Конечно мы можем обойти эту проблему, разместив все нужные компоненты в один "контейнер" и преобразовать этот контейнер в один большой ActiveX контрол. Конечно, наилучшим контейнером мог бы быть TForm (так что мы могли бы разрабатывать привычным образом), и имя этому было бы <emphasis>ActiveForm</emphasis> . ActiveForms мог бы интерпритироваться как обычная форма, которая может содержать любые компоненты, включая TTable, TDataSource, TDBGrid, TDBNavigator, и т.д. и они были бы хорошим потенциалом ActiveX для Дельфи программиста.</p>
    <p>Подобно любому ActiveX контролу, ActiveForm требуется Win32 платформа для исполнения, но это должна быть Win32 платформа, так как ActiveForm это обычный ActiveX орган, и может быть использован внутри других средств разработки, поддерживающих ActiveX, таких как C++Builder, Visual Basic, PowerBuilder, и также Internet Explorer. Последнее означает, что мы можем использовать ActiveForm для распространения Интернет приложений в Интернет или Интранет.</p>
    <p>Простой откомпилированный ActiveForm проект может оказаться в .OCX размером свыше 300 Kb, даже если были использованы совсем немного контролов и всего лишь несколько строк кода. Компиляция с пакетами, VCLx0 (стандарт) или VCLDBx0 (data-aware) может уменьшить этот размер до 50 Kb, более мене функциональные ActiveForm будуь порядка 100 Kb. Пакеты значительно увеличивают размер (VCLx0 пакет это более мегабайта), но они должны ставиться у клиента только один раз, и могут быть уже предустановленны у клиента, что позволяет уменьшить время загрузки.</p>
    <p>Поскольку ActiveForm это просто другое Win32 приложение, то даже когда оно запускается из Internet Explorer то могут произойти неприятные вещи у неискушенных пользователей. По одной причине, ActiveForm имеет доступ ко всей машине, и если пользователь зарегистрировался в сети, то ActiveForm, подобно вирусу может сделать все что угодно на вашей машине (отформатировать жесткий диск? Послать e-mail? Разрушить базу данных? Все что вы в состоянии представить и еще более). Поэтому при загрузке из Интернета (но не внутренней сети компании), мы должны считать ActiveForm или любой ActiveX орган потенциальным вирусом. Авторы ActiveForm и ActiveX контролов могут использовать цифровую подпись, которая только подтверждает, что данная вещь принадлежит автору, но ничего не говорит о самом органе. Internet Explorer имеет некоторые настройки безопасности, которые могут быть установлены в максимум (не принимать не подписанные ActiveX), в средние (давать предупреждение, но позволить решать пользователю) или слабые (принимать все без предупреждения). Разработчики подобно нам могут использовать средние, но конечный пользователь должен всегда использовать максимальный настройки безопасности.</p>
    <p>Отвлекаясь от проблем с безопасностью, ActiveForm также требуется BDE на локальной машине (клиентская сторона) при использовании локальных баз и таблиц. Даже если алиас указывает, что база расположена на файл-сервере, BDE все равно должен быть установлен на клиентской машине. Использую MIDAS, TClientDataSets, DataSetProvider и Connection components, мы можем превратить ActiveForm в multi-tier приложение, когда база данных расположена на web сервере (или даже на отделном сервер баз данных).</p>
    <p>Поэтому, наиболее правильным решением будет использовать ActiveForms только внутри Интранет, где мы можем контролировать клиентские машины и предоставлять им алиас до базы данных на файл сервере. При этом мы в состоянии обеспечить, что бы на клиентской машине были установлены все необходимые пакеты, и нам не нужно тратить большие деньги на обеспечение безопасности (внутри компании, я надеюсь, что все ActiveForms разработаны своими работниками).</p>
    <p>Можно констатировать, что Delphi ActiveForm прекрасная вещь для Intranet.</p>
    <cite>
     <p><strong>Bug Report:</strong> ActiveX Controls in Internet Explorer 4.0 (or higher)</p>
     <p>По заявлению Microsoft, "в связи с архитектурными изменениями в Internet Explorer 4.0 (и выше), что требуется для поддержки более широкого спектра более эффективных контролов, некоторые ActiveX контролы могут выполняться не совсем так, как это было в Explorer 3.0. Основная причина в том, что эти контролы разработаны не в Apartment Model Aware."</p>
     <p>В Delphi 4 эта проблема разрешена и ActiveForm сделанные в Delphi 4 (и выше) теперь поддерживают Apartment threading model.</p>
    </cite>
   </section>
  </section>
  <section>
   <title>
    <p id="AutBody_0_toc485042113">5. Delphi Web Modules (internet)</p>
   </title>
   <section>
    <p>С помощью JBuilder возможно разрабатывать 100% pure Java апплеты, приложения., но мы не должны забывать и о том, что с помощью Дельфи так же можно создавать интересные Интранет решения используя такие вещи как <strong>ActiveForms</strong> и web modules…</p>
   </section>
   <section>
    <title>
     <p id="AutBody_0_toc485042114">5.1. Web Modules</p>
    </title>
    <p>ActiveForm это великое решение для Интранет, когда само приложение исполняется на клиентской машине. Для подлинно независимых от платформы решений, мы должны сфокусировать наше внимание на web сервера. В этом случае, мы можем использовать Delphi для написания CGI или WinCGI приложений, или ISAPI/NSAPI (Internet или Netscape Server API) DLL расширений для web сервера. Мы можем использовать HTML на клиентской стороне, с помощью CGI форм посылая данные от клиента на сервер, в то же время в ответ генерирует динамические HTML страницы.</p>
    <p>Написание CGI, WinCGI или ISAPI/NSAPI с помощью Дельфи не совсем тривиальная задача. Особенно переключение от одного решения к другому может оказаться очень трудным, так как поставщики продуктов третьих сторон, часто используют различные пути поддержки своих серверных Интернет приложений, например WebHub.</p>
    <p>Delphi 3 и 4 Client/Server (а также Delphi 4 Professional с дополнениями) и Delphi 5 Professional часто приходят со специальными мастерами (Wizard) и компонентами для поддержки такого рода серверных приложений, называемых как Web Modules (или также известные под названием WebBroker). Используя Web Module, мы можем создавать CGI, WinCGI и ISAPI/NSAPI серверные приложения, и в этом случае мы можем переходить от одного типа к другому, самом приложение полностью абстрагируется от деталей реализации. Единственная разница (учитывая тот факт, что ISAPI DLL остается загруженным на Web сервере, а CGI EXE нет) в том что, ISAPI приложение легче отлаживать, используя IntraBob, чем CGI приложение. В существующем проекте с Web модулем отсутствует возможность определения, что используется, CGI или ISAPI/NSAPI приложение; только главный модуль проекта содержит эту информацию (которую можно изменить, что бы перейти к другому типу Web серверного приложения). Я думаю, что очень важная вещь: программист использует один набор компонент для обработки WebActions, WebRequests, WebResponses и т.д.</p>
    <p>Используя специальный компонент WebDispatcher, мы можем даже мигрировать из существующих модулей данных (Data Modules) в Web модули. WebDispatcher встроен в обычный Web модуль, и используется для для диспетчеризации действия (Action) в Web модуле (Web серверное приложение может обрабатывать и выполнять разнообразные запросы и выполнять различные действия, для определения которых используется WebDispatcher).</p>
    <p>Каждый WebAction может программироваться отдельно, но так же использовать что угодно их WebModule. Это включает все таблицы и бизнес правила, также другие процедуры и ресурсы. WebAction может напрямую писать в строку Response, или использовать один их трех специальных компонент для генерации динамических HTML и обслуживать запросы.</p>
    <p>Компонент PageProducer используется для генерации динамических HTML страниц, включая специальные теги, которые могут использоваться для подстановки в run-time. Компонент DataSetTableProducer может использоваться для генерации динамических HTML страниц в табличном виде, используя колонки из таблицы базы данных. Вывод может полностью конфигурироваться, и требует наличия BDE на web сервере. Компонент QueryTableProducer подобен компоненту DataSetTableProducer, только использует запросы (query) вместо таблиц (table). Существует особая возможность использовать запросы с параметрами, встроенными в напрямую HTML CGI.</p>
    <p>Конечно, Web модули поддерживаю куки (cookies), но я лично предпочитаю использовать "невидимые поля" для хранения информации об состоянии.</p>
    <p><emphasis>Я заключаю, что Дельфи Web модули прекрасно подходят для написания Web серверных приложений для Интернета.</emphasis></p>
    <cite>
     <p><strong>Bug Report:</strong> TWinCGI OutputFile</p>
     <p>Владельцы Delphi 3 C/S при написании WinCGI приложений должны учитывать потенциальную проблему: функция OutputFile открывает в режиме fmOpenWrite, которая вылетит если файл отсутствует. Эта проблема отсутствует при использовании IIS/PWS (которые предварительно создают OutputFile), но WebSite и IntraBob в этом случае не создают выходной файл, так что они сгенерируют исключение "<emphasis>cannot open file</emphasis> ".</p>
     <p>Для исправления следует открыть файл CGIApp.pas и изменить "fmOpenWrite" на "fmCreate" в строках 410 и 507. </p>
    </cite>
   </section>
  </section>
 </body>
 <binary id="Any2FbImgLoader0" content-type="image/png">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
AElFTkSuQmCC</binary>
 <binary id="Any2FbImgLoader1" content-type="image/png">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
lOS9cGaYAAAAAElFTkSuQmCC</binary>
 <binary id="Any2FbImgLoader2" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAEgAAAAaCAIAAACbyY3sAAAABGdBTUEAALGIlZj0pgAAAIdJ
REFUeJztmCEOgDAMRTcygePIGxLHDbsjgGJuiAbGAUqa3/SZNVP/iS/aeFw9WGTSDvAXiZ99
W3VzCJJzPtsjFkIopeiFEYOIeEjf397h+1Zr5cFsx1wMDRdDw8XQcDE0XAwNF0PDxdBwMTTG
Bk1E7/ppgMjnt2XWDiLKOOacTTeJPGY7dgN5jB3pUMmhQwAAAABJRU5ErkJggg==</binary>
 <binary id="Any2FbImgLoader3" content-type="image/png">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
RU5ErkJggg==</binary>
 <binary id="Any2FbImgLoader4" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAH4AAAAZCAMAAADADGpYAAADAFBMVEUAAAC/AAAAvwC/vwAA
AL+/AL8Av7/AwMDA3MCmyvAYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMk
JCQlJSUmJiYnJycoKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2
NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dI
SEhJSUlKSkpLS0tMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVla
WlpbW1tcXFxdXV1eXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2ts
bGxtbW1ubm5vb29wcHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+
fn5/f3/t7e2BgYGCgoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+Q
kJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGi
oqKjo6OkpKSlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0
tLS1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v78HBwfBwcHCwsLDw8PExMTFxcXG
xsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY
2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq
6urr6+sBAQECAgIDAwMEBAQFBQUGBgbs7OwICAgJCQkKCgoLCwsMDAzu7u4NDQ0ODg4PDw8Q
EBARERESEhITExMUFBQVFRUWFhYXFxf/+/CgoKSAgID/AAAA/wD//wAAAP//AP8A///////S
vJHAAAAAAWJLR0QAiAUdSAAAAJpJREFUeJztlMEOwCAIQ73x/3/bmxtTM4F6xSWzxxZ5kTlK
2azKhZTgxgsVUoKDP/h/4BUIkRLw6jaLNxv+FIwjPli36qsGK7waDP/6thlMTbV+wEMDbcXx
T0Lws+/vgqmqWj/gWzU4Hn00nmJ9MkqKL9owBCPddHsxSv/2/rFmv3zYE7n/Pfy8sreemf/f
lu7BfwqPhVKCzboAdU0qvuTjT/8AAAAASUVORK5CYII=</binary>
 <binary id="Any2FbImgLoader5" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAH4AAAAZCAMAAADADGpYAAADAFBMVEUAAAC/AAAAvwC/vwAA
AL+/AL8Av7/AwMDA3MCmyvAYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMk
JCQlJSUmJiYnJycoKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2
NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dI
SEhJSUlKSkpLS0tMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVla
WlpbW1tcXFxdXV1eXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2ts
bGxtbW1ubm5vb29wcHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+
fn5/f3/t7e2BgYGCgoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+Q
kJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGi
oqKjo6OkpKSlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0
tLS1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v78HBwfBwcHCwsLDw8PExMTFxcXG
xsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY
2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq
6urr6+sBAQECAgIDAwMEBAQFBQUGBgbs7OwICAgJCQkKCgoLCwsMDAzu7u4NDQ0ODg4PDw8Q
EBARERESEhITExMUFBQVFRUWFhYXFxf/+/CgoKSAgID/AAAA/wD//wAAAP//AP8A///////S
vJHAAAAAAWJLR0QAiAUdSAAAAN5JREFUeJztljsSwyAMRNVx/9uqU8ASoJ8rZkQRK4WTXePH
CswE4HJRXlhidHxLC0uMMjyGTyUec+Ni8/FLLxaizG9d3Zipn6UfwP4V9i/Bt0YCoeRhW1cG
2I4uAxYrjOBiAz2eE0a81u3D9AQ2XnSNFwGYmaWfDfJ4NLrPsieg8Y8e0vPdKHiXfpbDo9WT
Vqb4rof0DxZe0hPl6a1+lr6pCmvPoLj2Wj9be79Z3c4foGznb/1w56sh5tQj6fG8+rd46kfv
Pfp+VZ96qv/fmf8v6e/+23kxxtmYV4lxuX5TB3e9LiFtUwAAAABJRU5ErkJggg==</binary>
 <binary id="Any2FbImgLoader6" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAH4AAAAZCAMAAADADGpYAAADAFBMVEUAAAC/AAAAvwC/vwAA
AL+/AL8Av7/AwMDA3MCmyvAYGBgZGRkaGhobGxscHBwdHR0eHh4fHx8gICAhISEiIiIjIyMk
JCQlJSUmJiYnJycoKCgpKSkqKiorKyssLCwtLS0uLi4vLy8wMDAxMTEyMjIzMzM0NDQ1NTU2
NjY3Nzc4ODg5OTk6Ojo7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NERERFRUVGRkZHR0dI
SEhJSUlKSkpLS0tMTExNTU1OTk5PT09QUFBRUVFSUlJTU1NUVFRVVVVWVlZXV1dYWFhZWVla
WlpbW1tcXFxdXV1eXl5fX19gYGBhYWFiYmJjY2NkZGRlZWVmZmZnZ2doaGhpaWlqampra2ts
bGxtbW1ubm5vb29wcHBxcXFycnJzc3N0dHR1dXV2dnZ3d3d4eHh5eXl6enp7e3t8fHx9fX1+
fn5/f3/t7e2BgYGCgoKDg4OEhISFhYWGhoaHh4eIiIiJiYmKioqLi4uMjIyNjY2Ojo6Pj4+Q
kJCRkZGSkpKTk5OUlJSVlZWWlpaXl5eYmJiZmZmampqbm5ucnJydnZ2enp6fn5+goKChoaGi
oqKjo6OkpKSlpaWmpqanp6eoqKipqamqqqqrq6usrKytra2urq6vr6+wsLCxsbGysrKzs7O0
tLS1tbW2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr6/v78HBwfBwcHCwsLDw8PExMTFxcXG
xsbHx8fIyMjJycnKysrLy8vMzMzNzc3Ozs7Pz8/Q0NDR0dHS0tLT09PU1NTV1dXW1tbX19fY
2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm5ubn5+fo6Ojp6enq
6urr6+sBAQECAgIDAwMEBAQFBQUGBgbs7OwICAgJCQkKCgoLCwsMDAzu7u4NDQ0ODg4PDw8Q
EBARERESEhITExMUFBQVFRUWFhYXFxf/+/CgoKSAgID/AAAA/wD//wAAAP//AP8A///////S
vJHAAAAAAWJLR0QAiAUdSAAAAN1JREFUeJztls0OwyAMg7nx/m+bm8c/SXAvbQWHNdOkze7y
xZSihXC4wEu2GAkfackWYxteltdOvHDj4OLLl/5+MxGhRteHr9JnYPoY5rfWLIwLOL7rCp8J
DN/09IZr1Y6a2ktWfBYYfuoGbwZQ+KIbfO9emTx9cQhe6w6vBjD4qrv0ZeFHFJde2tJ4vNUX
fId4/HRG+tIjvJsecEbXI0kfVb1x76GHhNHZvffPyrOdDzsijE53vuI/PfXgB4TVAZe+bn39
i92nnlr/78z/l/Rn/+1cGOlJuKgtxuH6AZm8d2J7GqlcAAAAAElFTkSuQmCC</binary>
 <binary id="Any2FbImgLoader7" content-type="image/png">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
/2o/iCHkufw/hlDZwPn2S5MAAAAASUVORK5CYII=</binary>
 <binary id="Any2FbImgLoader8" content-type="image/png">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
rkJggg==</binary>
 <binary id="Any2FbImgLoader9" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAYgAAABMCAMAAABAk9ACAAAAA3NCSVQICAjb4U/gAAAAMFBM
VEUAAAAAe3t7AAB7e3u9vb3/hIT///////////////////////////////////8AAADJgtwn
AAAAAWJLR0QAiAUdSAAABO1JREFUeJztnd162yAMhluXncL93+1q0C8WNqxJrWT6nqcxSBgJ
XgNOdrCPHPKgr4+cQg4UIJwoQDhRA/EVulOZQdz8OPznChBOFCCcKEA4UYBwogDhRAHCiQKE
E12DKKjZLudbzne0F0unPlKrDaIvjuGnOka6Cj4BYkNNDuP7hrmGCx3tRU4E1EVqNTP69yys
jeGHKn0WLYGz4Csg7CFaNzzmtyvRUS32ILKKVFrNil7Ox7CW1CXK0mY9K9Nl8CkQ7ddysyPj
AXwaiFTToHxqcZOtByDaNIzHsJrUdYutB9HinwWfAwFtjY6scT8NhFHk8gmINg21nH+a3MTo
DiDqYs3VM7x3BQQV6diri7AoU22lDsa+LI/g04U+BWKTZRMETQO2wzwK+hOPh+7pE6TXBdzq
Dz6OmPWmmSiBk+W0BCLVccPJV3D0+6nJpgaCD0btEg7tuYh8AiKLnm0Q+vHczxbcs4vIt8iJ
Kt1A4fHic8byDSZN1E6W0xqIWhbp4CqUJnm6yxrNllUZRaZ31TGITRRHILI05TzMkJd8xdWN
im+zfdbU69pjQaR28DVzOzp7E9Q22BfRxR5VGZHQ76s2CKgVKtogtEFnSCdphiUPJp0gHvgF
Pw3fKOazQKQ9JKxF9HamaoNRsWufLWxdRLNBcjMgxFTMg9hUhpBI4SVBC0IkiDe1TcH2jWI+
DUThV2VezAeT0XqfUDjjxL7DB253lqsX1QEInpgVEFlkiGnyksAFIRPEm/AWyzeK+XAQBUZd
+CHFR+hgopylC7+Tpe5xzxRKnhnj2ZfFDb50T4LY35FkwA4EWXKXID1x6pjUvmHMh4OQ55RM
/GjCO7WrfRehp+6w7ZxuQoNiaa8seQgCt0i65wpEOZtsDyBovBvvFpRXZ8Lm2lUjwtdb3nfE
MadqcyCSng5jrGpzlSBoxhlE2ugNSCeoQAx8dshEx2B5CAjc6GFDLBpEb8J3E+Uq/G0it8Ox
9XsR+aJYH898AqJOLsbam8ISEQPifgEUnt6UoAZh+8zUoYrj/hEIPJZaP1sztNGV+tmbsFZf
bNmFXeETR7Vh5KnFAdsZTRH/Ti5IbDyGLkMNIvHuqBIUIMrIZ6QOWbTmm/GQLIHg7ZBTxb2e
P9Ekbshda91R1+0/g+AnOOt0NQkRTGXYgSickLyHwkLHps8AAVmcj3QKhAyZhQW/D9EnmbYt
y/bSlVU+WXdrRM5TRXWRcy7GqceQZU33ksSN+diK/KbvmDoW8ulI5/6p9HCkJqg1E32S6ftP
tu9b94fzMHBSIU+K6mK8Awizrlq9JGOkKiz9kmv4jkkebhsMNcW/WbtQgHCiAOFEAcKJAoQT
BQgnChBOFCCcKEA4UYBwogDhRAJECd0oCeLzzZRfSAHCiQKEEwUIJ7JBfJ8d4nJmdK27J3dF
JojS/uByZvStuyd3RTMgYCV8BognanlFuNqa/lSpK9jr5e7JXdFrb00w4Z88/7WE5rsnd0Xv
CAKtrw+ie0GCvcjhW5MJgji8AYhXERwN8io4BIhfE25EYkOqKN7ljHgp6e1J7U53T+6K3gwE
LI0A8cvqtyaEESB+W3BIf+L3OTQ2792Tu6IXB3Guuyd3RQHCiQKEEwUIJwoQThQgnChAOFGA
cKIA4UQKROhGMYi7n4n/XQQidLsChBMFCCf6+rj7//4KNf0F0EC2XzKf1DUAAAAASUVORK5C
YII=</binary>
 <binary id="Any2FbImgLoader10" content-type="image/png">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
SLPVOmaoNQu36X8Fs1rV1ul1tcpHnLe4dXVbCzR3V3OyXp+JutUl+2xg0meGZlvlg7+DpqPl
+8zYHevN6i5T7PL5aZMmtPY8WHrOey3ap8rWGtb2seywdZrzYQ6TXZu91YHmvdYuH1WljmSf
4dfq5L6mwQPt1ZG1tlVUF444Erd1dX3aU9N9qbfU3RMJPTMasEX9vffhR22btvUDtnWrR3mz
uj/DW3W/cdX5EuMeLEGTk7qlPubBDpOeE1RGMdrMgSdfPXv82cNy5lPz2fJSfvrcfP3dD1d/
+7Utwt778KO7f3q9NnX8k0eP0zSXnmrzsTpW0az8rXcefP3dD9U2lH/71Ofsqbl1W1fXXWDj
7qotbJZ58+0HT756vbqk+ZK0xvLt27ppVd1n4ls3ufsz0K3siVTH+u/+6fWP33+357vTvdV7
vlltZf7wx9fLA6TP1r359oOrv/36P//9a/Xj94c/vt789dDnYNm6q3u+O1s/ch3S4VPdol13
7P6HSdF7gsooYr/vdVrpLGDwlzneHs0BnIiXzM0CNmGAqb4aeJG6BwfGnPc6K9UrHrK127BL
T+lkLYspTU3jXnCDpsXGa/VvPKZtyTy1/a36TlmZ3aTIUbYaelrsrQw7/j6HouUq0CQXNw7p
dm41U1lsvJad1rZLbVS/pLkoik8ePd7pSwwydTu3mqks+dIW0PTzTz+WF9P1PPZ3Sy9tARtJ
1YNZ7OAAwLTEK0AI8QoQQrwChBCvACHEK0CILROzqpO5ACiKouefBWyJ1+Pj4xHaArAg//tf
//HP//KvW4ttidc+VQDQZOwVIIR4BQghXgFCiFeAEOIVIIR4BQghXgFCiFeAEOIVIIR4BQgh
XgFCiFeAEOIVIIR4BQghXgFCiFeAEOIVIIR4BQghXgFCiFeAEOIVIIR4BQghXgFCiFeAEOIV
IIR4BQghXgFCiFeAEOK11f27d0YvCdwer0zdgJ09f/Y0Pf7g4ecbyzTz7vzqOrBN29y/e6dP
A3oWS4XT48m3rvpjzy3dqTzkKKd4LYP15OSktnxjyNYO2vJ4XsyRXAvinXI5tCV9GjOfxkOo
bOL1+bOnZbDe3NykhavVqiiK9Xr9y28vu19eHsBTHclbV7rT8EJzK86vruezad2NmVXjIVQ2
8VqqZmv54+Xl5T4V9jxLLY//7sIdz26Nj5T+/VrdZVh3staS6gvTswdIwAGNh9nKI17LrmvK
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
RU5ErkJggg==</binary>
 <binary id="Any2FbImgLoader11" content-type="image/png">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
41onAAAAAElFTkSuQmCC</binary>
 <binary id="image001.png" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAIwAAACkCAMAAABy4TZXAAADAFBMVEUSEhUYEBgcFAwhEBAY
GBgQGCEYECEYGCEhEBghECEhGBAhGBghGCEpGAgpGBApGBghIQghIRAYIRghIRgYISEYKSEh
ISEhKSEYHCkhGCkhISkpGCEhITEYKSkhKSkeLy4rHg4pKRgpISEpKSExHBgxKRg3HxNGIhEp
GCkpGDEpISkpJS05GCE1ISk5KSFIJyEpMSkxMRwzKykpKTEtLTExMTEpOTExOTE8MR9OMRo/
Ky1KKys9Nyk/NjFONSZJQC4hKTkhMTkpITkpKTkxITkxKT0pMTkxMTkhMUIpMUIxMUIhOTkp
OTkxOTkhOUIpOUI5KTk5KUI5MTk5MUI5OTlCMTlCMUJKNTkxOUIxQjkxQkI5OUI8Pz9HPzw5
SkJESj8hOUopMUopOUopQkoxOUoxQkoxSko5OUpCOUpKOUpKQkI5Qko5SkpCQkpCTkpKSkJK
QkpKSkpKUkopQlIxOVIxQlIxSlI5QlI5SlJCQlJCSlJKQlJKSlJKUlJKSlpCpcZkMRRmOCNg
RitvSSl6PiKHRCR3Ui6IUylUR0RmTkaJTDOKVTd1YUdyZmKOXTOJb1WZVTGUY0KrUTGlYTiY
aT6cc0Klaz+uaz6baE6tZ0qzZkyxc0aid1Cte1KZeGKqfF69Xj+1c069cE/MZEm1c1q1e0q5
d1bNdFa1gVe9flS9hFq5e2fGe1LGe1rJfFzVfF23hmW9hGvGhFq9jGfGjFrGhGPGhGvGjGfO
hFrOhGPOhGvKkGLSiF7OlGPWiF7ciWGEc3OliHPAhnPGjHPOhHPOjGvLkXDOlHPWf2vehGvW
jGvajG/WlGvelGvWlHPOnHOLe3utiXvQjnvOnHvakHfelHPWnHfWpXufjo62nJfQloXIqJ7I
trfTvrvSxMzWztnniW3nlHPemHfilH/nnHPenHvnnHvenITepXveoIjepYzqo4HioJDerYzn
pYzsqoziqZber6LvpZTqsZjpx8Ho09fe1t7o2t7ezufh2Ofn3ufe3u/n3u/n5+fn5+/x4Oa1
dY4VAAAAgHRSTlP/////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
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
KELUuW+YPAgAAAAASUVORK5CYII=</binary>
 <binary id="image003.jpg" content-type="image/jpeg">/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8l
JCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIo
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAAR
CADAAJkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA
AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK
FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG
h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl
5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA
AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk
NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE
hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk
5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtbq6uFu5gJ5QBI2AHPrUX2u5/5+Jf++zR
d/8AH5P/ANdG/nUVe7GMeVaH5RWrVfay957vqS/a7n/n4l/77NH2u5/5+Jf++zUVFVyx7GXt
6v8AM/vZL9ruf+fiX/vs0fa7n/n4l/77NRNtSIzSuI4x/Ex6/T1rG1HxJtBh05Ch6GU/eP8A
hXNVr0qelrs9bA5fjMX7yk1Hu2/wN6S7mgG64vXhGON8hBP4VTn8TW0K/LcXcrdyGwpNco0p
wZbiVnY+pyaryXmeUUfU1wTxE5baH1mHyejTXvycn5tnUN4yZPuxyH/fmb+lNHjcMcPDMP8A
rnMf61x7SFm5/SkBweKy553vc7/qVDl5eU7qHxZayHEk15F7792K0IryW4TfbXzzLjPyyHI+
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
aPJk/uP+Rpgf/9k=</binary>
</FictionBook>
