復活のAda

ある程度環境が整ったので、世界最強言語と評判のAdaを使用したプログラミングを再開してみる。

とりあえず、Socketを使って通信でもしてみようと思い、GNAT.Socketsについて調べてみる。が、しかし、さすがはAda、日本語の情報が皆無である。

あきらめて英語の情報を探していると、GNAT.Socketsを使ったコードのサンプルがあったので、改造してサーバのような何かを作ってみた。ちなみに、WikibooksのAdaに関するページの1部らしい。纏まっているので便利だ。

with Ada.Text_IO;             use Ada.Text_IO;
with GNAT.Sockets;            use GNAT.Sockets;
with Ada.Strings.Unbounded;   use Ada.Strings.Unbounded;

with Ada.Streams;
use type Ada.Streams.Stream_Element_Count;

procedure Sock is

   Server         : Socket_Type;
   Server_Address : Sock_Addr_Type;
   Client         : Socket_Type;
   Clinet_Adress  : Sock_Addr_Type;
   Channel        : Stream_Access;

   Send   : String := (1 => ASCII.CR, 2 => ASCII.LF,
                       3 => ASCII.CR, 4 => ASCII.LF);
   Offset : Ada.Streams.Stream_Element_Count;
   Data   : Ada.Streams.Stream_Element_Array (1 .. 1);

begin

   Initialize;
   Create_Socket (Server);
   Server_Address.Addr := Inet_Addr("127.0.0.1");
   Server_Address.Port := 8000;

   Bind_Socket (Server, Server_Address);
   Listen_Socket (Server);
   Ada.Text_IO.Put_Line ("Listening...");
   Accept_Socket (Server, Client, Clinet_Adress);
   Close_Socket (Server); -- Stop listening
   Channel := Stream (Client);

   loop
      Ada.Streams.Read (Channel.all, Data, Offset);
      exit when Offset = 0;
      for I in 1 .. Offset loop
         Ada.Text_IO.Put (Character'Val (Data (I)));
      end loop;
   end loop;

end Sock;

このコードで、TCPのポート8000でListenする。接続後は受信したデータを標準出力に表示してくれる。

Socket自体の使用方法はCと同一なのでそれほど難しくないのだが、リファレンスがろくにないのが何とも困る。

さて、Adaを勉強中の私はIOが理解できていない。Streams.Read()は第2引数のAda.Streams.Stream_Element_Array (size)が満杯になるまでバッファリングしてくれるようなのだが、用途によってはこれは好ましくない。上記のコードでは配列のサイズを1 .. 1として、1バイトごとに処理してるのだが、これは何か違う気がする。Direct_IOあたりを使うのが正しいのだろうか。

Adaはselectが言語構造に組み込まれているらしいので、次はそこら辺を弄ってみたい。が、その前に基本的なところをもう少し押さえる必要がありそうだ。