comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: Parameterised 'Image Attributes
  2023-08-28 17:33  1%                                   ` G.B.
@ 2023-08-28 19:08  0%                                     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2023-08-28 19:08 UTC (permalink / raw)


On 2023-08-28 19:33, G.B. wrote:
> On 28.08.23 18:09, Dmitry A. Kazakov wrote:
>> On 2023-08-28 17:42, Stephen Davies wrote:
>>> On Monday, 28 August 2023 at 11:58:24 UTC+1, Dmitry A. Kazakov wrote:
>>>> On 2023-08-28 11:18, Stephen Davies wrote:
>>>> This will not happen either. But here I would agree, it is clearly a
>>>> case of language littering.
>>>
>>> Littering, schmittering, how about adding Bin_Image, Oct_Image & 
>>> Hex_Image
>>> for Ints and Dec_Image for Ints & Reals ;-)
>>
>> Bin_Width_1_Image, Dec_Width_4_Image and so on... Cool, make Ada C 
>> again! (:-))
> 
> Or maybe leave type attributes alone. Instead, let Ada.Streams
> have I/O manipulating setters.
> 
> Then,  in order to preserve the meaning of "corresponding S'Output"
> (LRM 13.13.2) for every S'Input, add AI to the Ada run-time system.

I like the idea of unification of serialization and formatting.

However it does not solve the problem of parameters. In GUI frameworks 
facing this very problem the parameters for rendering are set into the 
graphic context/surface.

E.g. in the case of string formatting you would need a global object to 
set the parameters into. E.g. a set of procedures like 
Ada.Text_IO.Set_Field_Width, Ada.Text_IO.Set_Integer_Base etc. That 
would be incredibly boring and unsafe.

For stream serialization the parameters could be set on the stream 
itself. Which might break a lot of code if you added them to 
Root_Stream_Type.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Parameterised 'Image Attributes
  @ 2023-08-28 17:33  1%                                   ` G.B.
  2023-08-28 19:08  0%                                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: G.B. @ 2023-08-28 17:33 UTC (permalink / raw)


On 28.08.23 18:09, Dmitry A. Kazakov wrote:
> On 2023-08-28 17:42, Stephen Davies wrote:
>> On Monday, 28 August 2023 at 11:58:24 UTC+1, Dmitry A. Kazakov wrote:
>>> On 2023-08-28 11:18, Stephen Davies wrote:
>>> This will not happen either. But here I would agree, it is clearly a
>>> case of language littering.
>>
>> Littering, schmittering, how about adding Bin_Image, Oct_Image & Hex_Image
>> for Ints and Dec_Image for Ints & Reals ;-)
> 
> Bin_Width_1_Image, Dec_Width_4_Image and so on... Cool, make Ada C again! (:-))

Or maybe leave type attributes alone. Instead, let Ada.Streams
have I/O manipulating setters.

Then,  in order to preserve the meaning of "corresponding S'Output"
(LRM 13.13.2) for every S'Input, add AI to the Ada run-time system.

^ permalink raw reply	[relevance 1%]

* Re: GNAT Community 2020 (20200818-93): Big_Integer
  2023-06-30 19:28  2% GNAT Community 2020 (20200818-93): Big_Integer Frank Jørgen Jørgensen
@ 2023-06-30 21:07  1% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2023-06-30 21:07 UTC (permalink / raw)


On 2023-06-30 21:28, Frank Jørgen Jørgensen wrote:

> I'm running the below program with GNAT Community 2020 (20200818-93)
> on Windows 11 Home.
> I have some problems trying to save big numbers to a file - so I noticed this behaviour:
> If I open Test.dat in Visual Studio Hex editor,  it seems like this program saves this big number with a different bit pattern each time.
> Is that as expected?
> I do have some problems reading back the big numbers in my real code.
> When I compile I get the warning: "Ada.Numerics.Big_Numbers.Big_Integers"  is an Ada 202x unit.
> 
> --
> with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
> with Ada.Numerics.Big_Numbers.Big_Integers;
> 
> procedure Test is
> 
>        B1 : Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer;
>        F1 : File_Type;
>        S1 : Stream_Access;
>     begin
>        B1 := 1;
> 
>        Ada.Streams.Stream_IO.Create (F1, Out_File, "Test.dat");
>        S1 := Ada.Streams.Stream_IO.Stream (F1);
>        Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Write(S1, B1);
>        Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Output(S1, B1);
>        Ada.Streams.Stream_IO.Close (F1);
> end Test;

As a general rule, you should never use predefined implementations of 
stream attributes except for Stream_Element or Character. Anything else 
you must always override or else not use.

If you want to serialize signed integers use some portable format for 
it. E.g. a chained encoding.

Here is a test program for a straightforward implementation of chained 
store/restore:
-------------------------
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Numerics.Big_Numbers.Big_Integers;
with Ada.Exceptions;
with Ada.IO_Exceptions;

procedure Test is

    use Ada.Streams;
    use Ada.Numerics.Big_Numbers.Big_Integers;
    use Ada.Exceptions;
    use Ada.Streams.Stream_IO;

    Two : constant Big_Integer := To_Big_Integer (2);

    package Conversions is new Unsigned_Conversions (Stream_Element);
    use Conversions;

    function Get
             (  Stream : in out Root_Stream_Type'Class
             )  return Big_Integer is
       Result   : Big_Integer;
       Power    : Natural := 6;
       Negative : Boolean;
       Buffer   : Stream_Element_Array (1..1);
       Last     : Stream_Element_Offset;
       This     : Stream_Element renames Buffer (1);
    begin
       Stream.Read (Buffer, Last);
       if Last /= 1 then
          raise End_Error;
       end if;
       Result   := To_Big_Integer ((This and 2#0111_1110#) / 2);
       Negative := 0 /= (This and 1);
       if 0 = (This and 16#80#) then
          if Negative then
             return -Result - 1;
          else
             return Result;
          end if;
       end if;
       loop
          Stream.Read (Buffer, Last);
          if Last /= 1 then
             raise End_Error;
          end if;
          Result := Result +
             Two**Power * To_Big_Integer (This and 16#7F#);
          if 0 = (This and 16#80#) then
             if Negative then
                return -Result - 1;
             else
                return Result;
             end if;
          end if;
          Power := Power + 7;
       end loop;
    end Get;

    procedure Put
              (  Stream : in out Root_Stream_Type'Class;
                 Value  : Big_Integer
              )  is
       Item   : Big_Integer := Value;
       Buffer : Stream_Element_Array (1..1);
       This   : Stream_Element renames Buffer (1);
    begin
       if Item >= 0 then
          Item := Value;
          This := From_Big_Integer (Item mod (16#40#)) * 2;
       else
          Item := -(Value + 1);
          This := From_Big_Integer (Item mod (16#40#)) * 2 + 1;
       end if;
       Item := Item / 16#40#;
       if Item = 0 then
          Stream.Write (Buffer);
          return;
       end if;
       This := This or 16#80#;
       Stream.Write (Buffer);
       loop
          This := From_Big_Integer (Item mod 16#80#) or 16#80#;
          Item := Item / 16#80#;
          if Item = 0 then
             This := This and 16#7F#;
             Stream.Write (Buffer);
             return;
          end if;
          Stream.Write (Buffer);
       end loop;
    end Put;

    F : File_Type;
begin
    Create (F, Out_File, "Test.dat");
    for I in -1_000_000..1_000_000 loop
       Put (Stream (F).all, To_Big_Integer (I));
    end loop;
    Close (F);
    Open (F, In_File, "Test.dat");
    for I in -1_000_000..1_000_000 loop
       declare
          Value : constant Big_Integer := Get (Stream (F).all);
       begin
          if Value /= To_Big_Integer (I) then
             raise Data_Error;
          end if;
       end;
    end loop;
    Close (F);
end Test;
-------------------------
The above could be optimized to work with buffers rather than 
reading/writing stream octets one by one. It is a long story, but 
normally you would implement some data blocks with the length count on 
top of the stream in order to avoid inefficient octet by octet reading 
and add an error correction layer.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* GNAT Community 2020 (20200818-93):   Big_Integer
@ 2023-06-30 19:28  2% Frank Jørgen Jørgensen
  2023-06-30 21:07  1% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Frank Jørgen Jørgensen @ 2023-06-30 19:28 UTC (permalink / raw)


Hi

I'm running the below program with GNAT Community 2020 (20200818-93)
on Windows 11 Home.
I have some problems trying to save big numbers to a file - so I noticed this behaviour:
If I open Test.dat in Visual Studio Hex editor,  it seems like this program saves this big number with a different bit pattern each time.
Is that as expected?
I do have some problems reading back the big numbers in my real code.
When I compile I get the warning: "Ada.Numerics.Big_Numbers.Big_Integers"  is an Ada 202x unit.

Frank

--
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Numerics.Big_Numbers.Big_Integers;

procedure Test is

      B1 : Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer;
      F1 : File_Type;
      S1 : Stream_Access;
   begin
      B1 := 1;

      Ada.Streams.Stream_IO.Create (F1, Out_File, "Test.dat");
      S1 := Ada.Streams.Stream_IO.Stream (F1);
      Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Write(S1, B1);
      Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Output(S1, B1);
      Ada.Streams.Stream_IO.Close (F1);
end Test;

^ permalink raw reply	[relevance 2%]

* Re: Broadcast / iterate to all Connection objects via Simple Components?
  @ 2023-02-13 16:40  1%             ` Jeremy Grosser <jeremy@synack.me>
  0 siblings, 0 replies; 200+ results
From: Jeremy Grosser <jeremy@synack.me> @ 2023-02-13 16:40 UTC (permalink / raw)


> epoll is definitely the modern approach on linux, until of course someone finds 
> something even better. epoll is fully thread safe too, which is very nice when 
> used from Ada. 

For high performance networking, io_uring [1] is the new kid on the block, but the API involves a scary amount of pointer manipulation, so I'm not convinced that it's safe to use yet.

While epoll is thread safe, there are some subtleties. If you register a listening socket with epoll, then call epoll_wait from multiple threads, more than one thread may be woken up when the socket has a waiting incoming connection to be accepted. Only one thread will get a successful return from accept(), the others will return EAGAIN. This wastes cycles if your server handles lots of incoming connections. The recently added (kernel >=4.5) EPOLLEXCLUSIVE flag enables a mutex that ensures the event is only delivered to a single thread.

> They also have strong concerns about platform-agnostic support, and epoll is linux-specific 
> at this point (likely also BSD). There exists multiple libraries out there that provide an API 
> common to multiple platforms, and that use epoll on linux. Maybe that's what would make 
> sense, but nowadays with Alire, I would expect someone to build a crate there rather than 
> AdaCore modify GNAT.Sockets.

On BSD, the kqueue [2] API provides similar functionality to epoll. I believe kqueue is a better design, but you use what your platform supports.

libev [3] is the library I see used most commonly for cross-platform evented I/O. It will use the best available polling syscalls on whatever platform it's compiled for. Unfortunately, it's composed mostly of C preprocessor macros.

I've already written an epoll binding [5] that's in the Alire index. GNAT.Sockets provides the types and bindings for the portable syscalls.

For the Protohackers puzzles, I've written a small evented I/O server using those bindings [6]. Note that this server does not use events for the send() calls yet, which may block, though in practice it isn't an issue with the size of the payloads used in this application. I do plan to refactor this to buffer data to be sent when the Writable (EPOLLOUT) event is ready.

So far, I've found tasks and coroutines to be unnecessary for these servers, though coroutines would make it possible to implement Ada.Streams compatible Read and Write procedures, providing a cleaner interface that doesn't expose callbacks to the user.

[1] https://lwn.net/Articles/776703/
[2] https://people.freebsd.org/~jlemon/papers/kqueue.pdf
[3] https://linux.die.net/man/3/ev
[4]  https://github.com/JeremyGrosser/epoll-ada
[5] https://github.com/JeremyGrosser/protohackers/blob/master/src/mini.adb

^ permalink raw reply	[relevance 1%]

* Re: Sockets, Streams, and Element_Arrays: Much confusion
  2022-12-31 17:39  1% ` Simon Wright
@ 2022-12-31 19:36  0%   ` Mark Gardner
  0 siblings, 0 replies; 200+ results
From: Mark Gardner @ 2022-12-31 19:36 UTC (permalink / raw)


On 31/12/2022 19:39, Simon Wright wrote:
> [...]
> 
> The approach we adopted was to create a 'memory stream', which is a
> chunk of memory that you can treat as a stream (see for example
> ColdFrame.Memory_Streams at [1]). With Ada2022, you should be able to
> use Ada.Streams.Storage.Bounded[2].
> 

Wait, so if I know what shape my data is, and use a memory_stream (like 
the one in the Big Online Book of Linux Ada Programming chapter 11 [1]), 
I'm fine using Stream, in conjunction with Get_Address? That's 
wonderful. Not at all frustrated that I just wasted approximately three 
working days looking for a solution to a problem that didn't exist.

> Message'Write the record into the memory stream;
> transmit the written contents as one datagram.

I'm guessing with Memory_Stream'Write(Socket_Stream, Buffer);?

> 
> To read, create a memory stream large enough for the message you expect;
> read a datagram into the memory stream;
> Message'Read (Stream => the_memory_stream, Item => a_message);

Does this second buffer need to be added? If the datagram arrives (UDP), 
shouldn't GNAT.Sockets.Stream() be able to handle it?
> 
> You can use gnatbind's switch -xdr to "Use the target-independent XDR
> protocol for stream oriented attributes instead of the default
> implementation which is based on direct binary representations and is
> therefore target-and endianness-dependent".

Oh fun, I didn't think of that aspect. Thanks! Would I have to pass it 
as a command line flag, or would there be some kind of pragma I could use?

Thanks for the help so far, and happy new year!

[1] http://www.pegasoft.ca/resources/boblap/11.html#11.12

^ permalink raw reply	[relevance 0%]

* Re: Sockets, Streams, and Element_Arrays: Much confusion
    2022-12-31 13:11  1% ` Dmitry A. Kazakov
@ 2022-12-31 17:39  1% ` Simon Wright
  2022-12-31 19:36  0%   ` Mark Gardner
  1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2022-12-31 17:39 UTC (permalink / raw)


Mark Gardner <magardner2017@gmail.com> writes:

> GNAT.Sockets gives me a Stream_Element_Array, which I can't find any
> documentation on how to make use of other than "You should also be
> able to get a Stream, which you should use instead" (About ten years
> ago, on this very newsgroup, somebody said not to use streams with
> UDP, or at least not GNAT.Sockets.Stream).

The reasoning behind the recommendation not to use streams with UDP was
as follows (there's a faint possibility that it no longer applies!)

If the data type you want to send is e.g.

   type Message is record
      Id  : Integer;
      Val : Boolean;
   end record;

and you create a datagram socket and from that a stream, then use
Message'Write to the stream, GNAT will transmit each component of
Message separately in canonical order (the order they're written in the
type declaration). This results in two datagrams being sent, one of 4
bytes and one of 1 byte.

If you take the same approach at the destination, Message'Read reads one
datagram of 4 bytes, and one of 1 byte, and it all looks perfect from the
outside. If the destination is expecting a 5 byte record, of course,
things won't work so well.

The approach we adopted was to create a 'memory stream', which is a
chunk of memory that you can treat as a stream (see for example
ColdFrame.Memory_Streams at [1]). With Ada2022, you should be able to
use Ada.Streams.Storage.Bounded[2].

Message'Write the record into the memory stream;
transmit the written contents as one datagram.

To read, create a memory stream large enough for the message you expect;
read a datagram into the memory stream;
Message'Read (Stream => the_memory_stream, Item => a_message);

You can use gnatbind's switch -xdr to "Use the target-independent XDR
protocol for stream oriented attributes instead of the default
implementation which is based on direct binary representations and is
therefore target-and endianness-dependent".

[1]
https://github.com/simonjwright/coldframe/blob/master/lib/coldframe-memory_streams.ads
[2] http://www.ada-auth.org/standards/22rm/html/RM-13-13-1.html#p25

^ permalink raw reply	[relevance 1%]

* Re: Sockets, Streams, and Element_Arrays: Much confusion
  2022-12-31 13:50  0%   ` Mark Gardner
@ 2022-12-31 14:16  0%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2022-12-31 14:16 UTC (permalink / raw)


On 2022-12-31 14:50, Mark Gardner wrote:
> On 31/12/2022 15:11, Dmitry A. Kazakov wrote:
>> On 2022-12-31 13:11, Mark Gardner wrote:
>>
>>> ...
>>
>> Stream_Element_Array is declared in Ada.Streams as
>>
>>     type Stream_Element_Array is
>>        array(Stream_Element_Offset range <>) of
>>           aliased Stream_Element;
>>
>> For communication purpose it is an array of octets. Your datagram is 
>> represented as a Stream_Element_Array or a slice of.
> 
> According to RM 13.13.1, "Stream_Element is mod implementation-defined" 
> which to me says there is no guarantee that they will be octets, unless 
> this is specified elsewhere?

GNAT.Sockets is GNAT-specific. All GNAT compilers have Stream_Element 8 
bits. I can imagine some DSP implementation with Stream_Element of 32 
bits. But realistically add

    pragma Assert (Stream_Element'Size >= 8);

and be done with that.

> So, how would I do this directly on the elements? I mean, if it is an 
> octet-array to a string, I expect an element-to-element copy, or type 
> conversion to work, but what about integers?

Hmm, it cannot be string. It is a string encoded in some specific way 
(usually most peculiar (:-)). Then you will have to decode it into your 
machine type e.g. Wide_String or String.

An UTF-8 string you could put into String ignoring Ada's Latin-1 stuff, 
as most people would do:

    function To_String (S : Stream_Element_Array) return String is
    begin
       return Result : String (1..S'Length) do
          for I in S'Range loop
             Result (Positive (I - S'First + 1) := Character'Val (S (I));
          end loop;
       end return;
    end To_String;

> Do I need to do something like
> My_Int:=Unsigned_8(octet(1))+2**8*Unsigned_8(octet(2));
> or whatever endianness demands? Or is this the time to learn how to use 
> Unchecked_Conversion?

There are many ways to convert Stream_Element_Array "in situ" to string. 
However, in network protocols you rarely have any strings at all. 
Usually it is some binary data you need to decode into some machine 
type. (So is String or Wide_String actually)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Sockets, Streams, and Element_Arrays: Much confusion
  2022-12-31 13:11  1% ` Dmitry A. Kazakov
@ 2022-12-31 13:50  0%   ` Mark Gardner
  2022-12-31 14:16  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Mark Gardner @ 2022-12-31 13:50 UTC (permalink / raw)


On 31/12/2022 15:11, Dmitry A. Kazakov wrote:
> On 2022-12-31 13:11, Mark Gardner wrote:
> 
>> ...
> 
> Stream_Element_Array is declared in Ada.Streams as
> 
>     type Stream_Element_Array is
>        array(Stream_Element_Offset range <>) of
>           aliased Stream_Element;
> 
> For communication purpose it is an array of octets. Your datagram is 
> represented as a Stream_Element_Array or a slice of.
> 

According to RM 13.13.1, "Stream_Element is mod implementation-defined" 
which to me says there is no guarantee that they will be octets, unless 
this is specified elsewhere?

> As for streams, yes, it does not make sense to use them for networking, 
> unless you override all stream primitives. The reasons for that are
> 
> - non-portability of predefined primitives
> - low efficiency for complex data types
> - encoding inefficiency as well
> 
> You will need to handle some application protocol artifacts, checksums, 
> counters, strange encodings, sequence number etc. It is easier to this 
> directly on the Stream_Element_Array elements.

So, how would I do this directly on the elements? I mean, if it is an 
octet-array to a string, I expect an element-to-element copy, or type 
conversion to work, but what about integers? Do I need to do something like
My_Int:=Unsigned_8(octet(1))+2**8*Unsigned_8(octet(2));
or whatever endianness demands? Or is this the time to learn how to use 
Unchecked_Conversion?

> And, well, do not use UDP, expect for broadcasting. There is no reason 
> to use it. For multicast consider delivery-safe protocols like PGM. For 
> single cast use TCP/IP. (If you need low latency see the socket NO_DELAY 
> option)
> 

  Well, my use case just so happens to be broadcasting, and 
re-broadcasting data across a binary-tree-like p2p network.

^ permalink raw reply	[relevance 0%]

* Re: Sockets, Streams, and Element_Arrays: Much confusion
  @ 2022-12-31 13:11  1% ` Dmitry A. Kazakov
  2022-12-31 13:50  0%   ` Mark Gardner
  2022-12-31 17:39  1% ` Simon Wright
  1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2022-12-31 13:11 UTC (permalink / raw)


On 2022-12-31 13:11, Mark Gardner wrote:

> GNAT.Sockets gives me a Stream_Element_Array, which I can't find any 
> documentation on how to make use of other than "You should also be able 
> to get a Stream, which you should use instead" (About ten years ago, on 
> this very newsgroup, somebody said not to use streams with UDP, or at 
> least not GNAT.Sockets.Stream).

Stream_Element_Array is declared in Ada.Streams as

    type Stream_Element_Array is
       array(Stream_Element_Offset range <>) of
          aliased Stream_Element;

For communication purpose it is an array of octets. Your datagram is 
represented as a Stream_Element_Array or a slice of.

As for streams, yes, it does not make sense to use them for networking, 
unless you override all stream primitives. The reasons for that are

- non-portability of predefined primitives
- low efficiency for complex data types
- encoding inefficiency as well

You will need to handle some application protocol artifacts, checksums, 
counters, strange encodings, sequence number etc. It is easier to this 
directly on the Stream_Element_Array elements.

And, well, do not use UDP, expect for broadcasting. There is no reason 
to use it. For multicast consider delivery-safe protocols like PGM. For 
single cast use TCP/IP. (If you need low latency see the socket NO_DELAY 
option)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* Re: Usage of Stream Set_Index() function
  2022-01-14 20:35  0% ` Niklas Holsti
@ 2022-01-15 10:36  0%   ` DrPi
  0 siblings, 0 replies; 200+ results
From: DrPi @ 2022-01-15 10:36 UTC (permalink / raw)


Le 14/01/2022 à 21:35, Niklas Holsti a écrit :
> On 2022-01-14 20:30, DrPi wrote:
>>
>> Hi,
>>
>> I'm writing an application where I read a file with a complex structure.
>> For this, I use Ada.Streams.Stream_IO package.
>> To read the file, I need to position the file pointer to the correct 
>> location. I do this using Set_Index().
>>
>> In ARM A.12.1, it is stated :
>> For Read and Write with a Positive_Count parameter, the value of the 
>> current index is set to the value of the Positive_Count parameter plus 
>> the number of stream elements read or written.
>>
>> I don't understand the "plus the number of stream elements read or 
>> written".
> 
> 
> For Write, the ARM also says: "The Write procedure with a Positive_Count 
> parameter starts writing at the specified index". And then, after the 
> data have been written, naturally the current index of the stream has 
> been increased, to point at the position after the written data. That is 
> the meaning of the "plus" phrase.
> 
> And Read analogously. The "plus" phrase explains what the value of the 
> current index is _after_ the Read or Write. But both the Read and the 
> Write _start_ reading/writing at the index given in the From/To parameters.
> 
> 
>> Does this mean one can't go back to beginning of file once data have 
>> been read ?
> 
> 
> No, Set_Index can do that, whether the last action was writing or 
> reading. And the Write/Read with an index parameter can also do that.
> 
> But if you have set the current index to the desired position with 
> Set_Index, you don't need to use the Read/Write that have a 
> Positive_Count (index) parameter.
> 
> This code:
> 
>     Set_Index (F, I);
>     Write (F, Item);
> 
> is equivalent to:
> 
>     Write (F, Item, I);
> 
> and ditto Read.

Ok, so Set_Index() works as expected. Nothing special.

Reading the LRM made me understand things incorrectly because of the way 
it is written.

It is written :
32 The Set_Index procedure sets the current index to the specified value.

Then, it is written :
32.1/1 ...
32.2/1 ...
...

Reading this, I thought 32.1/1, 32.2/1 etc lines apply to 32 
(Set_Index() function).
So, I was completely lost to understand the meaning of these lines.

^ permalink raw reply	[relevance 0%]

* Re: Usage of Stream Set_Index() function
  2022-01-14 18:30  1% Usage of Stream Set_Index() function DrPi
@ 2022-01-14 20:35  0% ` Niklas Holsti
  2022-01-15 10:36  0%   ` DrPi
  0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2022-01-14 20:35 UTC (permalink / raw)


On 2022-01-14 20:30, DrPi wrote:
> 
> Hi,
> 
> I'm writing an application where I read a file with a complex structure.
> For this, I use Ada.Streams.Stream_IO package.
> To read the file, I need to position the file pointer to the correct 
> location. I do this using Set_Index().
> 
> In ARM A.12.1, it is stated :
> For Read and Write with a Positive_Count parameter, the value of the 
> current index is set to the value of the Positive_Count parameter plus 
> the number of stream elements read or written.
> 
> I don't understand the "plus the number of stream elements read or 
> written".


For Write, the ARM also says: "The Write procedure with a Positive_Count 
parameter starts writing at the specified index". And then, after the 
data have been written, naturally the current index of the stream has 
been increased, to point at the position after the written data. That is 
the meaning of the "plus" phrase.

And Read analogously. The "plus" phrase explains what the value of the 
current index is _after_ the Read or Write. But both the Read and the 
Write _start_ reading/writing at the index given in the From/To parameters.


> Does this mean one can't go back to beginning of file once data have 
> been read ?


No, Set_Index can do that, whether the last action was writing or 
reading. And the Write/Read with an index parameter can also do that.

But if you have set the current index to the desired position with 
Set_Index, you don't need to use the Read/Write that have a 
Positive_Count (index) parameter.

This code:

    Set_Index (F, I);
    Write (F, Item);

is equivalent to:

    Write (F, Item, I);

and ditto Read.

^ permalink raw reply	[relevance 0%]

* Usage of Stream Set_Index() function
@ 2022-01-14 18:30  1% DrPi
  2022-01-14 20:35  0% ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: DrPi @ 2022-01-14 18:30 UTC (permalink / raw)



Hi,

I'm writing an application where I read a file with a complex structure.
For this, I use Ada.Streams.Stream_IO package.
To read the file, I need to position the file pointer to the correct 
location. I do this using Set_Index().

In ARM A.12.1, it is stated :
For Read and Write with a Positive_Count parameter, the value of the 
current index is set to the value of the Positive_Count parameter plus 
the number of stream elements read or written.

I don't understand the "plus the number of stream elements read or written".

Does this mean one can't go back to beginning of file once data have 
been read ?

Nicolas

^ permalink raw reply	[relevance 1%]

* Re: Hi! How I can make _indexed_ stream file Input/Output ? Thanks.
  2021-07-05  4:06  0%   ` zac brown
@ 2021-07-05  4:06  0%     ` zac brown
  0 siblings, 0 replies; 200+ results
From: zac brown @ 2021-07-05  4:06 UTC (permalink / raw)


On Monday, July 5, 2021 at 2:06:36 PM UTC+10, zac brown wrote:
> On Saturday, July 3, 2021 at 6:57:31 AM UTC+10, Shark8 wrote: 
> > On Sunday, June 27, 2021 at 1:33:28 PM UTC-6, daniel wrote: 
> > > How I can make _indexed_ stream file Input/Output ? 
> > > 
> > > For 'indexed' i mean manually setting file position: 
> > > => 'from' in $type'input() and 
> > > => 'to' in $type'output() 
> > > 
> > > Actually I use Ada.Streams.Stream_IO. 
> > > 
> > > My main need is examples. 
> > > 
> > > Thanks! 
> > > Best Whishes, 
> > > Dani. 
> > Streams are a bit different than files; you see, streams are an abstraction on input/output and therefore different than files. Consider, for example, an output stream that controls a radio transmitter. There's no possible way to "unsend" the data: it's a write-only device. 
> > 
> > If you're using Ada's standard library, with the XXX_IO packages, I believe what you want is Ada.Direct_IO.

^ permalink raw reply	[relevance 0%]

* Re: Hi! How I can make _indexed_ stream file Input/Output ? Thanks.
  2021-07-02 20:57  0% ` Shark8
@ 2021-07-05  4:06  0%   ` zac brown
  2021-07-05  4:06  0%     ` zac brown
  0 siblings, 1 reply; 200+ results
From: zac brown @ 2021-07-05  4:06 UTC (permalink / raw)


On Saturday, July 3, 2021 at 6:57:31 AM UTC+10, Shark8 wrote:
> On Sunday, June 27, 2021 at 1:33:28 PM UTC-6, daniel wrote: 
> > How I can make _indexed_ stream file Input/Output ? 
> > 
> > For 'indexed' i mean manually setting file position: 
> > => 'from' in $type'input() and 
> > => 'to' in $type'output() 
> > 
> > Actually I use Ada.Streams.Stream_IO. 
> > 
> > My main need is examples. 
> > 
> > Thanks! 
> > Best Whishes, 
> > Dani.
> Streams are a bit different than files; you see, streams are an abstraction on input/output and therefore different than files. Consider, for example, an output stream that controls a radio transmitter. There's no possible way to "unsend" the data: it's a write-only device. 
> 
> If you're using Ada's standard library, with the XXX_IO packages, I believe what you want is Ada.Direct_IO.

^ permalink raw reply	[relevance 0%]

* Re: Hi! How I can make _indexed_ stream file Input/Output ? Thanks.
  2021-06-27 19:33  1% Hi! How I can make _indexed_ stream file Input/Output ? Thanks Daniel Norte Moraes
  2021-06-28  1:36  0% ` Dennis Lee Bieber
@ 2021-07-02 20:57  0% ` Shark8
  2021-07-05  4:06  0%   ` zac brown
  1 sibling, 1 reply; 200+ results
From: Shark8 @ 2021-07-02 20:57 UTC (permalink / raw)


On Sunday, June 27, 2021 at 1:33:28 PM UTC-6, daniel wrote:
> How I can make _indexed_ stream file Input/Output ? 
> 
> For 'indexed' i mean manually setting file position: 
> => 'from' in $type'input() and 
> => 'to' in $type'output() 
> 
> Actually I use Ada.Streams.Stream_IO. 
> 
> My main need is examples. 
> 
> Thanks! 
> Best Whishes, 
> Dani.

Streams are a bit different than files; you see, streams are an abstraction on input/output and therefore different than files. Consider, for example, an output stream that controls a radio transmitter. There's no possible way to "unsend" the data: it's a write-only device.

If you're using Ada's standard library, with the XXX_IO packages, I believe what you want is Ada.Direct_IO.

^ permalink raw reply	[relevance 0%]

* Re: Hi! How I can make _indexed_ stream file  Input/Output ? Thanks.
  2021-06-27 19:33  1% Hi! How I can make _indexed_ stream file Input/Output ? Thanks Daniel Norte Moraes
@ 2021-06-28  1:36  0% ` Dennis Lee Bieber
  2021-07-02 20:57  0% ` Shark8
  1 sibling, 0 replies; 200+ results
From: Dennis Lee Bieber @ 2021-06-28  1:36 UTC (permalink / raw)


On Sun, 27 Jun 2021 12:33:27 -0700 (PDT), Daniel Norte Moraes
<danielcheagle@gmail.com> declaimed the following:

>How I can make _indexed_  stream file  Input/Output ?
>
>For 'indexed' i mean manually  setting file position:
> => 'from'  in $type'input() and
>=> 'to' in $type'output()
>
>Actually I use Ada.Streams.Stream_IO.
>
>My main need is examples.
>

	What part of
https://www.adaic.org/resources/add_content/standards/05aarm/html/AA-A-12-1.html
is lacking?

"""
21	    -- Operations on position within file
22	    procedure Set_Index(File : in File_Type; To : in Positive_Count);
23	    function Index(File : in File_Type) return Positive_Count;
	    function Size (File : in File_Type) return Count;
"""
"""
31/1	{8652/0055} {AI95-00026-01} The Index function returns the current
file index, as a count (in stream elements) from the beginning of the file.
The position of the first element in the file is 1. 
31.a/1	This paragraph was deleted.Ramification: The notion of Index for
Stream_IO is analogous to that of Index in Direct_IO, except that the
former is measured in Stream_Element units, whereas the latter is in terms
of Element_Type values. 
32		The Set_Index procedure sets the current index to the specified
value.
32.1/1	   {8652/0055} {AI95-00026-01} If positioning is supported for the
external file, the current index is maintained as follows:
32.2/1	   {8652/0055} {AI95-00026-01} For Open and Create, if the Mode
parameter is Append_File, the current index is set to the current size of
the file plus one; otherwise, the current index is set to one.
32.3/1	 {8652/0055} {AI95-00026-01} For Reset, if the Mode parameter is
Append_File, or no Mode parameter is given and the current mode is
Append_File, the current index is set to the current size of the file plus
one; otherwise, the current index is set to one.
"""
"""
33		If positioning is not supported for the given file, then a call of
Index or Set_Index propagates Use_Error. Similarly, a call of Read or Write
with a Positive_Count parameter propagates Use_Error.
33.a/2	Implementation Note: {AI95-00085-01} It is permissible for an
implementation to implement mode Append_File using the Unix append mode
(the O_APPEND bit). Such an implementation does not support positioning
when the mode is Append_File, and therefore the operations listed above
must raise Use_Error. This is acceptable as there is no requirement that
any particular file support positioning; therefore it is acceptable that a
file support positioning when opened with mode Out_File, and the same file
not support positioning when opened with mode Append_File. But it is not
acceptable for a file to support positioning (by allowing the above
operations), but to do something other than the defined semantics (that is,
always write at the end, even when explicitly commanded to write somewhere
else). 
"""


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/

^ permalink raw reply	[relevance 0%]

* Hi! How I can make _indexed_ stream file  Input/Output ? Thanks.
@ 2021-06-27 19:33  1% Daniel Norte Moraes
  2021-06-28  1:36  0% ` Dennis Lee Bieber
  2021-07-02 20:57  0% ` Shark8
  0 siblings, 2 replies; 200+ results
From: Daniel Norte Moraes @ 2021-06-27 19:33 UTC (permalink / raw)


How I can make _indexed_  stream file  Input/Output ?

For 'indexed' i mean manually  setting file position:
 => 'from'  in $type'input() and
=> 'to' in $type'output()

Actually I use Ada.Streams.Stream_IO.

My main need is examples.

Thanks!
Best Whishes,
Dani.

^ permalink raw reply	[relevance 1%]

* ANN: Ada Resource Embedder for C, Ada and Go
@ 2021-06-11 13:30  1% Stephane Carrez
  0 siblings, 0 replies; 200+ results
From: Stephane Carrez @ 2021-06-11 13:30 UTC (permalink / raw)


Hi all,

I created a new tool to allow embedding any file in an Ada, C or Go binary.
While embedding files, you can apply some transformations such as
running a Javascript minifier (closure), compressing the file, encrypting it, ...
The tool generates Ada, C or Go files that you compile with your program.
In its simplest form, you can access the embedded content as a:

type Content_Access is access constant Ada.Streams.Stream_Element_Array;

So the generated code only depends on Ada.Streams.

There are many modes that are explained in the documentation.
For an overview, have a look at:

https://blog.vacs.fr/vacs/blogs/post.html?post=2021/06/11/Advanced-Resource-Embedder

And don't hesitate to fork, hack, and submit pull requests to:

https://github.com/stcarrez/resource-embedder

Well, for me it was a fun project :-)

Stephane

Ps: Go has a `go:embed` but It was fun to write the Go generator :-)

^ permalink raw reply	[relevance 1%]

* Re: Is it possible to redirect text output to a String or Unbounded_String?
  @ 2021-06-10 21:12  1% ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2021-06-10 21:12 UTC (permalink / raw)


On Wednesday, June 9, 2021 at 8:17:20 PM UTC-6, Jerry wrote:
> Is it possible to redirect text output to a String or Unbounded_String rather than to a file? 
> 
> I know there are versions of Put that take a string as a first argument but I don't want to have to write a special-purpose version of a stretch of code just for this purpose, since I want to keep the ability to also output text to a terminal. 
> 
> I suppose I could redirect text to a file and then somehow read it back in as one string but that seems like a kludge. 
> 
> Jerry
Well...
------------------------------------
    Generic
        Type FILE_TYPE(<>) is limited private;
        Type FILE_MODE     is (<>);
        Type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
        with Procedure Indirect_Put_Line(Item : String);
        -- put all the subprograms you need here; prefix with Indirect_
        Object : in out FILE_TYPE;
        Stream : in Stream_Access;
    Package Duplicating_IO is
        -- Declare all the subprograms used above w/o Indirect_
        Procedure Put_Line(Item : String);
    End Duplicating_IO;
------------------------------------
    Package Body Duplicating_IO is
        -- Implementations; if there's a lot consider generics+renames.
        Procedure Put_Line(Item : String) is
        Begin
            String'Output( Stream, Item );
            Indirect_Put_Line( Item );
        End Put_Line;
    End Duplicating_IO;
------------------------------------    
    OBJ : Ada.Text_IO.File_Type:= Ada.Text_IO.Standard_Output;
    STR : Ada.Text_IO.Text_Streams.Stream_Access renames
      Ada.Text_IO.Text_Streams.Stream( OBJ );
------------------------------------
    Package Split_IO is new Duplicating_IO
      (
       File_Type         => File_Type,
       File_Mode         => File_Mode,
       Stream_Access     => Ada.Text_IO.Text_Streams.Stream_Access,
       Indirect_Put_Line => Put_Line,
        Object           => OBJ,
        Stream           => STR
      );

^ permalink raw reply	[relevance 1%]

* Re: Better way to fill Storage_IO?
  2021-05-19  7:17  0%       ` J-P. Rosen
  2021-05-19  8:26  0%         ` Björn Lundin
@ 2021-05-19 15:39  0%         ` Simon Wright
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2021-05-19 15:39 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> writes:

> Le 18/05/2021 à 22:39, Simon Wright a écrit :
>> so as well as the current ARM 13.13.2(4), for subtype S of type T
>>     procedure S'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>>        Item : in T)
>> one could have for an object O
>>     procedure O'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class)
>> but we don't, not even in Ada 202x.
> For what benefit? Saving a few keystrokes?

I was going to remark on the unlikelihood of ARG's accepting this
keystroke-saving change unless there was evidence of massive demand. In
the case of 'Image, there was the popularity of AdaCore's 'Img
extension.

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-19  7:17  0%       ` J-P. Rosen
@ 2021-05-19  8:26  0%         ` Björn Lundin
  2021-05-19 15:39  0%         ` Simon Wright
  1 sibling, 0 replies; 200+ results
From: Björn Lundin @ 2021-05-19  8:26 UTC (permalink / raw)


Den 2021-05-19 kl. 09:17, skrev J-P. Rosen:
> Le 18/05/2021 à 22:39, Simon Wright a écrit :
>> so as well as the current ARM 13.13.2(4), for subtype S of type T
>>
>>     procedure S'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>>        Item : in T)
>>
>> one could have for an object O
>>
>>     procedure O'Write(
>>        Stream : not null access Ada.Streams.Root_Stream_Type'Class)
>>
>> but we don't, not even in Ada 202x.
> For what benefit? Saving a few keystrokes?
> 

The Integer'Image(An_Integer) changed to An_Integer'Image

the Verb(Object, Parameter) changed to Object.Verb(Parameter)


It does not have to save keystrokes, but it has to be more readable.
More readable is of course in the eye of the beholder.


package Coded_Values is

type WCS_Next_Location_Type_Type is (
   Reject_Position,
   Selection_Point,
   Transfer_Unit);

end Coded_Values;



with Coded_Values;
with Text_Io;

package Test is

   Next_Location : Coded_Values.WCS_Next_Location_Type_Type := 
Coded_Values.Selection_Point;


Given the above I do prefer


Text_IO.Put_Line ("Next is " & Next_Location'Image);

over

Text_IO.Put_Line ("Next is " & 
Coded_Values.WCS_Next_Location_Type_Type'Image(Next_Location));


or when a use clause is in effect
Text_IO.Put_Line ("Next is " & 
WCS_Next_Location_Type_Type'Image(Next_Location));


even with a use clause I prefer the 'image on the variable.
In my eyes

Text_IO.Put_Line ("Next is " & Next_Location'Image);

Is the better and more readable choice.


That is likely the case of the analog stream discussion above.


Syntax matter. If Ada is to grow it has to have a pleasant syntax,
that is not perceived as clumsy or overly wordy.


-- 
Björn

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-18 20:39  2%     ` Simon Wright
@ 2021-05-19  7:17  0%       ` J-P. Rosen
  2021-05-19  8:26  0%         ` Björn Lundin
  2021-05-19 15:39  0%         ` Simon Wright
  0 siblings, 2 replies; 200+ results
From: J-P. Rosen @ 2021-05-19  7:17 UTC (permalink / raw)


Le 18/05/2021 à 22:39, Simon Wright a écrit :
> so as well as the current ARM 13.13.2(4), for subtype S of type T
> 
>     procedure S'Write(
>        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>        Item : in T)
> 
> one could have for an object O
> 
>     procedure O'Write(
>        Stream : not null access Ada.Streams.Root_Stream_Type'Class)
> 
> but we don't, not even in Ada 202x.
For what benefit? Saving a few keystrokes?

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-17 19:23  0%   ` Michael Hardeman
@ 2021-05-18 20:39  2%     ` Simon Wright
  2021-05-19  7:17  0%       ` J-P. Rosen
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2021-05-18 20:39 UTC (permalink / raw)


Michael Hardeman <mhardeman25@gmail.com> writes:

> I was kind of hoping there would be an interface like
> Ada.Text_IO.Text_Streams, where you could just directly stream from
> the variable's address or access without having to write the variable
> into the stream first. I'm not sure, but the writing part seems a bit
> like an extra step.
[...]
> I was kind of trying to show you could move through the stream like a
> parser instead of just consuming the whole thing. i.e. like if you
> wanted to parse the hex into an array of Unsigned_32 or Unsigned_64
> for some algorithm.

I don't understand the scenario.

  Source   >>   Stream   >>   Destination

If Source and Destination are in the same process, there's no need to
involve streams at all.

If Source and Destination are separated - different processes on the
same computer, different computers (possibly with different endianness),
different times - we have to agree on a protocol as to what's sent over
the stream. For a String Z, perhaps the first 4 bytes are the
little-endian Z'First, the next are Z'Last, then the actual bytes of Z.

That's what streams are for (and that's what String'Output does).

Once you have the stream, you can go through it in any way you need to;
you must know what to expect so as to make sense of it. In your example,
you have to know that the bytes in the stream are hex characters.

==========

As to creating the stream: I suppose there could be something like
'Image, where the attribute could originally only be applied to a type:
you used to have to say

   Integer'Image (An_Integer)

whereas now you can say just

   An_Integer'Image

so as well as the current ARM 13.13.2(4), for subtype S of type T

   procedure S'Write(
      Stream : not null access Ada.Streams.Root_Stream_Type'Class;
      Item : in T)

one could have for an object O

   procedure O'Write(
      Stream : not null access Ada.Streams.Root_Stream_Type'Class)

but we don't, not even in Ada 202x.

^ permalink raw reply	[relevance 2%]

* Re: Better way to fill Storage_IO?
  2021-05-17 20:48  0%     ` Michael Hardeman
@ 2021-05-18 14:00  0%       ` Per Sandberg
  0 siblings, 0 replies; 200+ results
From: Per Sandberg @ 2021-05-18 14:00 UTC (permalink / raw)


To emulate a stream on "any" locatoion
https://github.com/persan/a-stream-tools
/P


On 17/05/2021 22:48, Michael Hardeman wrote:
> On Monday, May 17, 2021 at 4:20:14 PM UTC-4, Dmitry A. Kazakov wrote:
>> On 2021-05-17 21:14, Simon Wright wrote:
>>> Michael Hardeman <mhard...@gmail.com> writes:
>>>
>>>> So I've been messing around with the new Ada 2020 package
>>>> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
>>>> correctly it allows you to treat your program's memory like a stream
>>>> without having to open file descriptors (which should make it
>>>> faster?). That seems like a powerful abstraction to me and a great
>>>> addition to the language.
>> 1. It was always possible, since Ada 95, actually. So it is not that
>> great addition.
>>
>> 2. The package as described is not a replacement for I/O, because it
>> lacks blocking/synchronization and because it does not work between
>> processes. E.g. at the end of the stream Read must rather block for an
>> incoming Write. Both are quite possible to implement though.
>>
>> A great addition would be properly tagged protected objects and tasks. A
>> blocking stream cannot support timed entry call syntax like this:
>>
>> select
>> S := String'Input (Pipe'Access); -- This is not Ada!
>> or delay 1.0;
>> raise Timed_Out;
>> end select;
>>
>> And note another problem. Entries do not work with indefinite objects.
>> You cannot return String from an entry call.
>>
>> And yet another problem, you cannot use returned objects in many places,
>> like in an entry call above.
>>>> I was wondering if we could find a better way to fill the stream other
>>>> than writing the variables into it? Can anyone figure out a good way
>>>> to just stream a variable's bytes directly?
>> Allocators, of course. I am using both allocators and memory-mapped
>> streams (though of a greater variety, e.g. for blocked exchange,
>> encryption, interporcess communication).
>>> This *is* the way to just stream the variable's bytes directly. What
>>> sort of syntax were you hoping for?
>> Both allocators and streams require explicit specification of the type.
>> Clearly, that is a way around multiple dispatch, but it is way too
>> heavy. Access to stream is no more necessary in 'Input. It was not
>> necessary when it was introduced in Ada 95. The Rosen's trick allows
>> circumvent in- parameter modes, when necessary.
>>
>> -- 
>> Regards,
>> Dmitry A. Kazakov
>> http://www.dmitry-kazakov.de
> 
> Hey Dmitry,
> 
>> Allocators, of course. I am using both allocators and memory-mapped
>> streams (though of a greater variety, e.g. for blocked exchange,
>> encryption, interporcess communication).
> 
> Could you show me an example of how I could do this with allocators?
> 

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-17 20:20  0%   ` Dmitry A. Kazakov
  2021-05-17 20:48  0%     ` Michael Hardeman
@ 2021-05-18  9:08  0%     ` J-P. Rosen
  1 sibling, 0 replies; 200+ results
From: J-P. Rosen @ 2021-05-18  9:08 UTC (permalink / raw)


Le 17/05/2021 à 22:20, Dmitry A. Kazakov a écrit :
> On 2021-05-17 21:14, Simon Wright wrote:
>> Michael Hardeman <mhardeman25@gmail.com> writes:
>>
>>> So I've been messing around with the new Ada 2020 package
>>> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
>>> correctly it allows you to treat your program's memory like a stream
>>> without having to open file descriptors (which should make it
>>> faster?). That seems like a powerful abstraction to me and a great
>>> addition to the language.
> 
> 1. It was always possible, since Ada 95, actually. So it is not that 
> great addition.
For example, you can get Storage_Stream from Adalog's components page:
https://www.adalog.fr/en/components.html#Storage_Stream

[...]
> And note another problem. Entries do not work with indefinite objects. 
> You cannot return String from an entry call.
True, but you can return an indefinite holder containing the string.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-17 20:20  0%   ` Dmitry A. Kazakov
@ 2021-05-17 20:48  0%     ` Michael Hardeman
  2021-05-18 14:00  0%       ` Per Sandberg
  2021-05-18  9:08  0%     ` J-P. Rosen
  1 sibling, 1 reply; 200+ results
From: Michael Hardeman @ 2021-05-17 20:48 UTC (permalink / raw)


On Monday, May 17, 2021 at 4:20:14 PM UTC-4, Dmitry A. Kazakov wrote:
> On 2021-05-17 21:14, Simon Wright wrote: 
> > Michael Hardeman <mhard...@gmail.com> writes: 
> > 
> >> So I've been messing around with the new Ada 2020 package 
> >> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it 
> >> correctly it allows you to treat your program's memory like a stream 
> >> without having to open file descriptors (which should make it 
> >> faster?). That seems like a powerful abstraction to me and a great 
> >> addition to the language.
> 1. It was always possible, since Ada 95, actually. So it is not that 
> great addition. 
> 
> 2. The package as described is not a replacement for I/O, because it 
> lacks blocking/synchronization and because it does not work between 
> processes. E.g. at the end of the stream Read must rather block for an 
> incoming Write. Both are quite possible to implement though. 
> 
> A great addition would be properly tagged protected objects and tasks. A 
> blocking stream cannot support timed entry call syntax like this: 
> 
> select 
> S := String'Input (Pipe'Access); -- This is not Ada! 
> or delay 1.0; 
> raise Timed_Out; 
> end select; 
> 
> And note another problem. Entries do not work with indefinite objects. 
> You cannot return String from an entry call. 
> 
> And yet another problem, you cannot use returned objects in many places, 
> like in an entry call above.
> >> I was wondering if we could find a better way to fill the stream other 
> >> than writing the variables into it? Can anyone figure out a good way 
> >> to just stream a variable's bytes directly?
> Allocators, of course. I am using both allocators and memory-mapped 
> streams (though of a greater variety, e.g. for blocked exchange, 
> encryption, interporcess communication).
> > This *is* the way to just stream the variable's bytes directly. What 
> > sort of syntax were you hoping for?
> Both allocators and streams require explicit specification of the type. 
> Clearly, that is a way around multiple dispatch, but it is way too 
> heavy. Access to stream is no more necessary in 'Input. It was not 
> necessary when it was introduced in Ada 95. The Rosen's trick allows 
> circumvent in- parameter modes, when necessary. 
> 
> -- 
> Regards, 
> Dmitry A. Kazakov 
> http://www.dmitry-kazakov.de

Hey Dmitry,

> Allocators, of course. I am using both allocators and memory-mapped 
> streams (though of a greater variety, e.g. for blocked exchange, 
> encryption, interporcess communication).

Could you show me an example of how I could do this with allocators?

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-17 19:14  1% ` Simon Wright
  2021-05-17 19:23  0%   ` Michael Hardeman
@ 2021-05-17 20:20  0%   ` Dmitry A. Kazakov
  2021-05-17 20:48  0%     ` Michael Hardeman
  2021-05-18  9:08  0%     ` J-P. Rosen
  1 sibling, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2021-05-17 20:20 UTC (permalink / raw)


On 2021-05-17 21:14, Simon Wright wrote:
> Michael Hardeman <mhardeman25@gmail.com> writes:
> 
>> So I've been messing around with the new Ada 2020 package
>> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
>> correctly it allows you to treat your program's memory like a stream
>> without having to open file descriptors (which should make it
>> faster?). That seems like a powerful abstraction to me and a great
>> addition to the language.

1. It was always possible, since Ada 95, actually. So it is not that 
great addition.

2. The package as described is not a replacement for I/O, because it 
lacks blocking/synchronization and because it does not work between 
processes. E.g. at the end of the stream Read must rather block for an 
incoming Write. Both are quite possible to implement though.

A great addition would be properly tagged protected objects and tasks. A 
blocking stream cannot support timed entry call syntax like this:

    select
       S := String'Input (Pipe'Access); -- This is not Ada!
    or delay 1.0;
       raise Timed_Out;
    end select;

And note another problem. Entries do not work with indefinite objects. 
You cannot return String from an entry call.

And yet another problem, you cannot use returned objects in many places, 
like in an entry call above.

>> I was wondering if we could find a better way to fill the stream other
>> than writing the variables into it? Can anyone figure out a good way
>> to just stream a variable's bytes directly?

Allocators, of course. I am using both allocators and memory-mapped 
streams (though of a greater variety, e.g. for blocked exchange, 
encryption, interporcess communication).

> This *is* the way to just stream the variable's bytes directly. What
> sort of syntax were you hoping for?

Both allocators and streams require explicit specification of the type. 
Clearly, that is a way around multiple dispatch, but it is way too 
heavy. Access to stream is no more necessary in 'Input. It was not 
necessary when it was introduced in Ada 95. The Rosen's trick allows 
circumvent in- parameter modes, when necessary.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-17 19:14  1% ` Simon Wright
@ 2021-05-17 19:23  0%   ` Michael Hardeman
  2021-05-18 20:39  2%     ` Simon Wright
  2021-05-17 20:20  0%   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 200+ results
From: Michael Hardeman @ 2021-05-17 19:23 UTC (permalink / raw)


On Monday, May 17, 2021 at 3:14:43 PM UTC-4, Simon Wright wrote:
> 
> 'Output writes the discriminants of the object, if any, then the object; 
> 'Input uses them to reconstruct the object, so in this case that means 
> the bounds, and hence the length.
> > I was wondering if we could find a better way to fill the stream other 
> > than writing the variables into it? Can anyone figure out a good way 
> > to just stream a variable's bytes directly?
> This *is* the way to just stream the variable's bytes directly. What 
> sort of syntax were you hoping for?

I was kind of hoping there would be an interface like Ada.Text_IO.Text_Streams, where you could just directly stream from the variable's address or access without having to write the variable into the stream first. I'm not sure, but the writing part seems a bit like an extra step.

This would be my version: 
> 
> with Ada.Text_IO; use Ada.Text_IO; 
> with Ada.Streams.Storage.Unbounded; 
> 
> procedure Test is 
> Test : constant String := "040b2cec765b4bbbdb29d83b6dcaf776"; 
> Test_Stream : aliased Ada.Streams.Storage.Unbounded.Stream_Type; 
> begin 
> String'Output (Test_Stream'Access, Test); 
> declare 
> S : constant String := String'Input (Test_Stream'Access); 
> begin 
> Put_Line (S); 
> end; 
> end Test; 

I was kind of trying to show you could move through the stream like a parser instead of just consuming the whole thing. i.e. like if you wanted to parse the hex into an array of Unsigned_32 or Unsigned_64 for some algorithm.

^ permalink raw reply	[relevance 0%]

* Re: Better way to fill Storage_IO?
  2021-05-17 18:44  2% Better way to fill Storage_IO? Michael Hardeman
@ 2021-05-17 19:14  1% ` Simon Wright
  2021-05-17 19:23  0%   ` Michael Hardeman
  2021-05-17 20:20  0%   ` Dmitry A. Kazakov
  0 siblings, 2 replies; 200+ results
From: Simon Wright @ 2021-05-17 19:14 UTC (permalink / raw)


Michael Hardeman <mhardeman25@gmail.com> writes:

> So I've been messing around with the new Ada 2020 package
> Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it
> correctly it allows you to treat your program's memory like a stream
> without having to open file descriptors (which should make it
> faster?). That seems like a powerful abstraction to me and a great
> addition to the language.

This would be my version:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams.Storage.Unbounded;

procedure Test is
  Test : constant String := "040b2cec765b4bbbdb29d83b6dcaf776";
  Test_Stream : aliased Ada.Streams.Storage.Unbounded.Stream_Type;
begin
   String'Output (Test_Stream'Access, Test);
   declare
      S : constant String := String'Input (Test_Stream'Access);
   begin
      Put_Line (S);
   end;
end Test;

'Output writes the discriminants of the object, if any, then the object;
'Input uses them to reconstruct the object, so in this case that means
the bounds, and hence the length.

> I was wondering if we could find a better way to fill the stream other
> than writing the variables into it? Can anyone figure out a good way
> to just stream a variable's bytes directly?

This *is* the way to just stream the variable's bytes directly. What
sort of syntax were you hoping for?

^ permalink raw reply	[relevance 1%]

* Better way to fill Storage_IO?
@ 2021-05-17 18:44  2% Michael Hardeman
  2021-05-17 19:14  1% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Michael Hardeman @ 2021-05-17 18:44 UTC (permalink / raw)


So I've been messing around with the new Ada 2020 package Ada.Streams.Storage.Bounded/Unbounded; and if I'm understand it correctly it allows you to treat your program's memory like a stream without having to open file descriptors (which should make it faster?). That seems like a powerful abstraction to me and a great addition to the language.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams; use Ada.Streams;
with Ada.Streams.Storage.Unbounded; use Ada.Streams.Storage.Unbounded;

procedure Test is
  Test : String := "040b2cec765b4bbbdb29d83b6dcaf776";
  Test_Stream : aliased Stream_Type;
begin
  String'Write(Test_Stream'Access, Test);
  for I in 1 .. Element_Count (Test_Stream) loop
    declare
      C : Character;
    begin
      Character'Read (Test_Stream'Access, C);
      Put (C);
    end;
  end loop;
end Test;

I was wondering if we could find a better way to fill the stream other than writing the variables into it? Can anyone figure out a good way to just stream a variable's bytes directly?

^ permalink raw reply	[relevance 2%]

* Re: surprise data from Ada.Sequential_IO
  @ 2021-03-22 17:48  1% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2021-03-22 17:48 UTC (permalink / raw)


On 2021-03-22 18:13, John Perry wrote:

> I was using gnat 2020 CE on a Linux machine the other day, and wanted to write out data for three different types T1, T2, T3 to a file. I instantiated a Sequential_IO package for each; call them P1, P2, P3.
> 
> The following worked as expected (sorry for the abbreviations but I think it will be clear):
> 
>>> P1.Create; P1.Write; P1.Close; P2.Open(Append_File); P2.Write; P2.Close;
> 
> However, this:
> 
>>> P3.Open(Append_File); P3.Write; P3.Close;
> 
> ...wrote a few bytes of junk between T2's data and T3's data.
> 
> I used a hex editor to check the output file between writes, and there was no junk after P2.Close nor after P3.Open; it always came at the beginning of P3.Write.
> 
> I reworked the type definitions so that T3's data was included at the end of T2, and in this case P2.Write wrote the data properly, as desired. However, this is not the sort of permanent solution I'd want.
> 
> Has anyone else encountered this? Could this be due to alignment issues? Is there some way to avoid this without putting the data there?

I did not use Sequential_IO for decades. I doubt it was ever intended 
for the misuse you invented.

For practical point of view, I would consider this package obsolete, 
superseded by Ada.Streams.Stream_IO. It is exactly meant for your case, 
especially if you override the attributes of T1, T2, T3 (to make it 
portable).

And you are in full control of what is going on, e.g. no stuff like 
vertical formats and stupid EOF sequences.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* Re: set_index and and end_of_file with just a stream reference
  @ 2021-02-23 17:21  1%           ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2021-02-23 17:21 UTC (permalink / raw)


On Saturday, February 20, 2021 at 12:08:16 PM UTC-7, 0012com wrote:
> Okay :-) 
> what I wanted is: 
> I read an acronyme in the stream file, if good I input the adjacent record type, otherwise I would advance on the stream until the next acronyme with set_index(stream_access, index(stream_access) + composite_type_stream_size) and read the next acronyme (unbounded_string). 
> Now I just input both objects and verify the acronyme. 
> But I don't like writing an object that maybe won't be used.
Hm, what are your datatypes? Is this ONLY text, or are you able to impose your own structure?
You could have something like this:

-- Instantiated Container Packages.
Package String_Holder is new Ada.Containers.Indefinite_Holders(
       Element_Type => String,
       "="          => Ada.Strings.Equal_Case_Insensitive
      );
Package String_Map is new Ada.Containers.Indefinite_Ordered_Maps(
       "<"          => Ada.Strings.Less_Case_Insensitive,
       "="          => Ada.Strings.Equal_Case_Insensitive,
       Key_Type     => String,
       Element_Type => String
      );

-- The heart of the operating program.
With String_Holder, String_Map;
Package Acronyms is
  -- Because this is it's own type, you can put other things in the record, like a link to the place that it's defined, if needed.
  Type Initialism is new String_Holder.Holder with null record;

  Function Expand( Acronym : Initialism ) return String;
  Procedure Register( Acronym, Expansion : String );
--...
End Acronyms;

Package Body Acronyms is
    Acronym_Map : String_Map.Map;
  Procedure Register( Acronym, Expansion : String ) is
  Begin
    Acronym_Map.Insert( New_Item => Expansion, Key => Acronym );
  End Register;  

  Function Expand( Acronym : Initialism ) return String is
  Begin
    Return Acronym_Map( Acronym );
  Exception
    when others => Return Acronym; -- I forget if it's CONSTRAINT_ERROR or ASSERT_ERROR when the element is not present.
  End Expand;
End Acronyms;

-- in your main Acronym-Stream package...
-- Text_Soup is a variant record for handling portions of an acronym-expanding string; your main data-structure would probably be an Indefinite_Vector of Text_Soup'Class,
-- you might not need Input or output, depending on your usage, but for automatically expanding the initialism you'd need to use Acronyms.Expand.

    Type Text_Soup(<>) is tagged private;
    procedure Output(
       Stream : not null access Ada.Streams.Root_Stream_Type'Class;
       Item   : in Text_Soup'Class);
    function Input(
       Stream : not null access Ada.Streams.Root_Stream_Type'Class)
       return Text_Soup'Class;

   -- Other public operations.
PRIVATE
    For Text_Soup'Class'Input  use Input;
    For Text_Soup'Class'Output use Output;

Type Text_Soup(Length : Natural) is record
  case Length is
    when 0 => Acronym : Initialism;
    when others => Text : String(1..Length);
  end case;
end record;
--...


^ permalink raw reply	[relevance 1%]

* Re: General circular buffer example not tied to any specific type
  @ 2020-09-24  4:39  1%   ` J-P. Rosen
  0 siblings, 0 replies; 200+ results
From: J-P. Rosen @ 2020-09-24  4:39 UTC (permalink / raw)


Le 24/09/2020 à 06:10, nimaopatel121@gmail.com a écrit :
> On Saturday, 4 July 2020 22:30:28 UTC+5:30, Daniel  wrote:
>> Hello, any theoric 
>>  example of buffer i can find is always tied to an specific type.
>>
>> I'm looking for any example of ravenscar buffer able for using any type of data at the same time.
>>
>> I suppose it will need to serialize all  data and manipulate it as a group of bytes.
>>
>> Does any body knows any example of this written in Ada?
> 
Hmmm, you know, Ada is a strongly typed language, therefore what you put
in a buffer must have a well defined type.

There are two possibilities:
1) If you can accept several buffers, one for each type, make it generic
and instantiate it as many times as you need

2) Make a buffer of Stream_Elements, and use the streaming attributes
('Read, 'Write) to turn any type into stream elements.

Ada.Streams.Stream_IO can also be handy in some cases.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[relevance 1%]

* Re: Simple parse from https website
  2020-04-02 17:16  1%     ` Dmitry A. Kazakov
@ 2020-04-02 18:27  0%       ` Rego, P.
  0 siblings, 0 replies; 200+ results
From: Rego, P. @ 2020-04-02 18:27 UTC (permalink / raw)


> No, that site looks OK. I modified my OpenSSL HTTP client. I just added 
> JSON parser and procedure Dump to print the JSON object:
> 
> ----------------------------- test_https_openssl_json_client.adb -----
> with Ada.Exceptions;               use Ada.Exceptions;
> with Ada.Text_IO;                  use Ada.Text_IO;
> with Ada.Streams;                  use Ada.Streams;
> --with GNAT.Exception_Traces;      use GNAT.Exception_Traces;
> with GNAT.Sockets.Server.Handles;  use GNAT.Sockets.Server.Handles;
> with GNAT.Sockets.Server.OpenSSL;  use GNAT.Sockets.Server.OpenSSL;
> with OpenSSL;                      use OpenSSL;
> with Parsers.JSON;                 use Parsers.JSON;
> with Parsers.JSON.String_Source;   use Parsers.JSON.String_Source;
> with Strings_Edit.Integers;        use Strings_Edit.Integers;
> with Strings_Edit.Quoted;          use Strings_Edit.Quoted;
> with Strings_Edit.Streams;         use Strings_Edit.Streams;
> with Strings_Edit.Long_Floats;     use Strings_Edit.Long_Floats;
> with Test_HTTP_Servers.OpenSSL;    use Test_HTTP_Servers.OpenSSL;
> 
> with GNAT.Sockets.Connection_State_Machine.HTTP_Client.Signaled;
> with GNAT.Sockets.Server.Pooled;
> with Parsers.String_Source;
> with Stack_Storage;
> 
> procedure Test_HTTPS_OpenSSL_JSON_Client is
>     use GNAT.Sockets.Connection_State_Machine.HTTP_Client.Signaled;
> 
>     Address : constant String := "poloniex.com";
>     Path    : constant String := "public?command=returnTicker";
>     Port    : constant := 443;
> 
>     procedure Dump (Prefix : String; Value : JSON_Value) is
>     begin
>        case Value.JSON_Type is
>           when JSON_Boolean =>
>              Put_Line (Prefix & Boolean'Image (Value.Condition));
>           when JSON_Null =>
>              Put_Line (Prefix & "null");
>           when JSON_Number =>
>              Put_Line (Prefix & Image (Value.Value));
>           when JSON_String =>
>              Put_Line (Prefix & Quote (Value.Text.all));
>           when JSON_Array =>
>              Put_Line (Prefix & "(");
>              for Index in Value.Sequence'Range loop
>                 Dump (Prefix & "   ", Value.Sequence (Index));
>              end loop;
>              Put_Line (Prefix & ")");
>           when JSON_Object =>
>              Put_Line (Prefix & "{");
>              for Index in Value.Map'Range loop
>                 Put_Line (Prefix & "   " & Value.Map (Index).Name.all & 
> "=");
>                 Dump (Prefix & "      ", Value.Map (Index).Value);
>              end loop;
>              Put_Line (Prefix & "}");
>        end case;
>     end Dump;
> begin
>     declare
>        Factory : aliased HTTPS_OpenSSL_Factory
>                          (  Request_Length  => 200,
>                             Input_Size      => 40,
>                             Output_Size     => 1024,
>                             Decoded_Size    => 40,
>                             Max_Connections => 100
>                          );
>     begin
>        Set_Default_Verify_Paths (Factory, Client_Context);
>        declare
>           Message   : aliased String_Stream (1024 * 100);
>           Server    : aliased GNAT.Sockets.Server.
>                               Connections_Server (Factory'Access, 0);
>           Reference : GNAT.Sockets.Server.Handles.Handle;
>        begin
>           Put_Line ("HTTP client started");
>           Set
>           (  Reference,
>              new HTTP_Session_Signaled
>                  (  Server'Unchecked_Access,
>                     200,
>                     512,
>                     1024
>           )      );
>           declare
>              Client : HTTP_Session_Signaled renames
>                       HTTP_Session_Signaled (Ptr (Reference).all);
>           begin
>              Connect (Client, Address, Port);
>              Get
>              (  Client,
>                 "https://" & Address & "/" & Path,
>                 Message'Unchecked_Access
>              );
>              Wait (Client, False);
>              Put_Line
>              (  Image (Get_Response_Code (Client))
>              &  " "
>              &  Get_Response_Reason (Client)
>              &  " Message >>>>>>>>>>>>>>>>>>>>"
>              );
>              declare
>                 Content : aliased String := Get (Message);
>                 Source  : aliased Parsers.String_Source.
>                                   Source (Content'Access);
>                 Arena   : aliased Stack_Storage.Pool (1024, 10);
>                 Data    : constant JSON_Value :=
>                                    Parse (Source'Access, Arena'Access);
>              begin
>                 Dump ("", Data);
>              end;
>              Put_Line ("<<<<<<<<<<<<<<<<<<<< Message");
>           end;
>           Put_Line ("HTTP client stopping");
>        end;
>     end;
> exception
>     when Error : others =>
>        Put_Line ("Error: " & Exception_Information (Error));
> end Test_HTTPS_OpenSSL_JSON_Client;
> ----------------------------- test_https_openssl_json_client.adb -----
> 
> It connects fine and spills lots of garbage like:
> 
>    ...
>     USDT_SNX=
>        {
>           id=
>              290.9999999999999
>           last=
>              "0.00000000"
>           lowestAsk=
>              "0.00000000"
>           highestBid=
>              "0.00000000"
>           percentChange=
>              "0.00000000"
>           baseVolume=
>              "0.00000000"
>           quoteVolume=
>              "0.00000000"
>           isFrozen=
>              "0"
>           high24hr=
>              "0.00000000"
>           low24hr=
>              "0.00000000"
>        }
>     TRX_SNX=
>        {
>           id=
>              292.0000000000000
>           last=
>              "0.00000000"
>           lowestAsk=
>              "0.00000000"
>           highestBid=
>              "0.00000000"
>           percentChange=
>              "0.00000000"
>      ...
> 
> and so on. Funny enough, they put numbers as strings, so it seems.
> 
> It is not very efficient as written. You see, the code it accumulates 
> all response in a string stream buffer. Then takes a string from that. 
> Then it parses the obtained string into a JSON object. So it is two 
> copies too many. One could parse the response on the fly without 
> accumulating it whole in the memory. But it would mean more efforts.

Omg... (almost) Perfect(!lol)...just discovered that GNAT.Sockets has a signature change, some subpackages are no more exposed (like GNAT.SOCKETS.Server). I am using GNAT Community 2019.

Builder results
        17:6 file "g-scstma.ads" not found
        6:6 file "g-socser.ads" not found
        7:6 file "g-socser.ads" not found
        18:6 file "g-socser.ads" not found
        8:6 file "openssl.ads" not found
        9:6 file "parsers.ads" not found
        10:6 file "parsers.ads" not found
        19:6 file "parsers.ads" not found
        20:6 file "stack_storage.ads" not found
        11:6 file "strings_edit.ads" not found
        12:6 file "strings_edit.ads" not found
        13:6 file "strings_edit.ads" not found
        14:6 file "strings_edit.ads" not found
        15:6 file "test_http_servers.ads" not found


^ permalink raw reply	[relevance 0%]

* Re: Simple parse from https website
  @ 2020-04-02 17:16  1%     ` Dmitry A. Kazakov
  2020-04-02 18:27  0%       ` Rego, P.
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2020-04-02 17:16 UTC (permalink / raw)


On 2020-04-02 16:48, Rego, P. wrote:

> Ops...not, just testing more simpler cases. I am trying to get the data from
> https://poloniex.com/public?command=returnTicker
> 
> Just tried with google to check if it's problem from polo ticker. But the exception was the same.

No, that site looks OK. I modified my OpenSSL HTTP client. I just added 
JSON parser and procedure Dump to print the JSON object:

----------------------------- test_https_openssl_json_client.adb -----
with Ada.Exceptions;               use Ada.Exceptions;
with Ada.Text_IO;                  use Ada.Text_IO;
with Ada.Streams;                  use Ada.Streams;
--with GNAT.Exception_Traces;      use GNAT.Exception_Traces;
with GNAT.Sockets.Server.Handles;  use GNAT.Sockets.Server.Handles;
with GNAT.Sockets.Server.OpenSSL;  use GNAT.Sockets.Server.OpenSSL;
with OpenSSL;                      use OpenSSL;
with Parsers.JSON;                 use Parsers.JSON;
with Parsers.JSON.String_Source;   use Parsers.JSON.String_Source;
with Strings_Edit.Integers;        use Strings_Edit.Integers;
with Strings_Edit.Quoted;          use Strings_Edit.Quoted;
with Strings_Edit.Streams;         use Strings_Edit.Streams;
with Strings_Edit.Long_Floats;     use Strings_Edit.Long_Floats;
with Test_HTTP_Servers.OpenSSL;    use Test_HTTP_Servers.OpenSSL;

with GNAT.Sockets.Connection_State_Machine.HTTP_Client.Signaled;
with GNAT.Sockets.Server.Pooled;
with Parsers.String_Source;
with Stack_Storage;

procedure Test_HTTPS_OpenSSL_JSON_Client is
    use GNAT.Sockets.Connection_State_Machine.HTTP_Client.Signaled;

    Address : constant String := "poloniex.com";
    Path    : constant String := "public?command=returnTicker";
    Port    : constant := 443;

    procedure Dump (Prefix : String; Value : JSON_Value) is
    begin
       case Value.JSON_Type is
          when JSON_Boolean =>
             Put_Line (Prefix & Boolean'Image (Value.Condition));
          when JSON_Null =>
             Put_Line (Prefix & "null");
          when JSON_Number =>
             Put_Line (Prefix & Image (Value.Value));
          when JSON_String =>
             Put_Line (Prefix & Quote (Value.Text.all));
          when JSON_Array =>
             Put_Line (Prefix & "(");
             for Index in Value.Sequence'Range loop
                Dump (Prefix & "   ", Value.Sequence (Index));
             end loop;
             Put_Line (Prefix & ")");
          when JSON_Object =>
             Put_Line (Prefix & "{");
             for Index in Value.Map'Range loop
                Put_Line (Prefix & "   " & Value.Map (Index).Name.all & 
"=");
                Dump (Prefix & "      ", Value.Map (Index).Value);
             end loop;
             Put_Line (Prefix & "}");
       end case;
    end Dump;
begin
    declare
       Factory : aliased HTTPS_OpenSSL_Factory
                         (  Request_Length  => 200,
                            Input_Size      => 40,
                            Output_Size     => 1024,
                            Decoded_Size    => 40,
                            Max_Connections => 100
                         );
    begin
       Set_Default_Verify_Paths (Factory, Client_Context);
       declare
          Message   : aliased String_Stream (1024 * 100);
          Server    : aliased GNAT.Sockets.Server.
                              Connections_Server (Factory'Access, 0);
          Reference : GNAT.Sockets.Server.Handles.Handle;
       begin
          Put_Line ("HTTP client started");
          Set
          (  Reference,
             new HTTP_Session_Signaled
                 (  Server'Unchecked_Access,
                    200,
                    512,
                    1024
          )      );
          declare
             Client : HTTP_Session_Signaled renames
                      HTTP_Session_Signaled (Ptr (Reference).all);
          begin
             Connect (Client, Address, Port);
             Get
             (  Client,
                "https://" & Address & "/" & Path,
                Message'Unchecked_Access
             );
             Wait (Client, False);
             Put_Line
             (  Image (Get_Response_Code (Client))
             &  " "
             &  Get_Response_Reason (Client)
             &  " Message >>>>>>>>>>>>>>>>>>>>"
             );
             declare
                Content : aliased String := Get (Message);
                Source  : aliased Parsers.String_Source.
                                  Source (Content'Access);
                Arena   : aliased Stack_Storage.Pool (1024, 10);
                Data    : constant JSON_Value :=
                                   Parse (Source'Access, Arena'Access);
             begin
                Dump ("", Data);
             end;
             Put_Line ("<<<<<<<<<<<<<<<<<<<< Message");
          end;
          Put_Line ("HTTP client stopping");
       end;
    end;
exception
    when Error : others =>
       Put_Line ("Error: " & Exception_Information (Error));
end Test_HTTPS_OpenSSL_JSON_Client;
----------------------------- test_https_openssl_json_client.adb -----

It connects fine and spills lots of garbage like:

   ...
    USDT_SNX=
       {
          id=
             290.9999999999999
          last=
             "0.00000000"
          lowestAsk=
             "0.00000000"
          highestBid=
             "0.00000000"
          percentChange=
             "0.00000000"
          baseVolume=
             "0.00000000"
          quoteVolume=
             "0.00000000"
          isFrozen=
             "0"
          high24hr=
             "0.00000000"
          low24hr=
             "0.00000000"
       }
    TRX_SNX=
       {
          id=
             292.0000000000000
          last=
             "0.00000000"
          lowestAsk=
             "0.00000000"
          highestBid=
             "0.00000000"
          percentChange=
             "0.00000000"
     ...

and so on. Funny enough, they put numbers as strings, so it seems.

It is not very efficient as written. You see, the code it accumulates 
all response in a string stream buffer. Then takes a string from that. 
Then it parses the obtained string into a JSON object. So it is two 
copies too many. One could parse the response on the fly without 
accumulating it whole in the memory. But it would mean more efforts.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* Re: Creating several types from a base type and conversion
  @ 2020-01-24 15:54  1%   ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2020-01-24 15:54 UTC (permalink / raw)


Optikos <ZUERCHER_Andreas@outlook.com> writes:

> Instead of depending on a big-language solution of a very-feature-rich
> compiler, there is a common industrial practice in both Ada and other
> languages that I mentioned in my 2 replies: use 2 different packages
> with same-named identifiers (especially functions or procedures) to
> link in either the little-endian implementation or big-endian
> implementation

An alternative approach (which I've now abandoned in favour of the GNAT
Scalar_Storage_Order) was, given e.g.

   type SNTP_Timestamp is delta 2.0 ** (-32) range -2.0 ** 31 .. 2.0 ** 31;
   for SNTP_Timestamp'Size use 64;

   subtype Timestamp_Slice is Ada.Streams.Stream_Element_Array (1 .. 8);

to provide conversion functions like

   function To_Timestamp_Slice
     (T : SNTP_Timestamp) return Timestamp_Slice is
      function Convert
      is new Ada.Unchecked_Conversion (SNTP_Timestamp,
                                       Timestamp_Slice);
      Tmp : constant Timestamp_Slice := Convert (T);
   begin
      if Big_Endian then
         return Tmp;
      else
         return (1 => Tmp (8),
                 2 => Tmp (7),
                 3 => Tmp (6),
                 4 => Tmp (5),
                 5 => Tmp (4),
                 6 => Tmp (3),
                 7 => Tmp (2),
                 8 => Tmp (1));
      end if;
   end To_Timestamp_Slice;

(Big_Endian was a compile-time constant; GNAT is clever enough not to
generate any object code for the "other" branch).

It got a bit more interesting where there were bit fields involved; the
two branches can declare appropriately-represented derived types and use
type conversion between base and derived type to get the compiler to do
the hard work. See e.g. [1] starting at line 43.

[1] https://sourceforge.net/p/coldframe/adasntp/code/ci/Rel_20070311/tree/SNTP.impl/sntp_support.adb


^ permalink raw reply	[relevance 1%]

* Re: HTTP Range Requests and streams
  2020-01-20  8:07  1% HTTP Range Requests and streams gautier_niouzes
@ 2020-01-20  8:34  0% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2020-01-20  8:34 UTC (permalink / raw)


On 2020-01-20 09:07, gautier_niouzes@hotmail.com wrote:

> Is there a library supporting HTTP Range Requests (request only portions of a resource on the server: https://en.wikipedia.org/wiki/Byte_serving ) ?
> 
> Just curious...
> 
> An idea would be to map a stream type (a derived type from Ada.Streams.Root_Stream_Type, with methods Index and Set_Index) onto that mechanism.

Do you mean file transfer built-in into the server? A HTTP server 
library merely implements the protocol. What and how the user 
implementation of the server does on top of that is not the library 
business.

The HTTP implementation in Simple Components gets you a request 
callback. In the response you can give an access to a 
Root_Stream_Type'Class object to take the body from.

Now, if you wanted not the whole stream, but a part of it, you could do

    type Stream_Slice
         (  Content : not null access Root_Stream_Type'Class;
            Start   : Stream_Element_Offset
            Size    : Stream_Element_Count
         )  is
    record
       Read_Count : Stream_Element_Count := 0;
    end record;
    overriding procedure Read (...) -- Call Set_Index when Read_Count = 0

I think you get the idea.

I am not sure of it, but I believe that GNAT AWS also allows giving a 
stream to take the response body from.

So IMO it should work relatively smoothly with either.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* HTTP Range Requests and streams
@ 2020-01-20  8:07  1% gautier_niouzes
  2020-01-20  8:34  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: gautier_niouzes @ 2020-01-20  8:07 UTC (permalink / raw)


Hi,

Is there a library supporting HTTP Range Requests (request only portions of a resource on the server: https://en.wikipedia.org/wiki/Byte_serving ) ?

Just curious...

An idea would be to map a stream type (a derived type from Ada.Streams.Root_Stream_Type, with methods Index and Set_Index) onto that mechanism.

_________________________ 
Gautier's Ada programming 
http://gautiersblog.blogspot.com/search/label/Ada 
NB: follow the above link for a valid e-mail address 

^ permalink raw reply	[relevance 1%]

* Re: How to transfer Class-Wide object to a Task ?
  2019-10-14 21:57  1%   ` Shark8
@ 2019-10-15  5:43  0%     ` William FRANCK
  0 siblings, 0 replies; 200+ results
From: William FRANCK @ 2019-10-15  5:43 UTC (permalink / raw)


Thank you Shark,
I'll give it a try too :-)

And send you all a more complete source code of my use case.

William


On 2019-10-14 21:57:57 +0000, Shark8 said:


> On Monday, October 14, 2019 at 2:21:50 PM UTC-6, William FRANCK wrote:
>> On 2019-10-14 19:41:53 +0000, William FRANCK said:
>> 
> Maybe something like this:
> 
>     procedure Example is
>         Package Types is
>             Subtype Params is Ada.Streams.Root_Stream_Type'Class;
>             Type Root   is abstract tagged null record;
>             Function Create (Parameters : not null access Params) 
> return Root is abstract;
> 
>             Type Circle is new Root with record
>                 Radius : Float;
>             end record;
> 
>             Type Square is new Root with record
>                 Side : Integer;
>             end record;
>         Private
> 
>             Function Create (Parameters : not null access Params) 
> return Square;
>             Function Create (Parameters : not null access Params) 
> return Circle;
>         End Types;
> 
> 
>         Use Types;
>         Package Class_Holder is new 
> Ada.Containers.Indefinite_Holders(Root'Class);
>         Task Type Producer( Stream : not null access 
> Ada.Streams.Root_Stream_Type'Class ) is
>             Entry Get( Object: out Class_Holder.Holder );
>         End Producer;
> 
>         Task body Producer is
>             Function MAKE is new Ada.Tags.Generic_Dispatching_Constructor(
>                T           => Types.Root,
>                Parameters  => Ada.Streams.Root_Stream_Type'Class,
>                Constructor => Types.Create
>               );
> 
>             Function To_Tag return Ada.Tags.Tag is
>             Begin
>                 Return Square'Tag;
> --                  (if    Ch = 'C' then Circle'Tag
> --                   elsif Ch = 'S' then Square'Tag
> --                   else raise Constraint_Error with "Tag '"&Ch&"' is 
> invalid.");
>             End;
> 
>         Begin
>             accept Get (Object : out Class_Holder.Holder) do
>                 Object:=
>                   Class_Holder.To_Holder( MAKE(To_Tag, Stream) );
>             end Get;
>         end Producer;
> 
>         Function Get(P : Producer) return Root'Class is
>             H : Class_Holder.Holder;
>         Begin
>             P.Get(H);
>             Return H.Element;
>         End Get;
> 
> 
> 
>         Package Body Types is
>             Function Create(Parameters : not null access Params) return 
> Square is
>             Begin
>                 Return (Side => 3);
>             End;
> 
>             Function Create(Parameters : not null access Params) return 
> Circle is
>             Begin
>                 Return (Radius => 2.2);
>             End;
>         End Types;
> 
>     begin
>         Ada.Text_IO.Put_Line( "START EXAMPLE." );
>         declare
>             I : Ada.Text_IO.File_Type renames Ada.Text_IO.Standard_Input;
>             P : Producer( Ada.Text_IO.Text_Streams.Stream(I) );
>             O : Root'Class := Get(P);
>         begin
>             Ada.Text_IO.Put_Line( "Tag: " & Ada.Tags.Expanded_Name(O'Tag) );
>         end;
>         Ada.Text_IO.Put_Line( "STOP EXAMPLE." );
>     end Example;


^ permalink raw reply	[relevance 0%]

* Re: How to transfer Class-Wide object to a Task ?
  @ 2019-10-14 21:57  1%   ` Shark8
  2019-10-15  5:43  0%     ` William FRANCK
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2019-10-14 21:57 UTC (permalink / raw)


On Monday, October 14, 2019 at 2:21:50 PM UTC-6, William FRANCK wrote:
> On 2019-10-14 19:41:53 +0000, William FRANCK said:
> 
Maybe something like this:

    procedure Example is
        Package Types is
            Subtype Params is Ada.Streams.Root_Stream_Type'Class;
            Type Root   is abstract tagged null record;
            Function Create (Parameters : not null access Params) return Root is abstract;
            
            Type Circle is new Root with record
                Radius : Float;
            end record;
            
            Type Square is new Root with record
                Side : Integer;
            end record;
        Private
            
            Function Create (Parameters : not null access Params) return Square;
            Function Create (Parameters : not null access Params) return Circle;
        End Types;
        
        
        Use Types;
        Package Class_Holder is new Ada.Containers.Indefinite_Holders(Root'Class);
        Task Type Producer( Stream : not null access Ada.Streams.Root_Stream_Type'Class ) is
            Entry Get( Object: out Class_Holder.Holder );
        End Producer;
        
        Task body Producer is
            Function MAKE is new Ada.Tags.Generic_Dispatching_Constructor(
               T           => Types.Root,
               Parameters  => Ada.Streams.Root_Stream_Type'Class,
               Constructor => Types.Create
              );

            Function To_Tag return Ada.Tags.Tag is
            Begin
                Return Square'Tag;
--                  (if    Ch = 'C' then Circle'Tag
--                   elsif Ch = 'S' then Square'Tag
--                   else raise Constraint_Error with "Tag '"&Ch&"' is invalid.");
            End;
            
        Begin
            accept Get (Object : out Class_Holder.Holder) do
                Object:=
                  Class_Holder.To_Holder( MAKE(To_Tag, Stream) );
            end Get;
        end Producer;
        
        Function Get(P : Producer) return Root'Class is
            H : Class_Holder.Holder;
        Begin
            P.Get(H);
            Return H.Element;
        End Get;
        
        
        
        Package Body Types is
            Function Create(Parameters : not null access Params) return Square is
            Begin
                Return (Side => 3);
            End;
            
            Function Create(Parameters : not null access Params) return Circle is
            Begin
                Return (Radius => 2.2);
            End;
        End Types;
        
    begin
        Ada.Text_IO.Put_Line( "START EXAMPLE." );
        declare
            I : Ada.Text_IO.File_Type renames Ada.Text_IO.Standard_Input;
            P : Producer( Ada.Text_IO.Text_Streams.Stream(I) );
            O : Root'Class := Get(P);
        begin
            Ada.Text_IO.Put_Line( "Tag: " & Ada.Tags.Expanded_Name(O'Tag) );
        end;
        Ada.Text_IO.Put_Line( "STOP EXAMPLE." );
    end Example;

^ permalink raw reply	[relevance 1%]

* Re: Ada x <whatever> Datagram Sockets
  @ 2019-02-12 11:35  2%                     ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2019-02-12 11:35 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Simon Wright" <simon@pushface.org> wrote in message 
> news:ly5ztry1f8.fsf@pushface.org...
>> "Randy Brukardt" <randy@rrsoftware.com> writes:
> ...
>> [1] not sure that FIFO_Streams offers this without copying the contents
>> out?
>
> It doesn't, but I'm not sure how it could. It's not possible for a single 
> data type to be two different streams at the same time. Moreover, at least 
> some of the time, the result isn't going to a stream at all. And I haven't 
> personally seen a case where the extra cost of copying the data is 
> significant (the target stream/API being much slower). I could see where it 
> might matter, particularly in a transfer to some other kind of memory.

You may well be right about the extra cost. As I saw it, I needed to
eliminate the need for the users to declare a buffer, read into it, and
send it to the socket (represented in GNAT.Sockets as a stream), when
there was already a perfectly good buffer in the memory stream. There
were quite a few users.

I had fun getting FIFO_Streams to build in Ada 2012. Obviously had to
remove the 2020 aspects, and recast the (declare ...). Only the bounded
version, because the unbounded version would be much more
work. Unfortunately this means GNATprove couldn't be used, because
SPARK2014 doesn't allow discriminants on derived types (SPARK RM
3.7(2)). All the same, the assertions were a huge help.

Test code:

   with Ada.Streams.FIFO_Streams.Bounded;
   with Ada.Text_IO; use Ada.Text_IO;
   procedure Test is
      S : aliased Ada.Streams.FIFO_Streams.Bounded.Stream_Type (31);
   begin
      for J in 1 .. 9 loop
         String'Output (S'Access, "hello!" & J'Image);
         declare
            Buff : Ada.Streams.Stream_Element_Array (1 .. 32);
            Last : Ada.Streams.Stream_Element_Offset;
         begin
            S.Read (Item   => Buff,
                    Last   => Last);
            for K in 1 .. Last loop
               Put (Buff (K)'Image);
            end loop;
            New_Line;
         end;
      end loop;
   end Test;

Output:

   $ ./test
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 49
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 50
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 51
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 52
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 53
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 54
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 55
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 56
    1 0 0 0 8 0 0 0 104 101 108 108 111 33 32 57


^ permalink raw reply	[relevance 2%]

* Re: Ada x <whatever> Datagram Sockets
  2019-02-08 21:26  2%               ` Jeffrey R. Carter
@ 2019-02-08 22:02  0%                 ` Rego, P.
  0 siblings, 0 replies; 200+ results
From: Rego, P. @ 2019-02-08 22:02 UTC (permalink / raw)


On Friday, February 8, 2019 at 7:26:20 PM UTC-2, Jeffrey R. Carter wrote:
> Now that I look at it in more detail, it's probably better to do something like
> 
> function To_String (Buffer : Ada.Streams.Stream_Element_Array) return String is
>     Result : String (1 .. Buffer'Length);
>     Last   : Natural := 0;
> begin -- To_String
>     Convert : for I in Buffer'range loop
>        exit Convert when Buffer (I) = 0; -- If NUL terminated
> 
>        Last := Last + 1;
>        Result (Last) := Character'Val (Buffer (I) );
>     end loop Convert;
> 
>     return Result (1 .. Last);
> end To_String;
> 
> Buffer : Ada.Streams.Stream_Element_Array (1 .. Big_Enough);
> Last   : Ada.Streams.Stream_Element_Offset;
> ...
> Receive_Socket (Socket => Socket, Item => Buffer, Last => Last);
> 
> Do_Something (To => To_String (Buffer (1 .. Last) ) );

It worked perfectly. Thank you Jeff and everybody.
Now I am going to make a proper design of the system :-)

^ permalink raw reply	[relevance 0%]

* Re: Ada x <whatever> Datagram Sockets
  @ 2019-02-08 21:26  2%               ` Jeffrey R. Carter
  2019-02-08 22:02  0%                 ` Rego, P.
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2019-02-08 21:26 UTC (permalink / raw)


On 2/8/19 9:35 PM, Rego, P. wrote:
>> What the OP needs to do is
>>
>> 1. Get Length, the length of the data.
>> 2. Create C : Interfaces.C.char_array (1 .. Length)
>> 3. Transfer the data into C
>> 4. Use Interfaces.C.To_Ada (C) to transform C into an Ada String

Now that I look at it in more detail, it's probably better to do something like

function To_String (Buffer : Ada.Streams.Stream_Element_Array) return String is
    Result : String (1 .. Buffer'Length);
    Last   : Natural := 0;
begin -- To_String
    Convert : for I in Buffer'range loop
       exit Convert when Buffer (I) = 0; -- If NUL terminated

       Last := Last + 1;
       Result (Last) := Character'Val (Buffer (I) );
    end loop Convert;

    return Result (1 .. Last);
end To_String;

Buffer : Ada.Streams.Stream_Element_Array (1 .. Big_Enough);
Last   : Ada.Streams.Stream_Element_Offset;
...
Receive_Socket (Socket => Socket, Item => Buffer, Last => Last);

Do_Something (To => To_String (Buffer (1 .. Last) ) );

-- 
Jeff Carter
"I've seen projects fail miserably for blindly
applying the Agile catechism: we're Agile, we
don't need to stop and think, we just go ahead
and code!"
Bertrand Meyer
150


^ permalink raw reply	[relevance 2%]

* Re: Ada x <whatever> Datagram Sockets
  2019-02-08 19:41  2%           ` Rego, P.
@ 2019-02-08 20:31  0%             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2019-02-08 20:31 UTC (permalink / raw)


On 2019-02-08 20:41, Rego, P. wrote:
>> How is it controversial? The example works fine when the server and client
>> are both written in Ada, as they would then agree on the protocol.
>> But when dealing with cross-language communication, you're better off using
>> Send_Socket/Receive_Socket directly. No need to re-implement
> 
> I am trying this approach, but it seems that both g-socket.ads Send_Socket signatures also use Ada Streams
> 
>     procedure Receive_Socket
>       (Socket : Socket_Type;
>        Item   : out Ada.Streams.Stream_Element_Array;
>        Last   : out Ada.Streams.Stream_Element_Offset;
>        Flags  : Request_Flag_Type := No_Request_Flag);
> 
>     procedure Receive_Socket
>       (Socket : Socket_Type;
>        Item   : out Ada.Streams.Stream_Element_Array;
>        Last   : out Ada.Streams.Stream_Element_Offset;
>        From   : out Sock_Addr_Type;
>        Flags  : Request_Flag_Type := No_Request_Flag);

No. Stream_Element_Array is a plain array. Receive_Socket fill it and 
return the index of last updated element.

    declare
       Buffer : Stream_Element_Array (1..Max_Packet_Length);
       Last   : Stream_Element_Offset;
    begin
       Receive_Socket (Socket, Buffer, Last);
       -- Buffer (1..Last) is the receipt

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Ada x <whatever> Datagram Sockets
  2019-02-07  7:23  0%         ` Egil H H
@ 2019-02-08 19:41  2%           ` Rego, P.
  2019-02-08 20:31  0%             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Rego, P. @ 2019-02-08 19:41 UTC (permalink / raw)


> How is it controversial? The example works fine when the server and client
> are both written in Ada, as they would then agree on the protocol.
> But when dealing with cross-language communication, you're better off using
> Send_Socket/Receive_Socket directly. No need to re-implement

I am trying this approach, but it seems that both g-socket.ads Send_Socket signatures also use Ada Streams

   procedure Receive_Socket
     (Socket : Socket_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      Flags  : Request_Flag_Type := No_Request_Flag);

   procedure Receive_Socket
     (Socket : Socket_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      From   : out Sock_Addr_Type;
      Flags  : Request_Flag_Type := No_Request_Flag);

^ permalink raw reply	[relevance 2%]

* Re: Ada x <whatever> Datagram Sockets
  2019-02-07  6:41  1%       ` Rego, P.
  2019-02-07  7:23  0%         ` Egil H H
  2019-02-07  8:28  0%         ` Dmitry A. Kazakov
@ 2019-02-07 11:47  0%         ` Jere
    2 siblings, 1 reply; 200+ results
From: Jere @ 2019-02-07 11:47 UTC (permalink / raw)


On Thursday, February 7, 2019 at 1:41:28 AM UTC-5, Rego, P. wrote:
> On Thursday, February 7, 2019 at 4:00:11 AM UTC-2, Egil H H wrote:
> > > > On Wednesday, February 6, 2019 at 6:10:37 PM UTC-5, Rego, P. wrote:
> > > 
> > > Just the string "test". I also confirmed that the MQL container (uchar data[]) has really the size 5.
> > > 
> > 
> > Right, Ada strings are not zero-terminated, and the size of the string needs 
> > to come from somewhere, which is why String'Input will interpret the first x bits (probably 32, but may depend on your platform) as the length. So in this
> > case, "test" becomes a big number and 'Input will most likely try to allocate
> > just under 2GB  on your stack (and probably at least twice, in order to copy
> > the result into your string).
> A C++ uchar in Windows machine is usually 1 byte, so assuming that both use the same signature, both messages (from C++ and from Ada) should be of same size, right? 
> 
The problem is you are telling it to send it one way and receive it
in another way.  In C++ you tell the code to send:
't' 'e' 's' 't' '\0'

In Ada you are telling it to receive:

<length byte 1..4> <data byte 1..length>

if it reads your c++ packet in that format, assuming a little endian 
system:

<0x74736574> <\0 + random junk>

That translates to specifying a length of 1953719668 bytes, which is 
above the 65507 limit.

For giggles try modifying your receive code a bit:

      declare
         subtype Test_String is String(1..5);
         Message : Test_String := Test_String'Input (Channel);
      begin
         Address := SOCKETS.Get_Address (Channel);
         Text_IO.Put_Line (Message & " from " & SOCKETS.Image (Address));
         Test_String'Output (Channel, Message);
      end; 

I don't recall if C actually sends the '\0' at the end or not
for sockets, so if it doesn't, then change the Test_String declaration
to

      subtype Test_String is String(1..4);

However, I think it does send the '\0', so you will also have to
handle that in your Ada code (since strings don't terminate with a
'\0' in Ada).

Changing String to a constrained subtype might change the pattern
to be closer to the C++ pattern sent.  This doesn't solve your problem
because you never know how long the data is for real data, but would
at least (hopefully) get you talking.

> 
> > 
> > Don't use Ada stream attributes to communicate with other languages.
> > 
> > And, as some will tell you, don't use them at all, especially for arrays, as
> > each array element may end up being transferred as a single data packet, destroying performance.
> 
> This is quite controversial, in this case. I'd usually agree with you, however the use of Ada stream is not by choice. The whole GNAT Ada package uses Ada streams, and actually the above code was entirely extracted from the comments from g-sockets.ads with minimum modification. I don't think it would be wise to re-implement Ada Sockets pkg to be more efficient.

I've never used streams with the GNAT socket package for production code,
so I cannot comment on them, but the package definitely offers other
options besides streams.  I generally have a task that periodically
reads up to a specific number of bytes into a buffer and then my other
tasks can handle the data as they see fit.  You can even have the OS
tell you how many bytes are available to read before you do.

^ permalink raw reply	[relevance 0%]

* Re: Ada x <whatever> Datagram Sockets
  2019-02-07  6:41  1%       ` Rego, P.
  2019-02-07  7:23  0%         ` Egil H H
@ 2019-02-07  8:28  0%         ` Dmitry A. Kazakov
    2019-02-07 11:47  0%         ` Jere
  2 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2019-02-07  8:28 UTC (permalink / raw)


On 2019-02-07 07:41, Rego, P. wrote:

> This is quite controversial, in this case. I'd usually agree with you, however the use of Ada stream is not by choice. The whole GNAT Ada package uses Ada streams, and actually the above code was entirely extracted from the comments from g-sockets.ads with minimum modification. I don't think it would be wise to re-implement Ada Sockets pkg to be more efficient.

Well, using streams directly with UDP is calling for trouble (and highly 
non-portable too). You should probably never use streams with TCP 
either. Certainly not if socket options like NO_DELAY are planned. 
Streams will never ever work with non-blocking sockets, obviously.

(There are other concerns with stream attributes beyond performance that 
however do not apply to strings)

Anyway, the way to do it is to have an outgoing packet buffer of 
Stream_Element_Array. You put data there and then send all buffer to the 
socket (write to the file etc), in one piece.

If you want to use streams. Put a memory-mapped stream on top of the 
Stream_Element_Array. Write packet whole. Flush the buffer contents to 
the socket/file.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Ada x <whatever> Datagram Sockets
  2019-02-07  6:41  1%       ` Rego, P.
@ 2019-02-07  7:23  0%         ` Egil H H
  2019-02-08 19:41  2%           ` Rego, P.
  2019-02-07  8:28  0%         ` Dmitry A. Kazakov
  2019-02-07 11:47  0%         ` Jere
  2 siblings, 1 reply; 200+ results
From: Egil H H @ 2019-02-07  7:23 UTC (permalink / raw)


On Thursday, February 7, 2019 at 7:41:28 AM UTC+1, Rego, P. wrote:
> On Thursday, February 7, 2019 at 4:00:11 AM UTC-2, Egil H H wrote:
> > > > On Wednesday, February 6, 2019 at 6:10:37 PM UTC-5, Rego, P. wrote:
> > > 
> > > Just the string "test". I also confirmed that the MQL container (uchar data[]) has really the size 5.
> > > 
> > 
> > Right, Ada strings are not zero-terminated, and the size of the string needs 
> > to come from somewhere, which is why String'Input will interpret the first x bits (probably 32, but may depend on your platform) as the length. So in this
> > case, "test" becomes a big number and 'Input will most likely try to allocate
> > just under 2GB  on your stack (and probably at least twice, in order to copy
> > the result into your string).
> A C++ uchar in Windows machine is usually 1 byte, so assuming that both use the same signature, both messages (from C++ and from Ada) should be of same size, right? 
> 

The *message* may be of the same size, but that doesn't matter, as long as
it's interpreted differently in C++ vs Ada.
C++ apparently puts an extra character in your message (you said "test"
was length 5...)
Ada interprets your string (presumably the first 4 bytes, which is usually
the size of Positive/Integer) as a very big number.

> > 
> > Don't use Ada stream attributes to communicate with other languages.
> > 
> > And, as some will tell you, don't use them at all, especially for arrays, as
> > each array element may end up being transferred as a single data packet, destroying performance.
> 
> This is quite controversial, in this case. I'd usually agree with you, however the use of Ada stream is not by choice. The whole GNAT Ada package uses Ada streams, and actually the above code was entirely extracted from the comments from g-sockets.ads with minimum modification. I don't think it would be wise to re-implement Ada Sockets pkg to be more efficient.


How is it controversial? The example works fine when the server and client
are both written in Ada, as they would then agree on the protocol.
But when dealing with cross-language communication, you're better off using
Send_Socket/Receive_Socket directly. No need to re-implement

-- 
~egilhh


^ permalink raw reply	[relevance 0%]

* Re: Ada x <whatever> Datagram Sockets
  @ 2019-02-07  6:41  1%       ` Rego, P.
  2019-02-07  7:23  0%         ` Egil H H
                           ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Rego, P. @ 2019-02-07  6:41 UTC (permalink / raw)


On Thursday, February 7, 2019 at 4:00:11 AM UTC-2, Egil H H wrote:
> > > On Wednesday, February 6, 2019 at 6:10:37 PM UTC-5, Rego, P. wrote:
> > 
> > Just the string "test". I also confirmed that the MQL container (uchar data[]) has really the size 5.
> > 
> 
> Right, Ada strings are not zero-terminated, and the size of the string needs 
> to come from somewhere, which is why String'Input will interpret the first x bits (probably 32, but may depend on your platform) as the length. So in this
> case, "test" becomes a big number and 'Input will most likely try to allocate
> just under 2GB  on your stack (and probably at least twice, in order to copy
> the result into your string).
A C++ uchar in Windows machine is usually 1 byte, so assuming that both use the same signature, both messages (from C++ and from Ada) should be of same size, right? 

(I checked both send commands used by Ada sockets and MQL sockets, and they both are using standard win32 signatures, I mean for C++ case

int sendto(
  SOCKET         s,
  const char     *buf,
  int            len,
  int            flags,
  const sockaddr *to,
  int            tolen
);

and in Ada case a imported function
   function C_Sendto
     (S     : C.int;
      Msg   : System.Address;
      Len   : C.int;
      Flags : C.int;
      To    : System.Address;
      Tolen : C.int) return C.int;
)

> 
> Don't use Ada stream attributes to communicate with other languages.
> 
> And, as some will tell you, don't use them at all, especially for arrays, as
> each array element may end up being transferred as a single data packet, destroying performance.

This is quite controversial, in this case. I'd usually agree with you, however the use of Ada stream is not by choice. The whole GNAT Ada package uses Ada streams, and actually the above code was entirely extracted from the comments from g-sockets.ads with minimum modification. I don't think it would be wise to re-implement Ada Sockets pkg to be more efficient.


^ permalink raw reply	[relevance 1%]

* Re: AI12-0218: What is the portable representation clause for processing IETF packets on little-endian machines?
  @ 2018-05-11  7:55  2%           ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2018-05-11  7:55 UTC (permalink / raw)


"Dan'l Miller" <optikos@verizon.net> writes:

> Still, standard Ada has no good Ada-esque solution to heterogenous
> endianness at the perimeter of a system, other than writing C-esque
> pointer-arithmetic code with the various unchecked_ constructs (which
> even C programmers don't generally do; they utilize
> conditionally-compiled macros that correctly type-cast
> meticulously*-laid-out structs-of-bitfields onto that packet's header
> or IC register's word.

I've used (effectively) conditionally-compiled sections of code for
this.

From an SNTP implementation: in BE, the first 32 bits of a packet are

   --   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   --  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   --  |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
   --  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

and looking just at the top (first) byte, the package spec contains

   type Leap_Indicator is (No_Warning,
                           Last_Minute_Has_61_Seconds,
                           Last_Minute_Has_59_Seconds,
                           Alarm_Condition);

   type Version is range 3 .. 4;

   type Mode is (Reserved,
                 Symmetric_Active,
                 Symmetric_Passive,
                 Client,
                 Server,
                 Broadcast,
                 Reserved_For_NTP_Control_Message,
                 Reserved_For_Private_Use);

   type Status is record
      LI : Leap_Indicator;
      VN : Version;
      M : Mode;
   end record;

in native layout (nowadays I'd be a lot more specific about
sizes). Conversions:

   function To_Stream_Element (S : Status) return Ada.Streams.Stream_Element;

   function To_Status (S : Ada.Streams.Stream_Element) return Status;

In the body,

   Big_Endian : constant Boolean
     := System."=" (System.Default_Bit_Order, System.High_Order_First);

and

   function To_Status (S : Ada.Streams.Stream_Element) return Status is
   begin
      --  these two sections are conditionally compiled (by GNAT,
      --  anyway) because Big_Endian is constant.
      if Big_Endian then
         declare
            --  create a BE type with BE representation
            type Host_Status is record
               LI : Leap_Indicator;
               VN : Version;
               M : Mode;
            end record;
            for Host_Status use record
               LI at 0 range 0 .. 1;
               VN at 0 range 2 .. 4;
               M  at 0 range 5 .. 7;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
                                             Host_Status);
            V : constant Host_Status := Convert (S);
         begin
            --  let the compiler convert from BE representation to host
            return (LI => V.LI, VN => V.VN, M => V.M);
         end;
      else
         declare
            --  create an LE type with LE representation
            type Host_Status is record
               LI : Leap_Indicator;
               VN : Version;
               M : Mode;
            end record;
            for Host_Status use record
               LI at 0 range 6 .. 7;
               VN at 0 range 3 .. 5;
               M  at 0 range 0 .. 2;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
                                             Host_Status);
            V : constant Host_Status := Convert (S);
         begin
            --  let the compiler convert from LE representation to host
            return (LI => V.LI, VN => V.VN, M => V.M);
         end;
      end if;
   end To_Status;

No denying it's a lot of work. Much easier for 2-, 4-, 8-byte objects:

   type SNTP_Timestamp is delta 2.0 ** (-32) range -2.0 ** 31 .. 2.0 ** 31;
   for SNTP_Timestamp'Size use 64;

   subtype Timestamp_Slice is Ada.Streams.Stream_Element_Array (1 .. 8);

   function To_SNTP_Timestamp (T : Timestamp_Slice) return SNTP_Timestamp is
      function Convert is new Ada.Unchecked_Conversion (Timestamp_Slice,
                                                        SNTP_Timestamp);
   begin
      if Big_Endian then
         return Convert (T);
      else
         return Convert ((1 => T (8),
                          2 => T (7),
                          3 => T (6),
                          4 => T (5),
                          5 => T (4),
                          6 => T (3),
                          7 => T (2),
                          8 => T (1)));
      end if;
   end To_SNTP_Timestamp;


^ permalink raw reply	[relevance 2%]

* Re: Overriding procedure as null
  2018-03-27 20:26  2% Overriding procedure as null gautier_niouzes
@ 2018-03-28  0:08  0% ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2018-03-28  0:08 UTC (permalink / raw)


<gautier_niouzes@hotmail.com> wrote in message 
news:77e909f6-9f24-4638-ba6a-1872e5a46580@googlegroups.com...
> Hello,
>
> I've just come across a little "legal" case that was easy to solve 
> practically, but I'm curious about what is "right" Ada.
>...
>    overriding procedure Write

You're not supposed to repeat "overriding" on bodies. It should be thought 
of like "generic" or aspects, which are not part of the profile. It's not 
illegal, but it's bad practice.

>     (Stream : in out Search_stream;
>      Item   : in     Ada.Streams.Stream_Element_Array) is
>    begin
>      null;  --  Something done in real case.
>    end;
>
>  begin
>    null;
>  end;
>
> GNAT (GPL 2017/Win32) compiles seamlessly.
> ObjectAda (9.2) issues, for the 2nd "Read":
>  test_overriding.adb: Error: line 18 col 24 LRM:8.3(26), Illegal to 
> override declaration in same region, prior declaration is Read at line 7
>
> It looks like OA considers the 2nd occurrence as a specification, not a 
> body - with "is null", it could be both actually.
> Who's right ?

A body freezes everything, and nothing can be overridden after. We had some 
issues with these rules, so it's possible that both are right (Ada 2005 and 
Ada 2012 may differ on these rules).

We've got an ARG meeting on Monday, so I don't have time to investigate 
further, sorry.

                 Randy. 



^ permalink raw reply	[relevance 0%]

* Overriding procedure as null
@ 2018-03-27 20:26  2% gautier_niouzes
  2018-03-28  0:08  0% ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: gautier_niouzes @ 2018-03-27 20:26 UTC (permalink / raw)


Hello,

I've just come across a little "legal" case that was easy to solve practically, but I'm curious about what is "right" Ada.

Consider the following program:

  with Ada.Streams;

  procedure test_overriding is

    type Search_stream is new Ada.Streams.Root_Stream_Type with null record;

    overriding procedure Read
      (Stream : in out Search_stream;
       Item   :    out Ada.Streams.Stream_Element_Array;
       Last   :    out Ada.Streams.Stream_Element_Offset);

    overriding procedure Write
     (Stream : in out Search_stream;
      Item   : in     Ada.Streams.Stream_Element_Array);

    --  Implementation of Read & Write:

    overriding procedure Read
      (Stream : in out Search_stream;
       Item   :    out Ada.Streams.Stream_Element_Array;
       Last   :    out Ada.Streams.Stream_Element_Offset) is null;  --  Unused

    overriding procedure Write
     (Stream : in out Search_stream;
      Item   : in     Ada.Streams.Stream_Element_Array) is
    begin
      null;  --  Something done in real case.
    end;

  begin
    null;
  end;

GNAT (GPL 2017/Win32) compiles seamlessly.
ObjectAda (9.2) issues, for the 2nd "Read":
  test_overriding.adb: Error: line 18 col 24 LRM:8.3(26), Illegal to override declaration in same region, prior declaration is Read at line 7

It looks like OA considers the 2nd occurrence as a specification, not a body - with "is null", it could be both actually.
Who's right ?

To make both compilers happy I just put the "Read(...) is null" at the first place and remove the 2nd one, so it is only a theory/law problem.

More interestingly, if I completely remove the Read procedure, OA still compiles fine and GNAT issues an error  (rightfully I think):
test_overriding.adb:5:10: type must be declared abstract or "read" overridden
test_overriding.adb:5:10: "read" has been inherited from subprogram at a-stream.ads:57

_________________________ 
Gautier's Ada programming 
http://www.openhub.net/accounts/gautier_bd


^ permalink raw reply	[relevance 2%]

* Re: TCP Server & Client
  2018-03-25  8:22  1% ` Simon Wright
@ 2018-03-25 19:17  0%   ` Andrew Shvets
  0 siblings, 0 replies; 200+ results
From: Andrew Shvets @ 2018-03-25 19:17 UTC (permalink / raw)


On Sunday, March 25, 2018 at 4:22:32 AM UTC-4, Simon Wright wrote:
> Andrew Shvets <an....@gmail.com> writes:
> 
> > procedure TCP_Client is
> [...]
> >   GNAT.Sockets.Create_Socket(Socket, GNAT.Sockets.Family_Inet, GNAT.Sockets.Socket_Stream);
> 
> >   GNAT.Sockets.Set_Socket_Option(Socket, GNAT.Sockets.Socket_Level, (GNAT.Sockets.Reuse_Address, True));
> 
> >   GNAT.Sockets.Send_Socket(Socket, Data, Last, Address);
> 
> If you look at the spec of GNAT.Sockets for a long time you will see
> that there are 3 versions of Send_Socket, only 2 of which I would expect
> to use, and you've chosen the wrong one (the last, datagram,
> version). You need the second:
> 
>    procedure Send_Socket
>      (Socket : Socket_Type;
>       Item   : Ada.Streams.Stream_Element_Array;
>       Last   : out Ada.Streams.Stream_Element_Offset;
>       Flags  : Request_Flag_Type := No_Request_Flag);
> 
> More importantly, you've left out the Connect_Socket call (which is what
> the server Accept_Socket call is waiting for).
> 
> Check out the commentary at the beginning of g-socket.ads, look for
> 'task body ping'.
> 
> 
> Also, in TCP_Server, you should be calling Receive_Socket on Sock (the
> new socket which is actually connected to TCP_Client).

Thank you Simon.  That did the trick.


^ permalink raw reply	[relevance 0%]

* Re: TCP Server & Client
  2018-03-25  4:04  2% TCP Server & Client Andrew Shvets
@ 2018-03-25  8:22  1% ` Simon Wright
  2018-03-25 19:17  0%   ` Andrew Shvets
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2018-03-25  8:22 UTC (permalink / raw)


Andrew Shvets <andrew.shvets@gmail.com> writes:

> procedure TCP_Client is
[...]
>   GNAT.Sockets.Create_Socket(Socket, GNAT.Sockets.Family_Inet, GNAT.Sockets.Socket_Stream);

>   GNAT.Sockets.Set_Socket_Option(Socket, GNAT.Sockets.Socket_Level, (GNAT.Sockets.Reuse_Address, True));

>   GNAT.Sockets.Send_Socket(Socket, Data, Last, Address);

If you look at the spec of GNAT.Sockets for a long time you will see
that there are 3 versions of Send_Socket, only 2 of which I would expect
to use, and you've chosen the wrong one (the last, datagram,
version). You need the second:

   procedure Send_Socket
     (Socket : Socket_Type;
      Item   : Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      Flags  : Request_Flag_Type := No_Request_Flag);

More importantly, you've left out the Connect_Socket call (which is what
the server Accept_Socket call is waiting for).

Check out the commentary at the beginning of g-socket.ads, look for
'task body ping'.


Also, in TCP_Server, you should be calling Receive_Socket on Sock (the
new socket which is actually connected to TCP_Client).


^ permalink raw reply	[relevance 1%]

* TCP Server & Client
@ 2018-03-25  4:04  2% Andrew Shvets
  2018-03-25  8:22  1% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Andrew Shvets @ 2018-03-25  4:04 UTC (permalink / raw)


Hello, I'm trying to write a small client/server example:

This is the client:
==============================================================================
with Ada.Streams;
with Ada.Text_IO;

with GNAT.Sockets;

procedure TCP_Client is
  Address : GNAT.Sockets.Sock_Addr_Type;
  Socket : GNAT.Sockets.Socket_Type;
  Data : constant Ada.Streams.Stream_Element_Array(1 .. 512) := (others => 42);
  Last : Ada.Streams.Stream_Element_Offset;
begin
  GNAT.Sockets.Initialize;

  Address.Port := 50001;
  Address.Addr := GNAT.Sockets.Inet_Addr("127.0.0.1");
  Ada.Text_IO.Put_Line("Hello 1");
  GNAT.Sockets.Create_Socket(Socket, GNAT.Sockets.Family_Inet, GNAT.Sockets.Socket_Stream);
  Ada.Text_IO.Put_Line("Hello 2");
  GNAT.Sockets.Set_Socket_Option(Socket, GNAT.Sockets.Socket_Level, (GNAT.Sockets.Reuse_Address, True));
  Ada.Text_IO.Put_Line("Hello 3");
  GNAT.Sockets.Send_Socket(Socket, Data, Last, Address);
  Ada.Text_IO.Put_Line("last :" & Last'Img);

  GNAT.Sockets.Finalize;
end TCP_Client;
==============================================================================

This is the server:
==============================================================================
with Ada.Streams;
with Ada.Text_IO;

with GNAT.Sockets;

procedure TCP_Server is
  Server : GNAT.Sockets.Socket_Type;
  Sock   : GNAT.Sockets.Socket_Type;
  Address : GNAT.Sockets.Sock_Addr_Type;
  From : GNAT.Sockets.Sock_Addr_Type;
  Data : Ada.Streams.Stream_Element_Array(1 .. 512);
  Last : Ada.Streams.Stream_Element_Offset;
  Watchdog : Natural := 0;
begin
  GNAT.Sockets.Initialize;

  GNAT.Sockets.Create_Socket(Server, GNAT.Sockets.Family_Inet, GNAT.Sockets.Socket_Stream);
  GNAT.Sockets.Set_Socket_Option(Server, GNAT.Sockets.Socket_Level, (GNAT.Sockets.Reuse_Address, True));
  Address.Addr := GNAT.Sockets.Any_Inet_Addr;
  Address.Port := 50001;
  GNAT.Sockets.Bind_Socket(Server, Address);

  loop
    begin
      GNAT.Sockets.Listen_Socket(Server);
      GNAT.Sockets.Accept_Socket(Server, Sock, Address); 
      GNAT.Sockets.Receive_Socket(Server, Data, Last, From);
      Ada.Text_IO.Put_Line("last : " & Last'Img);
      Ada.Text_IO.Put_Line("from : " & GNAT.Sockets.Image(From.Addr));
    exception
      when GNAT.Sockets.Socket_Error =>
        Ada.Text_IO.Put_Line("ERROR: Socket error caught.");
    end;
  end loop;
end TCP_Server;
==============================================================================


When I run the client, this is what I see:
Hello 1
Hello 2
Hello 3

raised GNAT.SOCKETS.SOCKET_ERROR : [32] Broken pipe




Why is this happening?  If possible, I'd like to use the Send_Socket method in the client.  Thanks.


^ permalink raw reply	[relevance 2%]

* Re: body stub not allowed in inner scope
  @ 2018-03-01 17:37  1%       ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2018-03-01 17:37 UTC (permalink / raw)


On Wednesday, February 28, 2018 at 4:23:32 PM UTC-7, Randy Brukardt wrote:
> "Mehdi Saada" wrote in message 
> news:15c49c4e-726a-4fd7-bf35-c7d27ff9a491...
> > Thanks.
> > But that's ugly... How about fixing this for the next norm ?
> 
> Does anyone other than ACATS tests actually use stubs these days? Why?

I do, sometimes.
Usually to put a particularly knotty or verbose chunk of code. For example, in an interpreter I was writing I put all the operators, which 'explodes' (m*n; m = #types, n = #operators) based on the number of internal types, in their own package and made the body separate.

I've also used it with parsing & stream-I/O functions:
Function Parse( Text : String ) return Program;
Function Parse( Text : String ) return Program is Separate;

Procedure Read(
        Stream : not null access Ada.Streams.Root_Stream_Type'Class;
        Item   : out  T) is Separate;

> (We used to use them extensively, but only because Janus/Ada on 16-bit MS-DOS 
> limited a single unit to 64K of generated code -- and our editors couldn't 
> handle more than 256K of source code at a time. None of that makes sense 
> today.)

This is true; but it does make sense for organizing and isolating portions of the codebase even further w/o having to muck up the library-hierarchy... and might be required at a certain level (eg primitive ops).


^ permalink raw reply	[relevance 1%]

* article on acces types and dynamic serialization in Ada (2003)
@ 2018-02-21 23:57  1% Mehdi Saada
  0 siblings, 0 replies; 200+ results
From: Mehdi Saada @ 2018-02-21 23:57 UTC (permalink / raw)


Hello everyone.
I already mailed you Simon Wright about it, but I've more info and questions, so it put it here. First the context:
I played with streams yesterday to learn more, and stumbled on something not really intuitive, at least. what means exactly Some_access_type'Write(Stream1, Some_Pointer) ?
I could figure out it's implementation defined, so you can't guess.
So that
Some_access_type'Write(stream(Stream_File), Pointer1);
...
Reset(Stream_File, IN_FILE);
Some_access_type'Read(stream(Stream_file), Pointer2);
doesn't work: reaching Pointer2.all raises "erroneous memory access", though Pointer2 isn't null.
Strange, since in my exemple, all happen in the same, hum, "scope of declaration" (apropriate term ?). Any address or whatever information the pointer is made of, should still be valid. Any pool pointed at still exists.
Doesn't feel like a "sane" legal behavior. I also saw a "normal" record object with a pool-specific pointer like this one
type FOO is record
  ...
  BAR: access INTEGER := new INTEGER'(15);
end record;
serializes well, I can read Bar.all. Funny, but where the difference since (according to Ada wikibook) a priori the default 'Write is called for each record component ?

Then I found today that https://infoscience.epfl.ch/record/54724/files/IC_TECH_REPORT_200363.pdf : Automatic Serialization of Dynamic Structures in Ada Technical Report

I was surprised I could read and understand it all with some concentration. And a bit proud, to be honnest ! I would have thought it to be like Chinese at my level.
It was 13 years ago, but I couldn't find a more recent papier on the subject of dynamic serialization, nor has new Dynamic_Stream aspects/attributes been added since then. I didn't read anything either in the stream or access types related sections.

I tried more, but can't write well yet that more complicated exemple:
with Ada.Streams.Stream_IO, Ada.Strings.Unbounded.Text_IO, Ada.Text_IO;
use Ada.Streams.Stream_IO, Ada.Streams, Ada.Strings.Unbounded, Ada.Strings.Unbounded.Text_IO;
procedure Main is
   subtype TSF is File_Type;
   FILE : TSF;
   type CHAMPS;
   type ACCESS_CHAMPS is access ALL CHAMPS;
   type CHAMPS (A: ACCESS_CHAMPS) is record
      NOTE : NATURAL range 0 .. 20 := 0;
   end record;
   
   C2, C1 , C3  :  aliased CHAMPS := (A => null, note => 5); 
begin
        
   C1 := (C2'Access, 14);
   C2 := (A => C1'Access, Note => 5 ); 
   Create (FILE, Append_File, Name => "tentative.stream");
   CHAMPS'Write (Stream (FILE), C2);
   Reset (File => FILE,
	  Mode => In_File );
   CHAMPS'Read(Stream(FILE), C3);
   ada.Text_IO.Put_line (INTEGER'Image (C3.A.all.Note));
   CLOSE(FILE);
end;

raises CONSTRAINT_ERROR : main.adb:15 discriminant check failed
I read as I could about access discrimant aliasing and autoreferencing types, but visibly lack practice ;-)  
Could you help me finish that exemple ? I would be delighted to see what happens by myself, since the former exemple (Some_Access'Write and 'Read) proves interesting.

Gosh, the pleasure these things give me...

^ permalink raw reply	[relevance 1%]

* Re: Unbounded_String'Write et al in GNAT
  @ 2017-11-14 15:05  1% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-11-14 15:05 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> GNAT has 
>
>    for Unbounded_String'Write  use Unbounded_String_Write;
>    for Unbounded_String'Read   use Unbounded_String_Read;
>    for Unbounded_String'Output use Unbounded_String_Write;
>    for Unbounded_String'Input  use Unbounded_String_Input;
>
> in package Ada.Strings.Unbounded.
>
> Ada2012 seems not to provide them.
>
> Is it standard conformant?
>
> Or better, should we add this to the standard?

No.

ARM 13.13.2(2)ff [1] says

For every subtype S of a specific type T, the following attributes are
defined. 

S'Write
S'Write denotes a procedure with the following specification: 
procedure S'Write(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : in T)
S'Write writes the value of Item to Stream.

S'Read
S'Read denotes a procedure with the following specification: 
procedure S'Read(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : out T)
S'Read reads the value of Item from Stream.

And (18) says much the same about 'Output, 'Input.

So Unbounded_String _must_ support 'Read, 'Write, 'Output, 'Input, but
it's up to the compiler vendor to implement them, which GNAT does *in*
*the* *private* *part* - which is exactly the way the standard expects
any other vendor to do it. The ARG goes to a lot of trouble to ensure
that a vendor can implement the standard's requirements.

[1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-13-13-2.html#p2

^ permalink raw reply	[relevance 1%]

* Re: Finding the end of a stream from a socket
  2017-10-22 12:26  2%         ` Andrew Shvets
  2017-10-22 12:28  0%           ` Andrew Shvets
@ 2017-10-22 13:28  0%           ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-10-22 13:28 UTC (permalink / raw)


On 2017-10-22 14:26, Andrew Shvets wrote:

> One more question.  How do I convert a string to a Stream_Element?
> 
> This is what I have:
> 
>    Out_String : constant String := "I like cake!";
>    Out_Data : Ada.Streams.Stream_Element_Array(1 .. 12);
> begin
> ...
>    for elem in 1 .. Out_Data'Length loop
>      Out_Data(Ada.Streams.Stream_Element_Offset(elem)) :=
>        Ada.Streams.Stream_Element(Character'Val(Out_String(elem)));
>    end loop;

    Out_String : constant String := ...;
    Out_Data   : constant Stream_Element_Array (1..Out_String'Length);
begin
    for Octet in Out_Data'Range loop
       Out_Data (Octet) :=
          Character'Pos (Out_String (Integer(Octet-1)+Out_String'First));
    end loop;


-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Finding the end of a stream from a socket
  2017-10-22 12:26  2%         ` Andrew Shvets
@ 2017-10-22 12:28  0%           ` Andrew Shvets
  2017-10-22 13:28  0%           ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Andrew Shvets @ 2017-10-22 12:28 UTC (permalink / raw)


On Sunday, October 22, 2017 at 8:26:54 AM UTC-4, Andrew Shvets wrote:
> On Saturday, October 21, 2017 at 3:19:36 PM UTC-4, Dmitry A. Kazakov wrote:
> > On 2017-10-21 20:11, Dennis Lee Bieber wrote:
> > > On Sat, 21 Oct 2017 06:45:22 -0700 (PDT), Andrew Shvets
> > > <andr.....@gmail.com> declaimed the following:
> > > 
> > >>   GNAT.Sockets.Bind_Socket(Receiver, (GNAT.Sockets.Family_Inet, GNAT.Sockets.Inet_Addr("127.0.0.1"), 50000));
> > >>   GNAT.Sockets.Listen_Socket(Receiver);
> > >>
> > > 	From those statements I'm guessing you are trying to set this program
> > > up as a server, and have some other program which will connect to send data
> > > to this one.
> > > 
> > >>   Ada.Text_IO.Put_Line(" !! TCP Server started !!");
> > >>
> > >>   loop
> > >>     Ada.Text_IO.Put_Line(" FOO 1");
> > >>     GNAT.Sockets.Connect_Socket(Receiver,  Client_Addr);
> > > 
> > > 	But here you are saying /this/ program is going to connect to a server
> > > at (undefined) Client_Addr.
> > > 
> > > 	I suspect you really need to be using g.s.Accept_Socket() instead.
> > 
> > Also note that Accept_Socket will return another socket. This one you 
> > should use for communication.
> > 
> > A typical scenario for blocking sockets:
> > 
> >     loop -- Connection listening
> >        Accept_Socket -- Get communication socket
> >        Start a new session task with the communication socket
> >     end loop;
> > 
> > The session task deals with the connection using the socket returned by 
> > Accept_Socket. Once the session is complete it closes that socket and 
> > terminates.
> > 
> > -- 
> > Regards,
> > Dmitry A. Kazakov
> > http://www.dmitry-kazakov.de
> 
> One more question.  How do I convert a string to a Stream_Element?
> 
> 
> This is what I have:
> 
>   Out_String : constant String := "I like cake!";
>   Out_Data : Ada.Streams.Stream_Element_Array(1 .. 12);
> begin
> ...
>   for elem in 1 .. Out_Data'Length loop
>     Out_Data(Ada.Streams.Stream_Element_Offset(elem)) :=
>       Ada.Streams.Stream_Element(Character'Val(Out_String(elem)));
>   end loop;

I want to write this out to a receiver?

^ permalink raw reply	[relevance 0%]

* Re: Finding the end of a stream from a socket
  @ 2017-10-22 12:26  2%         ` Andrew Shvets
  2017-10-22 12:28  0%           ` Andrew Shvets
  2017-10-22 13:28  0%           ` Dmitry A. Kazakov
  0 siblings, 2 replies; 200+ results
From: Andrew Shvets @ 2017-10-22 12:26 UTC (permalink / raw)


On Saturday, October 21, 2017 at 3:19:36 PM UTC-4, Dmitry A. Kazakov wrote:
> On 2017-10-21 20:11, Dennis Lee Bieber wrote:
> > On Sat, 21 Oct 2017 06:45:22 -0700 (PDT), Andrew Shvets
> > <andr.....@gmail.com> declaimed the following:
> > 
> >>   GNAT.Sockets.Bind_Socket(Receiver, (GNAT.Sockets.Family_Inet, GNAT.Sockets.Inet_Addr("127.0.0.1"), 50000));
> >>   GNAT.Sockets.Listen_Socket(Receiver);
> >>
> > 	From those statements I'm guessing you are trying to set this program
> > up as a server, and have some other program which will connect to send data
> > to this one.
> > 
> >>   Ada.Text_IO.Put_Line(" !! TCP Server started !!");
> >>
> >>   loop
> >>     Ada.Text_IO.Put_Line(" FOO 1");
> >>     GNAT.Sockets.Connect_Socket(Receiver,  Client_Addr);
> > 
> > 	But here you are saying /this/ program is going to connect to a server
> > at (undefined) Client_Addr.
> > 
> > 	I suspect you really need to be using g.s.Accept_Socket() instead.
> 
> Also note that Accept_Socket will return another socket. This one you 
> should use for communication.
> 
> A typical scenario for blocking sockets:
> 
>     loop -- Connection listening
>        Accept_Socket -- Get communication socket
>        Start a new session task with the communication socket
>     end loop;
> 
> The session task deals with the connection using the socket returned by 
> Accept_Socket. Once the session is complete it closes that socket and 
> terminates.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

One more question.  How do I convert a string to a Stream_Element?


This is what I have:

  Out_String : constant String := "I like cake!";
  Out_Data : Ada.Streams.Stream_Element_Array(1 .. 12);
begin
...
  for elem in 1 .. Out_Data'Length loop
    Out_Data(Ada.Streams.Stream_Element_Offset(elem)) :=
      Ada.Streams.Stream_Element(Character'Val(Out_String(elem)));
  end loop;


^ permalink raw reply	[relevance 2%]

* Re: Finding the end of a stream from a socket
  2017-10-21 17:34  0%   ` Andrew Shvets
@ 2017-10-21 19:18  0%     ` Andrew Shvets
  0 siblings, 0 replies; 200+ results
From: Andrew Shvets @ 2017-10-21 19:18 UTC (permalink / raw)


On Saturday, October 21, 2017 at 1:34:15 PM UTC-4, Andrew Shvets wrote:
> On Saturday, October 21, 2017 at 4:44:42 AM UTC-4, Dmitry A. Kazakov wrote:
> > On 2017-10-21 04:05, Andrew Shvets wrote:
> > 
> > > I've been recently trying to make a small TCP server (a toy.) I have
> > > a channel that reads Characters and was trying to find the end of
> > > the stream. Reading the documentation, I came across the following
> > > in  g-socket.ads:
> > > 
> > > type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
> > > --  Same interface as Ada.Streams.Stream_IO
> > > 
> > > I was trying to have a way to find out when the last Character was 
> > > read from the stream. I could catch the Ada.IO_Exceptions.End_Error 
> > > exception, but I'm wondering if there is a better way.
> > 
> > End_Error is the best possible way, when applied. GNAT socket streams do 
> > not raise End_Error, AFAIK.
> > 
> > > while not Ada.Streams.Stream_IO.End_Of_File(Channel) loop
> > >    Character'Read(Channel, Received_Char);
> > >    Ada.Text_IO.Put(Received_Char);
> > > end loop;
> > 
> > This is a bad idea even when if it can work. In the case of sockets 
> > there is no file end. When the connection is closed by the peer the 
> > stream will stop both returning data and blocking. I suppose that will 
> > cause Constraint_Error in Character'Read.
> > 
> > In practice there is a higher level protocol on top of the socket 
> > stream, so that it is always known how many octets to read next.
> > 
> > Regarding your case, try this:
> > 
> >     Buffer : Stream_Element_Array (1..Buffer_Size);
> >     Last   : Stream_Element_Offset;
> > begin
> >     loop
> >        Receive_Socket (Socket, Buffer, Last);
> >        exit when Last < Buffer'First; -- Connection is closed by the peer
> >        for Octet in Buffer'First..Last loop -- Dump octets as-is
> >           Put (Character'Val (Buffer (Octet)));
> >        end loop;
> >     end loop;
> > 
> > -- 
> > Regards,
> > Dmitry A. Kazakov
> > http://www.dmitry-kazakov.de
> 
> Hi Dmitry,
> 
> This is my entire code.
> https://gist.github.com/anonymous/b7c3a5bdcd8c78453a643b6785573131

On this line:
GNAT.Sockets.Connect_Socket(Receiver,  Client_Addr);


I get the following exception:
!! TCP Server started !!
FOO 1

raised GNAT.SOCKETS.SOCKET_ERROR :[10022] Unknown system error


Weird, I thought, then I uncommented the Connect_Socket procedure call, since the socket is already being used to listen, it should be "connected".  When I did this, I got this error:

https://gist.github.com/anonymous/b79594f71309df87fc8fcc44bd6a28ee

What gets me, what is trying to connect from 0.0.0.0:0?  I have never seen or heard of this address being used.


^ permalink raw reply	[relevance 0%]

* Re: Finding the end of a stream from a socket
  2017-10-21  8:44  0% ` Dmitry A. Kazakov
  2017-10-21 13:45  0%   ` Andrew Shvets
@ 2017-10-21 17:34  0%   ` Andrew Shvets
  2017-10-21 19:18  0%     ` Andrew Shvets
  1 sibling, 1 reply; 200+ results
From: Andrew Shvets @ 2017-10-21 17:34 UTC (permalink / raw)


On Saturday, October 21, 2017 at 4:44:42 AM UTC-4, Dmitry A. Kazakov wrote:
> On 2017-10-21 04:05, Andrew Shvets wrote:
> 
> > I've been recently trying to make a small TCP server (a toy.) I have
> > a channel that reads Characters and was trying to find the end of
> > the stream. Reading the documentation, I came across the following
> > in  g-socket.ads:
> > 
> > type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
> > --  Same interface as Ada.Streams.Stream_IO
> > 
> > I was trying to have a way to find out when the last Character was 
> > read from the stream. I could catch the Ada.IO_Exceptions.End_Error 
> > exception, but I'm wondering if there is a better way.
> 
> End_Error is the best possible way, when applied. GNAT socket streams do 
> not raise End_Error, AFAIK.
> 
> > while not Ada.Streams.Stream_IO.End_Of_File(Channel) loop
> >    Character'Read(Channel, Received_Char);
> >    Ada.Text_IO.Put(Received_Char);
> > end loop;
> 
> This is a bad idea even when if it can work. In the case of sockets 
> there is no file end. When the connection is closed by the peer the 
> stream will stop both returning data and blocking. I suppose that will 
> cause Constraint_Error in Character'Read.
> 
> In practice there is a higher level protocol on top of the socket 
> stream, so that it is always known how many octets to read next.
> 
> Regarding your case, try this:
> 
>     Buffer : Stream_Element_Array (1..Buffer_Size);
>     Last   : Stream_Element_Offset;
> begin
>     loop
>        Receive_Socket (Socket, Buffer, Last);
>        exit when Last < Buffer'First; -- Connection is closed by the peer
>        for Octet in Buffer'First..Last loop -- Dump octets as-is
>           Put (Character'Val (Buffer (Octet)));
>        end loop;
>     end loop;
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Hi Dmitry,

This is my entire code.
https://gist.github.com/anonymous/b7c3a5bdcd8c78453a643b6785573131


^ permalink raw reply	[relevance 0%]

* Re: Finding the end of a stream from a socket
  2017-10-21  8:44  0% ` Dmitry A. Kazakov
@ 2017-10-21 13:45  0%   ` Andrew Shvets
    2017-10-21 17:34  0%   ` Andrew Shvets
  1 sibling, 1 reply; 200+ results
From: Andrew Shvets @ 2017-10-21 13:45 UTC (permalink / raw)


On Saturday, October 21, 2017 at 4:44:42 AM UTC-4, Dmitry A. Kazakov wrote:
> On 2017-10-21 04:05, Andrew Shvets wrote:
> 
> > I've been recently trying to make a small TCP server (a toy.) I have
> > a channel that reads Characters and was trying to find the end of
> > the stream. Reading the documentation, I came across the following
> > in  g-socket.ads:
> > 
> > type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
> > --  Same interface as Ada.Streams.Stream_IO
> > 
> > I was trying to have a way to find out when the last Character was 
> > read from the stream. I could catch the Ada.IO_Exceptions.End_Error 
> > exception, but I'm wondering if there is a better way.
> 
> End_Error is the best possible way, when applied. GNAT socket streams do 
> not raise End_Error, AFAIK.
> 
> > while not Ada.Streams.Stream_IO.End_Of_File(Channel) loop
> >    Character'Read(Channel, Received_Char);
> >    Ada.Text_IO.Put(Received_Char);
> > end loop;
> 
> This is a bad idea even when if it can work. In the case of sockets 
> there is no file end. When the connection is closed by the peer the 
> stream will stop both returning data and blocking. I suppose that will 
> cause Constraint_Error in Character'Read.
> 
> In practice there is a higher level protocol on top of the socket 
> stream, so that it is always known how many octets to read next.
> 
> Regarding your case, try this:
> 
>     Buffer : Stream_Element_Array (1..Buffer_Size);
>     Last   : Stream_Element_Offset;
> begin
>     loop
>        Receive_Socket (Socket, Buffer, Last);
>        exit when Last < Buffer'First; -- Connection is closed by the peer
>        for Octet in Buffer'First..Last loop -- Dump octets as-is
>           Put (Character'Val (Buffer (Octet)));
>        end loop;
>     end loop;
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Thanks for your reply.  I did what you recommended.


  loop
    begin
      GNAT.Sockets.Receive_Socket(Receiver, Buffer, Last);

      -- the connection was reset by peer.
      exit when Last < Buffer'First;

      for Octet in Buffer'First .. Last loop
        Ada.Text_IO.Put(Character'Val(Buffer(Octet)));
      end loop;
    exception
      when Ada.IO_Exceptions.End_Error =>
        Ada.Text_IO.Put_Line(Ada.Text_IO.Standard_Error, " ERROR: Issue encountered while receiving data from user.");
    end;
  end loop;


I get the following error when I make the Receive_Socket procedure call:

raised GNAT.SOCKETS.SOCKET_ERROR : [107] Transport endpoint is not connected


^ permalink raw reply	[relevance 0%]

* Re: Finding the end of a stream from a socket
  2017-10-21  2:05  2% Finding the end of a stream from a socket Andrew Shvets
@ 2017-10-21  8:44  0% ` Dmitry A. Kazakov
  2017-10-21 13:45  0%   ` Andrew Shvets
  2017-10-21 17:34  0%   ` Andrew Shvets
  0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-10-21  8:44 UTC (permalink / raw)


On 2017-10-21 04:05, Andrew Shvets wrote:

> I've been recently trying to make a small TCP server (a toy.) I have
> a channel that reads Characters and was trying to find the end of
> the stream. Reading the documentation, I came across the following
> in  g-socket.ads:
> 
> type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
> --  Same interface as Ada.Streams.Stream_IO
> 
> I was trying to have a way to find out when the last Character was 
> read from the stream. I could catch the Ada.IO_Exceptions.End_Error 
> exception, but I'm wondering if there is a better way.

End_Error is the best possible way, when applied. GNAT socket streams do 
not raise End_Error, AFAIK.

> while not Ada.Streams.Stream_IO.End_Of_File(Channel) loop
>    Character'Read(Channel, Received_Char);
>    Ada.Text_IO.Put(Received_Char);
> end loop;

This is a bad idea even when if it can work. In the case of sockets 
there is no file end. When the connection is closed by the peer the 
stream will stop both returning data and blocking. I suppose that will 
cause Constraint_Error in Character'Read.

In practice there is a higher level protocol on top of the socket 
stream, so that it is always known how many octets to read next.

Regarding your case, try this:

    Buffer : Stream_Element_Array (1..Buffer_Size);
    Last   : Stream_Element_Offset;
begin
    loop
       Receive_Socket (Socket, Buffer, Last);
       exit when Last < Buffer'First; -- Connection is closed by the peer
       for Octet in Buffer'First..Last loop -- Dump octets as-is
          Put (Character'Val (Buffer (Octet)));
       end loop;
    end loop;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Finding the end of a stream from a socket
@ 2017-10-21  2:05  2% Andrew Shvets
  2017-10-21  8:44  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Andrew Shvets @ 2017-10-21  2:05 UTC (permalink / raw)


Hello,

I've been recently trying to make a small TCP server (a toy.)  I have a channel that reads Characters and was trying to find the end of the stream.  Reading the documentation, I came across the following in g-socket.ads:


type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class; 
--  Same interface as Ada.Streams.Stream_IO


I was trying to have a way to find out when the last Character was read from the stream.  I could catch the Ada.IO_Exceptions.End_Error exception, but I'm wondering if there is a better way.


Channel       : GNAT.Sockets.Stream_Access;

....

while not Ada.Streams.Stream_IO.End_Of_File(Channel) loop
  Character'Read(Channel, Received_Char);
  Ada.Text_IO.Put(Received_Char);
end loop;





Many thank yous in advance for your help!


^ permalink raw reply	[relevance 2%]

* Re: NTP
  @ 2017-09-16  9:29  1% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-09-16  9:29 UTC (permalink / raw)


On 2017-09-16 08:40, Anatoly Chernyshev wrote:

> Is there a way to get time via the Network Time Protocol in Ada? It
> doesn't look like AWS has it (or I've missed something).
> 
> Currently I'm getting around spawning the Cygwin "nc" command, but it hurts my feelings.

Do you mean send a single UDP request to an NTP server and convert the 
response to Ada time?

You can try this:
----------------------------------------------------------------------
with Ada.Text_IO;              use Ada.Text_IO;
with Ada.Calendar;             use Ada.Calendar;
with Ada.Calendar.Formatting;  use Ada.Calendar.Formatting;
with Ada.Exceptions;           use Ada.Exceptions;
with Ada.Streams;              use Ada.Streams;
with GNAT.Sockets;             use GNAT.Sockets;
with Interfaces;               use Interfaces;

procedure Test is

    function Get_NTP_Time
             (  Server  : String;
                Timeout : Timeval_Duration := 10.0
             )  return Time is
       NTP_Packet_Size : constant := 48;
          -- RFC 5905: Official NTP era begins at 1 Jan 1900. We cannot
          -- have it in Ada.Calendar.Time, so taking a later time. Note
          -- Time_Zone = 0 in order to have it UTC
       Era : constant Time := Time_Of (1999, 12, 31, Time_Zone => 0);
          -- RFC 5905: seconds since 1 Jan 1900 to 31 Dec 1999
       Era_Offset : constant := 3_155_587_200;

       Socket   : Socket_Type;
       Address  : Sock_Addr_Type;
       Seconds  : Unsigned_32;
       Fraction : Unsigned_32;
       Last     : Stream_Element_Offset;
       Data     : Stream_Element_Array (1..NTP_Packet_Size) :=
                     (  1  => 2#1110_0011#, -- LI, Version, Mode
                        2  => 0,            -- Stratum, or type of clock
                        3  => 0,            -- Polling Interval
                        4  => 16#EC#,       -- Peer Clock Precision
                        13 => 49,
                        14 => 16#4E#,
                        15 => 49,
                        16 => 52,
                        others => 0
                     );
    begin
       Address.Addr := Addresses (Get_Host_By_Name (Server), 1);
       Address.Port := 123; -- NTP port
       Create_Socket (Socket, Family_Inet, Socket_Datagram);
       Set_Socket_Option
       (  Socket,
          Socket_Level,
          (Receive_Timeout, Timeout)
       );
       Send_Socket (Socket, Data, Last, Address);
       Receive_Socket (Socket, Data, Last, Address);
       if Last /= Data'Last then
          Raise_Exception (Data_Error'Identity, "Mangled response");
       end if;
       Seconds := (  Unsigned_32 (Data (41)) * 2**24
                  +  Unsigned_32 (Data (42)) * 2**16
                  +  Unsigned_32 (Data (43)) * 2**8
                  +  Unsigned_32 (Data (44))
                  -  Era_OFfset
                  );
       Fraction := (  Unsigned_32 (Data (45)) * 2**24
                   +  Unsigned_32 (Data (46)) * 2**16
                   +  Unsigned_32 (Data (47)) * 2**8
                   +  Unsigned_32 (Data (48))
                   );
       return (  Era
              +  Duration (Seconds)
         --     +  Duration (Long_Float (Fraction) / 2.0**32)
              );
    end Get_NTP_Time;

    Stamp : Time;
begin
    Stamp := Get_NTP_Time ("time.nist.gov");
    Put_Line ("NTP time " & Image (Stamp));
exception
    when Error : others =>
       Put_Line ("Error: " & Exception_Information (Error));
end Test;
-------------------------------------------------------------------

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* Re: use Ada.Text_IO in main() or Package?
  @ 2017-09-14  9:49  1%         ` gautier_niouzes
  0 siblings, 0 replies; 200+ results
From: gautier_niouzes @ 2017-09-14  9:49 UTC (permalink / raw)


Le jeudi 14 septembre 2017 11:37:41 UTC+2, Mace Ayres a écrit :
> Tks. It does make sense. I haven't been programming much in last decades, never really go into OOP much, but I can see this is going to avoid a lot of issues, and enforces some rigor.

Actually it is just a question of what is depending on what.
Instead of Structures, you can take Ada.Text_IO itself as an example.
In the guts of package Ada.Text_IO, the GNAT run-time library has a package body file: a-textio.adb) with the following lines:

    with Ada.Streams;             use Ada.Streams;
    with Interfaces.C_Streams;    use Interfaces.C_Streams;

    with System.File_IO;
    with System.CRTL;
    with System.WCh_Cnv;          use System.WCh_Cnv;
    with System.WCh_Con;          use System.WCh_Con;

    with Ada.Unchecked_Conversion;
    with Ada.Unchecked_Deallocation;

It makes sense they are there and not expected to be in any Main() or any other referencing Ada.Text_IO.
I've never used System.File_IO for instance and would not: it is GNAT only and unknown in other Ada systems. And there is no need for that.
G.

^ permalink raw reply	[relevance 1%]

* Re: quiz for Sequential_IO Read
  2017-09-04 19:58  2%       ` Frank Buss
@ 2017-09-04 20:55  0%         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-09-04 20:55 UTC (permalink / raw)


On 2017-09-04 21:58, Frank Buss wrote:
> On 09/03/2017 03:11 PM, Dmitry A. Kazakov wrote:
>>
>> In practice Stream I/O is a better choice. You also should not use
>> compiler-generated serialization attributes (see T'Read, T'Write,
>> T'Input, T'Output attributes). These are not portable either. You should
>> always replace them with your own.
> 
> Ok, I wrote my program with Stream_IO. It will be reading from a FIFO 
> file for receiving MIDI signals, and then write to a sound device 
> continuously. I found a convenient package which defines low-level types 
> of fixed size, same as stdint.h in C. See below for the code. Would this 
> be portable on all systems (assuming they provide FIFO files) ?

You probably mean a pipe here?

> At least 
> it works on my Debian system so far.
> 
> 
> with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
> with Ada.Text_IO; use Ada.Text_IO;
> with Interfaces; use Interfaces;
> 
> procedure Hello is
> 
>     Data : Unsigned_8;
>     Input_File : Ada.Streams.Stream_IO.File_Type;
>     Input_Stream : Ada.Streams.Stream_IO.Stream_Access;
> 
>     task Main_Task is
>        entry Data_Received(Data : in Unsigned_8);
>     end Main_Task;
> 
>     task body Main_Task is
>     begin
>        loop
>           select
>              accept Data_Received(Data : in Unsigned_8) do
>                 Put("test: " & Unsigned_8'Image(Data));
>                 New_Line;
>              end Data_Received;
>           else
>              delay 0.1;

To avoid biased time error you should use "delay until" instead:

    delay until Last_Time + 0.1;
    Last_Time := Last_Time + 0.1;

And it is not a good idea to pass each octet to the task. A better 
design is to have a FIFO (ring buffer) to be filled by one task and read 
by another. It can be the same task as well.

>              -- TODO: create continuous sound output here
>           end select;
>        end loop;
>     end Main_Task;
> 
> begin
>     Open(Input_File, In_File, "/home/frank/midi");
>     Input_Stream := Stream(Input_File);
>     loop
>        Unsigned_8'Read(Input_Stream, Data);

Then you can read stream by pieces rather element by element. E.g.

    Buffer : Stream_Element_Array (1..Buffer_Size);
    Last   : Stream_Element_OFfset;
    ...

    Input_Stream.Read (Buffer, Last); -- Read available data
                                      -- Buffer (1..Last) is
                                      -- the data read

If you have FIFO to communicate with the task. It also can server as 
the input buffer. And you will simply read into the space between 
In_Index of the FIFO and either the FIFO's end index or Out_Index - 1, 
assuming FIFO is a ring buffer. You can use slice to do this:

    FIFO      : Stream_Element_Array (1..Buffer_Size);
    In_Index  : Stream_Element_Offset := 1; -- The index to write at
    Out_Index : Stream_Element_Offset := 1; -- The index to get data at

    ...
    if In_Index < Out_Index then
       Input_Stream.Read (FIFO (In_Index..Out_Index - 1), Last);
       In_Index := Last + 1;
    else
       Input_Stream.Read (FIFO (In_Index..FIFO'Last), Last);
       if Last = FIFO'Last then -- wrap
          In_Index := FIFO'First;
       else
          In_Index := Last + 1;
       end if;
    end if;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: quiz for Sequential_IO Read
  2017-09-03 13:11  0%     ` Dmitry A. Kazakov
@ 2017-09-04 19:58  2%       ` Frank Buss
  2017-09-04 20:55  0%         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Frank Buss @ 2017-09-04 19:58 UTC (permalink / raw)


On 09/03/2017 03:11 PM, Dmitry A. Kazakov wrote:
>
> In practice Stream I/O is a better choice. You also should not use
> compiler-generated serialization attributes (see T'Read, T'Write,
> T'Input, T'Output attributes). These are not portable either. You should
> always replace them with your own.

Ok, I wrote my program with Stream_IO. It will be reading from a FIFO 
file for receiving MIDI signals, and then write to a sound device 
continuously. I found a convenient package which defines low-level types 
of fixed size, same as stdint.h in C. See below for the code. Would this 
be portable on all systems (assuming they provide FIFO files) ? At least 
it works on my Debian system so far.


with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;

procedure Hello is

    Data : Unsigned_8;
    Input_File : Ada.Streams.Stream_IO.File_Type;
    Input_Stream : Ada.Streams.Stream_IO.Stream_Access;

    task Main_Task is
       entry Data_Received(Data : in Unsigned_8);
    end Main_Task;

    task body Main_Task is
    begin
       loop
          select
             accept Data_Received(Data : in Unsigned_8) do
                Put("test: " & Unsigned_8'Image(Data));
                New_Line;
             end Data_Received;
          else
             delay 0.1;
             -- TODO: create continuous sound output here
          end select;
       end loop;
    end Main_Task;

begin
    Open(Input_File, In_File, "/home/frank/midi");
    Input_Stream := Stream(Input_File);
    loop
       Unsigned_8'Read(Input_Stream, Data);
       Main_Task.Data_Received(Data);
    end loop;
end;


-- 
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss


^ permalink raw reply	[relevance 2%]

* Re: quiz for Sequential_IO Read
  2017-09-03 12:43  0%   ` Frank Buss
@ 2017-09-03 13:11  0%     ` Dmitry A. Kazakov
  2017-09-04 19:58  2%       ` Frank Buss
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2017-09-03 13:11 UTC (permalink / raw)


On 2017-09-03 14:43, Frank Buss wrote:
> On 09/03/2017 02:26 PM, Dmitry A. Kazakov wrote:
>> On 2017-09-03 13:01, Frank Buss wrote:
>>> What does this program output?
>>
>> Garbage.
>>
>>> with Ada.Sequential_IO;
>>> with Ada.Text_IO; use Ada.Text_IO;
>>>
>>> procedure Hello is
>>>
>>>     type Byte is range 0..255;
>>>
>>>     package Byte_IO is new Ada.Sequential_IO(Byte);
>>
>> Ada.Streams.Stream_IO is for the purpose.
>>
>> (Sequential_IO is practically never used)
> 
> I started learning Ada today,

Great!

> where can I read about good coding 
> practice, and how would the example look like with Stream_IO, and maybe 
> even a correct version?
> 
> I read about Sequential_IO in the Ada Programming wikibook, where it is 
> recommended for homogeneous binary data:
> 
> https://en.wikibooks.org/wiki/Ada_Programming/Input_Output

Well, Sequential_IO is not recommended because:

1. It would make your program non-portable;
2. It would hinder interoperability with programs written on other 
languages;
3. It requires homogeneous data, which is never the case in real life
4. It limits I/O to files

In practice Stream I/O is a better choice. You also should not use 
compiler-generated serialization attributes (see T'Read, T'Write, 
T'Input, T'Output attributes). These are not portable either. You should 
always replace them with your own.

P.S. Sequential_IO was introduced in Ada 83. A lot of things changed 
since then.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: quiz for Sequential_IO Read
  2017-09-03 12:26  1% ` Dmitry A. Kazakov
@ 2017-09-03 12:43  0%   ` Frank Buss
  2017-09-03 13:11  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Frank Buss @ 2017-09-03 12:43 UTC (permalink / raw)


On 09/03/2017 02:26 PM, Dmitry A. Kazakov wrote:
> On 2017-09-03 13:01, Frank Buss wrote:
>> What does this program output?
>
> Garbage.
>
>> with Ada.Sequential_IO;
>> with Ada.Text_IO; use Ada.Text_IO;
>>
>> procedure Hello is
>>
>>     type Byte is range 0..255;
>>
>>     package Byte_IO is new Ada.Sequential_IO(Byte);
>
> Ada.Streams.Stream_IO is for the purpose.
>
> (Sequential_IO is practically never used)

I started learning Ada today, where can I read about good coding 
practice, and how would the example look like with Stream_IO, and maybe 
even a correct version?

I read about Sequential_IO in the Ada Programming wikibook, where it is 
recommended for homogeneous binary data:

https://en.wikibooks.org/wiki/Ada_Programming/Input_Output

-- 
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss

^ permalink raw reply	[relevance 0%]

* Re: quiz for Sequential_IO Read
  @ 2017-09-03 12:26  1% ` Dmitry A. Kazakov
  2017-09-03 12:43  0%   ` Frank Buss
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2017-09-03 12:26 UTC (permalink / raw)


On 2017-09-03 13:01, Frank Buss wrote:
> What does this program output?

Garbage.

> with Ada.Sequential_IO;
> with Ada.Text_IO; use Ada.Text_IO;
> 
> procedure Hello is
> 
>     type Byte is range 0..255;
> 
>     package Byte_IO is new Ada.Sequential_IO(Byte);

Ada.Streams.Stream_IO is for the purpose.

(Sequential_IO is practically never used)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* Re: win32 interfacing check (SetClipboardData)
  2017-09-02  9:38  0%           ` Xavier Petit
@ 2017-09-02 12:29  0%             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-09-02 12:29 UTC (permalink / raw)


On 2017-09-02 11:38, Xavier Petit wrote:
> Le 01/09/2017 à 15:10, Dmitry A. Kazakov a écrit :
>> On 01/09/2017 14:51, Xavier Petit wrote:
>>> Thanks but even with Set_Clipboard 
>>> (Ada.[Wide_]Wide_Text_IO.Get_Line); I was getting weird clipboard 
>>> text without -gnatW8 flag.
>>
>> But these are not UTF-8! They are UCS-2 and UCS-4.
> Yes but having a look at :
> https://gcc.gnu.org/onlinedocs/gnat_ugn/Character-Set-Control.html
> https://gcc.gnu.org/onlinedocs/gnat_ugn/Wide_005fCharacter-Encodings.html
> https://gcc.gnu.org/onlinedocs/gnat_ugn/Wide_005fWide_005fCharacter-Encodings.html 

These about the source code encoding not about run-time I/O.

> So it means Get_Line returns a Wide_Wide_String without the USC-4 
> encoding ? because Encode doesn't return UTF-(8/16) encoding without the 
> flag.

It depends on the input file. Get_Line will work only if the text file 
you are reading from is UCS-4 encoded. Where did you get such files?

AFAIK, GNAT implementation supports the Form parameter in Open, where 
you can specify the file encoding if that is different from the string 
encoding, e.g. UTF-8 when Wide_Wide_Text_IO deals with UCS-4. I suppose 
that should recode the input into the designated string encoding. 
However I never tried this and do not intend to.

>> If you have a UTF-8 encoded file (e.g. created using Notepad++, saved 
>> without BOM), you should use Ada.Streams.Stream_IO, best in binary 
>> mode if you are using GNAT.
>>
>> You will have to detect line ends manually, but at least there will be 
>> guaranty that the run-time does not mangle anything.
> Ok, “binary mode”, do you mean using Stream_Element_Array ?
> 
>> If you are using Windows calls with the "W" suffix, then all strings 
>> there are already UTF-16 and you don't need to convert anything.
> Ok, if I stay with win32 functions, I'll get only UTF-16, if I mess with 
> external text sources (like files) or Ada standard, I'll deal with 
> others text encoding formats like UTF-8, UCS-2, etc...

When dealing with external files I read them using Stream_IO and recode 
manually to UTF-8 if necessary. Luckily in the recent time the supply of 
files encoded in Latin-1, UCS-2 and other increasingly idiotic formats 
is almost depleted. So there is little to worry about...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: win32 interfacing check (SetClipboardData)
  2017-09-01 13:10  1%         ` Dmitry A. Kazakov
@ 2017-09-02  9:38  0%           ` Xavier Petit
  2017-09-02 12:29  0%             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Xavier Petit @ 2017-09-02  9:38 UTC (permalink / raw)


Le 01/09/2017 à 15:10, Dmitry A. Kazakov a écrit :
> On 01/09/2017 14:51, Xavier Petit wrote:
>> Thanks but even with Set_Clipboard (Ada.[Wide_]Wide_Text_IO.Get_Line); 
>> I was getting weird clipboard text without -gnatW8 flag.
> 
> But these are not UTF-8! They are UCS-2 and UCS-4.
Yes but having a look at :
https://gcc.gnu.org/onlinedocs/gnat_ugn/Character-Set-Control.html
https://gcc.gnu.org/onlinedocs/gnat_ugn/Wide_005fCharacter-Encodings.html
https://gcc.gnu.org/onlinedocs/gnat_ugn/Wide_005fWide_005fCharacter-Encodings.html

It appears that without the -gnatW8 flag, "Brackets Coding" is the default :
- “In this encoding, a wide character is represented by the following 
eight character sequence: [...]”
- “In this encoding, a wide wide character is represented by the 
following ten or twelve byte character sequence”

...and with the flag, "UTF-8 Coding" is used : “A wide character is 
represented using UCS Transformation Format 8 (UTF-8)”

I think I'm still missing something because one thing is sure :
Ada.Strings.UTF_Encoding.Wide_Wide_String.Encode 
(Ada.Wide_Wide_Text_IO.Get_Line) doesn't not work without the UTF-8 flag...

 From UTF_Encoding.Wide_Wide_Strings package :
“
The encoding routines take a Wide_Wide_String as input and encode the
result using the specified UTF encoding method.
Encode Wide_Wide_String using UTF-8 encoding
Encode Wide_Wide_String using UTF_16 encoding
”
So it means Get_Line returns a Wide_Wide_String without the USC-4 
encoding ? because Encode doesn't return UTF-(8/16) encoding without the 
flag.

> ([Wide_]Wide_Text_IO should never be used, there is no single case one 
> would need these.)
yeah I'm gonna try not to use the Wide_Wide packages, one thing I liked 
with Wide_Wide_String is the correct 'Length attribute.

> If you have a UTF-8 encoded file (e.g. created using Notepad++, saved 
> without BOM), you should use Ada.Streams.Stream_IO, best in binary mode 
> if you are using GNAT.
> 
> You will have to detect line ends manually, but at least there will be 
> guaranty that the run-time does not mangle anything.
Ok, “binary mode”, do you mean using Stream_Element_Array ?

> If you are using Windows calls with the "W" suffix, then all strings 
> there are already UTF-16 and you don't need to convert anything.
Ok, if I stay with win32 functions, I'll get only UTF-16, if I mess with 
external text sources (like files) or Ada standard, I'll deal with 
others text encoding formats like UTF-8, UCS-2, etc...

^ permalink raw reply	[relevance 0%]

* Re: win32 interfacing check (SetClipboardData)
  @ 2017-09-01 13:10  1%         ` Dmitry A. Kazakov
  2017-09-02  9:38  0%           ` Xavier Petit
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2017-09-01 13:10 UTC (permalink / raw)


On 01/09/2017 14:51, Xavier Petit wrote:
> Thanks but even with Set_Clipboard (Ada.[Wide_]Wide_Text_IO.Get_Line); I 
> was getting weird clipboard text without -gnatW8 flag.

But these are not UTF-8! They are UCS-2 and UCS-4.

([Wide_]Wide_Text_IO should never be used, there is no single case one 
would need these.)

If you have a UTF-8 encoded file (e.g. created using Notepad++, saved 
without BOM), you should use Ada.Streams.Stream_IO, best in binary mode 
if you are using GNAT.

You will have to detect line ends manually, but at least there will be 
guaranty that the run-time does not mangle anything.

If you are using Windows calls with the "W" suffix, then all strings 
there are already UTF-16 and you don't need to convert anything.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 1%]

* Re: T'Interface attribute
  2017-08-03  7:26  1%   ` Dmitry A. Kazakov
@ 2017-08-04 23:51  0%     ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2017-08-04 23:51 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:oluj7t$8uo$1@gioia.aioe.org...
> On 2017-08-03 06:46, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:olskua$1bfd$1@gioia.aioe.org...
>>> In order to reduce name space contamination I would propose attribute
>>> T'Interface which for any tagged type T would denote an interface type
>>> with all *new* primitive operations, e.g.
>>
>> Past experience say that such attributes (that is, those that designate 
>> some
>> sort of type or subtype) don't work out very well in Ada. For instance, 
>> we
>> considered T'Access in Ada 2005, but gave that up because of various
>> problems (and replaced with with anonymous access types, which are 
>> worse).
>> The worst problem was that there was no limit to the attribute, you could
>> write T'Access'Access'Access - and you can't prevent this since T could 
>> be a
>> generic formal type that itself is some T'Access.
>
> In this case generic would not be a problem because T must be tagged to 
> have T'Interface.
>
> As a side note, differently to 'Access, 'Length and actually 'Class, 
> 'Interface is idempotent:
>
>    T'Interface ::= T'Interface'Interface

Ada defines 'Class this way, too, I think in part to mitigate these 
problems.

The problem with formals is from the actual being T'Interface:

    generic
       type T is abstract tagged private;
    package Gen is
        procedure P (Item : in T'Interface);
    end Gen;

    package Inst is new Gen (Some_Tagged_Type'Interface);

The parameter of P is essentially Some_Tagged_Type'Interface'Interface.

>> Almost all Ada compilers materialize all Ada types in their symbol table, 
>> so
>> the effect of having a T'Interface would be that it would be 
>> automatically
>> declared for all tagged type declarations. Most Ada compilers also
>> materialize all of the primitive operations in their symbol table, so 
>> there
>> would be a large increase in memory usage and some time increase (all
>> lookups would have twice as many primitives to look through).
>
> This is an intended effect. Yes, there would likely be two tags for each 
> declared type.
>
> Which by the way will fix Ada.Streams and System.Storage_Pools design for 
> free. Since we will finally have:
>
>    Root_Stream_Type'Interface
>
> and
>
>    Root_Storage_Pool'Interface
>
> E.g.
>
>    type Serialized_Widget is
>       new Gtk_Widget_Record and Root_Stream_Type'Interface with private;

The problem with "fixing" Root_Stream_Type etc. is the "no hidden 
interfaces" rule. These types are often used in private derivations, and 
that is illegal for interfaces. (Attempts to weaken the "no hidden 
interfaces" rule have led to various definitional nightmares - it does not 
look likely. AI12-0023-1 discusses the latest attempts - it's still open but 
hasn't been discussed since Stockholm.)

That suggests a problem with this idea: effectivelly all types would have an 
associated interface. But interfaces can never be hidden (certainly not 
without restrictions as discussed in AI12-0023-1), so that would seem to 
imply that no hidden type derivations could occur. That would be a massive 
compatibility problem.

>> P.S. And as always, explain the problem to be solved as well as the 
>> possible
>> solution. That is always necessary to understand the value of a proposal.
>
> I have a design rule to have an explicit interface declared for each 
> tagged type. It saves much of redesign later.

I've generally materialized that as "the root of an abstraction should 
always be declared abstract".

>> P.P.S. I personally have never seen a real-world example where an 
>> interface
>> actually helps. There's lots and lots of book examples and show examples 
>> and
>> so on, but in practice you end up with only a single implementation so 
>> there
>> really is nothing gained by involving a lot of dispatching calls. Ergo, 
>> I'm
>> against anything (new) involving interfaces. YMMV.
>
> I have no idea how you manage keep Claw out of interfaces, really. 
> Multiple inheritance is a huge help and relief. I am using interfaces 
> extensively unless backward Ada 95 compatibility hinders me. E.g. in AICWL 
> all widget layers implement interfaces like Scalable_Layer, Gauge_Needle, 
> Waveform_Amplifier etc. It would not work otherwise.

In Claw, the only places that we got much benefit from OOP (beyond 
dispatching callbacks, the reason we used OOP in the first place) was in 
sharing implementations across related types. But that doesn't work for Ada 
interfaces, because you can't have any components in the type -- meaning 
that writing real implementations is impossible. One can use abstract types 
in this way (and we did so extensively).

We didn't find much use for dispatching (outside of the callbacks as 
previously mentioned; those only need to work on root types since they come 
directly from the message loop engine). If you don't need (or can use) 
dispatching, and since you can't use implementation inheritance, the use of 
interfaces buys nothing.

(Of course, we didn't have interfaces when Claw was designed, so it wasn't 
even an option. Perhaps we'd have done something differently had they been 
available -- but I doubt it.)

That pattern has persisted in pretty much all of my recent programs; I don't 
usually have very deep hierarchies and dispatching is limited to the root 
types (which I declare abstract for maximum sharing).

I realize other people end up with other patterns, but I'm not going to 
champion something I don't find useful. (I doubt I could do a good job of 
championing it anyway).

                                       Randy.



^ permalink raw reply	[relevance 0%]

* Re: T'Interface attribute
  @ 2017-08-03  7:26  1%   ` Dmitry A. Kazakov
  2017-08-04 23:51  0%     ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2017-08-03  7:26 UTC (permalink / raw)


On 2017-08-03 06:46, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:olskua$1bfd$1@gioia.aioe.org...
>> In order to reduce name space contamination I would propose attribute
>> T'Interface which for any tagged type T would denote an interface type
>> with all *new* primitive operations, e.g.
> 
> Past experience say that such attributes (that is, those that designate some
> sort of type or subtype) don't work out very well in Ada. For instance, we
> considered T'Access in Ada 2005, but gave that up because of various
> problems (and replaced with with anonymous access types, which are worse).
> The worst problem was that there was no limit to the attribute, you could
> write T'Access'Access'Access - and you can't prevent this since T could be a
> generic formal type that itself is some T'Access.

In this case generic would not be a problem because T must be tagged to 
have T'Interface.

As a side note, differently to 'Access, 'Length and actually 'Class, 
'Interface is idempotent:

    T'Interface ::= T'Interface'Interface

> Almost all Ada compilers materialize all Ada types in their symbol table, so
> the effect of having a T'Interface would be that it would be automatically
> declared for all tagged type declarations. Most Ada compilers also
> materialize all of the primitive operations in their symbol table, so there
> would be a large increase in memory usage and some time increase (all
> lookups would have twice as many primitives to look through).

This is an intended effect. Yes, there would likely be two tags for each 
declared type.

Which by the way will fix Ada.Streams and System.Storage_Pools design 
for free. Since we will finally have:

    Root_Stream_Type'Interface

and

    Root_Storage_Pool'Interface

E.g.

    type Serialized_Widget is
       new Gtk_Widget_Record and Root_Stream_Type'Interface with private;

> P.S. And as always, explain the problem to be solved as well as the possible
> solution. That is always necessary to understand the value of a proposal.

I have a design rule to have an explicit interface declared for each 
tagged type. It saves much of redesign later.

> P.P.S. I personally have never seen a real-world example where an interface
> actually helps. There's lots and lots of book examples and show examples and
> so on, but in practice you end up with only a single implementation so there
> really is nothing gained by involving a lot of dispatching calls. Ergo, I'm
> against anything (new) involving interfaces. YMMV.

I have no idea how you manage keep Claw out of interfaces, really. 
Multiple inheritance is a huge help and relief. I am using interfaces 
extensively unless backward Ada 95 compatibility hinders me. E.g. in 
AICWL all widget layers implement interfaces like Scalable_Layer, 
Gauge_Needle, Waveform_Amplifier etc. It would not work otherwise.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 1%]

* Re: Smart Pointers and Tagged Type Hierarchies
  2017-07-24 15:41  1% Smart Pointers and Tagged Type Hierarchies Felix Krause
@ 2017-07-24 21:24  0% ` Chris Moore
  0 siblings, 0 replies; 200+ results
From: Chris Moore @ 2017-07-24 21:24 UTC (permalink / raw)


On 24/07/2017 16:41, Felix Krause wrote:
> With Ada's controlled types, it is possible to implement smart pointers 
> which manage heap objects with reference-counting. There is more than 
> one tutorial showing how that works.
> 
> A problem I encounter is how this can be used with type hierarchies i.e. 
> I have a smart pointer managing a tagged type, and I want to be able to 
> derive from that tagged type and still be able to use my smart pointer 
> with that new type. Let me give an example: Assume I want to implement 
> an abstract type Stream that represents a stream of events (has nothing 
> to do with Ada.Streams). I will use a slightly modified Rosen '95 name 
> scheme here for clarity: Reference is the smart pointer, Instance is the 
> actual object. Let this be the base type:
> 
<snip>
> 
> Some observations:
> 
> * Unless all implementations are child classes of Stream, it is 
> necessary to make the Instance type public.

Obv.

> * A derived type, if it wants to provide additional operations (like 
> Current_Position), must not only derive from Instance, but also from 
> Reference, to be able to provide an type-safe interface to those 
> operations.

Why?  All ops on Instance-derived types (including constructing 
subprograms) should be in terms of that type.  References are for access 
only (ho ho).

> * As types derived from Stream possibly need to derive Stream.Reference, 
> a consumer of a Stream object needs to take a Stream.Reference'Class as 
> input. This type cannot be used for a record field, so I need to 
> allocate it in heap memory and store a pointer if I want to memorize a 
> Stream.Reference value anywhere.

No.  This way lies madness.  A parallel hierarchy of References gains 
you very little and takes a lot of maintenance.

> * The implementation of Current_Position is cumbersome as I need the 
> Implementation_Access function and convert the result to 
> File_Stream.Instance, which creates a needless downcast check.

The downcast has to go *somewhere*.

<snip generic version>

I had to do this kind of thing a great deal in the Ada version of the 
mal lisp interpreter.  See for example:

https://github.com/zmower/mal/blob/master/ada/smart_pointers.ads
https://github.com/zmower/mal/blob/master/ada/types.ads

But my advice is to avoid tagged types if you can.  They only make sense 
if your problem is wildly dynamic or you want to be lazy when thinking 
about memory allocation.  mal qualified on both counts.


^ permalink raw reply	[relevance 0%]

* Smart Pointers and Tagged Type Hierarchies
@ 2017-07-24 15:41  1% Felix Krause
  2017-07-24 21:24  0% ` Chris Moore
  0 siblings, 1 reply; 200+ results
From: Felix Krause @ 2017-07-24 15:41 UTC (permalink / raw)


With Ada's controlled types, it is possible to implement smart pointers 
which manage heap objects with reference-counting. There is more than 
one tutorial showing how that works.

A problem I encounter is how this can be used with type hierarchies 
i.e. I have a smart pointer managing a tagged type, and I want to be 
able to derive from that tagged type and still be able to use my smart 
pointer with that new type. Let me give an example: Assume I want to 
implement an abstract type Stream that represents a stream of events 
(has nothing to do with Ada.Streams). I will use a slightly modified 
Rosen '95 name scheme here for clarity: Reference is the smart pointer, 
Instance is the actual object. Let this be the base type:

    package Stream is
       type Reference is new Ada.Finalization.Controlled with private;

       type Instance is abstract tagged limited private;
       type Instance_Pointer is access all Instance'Class;

       --  reference-counting implementation here
       overriding procedure Adjust (Object : in out Reference);
       overriding procedure Finalize (Object : in out Reference);

       --  fetches an event from the stream
       procedure Fetch (Object : in out Instance; Ret : out Event) is abstract;

       --  initialize the smart pointer with an object.
       --  the smart pointer takes control of that object and will 
deallocate it
       --  when reference count reaches zero.
       procedure Init (Object : in out Reference'Class; Impl : 
Instance_Pointer);

       function Implementation_Access (Object : Reference'Class) return 
Instance_Pointer;

       --  is called before deleting the instance. override if you have 
cleanup to do.
       procedure Finalize (Object : in out Instance) is null;
    private
       type Reference is new Ada.Finalization.Controlled with record
          Impl : Instance_Pointer;
       end record;

       type Instance is abstract tagged limited record
          Refcount : Natural := 1;
       end record;
    end Stream;

An example non-abstract type derived from this would be stream that 
reads events from a file:

    package File_Stream is
       type Reference is new Stream.Reference with null record;

       procedure Init (Object : in out Reference; Path : String);

       --  fetches the current position within the file
       procedure Current_Position (Object : in out Reference; Line, 
Column : out Positive);
    private
       type Instance is new Instance with record
          File : Ada.Text_IO.File_Access;
          --  possibly other fields, e.g. information needed for 
Current_Position
       end record;

       --  closes the file
       overriding procedure Finalize (Object : in out Instance);
    end File_Stream;

Some observations:

 * Unless all implementations are child classes of Stream, it is 
necessary to make the Instance type public.
 * A derived type, if it wants to provide additional operations (like 
Current_Position), must not only derive from Instance, but also from 
Reference, to be able to provide an type-safe interface to those 
operations.
 * As types derived from Stream possibly need to derive 
Stream.Reference, a consumer of a Stream object needs to take a 
Stream.Reference'Class as input. This type cannot be used for a record 
field, so I need to allocate it in heap memory and store a pointer if I 
want to memorize a Stream.Reference value anywhere.
 * The implementation of Current_Position is cumbersome as I need the 
Implementation_Access function and convert the result to 
File_Stream.Instance, which creates a needless downcast check.

I think this is not an ideal interface for the user and I am searching 
for a better alternative. One thing I thought of is having a generic 
pointer, so that only the Instance is tagged:

    package Stream is
       type Instance is abstract limited tagged private;

       --  fetches an event from the stream
       procedure Fetch (Object : in out Instance; Ret : out Event) is abstract;
    private
       type Instance is abstract tagged limited record
          Refcount : Natural := 1;
       end record;
    end Stream;

    generic
       type Implementation is new Stream.Instance with private;
    package Stream.Smart is
       type Reference is new Ada.Finalization.Controlled with private;

       --  reference-counting implementation
       overriding procedure Adjust (Object : in out Reference);
       overriding procedure Finalize (Object : in out Reference);
    private
       type Implementation_Access is access all Implementation'Class;

       type Reference is new Ada.Finalization.Controlled with record
          Data : access Implementation_Access;
       end record;
    end Stream.Smart;

This looks good at first glance. But now, all consumers of a Stream 
must also be generic and take an instance of the Smart package as 
generic parameter (at least if I want them to take the smart pointer 
and not Instance_Pointer as parameter, which is kind of the point).

Now I am wondering what others think of these approaches. Are there 
alternatives? Which one would be better from a user perspective?

-- 
Regards,
Felix Krause


^ permalink raw reply	[relevance 1%]

* Re: How to check syntax with GNAT?
  @ 2017-07-13  5:47  1% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-07-13  5:47 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> $ make my-check 
> gnatmake -p -Plibrdf.gpr \
>                  -XLIBRARY_KIND=static -XOBJ_DIR=./obj-static -
> Xsoversion=librdf-ada.so.2.0.14 -XMODE=Install -XDEBUG_MODE=check
> gnatgcc -c -gnatc -gnat2012 -gnatc rdf-raptor-bnode.adb
> ...
> gprlib rdf-ada.lexch
> ar cr /home/porton/Projects/redland-bindings/ada/lib/librdf-ada.a 
> /home/porton/Projects/redland-bindings/ada/obj-static/rdf-raptor-bnode.o 
> /home/porton/Projects/redland-bindings/ada/obj-static/rdf-raptor-iostream.o 
> ...
> /usr//bin/ar: /home/porton/Projects/redland-bindings/ada/obj-static/rdf-
> raptor-bnode.o: No such file or directory
> gprlib: call to archive builder /usr//bin/ar failed
> gprbuild: could not build library for project librdf
> gnatmake: objects up to date.
>
> Why does it attempt to build object files and the library despite of -gnatc 
> switch and how to make it not to attempt build object files?

It doesn't attempt to build object files; that's why the gprlib call
fails. It does build .ali files, though.

You can get gnatmake (actually, gprbuild) to stop after the compilation
by using its -c flag:

   lockheed:test-stm32f4 simon$ gnatmake -p -P testbed -c -cargs -gnatc
   Setup
      [mkdir]        object directory for project Testbed
   Compile
      [Ada]          testbed.adb
      [Ada]          containing.adb
      [Ada]          dispatching.adb
      [Ada]          floating_point.adb
      [Ada]          heartbeat.adb
      [Ada]          interrupts.adb
   interrupts.adb:44:09: (style) bad casing of "Handler" declared at line 41
      [Ada]          iteration.adb
      [Ada]          last_chance_handler.adb
      [Ada]          so.adb
      [Ada]          streams.adb
      [Ada]          strings.adb
      [Ada]          memory_streams.adb
   lockheed:test-stm32f4 simon$ ls .build/*.o
   ls: .build/*.o: No such file or directory

(the style warning is a compiler bug that I haven't reported yet!)

I say above "gnatmake (actually, gprbuild)" because nowadays (GCC 7, not
GCC 6) gnatmake checks whether gprbuild is available and execs it if so.

I do checks like this in the editor, because why wait to check the
closure rather than checking the change you just made? (of course this
isn't totally effective for spec changes). But, I have it (Emacs
ada-mode) set up to actually compile the unit being edited, by

 '(ada-prj-default-check-cmd
   "gprbuild -c -u -f -gnatc -p -P ${gpr_file} ${full_current}")

because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66162#c3 .

^ permalink raw reply	[relevance 1%]

* Re: Gnat Sockets - UDP timeout too short.
  2016-10-12 14:23  1% Gnat Sockets - UDP timeout too short ahlan
@ 2016-11-04  8:48  0% ` ahlan.marriott
  0 siblings, 0 replies; 200+ results
From: ahlan.marriott @ 2016-11-04  8:48 UTC (permalink / raw)


On Wednesday, 12 October 2016 16:23:39 UTC+2, ah...@marriott.org  wrote:
> Under Microsoft Windows 8.1 (and later) Gnat.Sockets.Receive_Socket returns too early whilst waiting for a UDP datagram.
> In our test program (below) we create a UDP socket, set the timeout for one second, bind it to a port and then call receive on the socket.
> We catch and resolve the Socket_Error exception and process the expected Connection_Timed_Out.
> We note the time before issuing Receive_Socket and the time when we catch the exception and then compare the elapsed time with the receive timeout.
> On Window systems prior to Win8.1 this seems to work as expected, the elapsed time is always greater than the receive timeout.
> However under Win8.1 (and later) the call to Receive_Socket returns approximately half a second too early!
> 
> Curiously, if I write the same thing using the Win32.WinSock API then it works as expected. Which I find odd because I would have thought that Gnat.Sockets would simply be a series of wrappers around a few WinApi calls. But then what do I know?
> 
> The effect of this bug is that programs using UDP protocols timeout earlier than they should do - which often leads to curious behaviour.
> 
> We have tested this on a couple of PCs running a variety of flavours of Ms-Windows. So far it seems that XP & Win7 work as expected whereas Win8 and Win10 fail.
> 
> Has anyone any idea what might cause this problem and how we might go about fixing it?
> 
> Best wishes,
> MfG
> Ahlan
> 
> ------------------------------
> with Ada.Text_IO;
> with Ada.Exceptions;
> with Ada.Real_Time;
> with Ada.Streams;
> with GNAT.Sockets;
> 
> package body Test is
> 
>   package Io  renames Ada.Text_IO;
>   package Net renames GNAT.Sockets;
> 
>   Receive_Timeout : constant Duration := 1.0;
> 
>   Receive_Timeout_Span : constant Ada.Real_Time.Time_Span := Ada.Real_Time.To_Time_Span (Receive_Timeout);
> 
>   procedure Work is
>     The_Datagram : Ada.Streams.Stream_Element_Array (1..20);
>     The_Last     : Ada.Streams.Stream_Element_Offset;
>     The_Socket   : Net.Socket_Type;
>     Start_Time   : Ada.Real_Time.Time;
>     End_Time     : Ada.Real_Time.Time;
>     use type Ada.Real_Time.Time;
>   begin
>     Net.Create_Socket (Socket => The_Socket,
>                        Family => Net.Family_Inet,
>                        Mode   => Net.Socket_Datagram);
>     Net.Set_Socket_Option (Socket => The_Socket,
>                            Option => (Net.Receive_Timeout, Timeout => Receive_Timeout));
>     Net.Bind_Socket (The_Socket, (Family => Net.Family_Inet,
>                                   Addr   => Net.Any_Inet_Addr,
>                                   Port   => 11154));
>     loop
>       begin
>         Start_Time := Ada.Real_Time.Clock;
>         Net.Receive_Socket (Socket => The_Socket,
>                             Item   => The_Datagram,
>                             Last   => The_Last);
>         Io.New_Line;
>         Io.Put_Line ("Unexpected reply!");
>         exit;
>       exception
>       when Occurrence: Net.Socket_Error =>
>         End_Time := Ada.Real_Time.Clock;
>         declare
>           Error : constant Net.Error_Type := Net.Resolve_Exception (Occurrence);
>           use type Net.Error_Type;
>         begin
>           if Error = Net.Connection_Timed_Out then
>             if End_Time >= (Start_Time + Receive_Timeout_Span) then
>               Io.Put (".");
>             else
>               Io.New_Line;
>               declare
>                 use type Ada.Real_Time.Time_Span;
>                 Shortfall : constant Ada.Real_Time.Time_Span := Receive_Timeout_Span - (End_Time - Start_Time);
>               begin
>                 Io.Put_Line ("Timeout too short by" & Ada.Real_Time.To_Duration (Shortfall)'img & "seconds");
>               end;
>             end if;
>           else
>             Io.Put_Line ("Socket_Error : Unexpected error=" & Error'img);
>             exit;
>           end if;
>         end;
>       when Event : others =>
>         Io.Put_Line ("Unexpected exception: " & Ada.Exceptions.Exception_Name (Event));
>       end;
>     end loop;
>   exception
>   when Event : others =>
>     Io.Put_Line ("Internal Error: " & Ada.Exceptions.Exception_Name (Event));
>   end Work;
To answer my own question...
Gnat sockets uses the Winsock function Recv and sets the timeout DWORD SO_RCVTIMEO in Milliseconds.
However according to the Microsoft Developers Network in Feb 2014 (and others articles) there was an undocumented minimum limit of 500ms which seems to have been implemented by Microsoft simply adding 500ms to whatever non-zero value was placed in SO_RECVTIMEO.
The consensus workaround was simply to deduct 500ms from the desired timeout.
This is indeed what Gnat.Sockets seems to have implemented at line 2297 in g-socket.adb
if V4 > 500 then V4 := V4 - 500; elsif v4 > 0 then V4 := 1 endif;
At line 1249 in g-socket.adb the 500 is added again if the timeout is retrieved.

It seems to me that recent versions of Windows no longer adds 500ms to the Recv timeout.
This would explain why under Win8 and Win10 our receive of UDP datagrams timeout half a second too soon.

Gnat.Sockets needs to determine the version of windows and only apply the correction if necessary.

The fun of course is going to be finding our which versions of Windows need the correction and which don’t. ;-)
Win8.1 and Win10 don't, Win7 and WinXp do.
Can anyone add to this list?

Best wishes
MfG
Ahlan


^ permalink raw reply	[relevance 0%]

* Gnat Sockets - UDP timeout too short.
@ 2016-10-12 14:23  1% ahlan
  2016-11-04  8:48  0% ` ahlan.marriott
  0 siblings, 1 reply; 200+ results
From: ahlan @ 2016-10-12 14:23 UTC (permalink / raw)


Under Microsoft Windows 8.1 (and later) Gnat.Sockets.Receive_Socket returns too early whilst waiting for a UDP datagram.
In our test program (below) we create a UDP socket, set the timeout for one second, bind it to a port and then call receive on the socket.
We catch and resolve the Socket_Error exception and process the expected Connection_Timed_Out.
We note the time before issuing Receive_Socket and the time when we catch the exception and then compare the elapsed time with the receive timeout.
On Window systems prior to Win8.1 this seems to work as expected, the elapsed time is always greater than the receive timeout.
However under Win8.1 (and later) the call to Receive_Socket returns approximately half a second too early!

Curiously, if I write the same thing using the Win32.WinSock API then it works as expected. Which I find odd because I would have thought that Gnat.Sockets would simply be a series of wrappers around a few WinApi calls. But then what do I know?

The effect of this bug is that programs using UDP protocols timeout earlier than they should do - which often leads to curious behaviour.

We have tested this on a couple of PCs running a variety of flavours of Ms-Windows. So far it seems that XP & Win7 work as expected whereas Win8 and Win10 fail.

Has anyone any idea what might cause this problem and how we might go about fixing it?

Best wishes,
MfG
Ahlan

------------------------------
with Ada.Text_IO;
with Ada.Exceptions;
with Ada.Real_Time;
with Ada.Streams;
with GNAT.Sockets;

package body Test is

  package Io  renames Ada.Text_IO;
  package Net renames GNAT.Sockets;

  Receive_Timeout : constant Duration := 1.0;

  Receive_Timeout_Span : constant Ada.Real_Time.Time_Span := Ada.Real_Time.To_Time_Span (Receive_Timeout);

  procedure Work is
    The_Datagram : Ada.Streams.Stream_Element_Array (1..20);
    The_Last     : Ada.Streams.Stream_Element_Offset;
    The_Socket   : Net.Socket_Type;
    Start_Time   : Ada.Real_Time.Time;
    End_Time     : Ada.Real_Time.Time;
    use type Ada.Real_Time.Time;
  begin
    Net.Create_Socket (Socket => The_Socket,
                       Family => Net.Family_Inet,
                       Mode   => Net.Socket_Datagram);
    Net.Set_Socket_Option (Socket => The_Socket,
                           Option => (Net.Receive_Timeout, Timeout => Receive_Timeout));
    Net.Bind_Socket (The_Socket, (Family => Net.Family_Inet,
                                  Addr   => Net.Any_Inet_Addr,
                                  Port   => 11154));
    loop
      begin
        Start_Time := Ada.Real_Time.Clock;
        Net.Receive_Socket (Socket => The_Socket,
                            Item   => The_Datagram,
                            Last   => The_Last);
        Io.New_Line;
        Io.Put_Line ("Unexpected reply!");
        exit;
      exception
      when Occurrence: Net.Socket_Error =>
        End_Time := Ada.Real_Time.Clock;
        declare
          Error : constant Net.Error_Type := Net.Resolve_Exception (Occurrence);
          use type Net.Error_Type;
        begin
          if Error = Net.Connection_Timed_Out then
            if End_Time >= (Start_Time + Receive_Timeout_Span) then
              Io.Put (".");
            else
              Io.New_Line;
              declare
                use type Ada.Real_Time.Time_Span;
                Shortfall : constant Ada.Real_Time.Time_Span := Receive_Timeout_Span - (End_Time - Start_Time);
              begin
                Io.Put_Line ("Timeout too short by" & Ada.Real_Time.To_Duration (Shortfall)'img & "seconds");
              end;
            end if;
          else
            Io.Put_Line ("Socket_Error : Unexpected error=" & Error'img);
            exit;
          end if;
        end;
      when Event : others =>
        Io.Put_Line ("Unexpected exception: " & Ada.Exceptions.Exception_Name (Event));
      end;
    end loop;
  exception
  when Event : others =>
    Io.Put_Line ("Internal Error: " & Ada.Exceptions.Exception_Name (Event));
  end Work;


^ permalink raw reply	[relevance 1%]

* Re: zLibAda vs ZipAda (which should I use, if any)?
    @ 2016-08-27 19:33  2% ` Aurele
  1 sibling, 0 replies; 200+ results
From: Aurele @ 2016-08-27 19:33 UTC (permalink / raw)


Thanks, was just looking at your To_Bmp demo and also noticed you had txt file (which I should have seen/read first).  So the steps are fairly straight forward....

1) Load the image header from stream
2) Prepare the retrieval of the image ?
3) Load/decode the image itself

Sounds easy. Thanks!

I have not check/looked yest but is the Zip-Ada "UnZip.Streams.Zipped_File_Type" type a subtype of "Ada.Streams.Stream_IO.File_Type" ? 

In otherwords, if I have:

 UnZip.Streams.Open( File         => FileType,
                     Archive_Info => ZipFileInfo,
                     Name         => ASU.To_String( Info_Ptr.Data_Ptr( 31 ).FullName ) );

can I user 

Ada.Streams.Stream_IO.Stream_Access( UnZip.Streams.Stream( FileType ) )

When in calling GID.Load_image_header( .....) ?



^ permalink raw reply	[relevance 2%]

* Re: zLibAda vs ZipAda (which should I use, if any)?
  2016-08-27 16:31  2%                         ` Aurele
@ 2016-08-27 19:15  0%                           ` gautier_niouzes
  0 siblings, 0 replies; 200+ results
From: gautier_niouzes @ 2016-08-27 19:15 UTC (permalink / raw)


Le samedi 27 août 2016 18:31:30 UTC+2, Aurele a écrit :
> Hi Gautier, I think your GID packages will provide the services I need. Very well done by the way.  
> 
> Maybe you can save me some time and guide me on its use for my needs.  I've inserted some code below that show how I'll load the images from the zip file using Zip-Ada, I arrange the data (not shown), and then I need to call GID procedure to load as Handle.
> 
> Any comments or ideas? 
> 
> declare
> 
>   package ASU renames Ada.Strings.Unbounded;
> 
>   type Entry_ID is new Integer range -1..Integer'Last;
> 
>   type iEntry is record
>     Texture_ID : ZipFile.Entry_ID;
>     FullName   : Ada.Strings.Unbounded.Unbounded_String;
>     Directory  : Ada.Strings.Unbounded.Unbounded_String;
>     EntryName  : Ada.Strings.Unbounded.Unbounded_String;
>     Extension  : Ada.Strings.Unbounded.Unbounded_String;
>   end record;
>   type iEntryEntry_Ptr is access all ZipFile.iEntry;
> 
>   subtype iEntry_Array_Size is Entry_ID;
> 
>   type iEntry_Array is array ( iEntry_Array_Size range <> ) of aliased ZipFile.iEntry;
>   type iEntry_Array_Ptr is access all ZipFile.iEntry_Array;
> 
>   type Information is record
>     File_Location   : Ada.Strings.Unbounded.Unbounded_String;
>     File_Name       : Ada.Strings.Unbounded.Unbounded_String;
>     Total_Entries   : Natural;
>     Texture_Entries : Natural;
>     Data_Ptr        : ZipFile.iEntry_Array_Ptr;
>   end record;
>   type Information_Ptr is access all ZipFile.Information;
> 
>   Zip_File_Name         : constant String := "Textures.zip";
>   Zip_File_Entries      : iEntry_Array_Size;
> 
>   lpTexture_Array       : aliased iEntry_Array_Ptr;
>   lpTexture_Info        : aliased Information_Ptr
> 
>   Local_Index           : Entry_ID;
> 
>   ZipFileInfo           : Zip.Zip_Info;
>   FileType              : UnZip.Streams.Zipped_File_Type;
> 
> -----------------------------------------------------------------
> begin
> 
>   Zip.Load( ZipFileInfo, Zip_File_Name );
> 
>   Zip_File_Entries := iEntry_Array_Size( Zip.Entries( ZipFileInfo ) );
> 
>   lpTexture_Array  := new ZipFile.iEntry_Array( 1..Zip_File_Entries );
>   lpTexture_Info   := new ZipFile.Information;
> 
>   -- Scan procedure not shown here but is straight forward...
>   Scan( ZipFileInfo, FileName, Info_Ptr ); -- FILL INFO_PTR
> 
>   -- Simple test....  try to retrieve an image at index = 10
> 
>   Local_Index := 10; -- TEST: image at index = 10
> 
>   UnZip.Streams.Open
>     ( File         => FileType,
>       Archive_Info => ZipFileInfo,
>       Name  => ASU.To_String( Info_Ptr.Data_Ptr( Local_Index ).FullName ) 
>      );
> 
>   -- ???????????????????????????????????????????????????????
>   -- LoadImage is below, no idea yet what has to be done
> 
>   LoadImage( FileNeme => Info_Ptr.Data_Ptr( Local_Index ).EntryName,
>              FileExt  => Info_Ptr.Data_Ptr( Local_Index ).Extension,
>              FullName => Ada.Streams.Stream_IO.Stream_Access( UnZip.Streams.Stream( FileType ) ) );
> 
>   UnZip.Streams.Close( FileType );
> 
> end;
> 
> 
> -----------------------------------------------------------------
> - TBD: Call "GID" procedure to load image (DIB or BMP (bitmap))
> 
> type Hande is access all System.Address;  
> hBitmap : Hande := NULL;
> 
> procedure LoadImage ( FileName : Ada.Strings.Unbounded.Unbounded_String;
>                       FileExt  : Ada.Strings.Unbounded.Unbounded_String;
>                       FullName : Ada.Strings.Unbounded.Unbounded_String ) is
> begin
>                    -- --------------------------
>   hBitmap := ?;    -- Call GID directly here ??? Steps ????
>                    -----------------------------
> end LoadImage;
> 
> -----------------------------------------------------------------
> 
> Cheers and thanks
> Aurele

I'm just copy-pasting useful things from the To_BMP example, which will be ok for a Windows bitmap. I skip the image rotation stuff to simplify...

  type Byte_Array is array(Integer range <>) of Unsigned_8;
  type p_Byte_Array is access Byte_Array;
  procedure Dispose is new Ada.Unchecked_Deallocation(Byte_Array, p_Byte_Array);

  img_buf: p_Byte_Array:= null;

  procedure Load_raw_image(
    image : in out GID.Image_descriptor;
    buffer: in out p_Byte_Array
  )
  is
    subtype Primary_color_range is Unsigned_8;
    subtype U16 is Unsigned_16;
    image_width: constant Positive:= GID.Pixel_width(image);
    image_height: constant Positive:= GID.Pixel_height(image);
    padded_line_size_x: constant Positive:=
      4 * Integer(Float'Ceiling(Float(image_width) * 3.0 / 4.0));
    padded_line_size_y: constant Positive:=
      4 * Integer(Float'Ceiling(Float(image_height) * 3.0 / 4.0));
    -- (in bytes)
    idx: Integer;
    --
    procedure Set_X_Y (x, y: Natural) is
    pragma Inline(Set_X_Y);
    begin
      idx:= 3 * x + padded_line_size_x * y;
    end Set_X_Y;
    --
    procedure Put_Pixel_without_bkg (
      red, green, blue : Primary_color_range;
      alpha            : Primary_color_range
    )
    is
    pragma Inline(Put_Pixel_without_bkg);
    pragma Warnings(off, alpha); -- alpha is just ignored
    begin
      buffer(idx..idx+2):= (blue, green, red);
      -- GID requires us to look to next pixel for next time:
      idx:= idx + 3;
    end Put_Pixel_without_bkg;
    --
    procedure BMP24_Load_without_bkg is
      new GID.Load_image_contents(
        Primary_color_range,
        Set_X_Y,
        Put_Pixel_without_bkg,
        Feedback,
        GID.fast
      );
    next_frame: Ada.Calendar.Day_Duration;
  begin
    Dispose(buffer);
    buffer:= new Byte_Array(0..padded_line_size_x * GID.Pixel_height(image) - 1);
    BMP24_Load_without_bkg(image, next_frame);
  end Load_raw_image;

...
    i: GID.Image_descriptor;
  begin
    GID.Load_image_header(i, Your_nice_stream_Access.all, True);
    Load_raw_image(i, img_buf);
  end;

Now you surely know better how to let the image buffer (img_buf) meet the hBitmap handle (some Windows-ish bureaucracy ;-) )
_________________________ 
Gautier's Ada programming 
http://gautiersblog.blogspot.com/search/label/Ada 
NB: follow the above link for a valid e-mail address 

^ permalink raw reply	[relevance 0%]

* Re: zLibAda vs ZipAda (which should I use, if any)?
  @ 2016-08-27 16:31  2%                         ` Aurele
  2016-08-27 19:15  0%                           ` gautier_niouzes
  0 siblings, 1 reply; 200+ results
From: Aurele @ 2016-08-27 16:31 UTC (permalink / raw)


Hi Gautier, I think your GID packages will provide the services I need. Very well done by the way.  

Maybe you can save me some time and guide me on its use for my needs.  I've inserted some code below that show how I'll load the images from the zip file using Zip-Ada, I arrange the data (not shown), and then I need to call GID procedure to load as Handle.

Any comments or ideas? 

declare

  package ASU renames Ada.Strings.Unbounded;

  type Entry_ID is new Integer range -1..Integer'Last;

  type iEntry is record
    Texture_ID : ZipFile.Entry_ID;
    FullName   : Ada.Strings.Unbounded.Unbounded_String;
    Directory  : Ada.Strings.Unbounded.Unbounded_String;
    EntryName  : Ada.Strings.Unbounded.Unbounded_String;
    Extension  : Ada.Strings.Unbounded.Unbounded_String;
  end record;
  type iEntryEntry_Ptr is access all ZipFile.iEntry;

  subtype iEntry_Array_Size is Entry_ID;

  type iEntry_Array is array ( iEntry_Array_Size range <> ) of aliased ZipFile.iEntry;
  type iEntry_Array_Ptr is access all ZipFile.iEntry_Array;

  type Information is record
    File_Location   : Ada.Strings.Unbounded.Unbounded_String;
    File_Name       : Ada.Strings.Unbounded.Unbounded_String;
    Total_Entries   : Natural;
    Texture_Entries : Natural;
    Data_Ptr        : ZipFile.iEntry_Array_Ptr;
  end record;
  type Information_Ptr is access all ZipFile.Information;

  Zip_File_Name         : constant String := "Textures.zip";
  Zip_File_Entries      : iEntry_Array_Size;

  lpTexture_Array       : aliased iEntry_Array_Ptr;
  lpTexture_Info        : aliased Information_Ptr

  Local_Index           : Entry_ID;

  ZipFileInfo           : Zip.Zip_Info;
  FileType              : UnZip.Streams.Zipped_File_Type;

-----------------------------------------------------------------
begin

  Zip.Load( ZipFileInfo, Zip_File_Name );

  Zip_File_Entries := iEntry_Array_Size( Zip.Entries( ZipFileInfo ) );

  lpTexture_Array  := new ZipFile.iEntry_Array( 1..Zip_File_Entries );
  lpTexture_Info   := new ZipFile.Information;

  -- Scan procedure not shown here but is straight forward...
  Scan( ZipFileInfo, FileName, Info_Ptr ); -- FILL INFO_PTR

  -- Simple test....  try to retrieve an image at index = 10

  Local_Index := 10; -- TEST: image at index = 10

  UnZip.Streams.Open
    ( File         => FileType,
      Archive_Info => ZipFileInfo,
      Name  => ASU.To_String( Info_Ptr.Data_Ptr( Local_Index ).FullName ) 
     );

  -- ???????????????????????????????????????????????????????
  -- LoadImage is below, no idea yet what has to be done

  LoadImage( FileNeme => Info_Ptr.Data_Ptr( Local_Index ).EntryName,
             FileExt  => Info_Ptr.Data_Ptr( Local_Index ).Extension,
             FullName => Ada.Streams.Stream_IO.Stream_Access( UnZip.Streams.Stream( FileType ) ) );

  UnZip.Streams.Close( FileType );

end;


-----------------------------------------------------------------
- TBD: Call "GID" procedure to load image (DIB or BMP (bitmap))

type Hande is access all System.Address;  
hBitmap : Hande := NULL;

procedure LoadImage ( FileName : Ada.Strings.Unbounded.Unbounded_String;
                      FileExt  : Ada.Strings.Unbounded.Unbounded_String;
                      FullName : Ada.Strings.Unbounded.Unbounded_String ) is
begin
                   -- --------------------------
  hBitmap := ?;    -- Call GID directly here ??? Steps ????
                   -----------------------------
end LoadImage;

-----------------------------------------------------------------

Cheers and thanks
Aurele


^ permalink raw reply	[relevance 2%]

* Re: How to write "Hello" to a text file without a line terminator
  2016-08-14  9:40  1%                     ` Simon Wright
@ 2016-08-14 10:17  1%                       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2016-08-14 10:17 UTC (permalink / raw)


On 2016-08-14 11:40, Simon Wright wrote:

> I am saying that (it seems to me that) it is impossible to read back
> from Sequential_IO with an unconstrained type even on the same machine
> with the same compiler.

You can through S'Input. Read is just a wrapper for S'Read, it could 
have been omitted too.

And regarding the design it should have been:

package Ada.Streams is
    type Abstract_Root_Stream_Type is limited interface;
    type Root_Stream_Type is new Abstract_Root_Stream_Type with private;

...
package Ada.Streams.Stream_IO is
    type File_Type is new Abstract_Root_Stream_Type with private;

and no

function Stream (File : in File_Type) return Stream_Access;

>> All that needed is pragma Assert that Stream_Element'Size = 8 and
>> Stream_Element_Array I/O.
>
> Ada.Streams.Stream_IO & String'Write is even simpler in 99.9% of cases.

Yes, when String'Component_Size = Stream_Element_Size = 8.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 1%]

* Re: How to write "Hello" to a text file without a line terminator
  @ 2016-08-14  9:40  1%                     ` Simon Wright
  2016-08-14 10:17  1%                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2016-08-14  9:40 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On 2016-08-14 10:30, Simon Wright wrote:
>
>> Come to think of it, what would the use case be for instantiating
>> Sequential (or Direct) IO with an unconstrained type?
>
> Direct_IO requires a constrained type.

So it does. And Sequential_IO explicitly permists an unconstrained
type. Still,

>> they both have
>> only procedural forms for Read, so how could you ever retrieve a value?
>
> Does it matter? It is not portable to use anyway.

I am saying that (it seems to me that) it is impossible to read back
from Sequential_IO with an unconstrained type even on the same machine
with the same compiler.

> All that needed is pragma Assert that Stream_Element'Size = 8 and
> Stream_Element_Array I/O.

Ada.Streams.Stream_IO & String'Write is even simpler in 99.9% of cases.


^ permalink raw reply	[relevance 1%]

* ANN: Cortex GNAT RTS 20160522
@ 2016-05-22 14:20  1% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-05-22 14:20 UTC (permalink / raw)


Available at
https://sourceforge.net/projects/cortex-gnat-rts/files/20160522/

This release includes GNAT Ada Run Time Systems (RTSs) based
on FreeRTOS (http://www.freertos.org) and targeted at boards with
Cortex-M3, -M4, -M4F MCUs (Arduino Due from http://www.arduino.org,
the STM32F4-series evaluation boards from STMicroelectronics at
http://www.st.com).

In each case, the board support for the RTS (configuration for size
and location of Flash, RAM; clock initialization; interrupt naming) is
in $RTS/adainclude. Support for the on-chip peripherals is also
included, in Ada spec files generated by SVD2Ada
(https://github.com/AdaCore/svd2ada).

The Ada source is either original or based on FSF GCC (mainly 4.9.1,
some later releases too).

(1) arduino-due is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the Arduino Due.

    See arduino-due/COPYING* for licensing terms.

    On-chip peripheral support in atsam3x8e/.

    Tests in test-arduino-due/.

(2) stm32f4 is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F4-DISC* board.

    See stm32f4/COPYING* for licensing terms.

    On-chip peripheral support in stm32f40x/.

    Tests in test-stm32f4/.

(3) stm32f429i is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F429I-DISC* board.

    See stm32f429i/COPYING* for licensing terms.

    On-chip peripheral support in stm32f429x/.

    Tests in test-stm32f429i/.

In this release,

* There is no longer any dependence on the STMicroelectronics'
  STM32Cube package.

* The support for on-chip peripherals is limited to the
  SVD2Ada-generated spec files. The AdaCore 'bareboard' software
  (currently https://github.com/AdaCore/bareboard, but a name change
  is under consideration) supports the STM32 line.

* Tasking no longer requires an explicit start
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/5/).

* Locking in interrupt-handling protected objects no longer inhibits
  all interrupts, only those of equal or lower priority
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/18/).

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 1%]

* ANN: Cortex GNAT RTS 20160314
@ 2016-03-14 17:42  1% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-03-14 17:42 UTC (permalink / raw)


At https://sourceforge.net/projects/cortex-gnat-rts/files/20160314/.

This release includes

* an RTS for the Arduino Due, arduino-due, and a minimal BSP,
  arduino-due-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i-disco-rtos, based on
  STMicroelectronics' STM32Cube package and FreeRTOS, and a
  corresponding partial BSP, stm32f429i-disco-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i, based on FreeRTOS, with
  a set of peripheral definition packages created by SVD2Ada.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 1%]

* ANN: Cortex GNAT RTS 20160207
@ 2016-02-07 22:45  1% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-02-07 22:45 UTC (permalink / raw)


This release is at Sourceforge[1].

This release includes an RTS for the Arduino Due, arduino-due, and a
minimal BSP, arduino-due-bsp.

For the STM32F429I-DISCO, there is one RTS, stm32f429i-disco-rtos, and
one BSP, stm32f429i-disco-bsp.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

* FreeRTOS is configured to detect stack overflow (if it is detected,
  the RTS loops inside vApplicationStackOverflowHook()).

The standard packages included (there are more,
implementation-specific, ones) are:

   Ada
   Ada.Containers
   Ada.Containers.Bounded_Hashed_Maps
   Ada.Containers.Bounded_Vectors
   Ada.Exceptions
   Ada.IO_Exceptions
   Ada.Interrupts
   Ada.Interrupts.Names
   Ada.Iterator_Interfaces
   Ada.Real_Time
   Ada.Streams
   Ada.Synchronous_Task_Control
   Ada.Tags
   Ada.Task_Identification
   Interfaces
   Interfaces.C
   Interfaces.C.Strings
   System
   System.Assertions
   System.Address_To_Access_Conversions
   System.Storage_Elements
   GNAT
   GNAT.Source_Info

The software is supplied built with for debugging (-g) and with suitable
optimisation (-Og), using GNAT GPL 2015 on Mac OS X (it should work
out of the box with a Linux-hosted GNAT GPL 2015 cross-compiler, but
will need recompiling for another compiler version).

[1] https://sourceforge.net/projects/cortex-gnat-rts/files/20160207/


^ permalink raw reply	[relevance 1%]

* Re: Out_File , excess line
  @ 2016-01-31 12:57  2%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2016-01-31 12:57 UTC (permalink / raw)


On 2016-01-31 12:25, Simon Wright wrote:

> The standard solution to copying a file would be
>
>     with Ada.Text_IO; use Ada.Text_IO;

No, that does not copy a file. That 1) interprets a file context as a 
text file specific to the given operating system and then 2) writes the 
interpretation into another file. So it is a file conversion.

One solution to copy a file is using Copy_File from Ada.Directories.

Another is using Ada.Streams.Stream_IO. Both are not ideal but will work 
in most cases.

E.g. your example with Ada.Streams.Stream_IO:

  with Ada.Exceptions;        use Ada.Exceptions;
  with Ada.Streams;           use Ada.Streams;
  with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;

  with Ada.Text_IO;

  procedure Fanzine is
     Buffer_Size : constant := 1024; -- Or more
     Input_File  : File_Type;
     Output_File : File_Type;
     Buffer      : Stream_Element_Array (1..Buffer_Size);
     Last        : Stream_Element_Offset;
     Count       : Stream_Element_Count := 0;
  begin
     Open (Input_File, In_File, "fanzine.adb");
     begin
        Create (Output_File, Out_File, "fanzine.adb.copy");
        loop
           Read (Input_File, Buffer, Last);
           exit when Last < Buffer'First;
           Count := Count + Last;
           Write (Output_File, Buffer (Buffer'First..Last));
       end loop;
    exception
       when End_Error =>
          null; -- Never here
    end;
    Close (Output_File);
    Close (Input_File);
    Ada.Text_IO.Put_Line
    (  "Written" & Stream_Element_Count'Image (Count) & " elements"
    );
exception
    when Error : others =>
       Ada.Text_IO.Put_Line ("Error " & Exception_Information (Error));
end Fanzine;

It is quite simple, if necessary, to detect line ends in a manner 
compatible with both Windows and Linux systems, given fixed encoding.

(Doing that independently of the encoding would probably be impossible, 
but who cares?)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 2%]

* Re: Out_File , excess line
  2016-01-27  9:26  0%   ` Simon Wright
@ 2016-01-27 20:28  0%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2016-01-27 20:28 UTC (permalink / raw)


On 2016-01-27 10:26, Simon Wright wrote:
> comicfanzine@gmail.com writes:
>
>> But , when we try to open the file manually , the text editor print :
>>
>> " This is not a text file . Type unknown ."
>>     PACKAGE ST_IO RENAMES Ada.Streams.Stream_IO ;
>>
>>     test_file : ST_IO.File_type ;
>>
>>     Input_Stream : ST_IO.Stream_Access ;
> [...]
>>     ST_IO.Create( File => test_file ,
>>                 Mode => ST_IO.Out_File ,
>>                 Name => "test" );
>>
>>      Input_Stream := ST_IO.Stream( test_file );
>>
>>      for j in 1..case_array'Length loop
>>        Unbounded_String'Write( Input_Stream , case_array(j) );
>>     end loop;
>
> 'Input_Stream' is a very odd name for a stream you're going to *output*
> to.
>
> What's happening is that (reasonably, though not as far as I can see
> discussed by the standard) GNAT treats Unbounded_String'Write as if an
> unbounded string is a discriminated type whose discriminants have
> defaults; that is, the discriminants (the array bounds) are output to
> the stream first, followed by the characters of the string. (This is
> what happens for String'Output; String'Write doesn't include the bounds;
> is the Unbounded_String'Write behaviour a bug or a feature?).
>
> So, if you Unbounded_String'Write "foo", you will get
> - 4 bytes containing binary 1, the first index of the content
> - 4 bytes containing binary 3, the last index of the content
> - 3 bytes of content, 'f' 'o' 'o'.
>
> Which looks nothing like a text file.
>
> You could try
>
>    String'Write (Input_Stream, To_String (case_array (j)) & ASCII.LF);

This one of many reasons why no Unbounded_String should ever be used for 
any text processing. That includes text buffers of course. Using 
standard containers of Unbounded_String is probably least efficient 
possible way to implement a text buffer.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Out_File , excess line
  2016-01-23 20:06  1% ` comicfanzine
@ 2016-01-27  9:26  0%   ` Simon Wright
  2016-01-27 20:28  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2016-01-27  9:26 UTC (permalink / raw)


comicfanzine@gmail.com writes:

> But , when we try to open the file manually , the text editor print :
>
> " This is not a text file . Type unknown . "
>    PACKAGE ST_IO RENAMES Ada.Streams.Stream_IO ;
>
>    test_file : ST_IO.File_type ;
>
>    Input_Stream : ST_IO.Stream_Access ;
[...]
>    ST_IO.Create( File => test_file ,
>                Mode => ST_IO.Out_File ,
>                Name => "test" );
>
>     Input_Stream := ST_IO.Stream( test_file );
>
>     for j in 1..case_array'Length loop
>       Unbounded_String'Write( Input_Stream , case_array(j) );
>    end loop;

'Input_Stream' is a very odd name for a stream you're going to *output*
to.

What's happening is that (reasonably, though not as far as I can see
discussed by the standard) GNAT treats Unbounded_String'Write as if an
unbounded string is a discriminated type whose discriminants have
defaults; that is, the discriminants (the array bounds) are output to
the stream first, followed by the characters of the string. (This is
what happens for String'Output; String'Write doesn't include the bounds;
is the Unbounded_String'Write behaviour a bug or a feature?).

So, if you Unbounded_String'Write "foo", you will get
- 4 bytes containing binary 1, the first index of the content
- 4 bytes containing binary 3, the last index of the content
- 3 bytes of content, 'f' 'o' 'o'.

Which looks nothing like a text file.

You could try

  String'Write (Input_Stream, To_String (case_array (j)) & ASCII.LF);

(should be OK on Unix systems, don't know about Windows. A text
editor should be OK with LF-terminated lines, Notepad not so much.)

[1] http://www.ada-auth.org/standards/12rm/html/RM-13-13-2.html#p9.1

^ permalink raw reply	[relevance 0%]

* Re: Out_File , excess line
    2016-01-22 20:01  1% ` comicfanzine
@ 2016-01-23 20:06  1% ` comicfanzine
  2016-01-27  9:26  0%   ` Simon Wright
    2 siblings, 1 reply; 200+ results
From: comicfanzine @ 2016-01-23 20:06 UTC (permalink / raw)


I figured out how to use the package ?

The code compile , and is launchable too .

But , when we try to open the file manually , the text editor print :

" This is not a text file . Type unknown . "

Same information for the file manager( Thunar ) .

??

---------------
WITH Ada.Text_IO.Unbounded_IO ; USE Ada.Text_IO.Unbounded_IO ;
WITH Ada.Strings.Unbounded ;    USE Ada.Strings.Unbounded ;
WITH Ada.Text_IO  ;             USE Ada.Text_IO  ;
WITH Ada.Streams.Stream_IO ;

Procedure count_nb_lines is

  this_file : File_type ;

  count_line : integer := 0 ;

Begin

    Open
     (File => this_file ,
      Mode => In_file ,
      Name => "count_nb_lines.adb");

   loop exit when End_Of_File( this_file );
     skip_line( this_file );
     count_line := count_line + 1 ;
   end loop ;


   declare

   Type Tableau_file is array( 1 .. count_line) of Unbounded_String ;

   case_array : Tableau_file ;


   PACKAGE ST_IO RENAMES Ada.Streams.Stream_IO ;

   test_file : ST_IO.File_type ;

   Input_Stream : ST_IO.Stream_Access ;

   begin

   Reset( this_file );

    Loop exit when End_Of_File( this_file );
        for i in 1..case_array'Length loop
         case_array(i) := get_line(this_file);
       end loop ;
   End loop;

   ST_IO.Create( File => test_file ,
               Mode => ST_IO.Out_File ,
               Name => "test" );

    Input_Stream := ST_IO.Stream( test_file );

    for j in 1..case_array'Length loop
      Unbounded_String'Write( Input_Stream , case_array(j) );
   end loop;

    end;
End count_nb_lines ;




^ permalink raw reply	[relevance 1%]

* Re: Out_File , excess line
  @ 2016-01-22 20:01  1% ` comicfanzine
  2016-01-23 20:06  1% ` comicfanzine
    2 siblings, 0 replies; 200+ results
From: comicfanzine @ 2016-01-22 20:01 UTC (permalink / raw)


I'm working with a text file .

Now , i use the package Ada.Text_IO.Unbounded_IO for text in Unbounded_Strings .

If i use the package Ada.Streams.Stream_IO , instead of Ada.Text_IO , for text handling , there is some changes to do :

Is there a Unbounded_String package for Stream_IO  ?

Or a another simplier way ?
-----------------------
WITH Ada.Text_IO.Unbounded_IO ; USE Ada.Text_IO.Unbounded_IO ;
WITH Ada.Strings.Unbounded ;    USE Ada.Strings.Unbounded ;
WITH Ada.Text_IO  ;             USE Ada.Text_IO  ;

Procedure count_nb_lines is

  this_file , test_file : File_type ;

  count : integer := 0 ;

Begin

    Open
     (File => this_file ,
      Mode => In_file ,
      Name => "count_nb_lines.adb");

   loop exit when End_Of_File( this_file );
     skip_line( this_file );
     count := count + 1 ;
   end loop ;

   Open
     (File => test_file ,
      Mode => Out_File ,
      Name => "test.adb");

   declare

   Type Tableau_lines_file is array( 1 .. count) of Unbounded_String;

   case_array : Tableau_lines_file ;

   begin

   Reset( this_file );

    Loop exit when End_Of_File( this_file );
        for i in 1..case_array'Length loop
         case_array(i) := get_line(this_file);
       end loop ;
   End loop;

    for j in 1..case_array'Length loop
      put_line( test_file , case_array(j) );
   end loop;

    end;
End count_nb_lines ;


^ permalink raw reply	[relevance 1%]

* Re: GNAT.Serial_Communication and Streams
  2015-11-22 21:54  1% ` Jeffrey R. Carter
  2015-11-24  1:29  0%   ` Randy Brukardt
@ 2015-11-24  8:28  0%   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2015-11-24  8:28 UTC (permalink / raw)


On Sun, 22 Nov 2015 14:54:04 -0700, Jeffrey R. Carter wrote:

> What about
> 
> procedure Send (Cmd : in String) is
>    Local  : constant String := Cmd & Ada.Characters.Latin_1.LF;
>    Output : constant Ada.Streams.Stream_Element_Array (1 .. Local'Length);
>    pragma Import (Ada, Output);
>    for Output'Address use Local'Address;
> begin -- Send
>    GNAT.Serial_Communication.Write (P, Output)?
> end Send;

If you wanted optimize it, then Cmd and LF should be written in separate
calls rather than making a local copies.

A case when a copying makes sense is in a packet-oriented protocol. Which
is not the case here since streams are used. Maybe it is still
packet-oriented because of the USB device class, but then interfacing it
through a stream is inappropriate.

P.S. I don't see anything wrong with the original code. Stream attributes
not to be trusted in general. An explicit conversion is clearer and
cleaner, IMO.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: GNAT.Serial_Communication and Streams
  2015-11-22 21:54  1% ` Jeffrey R. Carter
@ 2015-11-24  1:29  0%   ` Randy Brukardt
  2015-11-24  8:28  0%   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2015-11-24  1:29 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:n2tddf$eue$1@dont-email.me...
...
> What about
>
> procedure Send (Cmd : in String) is
>   Local  : constant String := Cmd & Ada.Characters.Latin_1.LF;
>   Output : constant Ada.Streams.Stream_Element_Array (1 .. Local'Length);
>   pragma Import (Ada, Output);
>   for Output'Address use Local'Address;
> begin -- Send
>   GNAT.Serial_Communication.Write (P, Output)?
> end Send;
>
> ?

Probably works on GNAT, but it's not portable Ada code. For one thing, it 
assumes that Implementation Advice 13.3(14) is followed (Janus/Ada does not 
follow that advice - after all, it is just advice, not a requirement). It 
also assumes that Local is not optimized at all (there is advice that Output 
not be optimized, but that doesn't apply to Local, and like all advice, it 
can be ignored).

Might not matter in this case (which is clearly GNAT-specific), but 
generally this is a pattern to avoid.

                     Randy.


^ permalink raw reply	[relevance 0%]

* Re: GNAT.Serial_Communication and Streams
  2015-11-22 21:40  2% GNAT.Serial_Communication and Streams rrr.eee.27
  2015-11-22 21:52  1% ` Simon Wright
@ 2015-11-22 21:54  1% ` Jeffrey R. Carter
  2015-11-24  1:29  0%   ` Randy Brukardt
  2015-11-24  8:28  0%   ` Dmitry A. Kazakov
  1 sibling, 2 replies; 200+ results
From: Jeffrey R. Carter @ 2015-11-22 21:54 UTC (permalink / raw)


On 11/22/2015 02:40 PM, rrr.eee.27@gmail.com wrote:
>    procedure Send_Command (Cmd : String)
>    is
>       Output_Max_Length : constant Ada.Streams.Stream_Element_Offset := 50;
>       Output : Ada.Streams.Stream_Element_Array (1 .. Output_Max_Length);
>    begin
>       for I in 1 .. Cmd'Length loop
>          Output (Ada.Streams.Stream_Element_Offset(I)) := Character'Pos(Cmd (Cmd'First + I - 1));
>       end loop;
>       Output (Cmd'Length+1) := Character'Pos(ASCII.LF);

What happens when Cmd'Length > 49?

>       GNAT.Serial_Communication.Write (P, Output(1..Cmd'Length+1));
>    end Send_Command;
> 
> 
> That works but feels completely strange to me. I'm sure that I'm missing something here. There must be an easier way to fill the output buffer with a standard string.

What about

procedure Send (Cmd : in String) is
   Local  : constant String := Cmd & Ada.Characters.Latin_1.LF;
   Output : constant Ada.Streams.Stream_Element_Array (1 .. Local'Length);
   pragma Import (Ada, Output);
   for Output'Address use Local'Address;
begin -- Send
   GNAT.Serial_Communication.Write (P, Output)?
end Send;

?

-- 
Jeff Carter
"When danger reared its ugly head, he bravely
turned his tail and fled."
Monty Python and the Holy Grail
60

^ permalink raw reply	[relevance 1%]

* Re: GNAT.Serial_Communication and Streams
  2015-11-22 21:40  2% GNAT.Serial_Communication and Streams rrr.eee.27
@ 2015-11-22 21:52  1% ` Simon Wright
  2015-11-22 21:54  1% ` Jeffrey R. Carter
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2015-11-22 21:52 UTC (permalink / raw)


rrr.eee.27@gmail.com writes:

> I want to send text strings via a serial line (actually, it is a USB
> device that presents itself as a serial CDC device).
>
> For sending text snippets I had to declare the following routine:
>
>    procedure Send_Command (Cmd : String)
>    is
>       Output_Max_Length : constant Ada.Streams.Stream_Element_Offset := 50;
>       Output : Ada.Streams.Stream_Element_Array (1 .. Output_Max_Length);
>    begin
>       for I in 1 .. Cmd'Length loop
>          Output (Ada.Streams.Stream_Element_Offset(I)) := Character'Pos(Cmd (Cmd'First + I - 1));
>       end loop;
>       Output (Cmd'Length+1) := Character'Pos(ASCII.LF);
>       GNAT.Serial_Communication.Write (P, Output(1..Cmd'Length+1));
>    end Send_Command;
>
>
> That works but feels completely strange to me. I'm sure that I'm
> missing something here. There must be an easier way to fill the output
> buffer with a standard string.

The clue is that

   type Serial_Port is new Ada.Streams.Root_Stream_Type with private;

which means that you aren't supposed to use the local Read/Write; they
are for the implementation of the 'Read/'Write type attributes (ARM
13.3.2),

   String'Write (P'Access, Cmd & ASCII.LF);

BTW, you should probably have declared

   Output : Ada.Streams.Stream_Element_Array (1 .. Cmd'Length + 1);

avoiding the need for Output_Max_Length.

^ permalink raw reply	[relevance 1%]

* GNAT.Serial_Communication and Streams
@ 2015-11-22 21:40  2% rrr.eee.27
  2015-11-22 21:52  1% ` Simon Wright
  2015-11-22 21:54  1% ` Jeffrey R. Carter
  0 siblings, 2 replies; 200+ results
From: rrr.eee.27 @ 2015-11-22 21:40 UTC (permalink / raw)


I want to send text strings via a serial line (actually, it is a USB device that presents itself as a serial CDC device).

For sending text snippets I had to declare the following routine:

   procedure Send_Command (Cmd : String)
   is
      Output_Max_Length : constant Ada.Streams.Stream_Element_Offset := 50;
      Output : Ada.Streams.Stream_Element_Array (1 .. Output_Max_Length);
   begin
      for I in 1 .. Cmd'Length loop
         Output (Ada.Streams.Stream_Element_Offset(I)) := Character'Pos(Cmd (Cmd'First + I - 1));
      end loop;
      Output (Cmd'Length+1) := Character'Pos(ASCII.LF);
      GNAT.Serial_Communication.Write (P, Output(1..Cmd'Length+1));
   end Send_Command;


That works but feels completely strange to me. I'm sure that I'm missing something here. There must be an easier way to fill the output buffer with a standard string.

RE

^ permalink raw reply	[relevance 2%]

* Re: Creating an empty file with Ada.Text_IO
  2015-08-25 15:26  1%     ` Maciej Sobczak
  2015-08-25 16:18  1%       ` J-P. Rosen
@ 2015-08-25 16:45  2%       ` G.B.
  1 sibling, 0 replies; 200+ results
From: G.B. @ 2015-08-25 16:45 UTC (permalink / raw)


On 25.08.15 17:26, Maciej Sobczak wrote:
>
>>     procedure Write_String_To_File (File_Name : in String; S : in String) is
>>        A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>>        F : Ada.Streams.Stream_IO.File_Type;
>>     begin
>>        -- convert S to stream elements
>>        for I in S'Range loop
>>           A (Ada.Streams.Stream_Element_Offset (I)) :=
>>              Ada.Streams.Stream_Element (Character'Pos (S (I)));
>>        end loop;
>
> Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.
>
> Correct version is:
>
>        for I in S'Range loop
>           A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
>              Ada.Streams.Stream_Element (Character'Pos (S (I)));
>        end loop;
>
> And there are actually several ways to write it.
> Now this procedure can write String slices that do not begin at index 1.
>
> (Frankly, this part of Ada is inherently error-prone. I stumble on it repeatedly.)
>

subtypes seem helpful. If S can be made of a constraint subtype,
too, then an unchecked conversion should work, too. (Does, using GNAT).


with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO;

procedure Test is

    subtype S_E_Offset is Ada.Streams.Stream_Element_Offset;
    use type S_E_Offset;
    -- static assert:
    Is_Positive_in_S_E_Offset : constant array (Boolean) of Integer :=
      (
       S_E_Offset'First > S_E_Offset (Positive'First) => 123,
       S_E_Offset'Last >= S_E_Offset (Positive'Last) => 123
      );

    procedure Write_String_To_File (File_Name : in String; S : in String) is
       subtype Index is S_E_Offset
         range S_E_Offset (S'First) .. S_E_Offset (S'Last);

       A : Ada.Streams.Stream_Element_Array (Index);
       F : Ada.Streams.Stream_IO.File_Type;
    begin
       -- convert S to stream elements
       for I in S'Range loop
          A (S_E_Offset (I)) :=
            Ada.Streams.Stream_Element (Character'Pos (S (I)));
       end loop;

       -- create a stream file and write the content (which might be empty)
       Ada.Streams.Stream_IO.Create (F, Ada.Streams.Stream_IO.Out_File, 
File_Name);
       Ada.Streams.Stream_IO.Write (F, A);
       Ada.Streams.Stream_IO.Close (F);
    end Write_String_To_File;

begin
    -- empty file:
    Write_String_To_File ("file1.txt", "");

    -- file with one, non-terminated line:
    Write_String_To_File ("file2.txt",
                          String'(22 => 'a',
                                  23 => 'b',
                                  24 => 'c'));

    -- file with "one line and a half":
    Write_String_To_File ("file3.txt",
       "abc" & Ada.Characters.Latin_1.LF & "xyz");
end Test;

^ permalink raw reply	[relevance 2%]

* Re: Creating an empty file with Ada.Text_IO
  2015-08-25 15:26  1%     ` Maciej Sobczak
@ 2015-08-25 16:18  1%       ` J-P. Rosen
  2015-08-25 16:45  2%       ` G.B.
  1 sibling, 0 replies; 200+ results
From: J-P. Rosen @ 2015-08-25 16:18 UTC (permalink / raw)


Le 25/08/2015 17:26, Maciej Sobczak a écrit :
>> procedure Write_String_To_File (File_Name : in String; S : in String) is
>> >       A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>> >       F : Ada.Streams.Stream_IO.File_Type;
>> >    begin
>> >       -- convert S to stream elements
>> >       for I in S'Range loop
>> >          A (Ada.Streams.Stream_Element_Offset (I)) :=
>> >             Ada.Streams.Stream_Element (Character'Pos (S (I)));
>> >       end loop;
> Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.
> 
> Correct version is:
> 
>       for I in S'Range loop
>          A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
>             Ada.Streams.Stream_Element (Character'Pos (S (I)));
>       end loop;
Or simply:
      A : Ada.Streams.Stream_Element_Array
         (Stream_Element_Offset(S'First) ..
          Stream_Element_Offset(S'Last));

(saves some computation in the loop)
-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[relevance 1%]

* Re: Creating an empty file with Ada.Text_IO
  2015-08-25  8:20  2%   ` Maciej Sobczak
@ 2015-08-25 15:26  1%     ` Maciej Sobczak
  2015-08-25 16:18  1%       ` J-P. Rosen
  2015-08-25 16:45  2%       ` G.B.
  0 siblings, 2 replies; 200+ results
From: Maciej Sobczak @ 2015-08-25 15:26 UTC (permalink / raw)



>    procedure Write_String_To_File (File_Name : in String; S : in String) is
>       A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>       F : Ada.Streams.Stream_IO.File_Type;
>    begin
>       -- convert S to stream elements
>       for I in S'Range loop
>          A (Ada.Streams.Stream_Element_Offset (I)) :=
>             Ada.Streams.Stream_Element (Character'Pos (S (I)));
>       end loop;

Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.

Correct version is:

      for I in S'Range loop
         A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
            Ada.Streams.Stream_Element (Character'Pos (S (I)));
      end loop;

And there are actually several ways to write it.
Now this procedure can write String slices that do not begin at index 1.

(Frankly, this part of Ada is inherently error-prone. I stumble on it repeatedly.)

-- 
Maciej Sobczak * http://www.inspirel.com

^ permalink raw reply	[relevance 1%]

* Re: Creating an empty file with Ada.Text_IO
  @ 2015-08-25  8:20  2%   ` Maciej Sobczak
  2015-08-25 15:26  1%     ` Maciej Sobczak
  0 siblings, 1 reply; 200+ results
From: Maciej Sobczak @ 2015-08-25  8:20 UTC (permalink / raw)


> > What are the recommended ways of:
> > a) creating empty files
> > b) writing a non-terminated line to (or generally at the end of) the file
> 
> Stream I/O.

Right. For those who might be looking for the same in the future:


with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO;

procedure Test is

   procedure Write_String_To_File (File_Name : in String; S : in String) is
      A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
      F : Ada.Streams.Stream_IO.File_Type;
   begin
      -- convert S to stream elements
      for I in S'Range loop
         A (Ada.Streams.Stream_Element_Offset (I)) :=
            Ada.Streams.Stream_Element (Character'Pos (S (I)));
      end loop;
      
      -- create a stream file and write the content (which might be empty)
      Ada.Streams.Stream_IO.Create (F, Ada.Streams.Stream_IO.Out_File, File_Name);
      Ada.Streams.Stream_IO.Write (F, A);
      Ada.Streams.Stream_IO.Close (F);
   end Write_String_To_File;

begin
   -- empty file:
   Write_String_To_File ("file1.txt", "");
   
   -- file with one, non-terminated line:
   Write_String_To_File ("file2.txt", "abc");
   
   -- file with "one line and a half":
   Write_String_To_File ("file3.txt",
      "abc" & Ada.Characters.Latin_1.LF & "xyz");
end Test;


The above is, of course, platform-specific in the sense that some compatibility between characters and stream elements is assumed. This works everywhere.

Having fun with platform-specific newline variants is left as an exercise to the reader. ;-)

-- 
Maciej Sobczak * http://www.inspirel.com


^ permalink raw reply	[relevance 2%]

* Re: ANN: GCC 5.1.0 for Mac OS X
  @ 2015-04-30 12:23  1% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2015-04-30 12:23 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> This is GCC 5.1.0

One user-visible change I've noted, in GNAT.Sockets, is that
Vector_Element.Length (used in Vector_Type, used in Receive_Vector and
Send_Vector) is now of type Interfaces.C.size_t; used to be
Ada.Streams.Stream_Element_Count. I guess this is for efficiency in
scatter-gather operations.

^ permalink raw reply	[relevance 1%]

* Re: Pipes-and-Filters
  @ 2015-04-27  7:18  1% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2015-04-27  7:18 UTC (permalink / raw)


On Sun, 26 Apr 2015 13:18:02 -0700 (PDT), dpt wrote:

> I want to port a Pipes-and-Filters framework
[...]
> Does something equivalent exists in Ada? 

Yes. It is Ada.Streams, the standard.

> I could not find anything by now.

RM 13.13

P.S. Of course, you should be specific about kind of stream implementation
you wanted. There are hundreds if not thousands of.

If you have interprocess communication in mind, streams are not a good idea
of. Stream is merely a transport, you need much meat above a stream to make
a decent communication protocol.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 1%]

* Re: stream_tools 1.0.1
  @ 2015-04-08 21:41  2% ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2015-04-08 21:41 UTC (permalink / raw)


"Per Sandberg" <per.s.sandberg@bahnhof.se> wrote in message 
news:5524cdd3$0$14715$862e30e2@ngroups.net...
> First release of stream-tools
>
> https://github.com/persan/a-stream-tools/releases/tag/1.0.1
>
> They provides a small set of utility streams.

For what it's worth, there was/is a proposal to include what you called a 
"memory stream" in Ada 202x. There's been one in Claw since it was created, 
and I hear that it comes up frequently enough that it probably should be 
standard.

The Claw version (Claw.Marshalling.Buffer_Type) uses a discriminanted type 
so that the dangerous use of 'Address isn't necessary. It expands the buffer 
when necessary, but I would expect that would get dropped from a Standard 
version. And probably the names would get changed. But here's the spec:

package Claw.Marshalling is

  type Buffer_Type(Initial_Length : Ada.Streams.Stream_Element_Count)
  is new Ada.Streams.Root_Stream_Type with private;

  procedure Read(
    Stream : in out Buffer_Type;
    Item   :    out Ada.Streams.Stream_Element_Array;
    Last   :    out Ada.Streams.Stream_Element_Offset);

  procedure Write(
    Stream : in out Buffer_Type;
    Item   : in     Ada.Streams.Stream_Element_Array);

  function Length(Stream : in Buffer_Type)
      return Ada.Streams.Stream_Element_Count;
        -- Return the total length of data written into the buffer.

  procedure Clear(Stream : in out Buffer_Type);
        -- Empty the buffer.

private
....


^ permalink raw reply	[relevance 2%]

* ANN: STM32F4 GNAT Run Time Systems 20150406
@ 2015-04-06 17:27  1% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2015-04-06 17:27 UTC (permalink / raw)


This is the fourth release of a GNAT RTS with the GCC Runtime Library
exception for STM32F4 boards.

(a) Tasking is implemented using FreeRTOS[3], which STMicroelectronics
    provide a copy of with their BSP.

(b) I've included a BSP with minimal higher-level Ada interfaces to the
    board hardware: clock, buttons, LEDs, LCD. In addition, there's a
    machine-generated translation of STMicroelectronics' type-specific
    header in stm32f429xx_h.ads, for low-level interfacing.

The release is at
https://sourceforge.net/projects/stm32f4-gnat-rts/files/20150406/.

From its README,

20150406
========

This release has been reorganised from previous releases.

There is one RTS, stm32f4-disco-rtos, and one BSP, stm32f4-disco-bsp.

Changes to the RTS from the previous release:
---------------------------------------------

These units (and supporting units) are now included:

  Ada.Containers.Bounded_Vectors (*)
  Ada.Containers.Bounded_Hashed_Maps (*)
  Ada.Containers.Generic_Array_Sort
  Ada.Containers.Generic_Constrained_Array_Sort
  Ada.IO_Exceptions
  Ada.Streams
  Ada.Task_Identification
  Interfaces.C
  Interfaces.C.Strings
  System.Assertions

  (*) The new iterators (for some F in Foo loop ...) are NOT supported
      (they require finalization).

The STM32F429I_Discovery tree has been moved to the BSP.

The following tickets have been fixed:

  2  Protected spec hides package Interfaces
  14 Last_Chance_Handler doesn’t stop tasking

Tasking is started by calling Start_FreeRTOS_Scheduler.

^ permalink raw reply	[relevance 1%]

* Did I find mamory leak in Generic Image Decoder (GID) ?
@ 2015-02-02  5:50  1% reinkor
  0 siblings, 0 replies; 200+ results
From: reinkor @ 2015-02-02  5:50 UTC (permalink / raw)


Dear All,

I tried out GID (Generic Image Decoder) from

http://sourceforge.net/projects/gen-img-dec/

The point was to read jpeg-images from my Ada program
"wrapped" in a function:

  function  read_jpg(cfile_jpg : String) return image1.imgc_t;

The source code is below. However, this function seems to eat memory
during (say 200) repeated calls to it (large images, 2000x1800 pixels each).

I did something very very stupid ?

reinert

----------------------------------------------------------------------

Here is the actual code:

with Ada.Streams.Stream_IO;
use Ada.Streams.Stream_IO;

with Ada.Characters.Latin_1;

with Interfaces.C;
with Interfaces.C.Strings;

with system;
with Ada.Unchecked_Conversion;
with Interfaces;

with GID;
with Ada.Calendar;
with Ada.Characters.Handling;           use Ada.Characters.Handling;
with Ada.Text_IO;                       use Ada.Text_IO;
with Ada.Unchecked_Deallocation;

with Text_IO; use Text_IO;




package body file_handling3 is

  package Int_Io is new Text_IO.Integer_Io (Integer);
  use Int_Io;

  use Interfaces;

  type Byte_Array is array(Integer range <>) of Unsigned_8;
  type p_Byte_Array is access Byte_Array;
  procedure Dispose is new Ada.Unchecked_Deallocation(Byte_Array, p_Byte_Array);


  img_buf: p_Byte_Array := null;

  procedure Free_buf is new Ada.Unchecked_Deallocation(Object => Byte_Array, Name => p_Byte_Array);

  procedure Load_raw_image(
    image : in out GID.Image_descriptor;
    buffer: in out p_Byte_Array;
    next_frame: out Ada.Calendar.Day_Duration
  )
  is
    subtype Primary_color_range is Unsigned_8;
    image_width : constant Positive:= GID.Pixel_Width(image);
    image_height: constant Positive:= GID.Pixel_height(image);
    idx: Natural;
    --
    procedure Set_X_Y (x, y: Natural) is
    begin
      idx:= 3 * (x + image_width * (image_height - 1 - y));
    end Set_X_Y;
    --
    procedure Put_Pixel (
      red, green, blue : Primary_color_range;
      alpha            : Primary_color_range
    )
    is
    pragma Warnings(off, alpha); -- alpha is just ignored
    begin
      buffer(idx..idx+2):= (red, green, blue);
      idx:= idx + 3;
      -- ^ GID requires us to look to next pixel on the right for next time.
    end Put_Pixel;

    stars: Natural:= 0;
    procedure Feedback(percents: Natural) is
      so_far: constant Natural:= percents / 5;
    begin
      for i in stars+1..so_far loop
        Put( Standard_Error, '*');
      end loop;
      stars:= so_far;
    end Feedback;

    procedure Load_image is
      new GID.Load_image_contents(
        Primary_color_range, Set_X_Y,
        Put_Pixel, Feedback, GID.fast
      );

  begin
    Dispose(buffer);
    buffer:= new Byte_Array(0..3 * image_width * image_height - 1);
    Load_image(image, next_frame);
  end Load_raw_image;



 function read_jpg(cfile_jpg : String) return image1.imgc_t is
    f: Ada.Streams.Stream_IO.File_Type;
    i: GID.Image_descriptor;
    name : String := cfile_jpg;
    up_name: constant String:= To_Upper(name);
    next_frame, current_frame: Ada.Calendar.Day_Duration:= 0.0;
    isx,isy : Integer;
 begin

    Open(f, In_File, name);
    GID.Load_image_header(
      i,
      Stream(f).all,
      try_tga =>
        name'Length >= 4 and then
        up_name(up_name'Last-3..up_name'Last) = ".TGA"
    );
    Load_raw_image(i, img_buf, next_frame);
    Close(f);
    isx := GID.Pixel_Width(i);
    isy := GID.Pixel_Height(i);
    New_line;
    Put(" isx,isy: ");Put(Integer'Image(isx));Put(Integer'Image(isy));
    New_line;

    declare
      img1 : image1.imgc_t(1..isx,1..isy) := (others => (others => image1.Black));
      Index : Positive;
    begin
      Index := img_buf'First;
      for j in img1'Range (2) loop
          for i in img1'Range (1) loop
              img1(i,isy - j + 1).red   := image1.Short_I(img_buf (Index + 0));
              img1(i,isy - j + 1).green := image1.Short_I(img_buf (Index + 1));
              img1(i,isy - j + 1).blue  := image1.Short_I(img_buf (Index + 2));
              Index := Index + 3;
          end loop;
      end loop;
      Free_buf(img_buf);

      return img1;
    end;
 end read_jpg;

end file_handling3;

^ permalink raw reply	[relevance 1%]

* Re: Ada.Containers warnings with gnat
  2014-11-17  8:13  2%         ` Björn Lundin
@ 2014-11-17 16:39  0%           ` Anh Vo
  0 siblings, 0 replies; 200+ results
From: Anh Vo @ 2014-11-17 16:39 UTC (permalink / raw)


On Monday, November 17, 2014 12:12:05 AM UTC-8, björn lundin wrote:
> On 2014-11-16 18:32, Jeffrey Carter wrote:
> > On 11/16/2014 04:37 AM, Björn Lundin wrote:
> >>
> >> It seems to be ok until I - in the body - do
> >>
> >> with Ada.Streams;
> > 
> > Delete this one and see what happens. It shouldn't change anything since
> > 
> >> with Ada.Streams.Stream_IO;
> > 
> > includes it.
> >  
> Spot on. No warnings anymore.
> Thanks.
> 
> But since the with-clause is in the body,
> one would think that the warnings would refer to the body, not the spec...
> 
> I actually with'ed Ada.Streams for symmetry reason,
> 
> with Ada;
> with Ada.Streams;
> with Ada.Streams.Stream_IO;
> 
> looks better (to me) than just
> 
> with Ada.Streams.Stream_IO;
>  
> It seems that I will need some cognitive training to change my preferences.
 
Yes, you should since it means more with less :-)

Anh Vo.


^ permalink raw reply	[relevance 0%]

* Re: Ada.Containers warnings with gnat
  2014-11-16 17:32  0%       ` Jeffrey Carter
@ 2014-11-17  8:13  2%         ` Björn Lundin
  2014-11-17 16:39  0%           ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: Björn Lundin @ 2014-11-17  8:13 UTC (permalink / raw)


On 2014-11-16 18:32, Jeffrey Carter wrote:
> On 11/16/2014 04:37 AM, Björn Lundin wrote:
>>
>> It seems to be ok until I - in the body - do
>>
>> with Ada.Streams;
> 
> Delete this one and see what happens. It shouldn't change anything since
> 
>> with Ada.Streams.Stream_IO;
> 
> includes it.
> 

Spot on. No warnings anymore.
Thanks.

But since the with-clause is in the body,
one would think that the warnings would refer to the body, not the spec...

I actually with'ed Ada.Streams for symmetry reason,

with Ada;
with Ada.Streams;
with Ada.Streams.Stream_IO;

looks better (to me) than just

with Ada.Streams.Stream_IO;


It seems that I will need some cognitive training to change my preferences.


--
Björn


^ permalink raw reply	[relevance 2%]

* Re: Ada.Containers warnings with gnat
  2014-11-16 11:37  2%     ` Björn Lundin
@ 2014-11-16 17:32  0%       ` Jeffrey Carter
  2014-11-17  8:13  2%         ` Björn Lundin
  0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2014-11-16 17:32 UTC (permalink / raw)


On 11/16/2014 04:37 AM, Björn Lundin wrote:
> 
> It seems to be ok until I - in the body - do
> 
> with Ada.Streams;

Delete this one and see what happens. It shouldn't change anything since

> with Ada.Streams.Stream_IO;

includes it.

-- 
Jeff Carter
"What I wouldn't give for a large sock with horse manure in it."
Annie Hall
42

^ permalink raw reply	[relevance 0%]

* Re: Ada.Containers warnings with gnat
  2014-11-16 10:05  0%   ` Björn Lundin
@ 2014-11-16 11:37  2%     ` Björn Lundin
  2014-11-16 17:32  0%       ` Jeffrey Carter
  0 siblings, 1 reply; 200+ results
From: Björn Lundin @ 2014-11-16 11:37 UTC (permalink / raw)


On 2014-11-16 11:05, Björn Lundin wrote:

It seems to be ok until I - in the body - do

with Ada.Streams;
with Ada.Streams.Stream_IO;

With no code actually using stream_io I get



   21.   package Sample_Map_Pack is new Ada.Containers.Ordered_Maps
          |
        >>> warning: in instantiation at a-coorma.ads:266
        >>> warning: no entities of package "Ada.Streams" are referenced

    27.   package Marketid_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:154
        >>> warning: in instantiation at a-cohama.adb:85
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:165
        >>> warning: in instantiation at a-cohama.adb:85
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:165
        >>> warning: in instantiation at a-cohama.adb:103
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:154
        >>> warning: in instantiation at a-cohama.adb:104
        >>> warning: no entities of package "Ada.Streams" are referenced

    34.   package Winner_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:154
        >>> warning: in instantiation at a-cohama.adb:85
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:165
        >>> warning: in instantiation at a-cohama.adb:85
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:165
        >>> warning: in instantiation at a-cohama.adb:103
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:154
        >>> warning: in instantiation at a-cohama.adb:104
        >>> warning: no entities of package "Ada.Streams" are referenced

    41.   package Win_Place_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:154
        >>> warning: in instantiation at a-cohama.adb:85
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:165
        >>> warning: in instantiation at a-cohama.adb:85
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:165
        >>> warning: in instantiation at a-cohama.adb:103
        >>> warning: no entities of package "Ada.Streams" are referenced
        >>> warning: in instantiation at a-chtgop.ads:154
        >>> warning: in instantiation at a-cohama.adb:104
        >>> warning: no entities of package "Ada.Streams" are referenced

 763 lines: No errors, 50 warnings



If I then move on to actually use Streams_io, the warnings are reduced to


==============Error messages for source file:
/home/bnl/bnlbot/botstart/bot-1-0/source/ada/local/utils/simulation_storage.ads
    21.   package Sample_Map_Pack is new Ada.Containers.Ordered_Maps
          |
        >>> warning: in instantiation at a-coorma.ads:266
        >>> warning: no entities of package "Ada.Streams" are referenced

    27.   package Marketid_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced

    34.   package Winner_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced

    41.   package Win_Place_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced

 763 lines: No errors, 8 warnings



the actual usage is just

    declare
     File   : Ada.Streams.Stream_IO.File_Type;
     Stream : Ada.Streams.Stream_IO.Stream_Access;
     Filename : String := Global_Map_Files(Marketid).Filename.Fix_String;
    begin
      Ada.Streams.Stream_IO.Open
          (File => File,
           Name => Filename,
           Mode => Ada.Streams.Stream_IO.In_File);
      Stream := Ada.Streams.Stream_IO.Stream (File);
      Marketid_Map_Pack.Map'Read(Stream, Marketid_Map);
      Ada.Streams.Stream_IO.Close(File);
      Log(Object & Service, "Marketid_Map read from file " & Filename);
    end;

for 3 different maps, and 3 corresponding Write sections


however I have put the generic instansiation between
pragma Warnings(Off)
pragma Warnings(On)

but it is still somewhat strange I think




--
Björn


^ permalink raw reply	[relevance 2%]

* Re: Things that OO programming lacks
  2014-11-15 19:46  1%                                               ` Georg Bauhaus
@ 2014-11-16 10:18  0%                                                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2014-11-16 10:18 UTC (permalink / raw)


On Sat, 15 Nov 2014 20:46:54 +0100, Georg Bauhaus wrote:

> On 14.11.14 17:32, Dmitry A. Kazakov wrote:
>>  But, again, what would be better?
> 
>>> Better? A mode of expressing what we know beyond our objects,
>>> in dedicated language:
> 
> I mean our objects, not OO objects. This is about expressing notions.

There is no "our objects" in non-object-oriented paradigms.

>>> For example, "connections" may refer to order of calls in time,
>>> and to "flow" caused by "data".
>>
>> For example Ada.Streams show us "connecting patterns".
> 
> Ada.Streams doesn't show much, since some connections are implicit.
> Which is the point. "Open" would be a hint at the object to/from
> which data will flow, but you'd still have questions if a different
> task object somehow has access to the stream.

Again, what paradigm are you talking about? Task is an object in OO. In
other paradigms there no such thing. E.g. in the procedural paradigm there
will be a set of subprograms to start, stop implicit tasks, proxy data
types like task ID, but never an explicit task object.

> You look at the task's definition,

And this is where you must start. Since the task is not an object, how a
task is spelled in your paradigm?

>>> Another important example is events.
>>
>> I didn't list event-driven ...  nobody should seriously consider
>> it as useful.
> 
> GUI...  Suppose it could be made less of a burden to program
> any advanced multithreaded GUI, adding controls and interactions.

GUI frameworks you are talking about are not written or interfaced in a
data-driven language (DDL). They are in OOPLs. The event-driven
architecture of such applications /= the programming paradigm, which is
still OO and partially procedural. 

When GUI applications are written in a DDL they are disaster, example:
LabView.

 > I want a program text to tell its readers what is supposed to happen
> in certain situations.  I want that information to be explicitly
> stated directly in source text, without inference, with the help
> of dedicated visible language features.

This is what *any* programming language does. Its text (program) describes
behavior (in some computational environment). What you probably missed is
that the behavior is *always* described in the language terms. Thus
"happens" and "situation" are the language domain terms, not the reality
terms. If you accept that, your statement is a truism. If you mean the
reality, the statement is just meaningless. Only God speaks the language
which computational environment is the reality.

> If Obj_1 and Obj_2 are objects, then I would like the language
> to have syntax, say "(*)", for
> 
>     Obj_1 (*) Obj_2
> 
> which would *not* be a function call.

Then these are not objects. The only thing you can do with objects is to
use the operations of. This is called typing.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Ada.Containers warnings with gnat
  2014-11-15 18:01  1% ` Jeffrey Carter
@ 2014-11-16 10:05  0%   ` Björn Lundin
  2014-11-16 11:37  2%     ` Björn Lundin
  0 siblings, 1 reply; 200+ results
From: Björn Lundin @ 2014-11-16 10:05 UTC (permalink / raw)


On 2014-11-15 19:01, Jeffrey Carter wrote:
> On 11/15/2014 07:35 AM, Björn Lundin wrote:
>>
>>
>> The simulator was in a single file before -> no problem.
>> So I then refactored and created a storage package and suddenly I get
>> warnings like
>>
>>  /home/bnl/bnlbot/botstart/bot-1-0/source/ada/local/utils/simulation_storage.ads
>>     17.   package Sample_Map_Pack is new Ada.Containers.Ordered_Maps
>>           |
>>         >>> warning: in instantiation at a-coorma.ads:266
>>         >>> warning: no entities of package "Ada.Streams" are referenced
>>
>>     23.   package Marketid_Map_Pack is new Ada.Containers.Hashed_Maps
>>           |
>>         >>> warning: in instantiation at a-cohama.ads:342
>>         >>> warning: no entities of package "Ada.Streams" are referenced
>>
>>     30.   package Winner_Map_Pack is new Ada.Containers.Hashed_Maps
>>           |
>>         >>> warning: in instantiation at a-cohama.ads:342
>>         >>> warning: no entities of package "Ada.Streams" are referenced
>>
>>     37.   package Win_Place_Map_Pack is new Ada.Containers.Hashed_Maps
>>           |
>>         >>> warning: in instantiation at a-cohama.ads:342
>>         >>> warning: no entities of package "Ada.Streams" are referenced
> 
> Did you change your compiler options? It appears that the compiler's
> implementations of these standard pkgs with Ada.Streams but never reference it,
> and that you're compiling with warnings of unreferenced things turned on.
> 


No, I did not. I just put the code into a package instead. That's it.
And I have never seen these kind of warnings on compiler/language
packages. It is like it recompiles them.

--
Björn

^ permalink raw reply	[relevance 0%]

* Re: Things that OO programming lacks
  2014-11-14 16:32  1%                                             ` Things that OO programming lacks Dmitry A. Kazakov
@ 2014-11-15 19:46  1%                                               ` Georg Bauhaus
  2014-11-16 10:18  0%                                                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2014-11-15 19:46 UTC (permalink / raw)


On 14.11.14 17:32, Dmitry A. Kazakov wrote:
>  But, again, what would be better?

>> Better? A mode of expressing what we know beyond our objects,
>> in dedicated language:

I mean our objects, not OO objects. This is about expressing notions.

>> For example, "connections" may refer to order of calls in time,
>> and to "flow" caused by "data".
>
> For example Ada.Streams show us "connecting patterns".

Ada.Streams doesn't show much, since some connections are implicit.
Which is the point. "Open" would be a hint at the object to/from
which data will flow, but you'd still have questions if a different
task object somehow has access to the stream. You look at the task's
definition, and you still miss the part that caused the I/O disaster.
That's because "connecting" data to the stream can happen anywhere
this stream is visible, and if you do *not* apply C-style discipline,
then the *language* won't help. (Broken record: "bad design, bad
design, bad design, ..." Another broken record: "use int properly,
use int properly, use int properly, ...")

Any competent engineer can write perfectly good programs in
the assembly language he knows, for the machine he knows.
That's beside the point, though, and it hides all the difficulty
that an undefined (before the fact) word like "competent engineer"
must produce.

>> Another important example is events.
>
> I didn't list event-driven ...  nobody should seriously consider
> it as useful.

GUI...  Suppose it could be made less of a burden to program
any advanced multithreaded GUI, adding controls and interactions.

> In relational there are relations (and a
> fixed set of types).

(I learned that in "relational" there are arbitrarily many types
("domains"). Even in some of its restricted SQL incarnations.)

> If you want going data-driven

I don't want to be driven. ;-) Starting from my universe, I notice that
it determines orders which cannot be designed away:

"First the water, then the acid, otherwise it won't be placid!"
"Be sure to open the lid before you add further ingredients,
  then close the lid again."

I need necessary orders to be expressed, not denied for methodological
reasons of a foreign universe. In short, I want a higher level:

- procedural includes assembly power (minus a bit)
- OO includes procedural power (minus a bit)
- ??? includes OO power (minus a bit)  <-- this I want

I want a program text to tell its readers what is supposed to happen
in certain situations.  I want that information to be explicitly
stated directly in source text, without inference, with the help
of dedicated visible language features.

By analogy, monads are a way of integrating I/O with functionism.
I want something like this in the OO programming world, at the level
of language definition, so that I can answer questions I might
be asked about a program and its effects simply by pointing my finger
at some one line of text.

If Obj_1 and Obj_2 are objects, then I would like the language
to have syntax, say "(*)", for

    Obj_1 (*) Obj_2

which would *not* be a function call.  I would like the language
to have syntax, say "{<#}" or "{#>}", for

   Event_1 {#>}  Obj_1, Obj_2, Obj_3

The cheap language version would start to make these pieces of syntax
mark relationSHIPs first, and then the compiler would check that these
relationships actually exist. If the marks turn into relations, fine,
but that makes relations just a way to formalize specific relationships
behind the scene.



^ permalink raw reply	[relevance 1%]

* Re: Ada.Containers warnings with gnat
  2014-11-15 14:35  2% Ada.Containers warnings with gnat Björn Lundin
@ 2014-11-15 18:01  1% ` Jeffrey Carter
  2014-11-16 10:05  0%   ` Björn Lundin
  0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2014-11-15 18:01 UTC (permalink / raw)


On 11/15/2014 07:35 AM, Björn Lundin wrote:
> 
> 
> The simulator was in a single file before -> no problem.
> So I then refactored and created a storage package and suddenly I get
> warnings like
> 
>  /home/bnl/bnlbot/botstart/bot-1-0/source/ada/local/utils/simulation_storage.ads
>     17.   package Sample_Map_Pack is new Ada.Containers.Ordered_Maps
>           |
>         >>> warning: in instantiation at a-coorma.ads:266
>         >>> warning: no entities of package "Ada.Streams" are referenced
> 
>     23.   package Marketid_Map_Pack is new Ada.Containers.Hashed_Maps
>           |
>         >>> warning: in instantiation at a-cohama.ads:342
>         >>> warning: no entities of package "Ada.Streams" are referenced
> 
>     30.   package Winner_Map_Pack is new Ada.Containers.Hashed_Maps
>           |
>         >>> warning: in instantiation at a-cohama.ads:342
>         >>> warning: no entities of package "Ada.Streams" are referenced
> 
>     37.   package Win_Place_Map_Pack is new Ada.Containers.Hashed_Maps
>           |
>         >>> warning: in instantiation at a-cohama.ads:342
>         >>> warning: no entities of package "Ada.Streams" are referenced

Did you change your compiler options? It appears that the compiler's
implementations of these standard pkgs with Ada.Streams but never reference it,
and that you're compiling with warnings of unreferenced things turned on.

-- 
Jeff Carter
"Gentlemen, you can't fight in here. This is the War Room!"
Dr. Strangelove
30


^ permalink raw reply	[relevance 1%]

* Ada.Containers warnings with gnat
@ 2014-11-15 14:35  2% Björn Lundin
  2014-11-15 18:01  1% ` Jeffrey Carter
  0 siblings, 1 reply; 200+ results
From: Björn Lundin @ 2014-11-15 14:35 UTC (permalink / raw)



Hi!
I'm using a db to keep data in, that I retrieve and
put into ordered and hashed maps from Ada.Containers.

I do this to
 * learn to use Ada standard containers, instead of home-rolled lists
 * to simulate outcome of different parameters into a business modell

Reading from db takes about 1 hour, with i5/ssd/12 gb ram
needless to say, I'd like this to go faster.

So, I rewrote the simulator to use the mentioned containers.
I then run it once, and save the maps into (largish ) files
instead via streams and 'write/'read.

fantastic performance.

The simulator was in a single file before -> no problem.
So I then refactored and created a storage package and suddenly I get
warnings like

 /home/bnl/bnlbot/botstart/bot-1-0/source/ada/local/utils/simulation_storage.ads
    17.   package Sample_Map_Pack is new Ada.Containers.Ordered_Maps
          |
        >>> warning: in instantiation at a-coorma.ads:266
        >>> warning: no entities of package "Ada.Streams" are referenced

    23.   package Marketid_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced

    30.   package Winner_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced

    37.   package Win_Place_Map_Pack is new Ada.Containers.Hashed_Maps
          |
        >>> warning: in instantiation at a-cohama.ads:342
        >>> warning: no entities of package "Ada.Streams" are referenced



what do the mean ?
The body of the package uses streams like

    Log("read Marketid_Map from file ");
    declare
     File   : Ada.Streams.Stream_IO.File_Type;
     Stream : Ada.Streams.Stream_IO.Stream_Access;
     Filename : String := Map_files(Marketid).Filename.Fix_String;
    begin
      Ada.Streams.Stream_IO.Open
          (File => File,
           Name => Filename,
           Mode => Ada.Streams.Stream_IO.In_File);
      Stream := Ada.Streams.Stream_IO.Stream (File);
      Marketid_Map_Pack.Map'Read(Stream, Marketid_Map);
      Ada.Streams.Stream_IO.Close(File);
      Log("Marketid_Map read from file " & Filename);
    end;




package spec is

---------------------------
with Ada;
with Ada.Strings;
with Ada.Strings.Hash;

with Ada.Containers;
with Ada.Containers.Hashed_Maps;
with Ada.Containers.Ordered_Maps;

with Calendar2;
with Bot_Types; use Bot_Types;
with Table_Apricesfinish;
with Table_Arunners;

package Simulation_Storage is

  package Sample_Map_Pack is new Ada.Containers.Ordered_Maps
        (Key_Type     => Calendar2.Time_Type,
         Element_Type => Table_Apricesfinish.Apricesfinish_List_Pack2.List,
         "<"          => Calendar2."<",
         "="          => Table_Apricesfinish.Apricesfinish_List_Pack2."=");

  package Marketid_Map_Pack is new Ada.Containers.Hashed_Maps
        (Market_Id_Type,
         Sample_Map_Pack.Map,
         Ada.Strings.Hash,
         "=",
         Sample_Map_Pack."=");

  package Winner_Map_Pack is new Ada.Containers.Hashed_Maps
        (Market_Id_Type,
         Table_Arunners.Arunners_List_Pack2.List,
         Ada.Strings.Hash,
         "=",
         Table_Arunners.Arunners_List_Pack2."=");

  package Win_Place_Map_Pack is new Ada.Containers.Hashed_Maps
        (Market_Id_Type,
         Market_Id_Type,
         Ada.Strings.Hash,
         "=",
         "=");


  procedure Create_Files_From_Database;
  procedure Fill_Maps(Marketid_Map  : out Marketid_Map_Pack.Map;
                      Winner_Map    : out Winner_Map_Pack.Map;
                      Win_Place_Map : out Win_Place_Map_Pack.Map) ;


end Simulation_Storage;



--
Björn

^ permalink raw reply	[relevance 2%]

* Re: Things that OO programming lacks
  @ 2014-11-14 16:32  1%                                             ` Dmitry A. Kazakov
  2014-11-15 19:46  1%                                               ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2014-11-14 16:32 UTC (permalink / raw)


On Fri, 14 Nov 2014 16:29:56 +0100, G.B. wrote:

> On 14.11.14 14:35, Dmitry A. Kazakov wrote:
>>> That's the theory. But in practice, having all the hard stuff written
>>> >already just promotes cutting and pasting of a different color. The code
>>> >that*uses*  those classes is normally not reusable. That's what is cutting
>>> >and pasting. It's been shoved down a level or two.
>> Maybe. But, again, what would be better?
> 
> Better? A mode of expressing what we know beyond our objects,
> in dedicated language:
> 
> Since programmers are starting to know more about patterns
> of connecting objects, I suppose something expressing those
> patterns more clearly would be useful.

What objects? There is none, as you thrown OO under the bus...

> For example, "connections" may refer to order of calls in time,
> and to "flow" caused by "data".

For example Ada.Streams show us "connecting patterns".

> Another important example is events.

I didn't list event-driven AKA data-driven paradigm in my list of
paradigms, since it is so horrific, that nobody should seriously consider
it as useful.

> Consider a system with many inputs, many outputs, and also
> some treads.

Which are? Remember the paradigms. If you are not going to introduce a new
one, there are no things you listed. In OO there are objects. In the
procedural paradigm there are subprograms (and a fixed set of types). In
functional there are functions. In relational there are relations (and a
fixed set of types). That is.

If you want going data-driven show how it could be done in the first
approximation at least more safer than randomly generated hexadecimal
code... (Saying no word about reuse)

[...]
> To me these look like a poor workarounds, Pre more than the types TK,
> even when they assist the client programmer writing calls of
> subprograms in proper order.

This is meaningless at best. If subprograms cannot be called freely, this
is a bad [procedural] design, per definition of. You should fix your
decomposition, as it evidently goes along wrong lines = couples
subprograms. Subprograms in procedural decomposition meant independent with
well defined interfaces. BTW, from this immediately follows, for example,
that global variables are bad.

> To have language for expressing connections in a program would
> be better.  We only got tools that show graphs of a few arrows,
> as in design diagrams for interfaces and models. But we do not
> really have source text specifically addressing order of events,
> and connections made on the occasion.

Not at all. There are tons of graphical languages having fancy lines all
over the screen. That helps in no way. In fact all of them are greatly less
safe, unmaintainable and inefficient as a bonus.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 1%]

* Re: What exactly is the licensing situation with GNAT?
  @ 2014-11-14 13:35  1%                                         ` Dmitry A. Kazakov
    0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2014-11-14 13:35 UTC (permalink / raw)


On Fri, 14 Nov 2014 10:38:17 +0000 (UTC), Stan Mills wrote:

> On 2014-11-14, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On Fri, 14 Nov 2014 09:02:49 +0000 (UTC), Stan Mills wrote:
>>
>>> On 2014-11-14, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>>>> On Thu, 13 Nov 2014 17:36:06 -0800, Hubert wrote:
>>>>
>>>>> That is a point that I have been contemplating for a while now but in 
>>>>> conjunction with Object Oriented Programming. When I look back at my 
>>>>> career I realize that I became lazier and lazier in terms of designing 
>>>>> before programming with the advent of OOP. I think OOP is designed to to 
>>>>> just that: 
>>>>
>>>> Hmm, actually OOD and OOP require more upfront design than traditional
>>>> procedural approach. Ad-hoch subprograms are much easier and quicker stuff
>>>> than ad-hoc type + subprograms (=class) with thinking about possible
>>>> inheritance etc.
>>> 
>>> That's if you are responsible for the whole thing or care about doing it properly.
>>> 
>>> The way OO is used today all the real work is expected to have already been
>>> done by the class library writers and the "coder" just cuts and pastes his
>>> way to the end of the program. Next!
>>
>> This is how everything is done today. Certainly it is not OO's fault or
>> OO's feature.
> 
> Oh, I beg to differ. Sun certainly dumbed down programming when they
> designed Java. It's about making unqualified people "productive" and the
> best way to do that is for qualified people to write as much code as
> possible for unqualified people to use. The primary feature of OO in
> practice is the huge set of class libraries to reduce the amount of future
> coding as much as possible to simple cut and paste of existing bad code.

Well, and the alternative would be? To re-implement everything each time?
Actually, the maturity of an engineering discipline is measured by the
level of reuse of standardised solutions and components.

> The
> only thing a regular programmer can't write in Java or C++ today is
> something that doesn't already have a class library to do it for him.

Maybe. In this context, can the regular programmer do anything better with
any of competing paradigms:

1. Procedural
2. Functional
3. Relational
 
I bet, that anybody is far better off with OO than with any from the above.

>> On the contrary, OO, specifically the concepts of inheritance and
>> instances, addresses software-reuse, which is exactly the opposite to the
>> cut and paste approach.
> 
> That's the theory. But in practice, having all the hard stuff written
> already just promotes cutting and pasting of a different color. The code
> that *uses* those classes is normally not reusable. That's what is cutting
> and pasting. It's been shoved down a level or two.

Maybe. But, again, what would be better?

As a simple example consider Ada's design of, say, Ada.Streams. This is an
OO design. The type Root_Stream_Type is as tagged as it could be.

Now, take either of the paradigms #1, #2, #3 and outline a better design of
streams. Could you?

> Don't try and impose your sense of rigor and order on chaos and think
> everybody works according to sound software engineering practice ;-)
[...]

But this is not an OO problem. The problem is with CS as a whole and with
missing software market. You need two things for having a decent
engineering discipline, that is a sound science (CS is trash) and a working
economical stimulus rewarding quality products and punishing swindlers (SW
market is ruined).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 1%]

* Re: A bad counterintuitive behaviour of Ada about OO
  @ 2014-08-08  8:34  1%             ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2014-08-08  8:34 UTC (permalink / raw)


On 08-Aug-14 01:54, Maciej Sobczak wrote:
> W dniu czwartek, 7 sierpnia 2014 10:50:52 UTC+2 użytkownik Dmitry A. Kazakov napisał:
>
>>> and no support for type covariance on return
>>> type Ada is way more broken than other languages I am aware of.
>>
>> I don't understand this. The return type is covariant in Ada.
>
> Can I have Better_Factory type with a primitive operation returning Better_Product?
>
> No, because Better_Product is a different type than Product and such operation
> would not be considered overriding. This works properly in just about any other
> language with support for OO.
>

Can't you use some class-wide functions, some primitive functions, and 
the Generic_Dispatching_Constructor function to do this?

IIRC something like:

   Type Base is abstract tagged null record;
   Function Product return Base is abstract; -- Primitive function.
   Function Get_Product return Base'Class;   -- Dispatches call to Product.
   -- Uses generic_dispatching constructor.
   Function Make(Stream : not null access
                          Ada.Streams.Root_Stream_Type'Class)
         return Base'Class;                  -- For Stream-creation.
   -- Perhaps some other creation functions.
   -- ...

   Type Child is tagged ...

Or am I misunderstanding you?

^ permalink raw reply	[relevance 1%]

* Re: On packages hierarchy
  2014-07-29 12:36  0%       ` Victor Porton
@ 2014-07-29 18:44  1%         ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2014-07-29 18:44 UTC (permalink / raw)


On 29-Jul-14 06:36, Victor Porton wrote:
> My raptor stream is derived from some my base class.

Why?
Is there some reason it needs to be exposed to the rest of the binding?
If so, why does it need to be exposed separately from the derivation of 
Root_Stream_Type? This is to say given a derivation from 
Root_Stream_Type, why not have all parameters that need that type use 
that type?

Is it because you want some uniformity of interface?
In that case you could have the "base class" be an interface rather than 
a tagged type -- in fact you could do both: have a base-interface from 
which your normal raptor-types are rooted in an abstract type and have 
the limited types derive from the interface. Ex:

     package test is
         Type Raptor is limited interface;
         -- All common operations of all raptor-types go here.
         Procedure First_Stub(Input: Raptor) is abstract;



         Type Raptor_Base is abstract new Raptor with null record;

         Type Raptor_Stream is new Ada.Streams.Root_Stream_Type and 
Raptor with
           null record;

         Overriding
         Procedure First_Stub(Input: Raptor_Stream) is null;

         Overriding
         procedure Read
           (Stream : in out Raptor_Stream;
            Item   : out Stream_Element_Array;
            Last   : out Stream_Element_Offset)
         is null;

         Overriding
         procedure Write
           (Stream : in out Raptor_Stream;
            Item   : Stream_Element_Array)
         is null;
     end test;



> Due no multiple type inheritance in Ada, it cannot be also derived from
> Root_Stream_Type. So I need a wrapper type.

Why expose the raptor-stream at all?
A lot of your problems seem to stem from trying to build from the 
low-level thin-binding to the high-level thick-binding while trying to 
keep [and expose] the low-level/thin-binding; try going the other way:
*Design the high-level binding first, /then/ in the hidden 
implementation/bodies implement-and-use the low-level binding.*

As a trivial example, consider OpenGL's gl_enum type and all the 
functions that use it with restrictions best used/expressed as 
full-blown types:

     package GL_Example is
         GL_MAX_LIGHTS : constant := 8;

         -- Light is a biased-representation of 1..8.
         -- May be implementation dependant, can be rectified with
         -- an expression function in the implementation call.
         Type Light_Number is range 1..GL_MAX_LIGHTS with size => 3;

         -- Safe_Float disallows non-numeric values.
         SubType Safe_Float is Float range Float'First..Float'Last;

         -- Enumeration of Open_GL's parameters for glLightf
         Type Light_Parameters is
           (SPOT_EXPONENT, SPOT_CUTOFF, CONSTANT_ATTENUATION, 
LINEAR_ATTENUATION, QUADRATIC_ATTENUATION);

         -- Thick Binding function.
         Procedure Light( Light_No  : Light_Number;
                          Parameter : Light_Parameters;
                          Value     : Safe_Float
                        ) with Inline;
     end GL_Example;

     package body GL_Example is
         -- GL Types
         Type GL_Enum  is new Interfaces.Unsigned_32;
         Type GL_Float is new Interfaces.IEEE_Float_32
			 Range Interfaces.IEEE_Float_32'Range;

         -- Conversions
         Function Convert is new Unchecked_Conversion
           (Source => Light_Number, Target => GL_Enum);
         Function Convert is new Unchecked_Conversion
           (Source => Light_Parameters, Target => GL_Enum);
         Function Convert is new Unchecked_Conversion
           (Source => Safe_Float, Target => GL_Float);



         -- Imported (thin-binding) functions
         procedure glLightf (light, pname : GL_Enum; param : GL_Float)
	with Import, Convention => stdcall, External_Name => "glLightf";

         -- Thick-binding bodies
         Procedure Light (Light_No  : Light_Number;
                          Parameter : Light_Parameters;
                          Value     : Safe_Float
                         ) is
         begin
             glLightf( Convert(Light_No), Convert(Parameter), 
Convert(Value) );
         end Light;

     end GL_Example;


^ permalink raw reply	[relevance 1%]

* Re: On packages hierarchy
  2014-07-28 23:24  1%     ` Shark8
@ 2014-07-29 12:36  0%       ` Victor Porton
  2014-07-29 18:44  1%         ` Shark8
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2014-07-29 12:36 UTC (permalink / raw)


Shark8 wrote:

> On 28-Jul-14 10:35, Victor Porton wrote:
>>> Why not just have a single stream type?
>> I want to make an interface to streams of Raptor C library.
>>
>> Because, as you say, we are to have a single stream type, this type
>> should be well-interfaces with that "single" Ada stream class.
>>
>>> >Moreover, Ada's root-stream is abstract, so you can't have objects of
>>> >that type.
>> Well, I mean object of Root_Stream_Type'Class.
> 
> Again, why?
> Your Raptor-stream type /will/ be an concrete-instance of
> Root_stream_type, and a member of its class, won't it? I mean unless I'm
> completely misunderstanding you...

My raptor stream is derived from some my base class.

Due no multiple type inheritance in Ada, it cannot be also derived from 
Root_Stream_Type. So I need a wrapper type.

>      Use Ada.Streams;
>      Type Dave is new Root_Stream_Type with null record;
> 
> 
>      overriding procedure Read
>       (Stream : in out Dave;
>        Item   : out Stream_Element_Array;
>        Last   : out Stream_Element_Offset);
> 
> 
>     procedure Write
>       (Stream : in out Dave;
>        Item   : Stream_Element_Array);
> 
> ---- Implementation:
> 
>   overriding procedure Read
>       (Stream : in out Dave;
>        Item   : out Stream_Element_Array;
>        Last   : out Stream_Element_Offset)
>     is null; -- Replace this with actual implementation.
> 
>   overriding procedure Write
>       (Stream : in out Dave;
>        Item   : Stream_Element_Array)
>     is null; -- Replace this with actual implementation.
> 
> Perhaps reading the first and second posts on this thread will help you
> understand:
> 
> http://computer-programming-forum.com/44-ada/07c6cd94dbb2d6b1.htm
-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 0%]

* Re: On packages hierarchy
  @ 2014-07-28 23:24  1%     ` Shark8
  2014-07-29 12:36  0%       ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2014-07-28 23:24 UTC (permalink / raw)


On 28-Jul-14 10:35, Victor Porton wrote:
>> Why not just have a single stream type?
> I want to make an interface to streams of Raptor C library.
>
> Because, as you say, we are to have a single stream type, this type should
> be well-interfaces with that "single" Ada stream class.
>
>> >Moreover, Ada's root-stream is abstract, so you can't have objects of
>> >that type.
> Well, I mean object of Root_Stream_Type'Class.

Again, why?
Your Raptor-stream type /will/ be an concrete-instance of 
Root_stream_type, and a member of its class, won't it? I mean unless I'm 
completely misunderstanding you...

     Use Ada.Streams;
     Type Dave is new Root_Stream_Type with null record;


     overriding procedure Read
      (Stream : in out Dave;
       Item   : out Stream_Element_Array;
       Last   : out Stream_Element_Offset);


    procedure Write
      (Stream : in out Dave;
       Item   : Stream_Element_Array);

---- Implementation:

  overriding procedure Read
      (Stream : in out Dave;
       Item   : out Stream_Element_Array;
       Last   : out Stream_Element_Offset)
    is null; -- Replace this with actual implementation.

  overriding procedure Write
      (Stream : in out Dave;
       Item   : Stream_Element_Array)
    is null; -- Replace this with actual implementation.

Perhaps reading the first and second posts on this thread will help you 
understand:

http://computer-programming-forum.com/44-ada/07c6cd94dbb2d6b1.htm


^ permalink raw reply	[relevance 1%]

* Re: A custom stream type
  @ 2014-07-27 20:39  2% ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2014-07-27 20:39 UTC (permalink / raw)


On 14-07-27 23:08 , Victor Porton wrote:
> I want to create a custom stream type (not the files provided by the OS, but 
> something different, such as saving results of write operations into a 
> container, or calling a C stream library or whatever).
> 
> How to do it with Ada2012?

Derive your stream type from the root of all streams:


   with Ada.Streams;

   ...


   type My_Stream is new Ada.Streams.Root_Stream_Type
   with record ... end record;


and then override (i.e. implement) the Read and Write operations for
My_Stream.

See the package Ada.Streams, RM 13.13.1.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



^ permalink raw reply	[relevance 2%]

* Re: Ada's ranking of popularity at IEEE Spectrum
  @ 2014-07-27 20:19  1%         ` sbelmont700
  0 siblings, 0 replies; 200+ results
From: sbelmont700 @ 2014-07-27 20:19 UTC (permalink / raw)


On Saturday, July 26, 2014 10:01:17 PM UTC-4, David Thompson wrote:
> 
> Huh? Except for application data, which a general-purpose transport
> 
> can't know about, OpenSSL goes to quite a bit of effort to make its
> 
> API about as strongly typed as can be accomplished in C, with mostly
> 
> opaque structs, access routines, shims for ASN.1 and PEM, etc. It's
> 
> not perfect, and certainly not as easy as in Ada, but it's far from
> 
> the all-too-common-in-C void* madness you suggest.


It all comes down to just how "Ada-like" you want it to be.  OpenSSL doesn't throw exceptions, so does the benefits of using them in a binding outweigh the slight deviation from the spec?  The write function takes a length, which in Ada would be inherent in the array, so do you deviate from the spec again?  It doesn't have reference counting (IIRC), so do you use controlled types?  Or do you even go 'full Ada' and make the client instantiate Integer_SSL or Float_SSL functions instead of sending everything as a string?  Or maybe even model it using Ada.Streams?

My point is that even 'good' APIs (like OpenSSL or OpenGL) inherently stink of untyped C, and it becomes a delicate balancing act of figuring out at what point you've failed to implement the spec everyone knows and instead succeeded at inventing a new (better) API that nobody wants.  Victor Porton's copious posts seem to suggest similar problems.

-sb


^ permalink raw reply	[relevance 1%]

* Re: Help with type definition
  @ 2014-06-28  7:26  1%   ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2014-06-28  7:26 UTC (permalink / raw)


On 27-Jun-14 16:05, hanslad@gmail.com wrote:
> Is there a type in Ada for unbounded byte arrays similar to the unbounded string?

You could use a vector; but you really don't need it for this problem; 
in fact it seems you're better off using a regular array.

>   "A ByteString is encoded as sequence of bytes preceded by its
>    length in bytes. The length is encoded as a 32-bit signed
>    integer as described above. If the length of the byte string
>    is -1 then the byte string is 'null'."

So, your from-the-wire reading algorithm would be something like this:

Type Byte_String is Array(Positive range <>) of Interfaces.Unsigned_8;

-- Assuming use of Ada.Streams
Function Read(Stream : not null access Root_Stream_Type'Class) return 
Byte_String is
   Length : Interfaces.Integer_32:= Interfaces.Integer_32'Input(Stream);
begin
   Return Result : Byte_Array(1..Length) do
    For Index in Result'Range loop
     Result(Index):= Interfaces.Unsigned_8'Input(Stream);
    end loop;
   end return;
end Read;

^ permalink raw reply	[relevance 1%]

* Re: Serial port configuration
  2014-04-06 18:57  0% ` Simon Wright
@ 2014-04-07 11:44  0%   ` hreba
  0 siblings, 0 replies; 200+ results
From: hreba @ 2014-04-07 11:44 UTC (permalink / raw)


On 04/06/2014 03:57 PM, Simon Wright wrote:
> hreba <hreba@terra.com.br> writes:
>
>> package body SerAux is
>>
>>     type Port_Data is new int;
>>     type Port_Data_Access is access Port_Data;
>>     type Port is new Ada.Streams.Root_Stream_Type with record
>>        H : Port_Data_Access;
>>     end record;
>
> The declaration of type Port needs to be in the spec; and you need to
> have the spec of Read there also.
>
>>     overriding procedure Read
>>       (--Port   : in out Serial_Port;
>>        Port   : in out Port;
>
> You can't use the name Port twice like that. I'd suggest using
> Serial_Port for the type name, like the original (why change?).

Thanks for the hints.
>
> In fact, why not just copy the contents of the GNAT version and change
> the bits you need to?
>
This might not be the most elegant solution, but the one with the least 
effort. I think I'll try that.
-- 
hreba

^ permalink raw reply	[relevance 0%]

* Re: Serial port configuration
  2014-04-06 16:22  1% Serial port configuration hreba
@ 2014-04-06 18:57  0% ` Simon Wright
  2014-04-07 11:44  0%   ` hreba
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2014-04-06 18:57 UTC (permalink / raw)


hreba <hreba@terra.com.br> writes:

> package body SerAux is
>
>    type Port_Data is new int;
>    type Port_Data_Access is access Port_Data;
>    type Port is new Ada.Streams.Root_Stream_Type with record
>       H : Port_Data_Access;
>    end record;

The declaration of type Port needs to be in the spec; and you need to
have the spec of Read there also.

>    overriding procedure Read
>      (--Port   : in out Serial_Port;
>       Port   : in out Port;

You can't use the name Port twice like that. I'd suggest using
Serial_Port for the type name, like the original (why change?).

In fact, why not just copy the contents of the GNAT version and change
the bits you need to?



^ permalink raw reply	[relevance 0%]

* Serial port configuration
@ 2014-04-06 16:22  1% hreba
  2014-04-06 18:57  0% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: hreba @ 2014-04-06 16:22 UTC (permalink / raw)


The problem
-----------
I am trying to communicate with an Arduino using 
GNAT.Serial_Communications, which I will abbreviate as "Serial". The 
"Set" procedure isn't detailed enough, I need "fcntl", "tcgetattr" and 
"tcsetattr" which are private in Serial. To call them, I need the file 
descriptor which is a private component of the type "Port".

The Idea
--------
1. Create a new package "SerAux"
2. declare "fcntl", "tcgetattr" and "tcsetattr" the same way as in
    "Serial", but public
3. define a new type "Port" the same way as in "Serial", but public,
    and do the conversion somehow.

The obstacles
-------------
Creating the new Port requires to override its methods "Read" and 
"Write", but even doing that the same way as in "Serial" gets me a lot 
of error messages. The SerAux.adb begins like this (reproduced from 
original line # 4 on):

--------------------------------------------------------------
...
package body SerAux is

    type Port_Data is new int;
    type Port_Data_Access is access Port_Data;
    type Port is new Ada.Streams.Root_Stream_Type with record
       H : Port_Data_Access;
    end record;


    overriding procedure Read
      (--Port   : in out Serial_Port;
       Port   : in out Port;
       Buffer : out Ada.Streams.Stream_Element_Array;
       Last   : out Ada.Streams.Stream_Element_Offset)
    is
    begin
       Read (Serial.Serial_Port(Port), Buffer, Last);
    end Read;

    ...
----------------------------------------------------------------

The error messages for this fragment are:

seraux.adb:8:09: type must be declared abstract or "Read" overridden
seraux.adb:8:09: "Read" has been inherited at line 8
seraux.adb:8:09: "Read" has been inherited from subprogram at 
a-stream.ads:54
seraux.adb:13:15: subprogram "Read" is not overriding
seraux.adb:15:23: formal parameter "Port" cannot be used before end of 
specification
seraux.adb:20:07: warning: possible infinite recursion
seraux.adb:20:07: warning: Storage_Error may be raised at run time
...
-----------------------------------------------------------------

The questions
-------------
1. Why is all that an error here and not in "Serial"?
2. Am I on the right way or would you solve the problem completely 
different?

Please consider that I am a beginner.

--
hreba


^ permalink raw reply	[relevance 1%]

* Re: Pass a serial port as user data in a GTK callback handler?
  2014-02-15 23:32  1% Pass a serial port as user data in a GTK callback handler? hreba
  2014-02-16  7:45  1% ` Niklas Holsti
@ 2014-02-17 16:13  0% ` adambeneschan
  1 sibling, 0 replies; 200+ results
From: adambeneschan @ 2014-02-17 16:13 UTC (permalink / raw)


On Saturday, February 15, 2014 3:32:58 PM UTC-8, hreba wrote:
> Hi,
> 
> I am new to Ada and still overwhelmed by the complexity of the language.
> 
> My actual programming exercise has a GTK GUI, and I want a callback 
> handler to communicate through a serial port, so I need to pass the port 
> in my user data, which must be of
> 
>     type User_Type (<>) is private;
> 
> which means it must be nonlimited.
> 
> But GNAT.Serial_Communications.Serial_Port is limited:
> 
>     type Serial_Port is new Ada.Streams.Root_Stream_Type with private;
>     type Root_Stream_Type is abstract tagged limited private;
> 
> I tried to pass a reference to the port, and it must be an "access all" 
> (because it is not allocated by my, but a preexisting variable (hardware 
> resource), as I understand it):
> 
>     port: access all GNAT.Serial_Communications.Serial_Port;
> 
> But then I get an error message
> 
>     "all" is not permitted for anonymous access types.
> 
> Is there a solution?

I agree with everyone else that anonymous access types aren't needed in this case, and you're better off using a named access type or something else.  Having said that, I just wanted to point out something about Ada: all anonymous access types are automatically "access all", i.e. they can refer to aliased variables.  So you could have solved the problem by just removing the "all" keyword.

                                 -- Adam


^ permalink raw reply	[relevance 0%]

* Re: Pass a serial port as user data in a GTK callback handler?
  2014-02-15 23:32  1% Pass a serial port as user data in a GTK callback handler? hreba
@ 2014-02-16  7:45  1% ` Niklas Holsti
  2014-02-17 16:13  0% ` adambeneschan
  1 sibling, 0 replies; 200+ results
From: Niklas Holsti @ 2014-02-16  7:45 UTC (permalink / raw)


On 14-02-16 01:32 , hreba wrote:
> Hi,
> 
> I am new to Ada and still overwhelmed by the complexity of the language.
> 
> My actual programming exercise has a GTK GUI, and I want a callback
> handler to communicate through a serial port, so I need to pass the port
> in my user data, which must be of
> 
>    type User_Type (<>) is private;
> 
> which means it must be nonlimited.
> 
> But GNAT.Serial_Communications.Serial_Port is limited:
> 
>    type Serial_Port is new Ada.Streams.Root_Stream_Type with private;
>    type Root_Stream_Type is abstract tagged limited private;
> 
> I tried to pass a reference to the port, and it must be an "access all"
> (because it is not allocated by my, but a preexisting variable (hardware
> resource), as I understand it):

On my machine (Win 7), the type Serial_Port is declared in
GNAT.Serial_Communications by deriving from
Ada.Streams.Root_Stream_Type, adding a component which refers AIUI to a
Windows "handle". This is definitely a SW object; the HW resource is
hidden beind Windows.

On some bare-machine GNAT port, Serial_Port might be closer to the HW,
but it is no doubt still a stream class, so it will not itself be mapped
to some HW register. It might contain the address of (i.e. a reference
to) a HW register.

Therefore, you should be able to create your own Serial_Port objects on
the stack, on the heap, or statically.

>    port: access all GNAT.Serial_Communications.Serial_Port;
> 
> But then I get an error message
> 
>    "all" is not permitted for anonymous access types.
> 
> Is there a solution?

Give the type a name so that it isn't "anonymous":

   type Port_Ref is access all GNAT.Serial_Communications.Serial_Port;

   port : Port_Ref;

Also remember to mark the actual Serial_Port object as "aliased" so that
you can take its 'Access.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[relevance 1%]

* Pass a serial port as user data in a GTK callback handler?
@ 2014-02-15 23:32  1% hreba
  2014-02-16  7:45  1% ` Niklas Holsti
  2014-02-17 16:13  0% ` adambeneschan
  0 siblings, 2 replies; 200+ results
From: hreba @ 2014-02-15 23:32 UTC (permalink / raw)


Hi,

I am new to Ada and still overwhelmed by the complexity of the language.

My actual programming exercise has a GTK GUI, and I want a callback 
handler to communicate through a serial port, so I need to pass the port 
in my user data, which must be of

    type User_Type (<>) is private;

which means it must be nonlimited.

But GNAT.Serial_Communications.Serial_Port is limited:

    type Serial_Port is new Ada.Streams.Root_Stream_Type with private;
    type Root_Stream_Type is abstract tagged limited private;

I tried to pass a reference to the port, and it must be an "access all" 
(because it is not allocated by my, but a preexisting variable (hardware 
resource), as I understand it):

    port: access all GNAT.Serial_Communications.Serial_Port;

But then I get an error message

    "all" is not permitted for anonymous access types.

Is there a solution?
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[relevance 1%]

* Re: Hello, and help with GNAT and Windows USB programming
  @ 2014-02-09 21:00  2% ` björn lundin
  0 siblings, 0 replies; 200+ results
From: björn lundin @ 2014-02-09 21:00 UTC (permalink / raw)


Den söndagen den 9:e februari 2014 kl. 20:59:41 UTC+1 skrev Gumpy:
> 2. Using GNAT, and potentially GNAT.Serial_Communications, how does one open >a USB port and read and write character strings to it (the thermocouple >interface has a simple character based command language for setup and taking >temperature readings). 

if the card is using serial comm, then you want to by a usb-to-serial converter.
It will act like a virtual com-port then
Use it like this (the code spoke with an Arduaino) 

with GNAT.Serial_Communications;
with Ada.Streams;
procedure Serial_Talker is
  TTY : GNAT.Serial_Communications.Serial_Port;
  ------------------------
  function String_To_Stream ( The_String : in String) return Ada.Streams.Stream_Element_Array is
    Return_Value : Ada.Streams.Stream_Element_Array(1..The_String'length);
  begin
    for Count in 1..Ada.Streams.Stream_Element_Offset(The_String'Length) loop
       Return_Value(Count) := Character'pos(The_String(Integer(Count)));
    end loop;
    return Return_Value(1..The_String'Length);
  end String_To_Stream;
  ------------------------
begin
 TTY.Open(Name => "/dev/ttyUSB0");
 TTY.Set (Rate      => GNAT.Serial_Communications.B9600,
          Bits      => GNAT.Serial_Communications.CS8,
          Stop_Bits => GNAT.Serial_Communications.One,
          Parity    => GNAT.Serial_Communications.None,
          Block     => True);
 TTY.Write(Buffer => (String_To_Stream("1"))); -- whatever you'd like
 TTY.Close;
end Serial_Talker;


need -gnat05 to compile

it was on Linux, and on Win
 TTY.Open(Name => "/dev/ttyUSB0");
would be like
 TTY.Open(Name => "COM4");
or perhaps 
 TTY.Open(Name => "COM4:");
or 
 TTY.Open(Name => "\\.\COM4");
or 
 TTY.Open(Name => "\\\\.\\COM4");


But i'm not sure you'd use serial comm though.

I have a velleman k8055
<http://www.velleman.eu/products/view/?country=be&lang=en&id=351346>
which I interfaced with bundled dlls.
No serial comm at all.
It involved looping around the usb devices and finding the card, with
id of manufacturer etc.

I have it on a broken machine, but I might be able to dig it up tomorrow,
if you think it will help
> 
> 3. Does anyone have any specific code examples for communicating on a USB >port that they would like to share, or a link to some example(s) online >somewhere? 
 
yes, as above


/Björn




^ permalink raw reply	[relevance 2%]

* Re: Binary and XML serialization of types
  2014-01-23 18:53  2% Binary and XML serialization of types hanslad
@ 2014-01-23 19:15  1% ` adambeneschan
  0 siblings, 0 replies; 200+ results
From: adambeneschan @ 2014-01-23 19:15 UTC (permalink / raw)


On Thursday, January 23, 2014 10:53:23 AM UTC-8, han...@gmail.com wrote:
> Hello,
> 
> I am an Ada beginner who is working on a private project.
> 
> The project is to implement a protocol which either does binary or xml serialization of the different defined records. 
> 
> I have tried to separate all the "encoding" details from the type declaration in a sub package like this:
> 
> 
> 
> package A.Types is
> 
>    type Guid_Array is array(1 .. 8) of Unsigned_8;
>    type Guid is  record
>       Data1 : Unsigned_32;
>       Data2 : Unsigned_16;
>       Data3 : Unsigned_16;
>       Data4 : Guid_Array;
>    end record;
> 
> end A.Types;

I think you simply want to do something like this.  Put the declaration of Guid_Write and the "for" clause in A.Types.  Then, in the body of A.Types:

    with A.Types.BinaryEncoder;
    package body A.Types is

       -- other stuff as needed

       procedure Guid_Write( 
           Stream : access Ada.Streams.Root_Stream_Type'Class; Item : Guid )
               renames A.Types.BinaryEncoder.Guid_Write;
                   -- this is called a "renaming-as-body"

or this, which amounts to the same thing:

    with A.Types.BinaryEncoder;
    package body A.Types is

       -- other stuff as needed

       procedure Guid_Write( 
           Stream : access Ada.Streams.Root_Stream_Type'Class; Item : Guid ) is
       begin
           A.Types.BinaryEncoder.Guid_Write (Stream, Item);
       end Guid_Write;

(Note: I think the "renames" will work, but I haven't tested it.  The second one will definitely work.)

Now you declare and implement Guid_Write in A.Types.BinaryEncoder as you were trying to do.  (You don't actually need to give it the same name.  You can call your "implementation" procedure Guid_Write_Impl, or Any_Other_Name_You_Feel_Like.)

What's going on is that if some client package says "with A.Types" and uses the Guid_Write type, and uses Guid_Write'Write(...) or Guid_Write'Output(...), the client has to know that there's a Write routine that isn't the default.  That's why the "for Guid_Write'Write use ..." has to be in the visible part of A.Types, so that other clients are allowed to know about it.
 
                            -- Adam


^ permalink raw reply	[relevance 1%]

* Binary and XML serialization of types
@ 2014-01-23 18:53  2% hanslad
  2014-01-23 19:15  1% ` adambeneschan
  0 siblings, 1 reply; 200+ results
From: hanslad @ 2014-01-23 18:53 UTC (permalink / raw)


Hello,
I am an Ada beginner who is working on a private project.
The project is to implement a protocol which either does binary or xml serialization of the different defined records. 
I have tried to separate all the "encoding" details from the type declaration in a sub package like this:

package A.Types is

   type Guid_Array is array(1 .. 8) of Unsigned_8;
   type Guid is  record
      Data1 : Unsigned_32;
      Data2 : Unsigned_16;
      Data3 : Unsigned_16;
      Data4 : Guid_Array;
   end record;

end A.Types;


with with Ada.Streams; use Ada.Streams;
package A.Types.BinaryEncoder is

   procedure Guid_Write(
   Stream : access Ada.Streams.Root_Stream_Type'Class; Item : Guid );
   for Guid'Write use Guid_Write;

end A.Types.Encoders;


I get the following error:

7:8 entity must be declared in this Scope

How can I separate all the encoding and decoding details from the type declaration? I like the idea of splitting this into packages with different functionality. Is this possible at all?
Sorry for posting such a beginners question.

Thanks,

HP
   

^ permalink raw reply	[relevance 2%]

* Re: Will Ada-95 Programs Written in MS Windows Run in MacOS and Linux Without Some Tweaking.
  @ 2013-12-11  0:34  1%             ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2013-12-11  0:34 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Simon Wright" <simon@pushface.org> wrote in message 
> news:lywqjf45za.fsf@pushface.org...
> ...
>> I'm not sure of the best way to get an Ada program not to care what
>> sort of input line terminators it's reading.
>
> I'm surprised that that would be a problem, at least for Unix and
> Windows files. It's pretty simple to design Text_IO so that it can
> read either properly; that's how Text_IO in Janus/Ada works. (The only
> difference for it between Windows and Unix versions is the characters
> output by New_Line).

GNAT is certainly not as clever as that. On Mac OS X, this program

========================================================================
with Ada.Streams.Stream_IO;
with Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;

procedure S is

   Data_File_Name : constant String := "s.dat";
   Text_File : Ada.Text_IO.File_Type;

   procedure Write_As_Stream (Data : String) is
      package ASS renames Ada.Streams.Stream_IO;
      Stream_File : ASS.File_Type;
   begin
      ASS.Open (Stream_File,
                Name => Data_File_Name,
                Mode => ASS.Out_File);
      declare
         Stream_Access : constant ASS.Stream_Access
           := ASS.Stream (Stream_File); -- the file has to be open already
      begin
         String'Write (Stream_Access, Data);
      end;
      ASS.Close (Stream_File);
   end Write_As_Stream;

begin

   Put_Line ("testing \n");
   Write_As_Stream (String'(1 => ASCII.LF));
   Open (Text_File, Name => Data_File_Name, Mode => In_File);
   Put_Line ("EOL is " & Boolean'Image (End_Of_Line (Text_File)));
   Put_Line ("EOF is " & Boolean'Image (End_Of_File (Text_File)));
   Close (Text_File);

   Put_Line ("testing \r\n");
   Write_As_Stream (String'(1 => ASCII.CR, 2 => ASCII.LF));
   Open (Text_File, Name => Data_File_Name, Mode => In_File);
   Put_Line ("EOL is " & Boolean'Image (End_Of_Line (Text_File)));
   Put_Line ("EOF is " & Boolean'Image (End_Of_File (Text_File)));
   Close (Text_File);

   declare
      Dummy : Integer;
   begin
      Put_Line ("testing \n42");
      Write_As_Stream (String'(1 => ASCII.LF) & "42");
      Open (Text_File, Name => Data_File_Name, Mode => In_File);
      Ada.Integer_Text_IO.Get (Text_File, Dummy);
      Put_Line ("Value is " & Integer'Image (Dummy));
      Close (Text_File);
   end;

   declare
      Dummy : Integer;
   begin
      Put_Line ("testing \r\n42");
      Write_As_Stream (String'(1 => ASCII.CR, 2 => ASCII.LF) & "42");
      Open (Text_File, Name => Data_File_Name, Mode => In_File);
      Ada.Integer_Text_IO.Get (Text_File, Dummy);
      Put_Line ("Value is " & Integer'Image (Dummy));
      Close (Text_File);
   end;

end S;
========================================================================

results in

------------------------------------------------------------------------
testing \n
EOL is TRUE
EOF is TRUE
testing \r\n
EOL is FALSE
EOF is FALSE
testing \n42
Value is  42
testing \r\n42

Execution terminated by unhandled exception
Exception name: ADA.IO_EXCEPTIONS.DATA_ERROR
------------------------------------------------------------------------

whereas on a Windows machine I get

------------------------------------------------------------------------
testing \n
EOL is TRUE
EOF is TRUE
testing \r\n
EOL is TRUE
EOF is TRUE
testing \n42
Value is  42
testing \r\n42
Value is  42
------------------------------------------------------------------------

so I feel a bug report coming on .. 

> But if you don't want to change the terminators (or your compiler has an 
> unnecessarily inflexible Text_IO), I'd suggest using Stream_IO. Of course, 
> then you'll have to do your own buffering of input (but that's usually a 
> good idea anyway).

Yes. Actually I tried Sequential_IO, but for just reading Characters
there's not a lot of difference ... is there?


^ permalink raw reply	[relevance 1%]

* Re: How to use GNAT.Serial_Communications ?
  2013-09-14  1:39  1% How to use GNAT.Serial_Communications ? elbric0
@ 2013-09-14  5:42  1% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2013-09-14  5:42 UTC (permalink / raw)


elbric0 <jasmin.stlaurent@gmail.com> writes:

> with GNAT.Serial_Communications; use GNAT.Serial_Communications;
>
> procedure Test_Serial is
>
>    Serial : Serial_Port;

     Serial : aliased Serial_Port;

>    C : Character;
>
> begin
>
>    Open (Port => Serial, Name => Name (1));
>
>    C := 'A';
>
>    Character'Write (Serial, C);

     Character'Write (Serial'Access, C);

>    Close (Serial);
>
> end Test_Serial;
> ----------------------------------------------------------------
>
> However the type of the first parameter of Character'Write is not
> correct. I get this error message: "expected access to
> Ada.Streams.Root_Stream_Type'Class".
>
> Can someone tell me what I should put there instead of Serial?

... as above; in GNAT.Serial_Communications,

   type Serial_Port is new Ada.Streams.Root_Stream_Type with private;

and, as the error message said, you need an access to one of those.

Serial has to be declared aliased so that 'Access can be taken
(otherwise, who knows, it might be kept in a register).

> Do you know any tutorial or code example that can help me?

Sorry, someone else may.


^ permalink raw reply	[relevance 1%]

* How to use GNAT.Serial_Communications ?
@ 2013-09-14  1:39  1% elbric0
  2013-09-14  5:42  1% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: elbric0 @ 2013-09-14  1:39 UTC (permalink / raw)


Hi,

I am learning Ada and try to figure how to communicate with an electronic device on a serial port.

I think the code to print 'A' to COM1 on Windows should be about that.

----------------------------------------------------------------
with GNAT.Serial_Communications; use GNAT.Serial_Communications;

procedure Test_Serial is

   Serial : Serial_Port;
   C : Character;

begin

   Open (Port => Serial, Name => Name (1));

   C := 'A';

   Character'Write (Serial, C);

   Close (Serial);

end Test_Serial;
----------------------------------------------------------------

However the type of the first parameter of Character'Write is not correct. I get this error message: "expected access to Ada.Streams.Root_Stream_Type'Class".

Can someone tell me what I should put there instead of Serial?

Do you know any tutorial or code example that can help me?

^ permalink raw reply	[relevance 1%]

* Re: Calling a File for Encryption from outside of the Main Ada-95 Holding Folder.
  2013-09-05 11:33  1%             ` Simon Wright
  2013-09-05 15:46  0%               ` Austin Obyrne
@ 2013-09-05 16:00  0%               ` Austin Obyrne
  1 sibling, 0 replies; 200+ results
From: Austin Obyrne @ 2013-09-05 16:00 UTC (permalink / raw)


On Thursday, September 5, 2013 12:33:32 PM UTC+1, Simon Wright wrote:
> Austin Obyrne <austin.obyrne@hotmail.com> writes: > I have tried Word Pad also and iit works equally well - but as you say > the file extension .doc is taboo - must not be used - .dat is fine It's not the file extension, it's the contents of the file! (I realise that many people would have trouble making the distinction). > Summarising. > > Users can use 'Notepad' with .dat file extension say > Users can use 'Wordpad' with .dat file extension It would be more normal to use .txt > If users insist on using MS Word then it must go through the AdaGIDE > editor with a .dat file extension (if any). Or Notepad, or Wordpad .. what you are doing is Copying the contents of the Word document, and Pasting them into an editor which doesn't understand Word's style and format information and only accepts the raw characters. Which is all that you are interested in. I don't think it's entirely reasonable from your users' point of view to only be able to deal with plain text files, though; for example, what about images? (.jpg, etc) which are going to give you the same problem. Perhaps you could consider reading the files using Ada.Streams.Stream_IO? Example use in procedure Output_Contents starting at line 182 of http://goo.gl/wcqkop

Could I take (.txt) for everything as standard in future and not bother with (.dat) even - I would like to be able to imply this as a caveat to my users - what do you say O' Wise One?

AdaGIDE will always accept .txt ???

I would like to use just one rule.

You guys have really sorted things for me - I am truly grateful for your help.

Knowing about the file extensons drop down menu options menu is just marvellous.

Grateful to everybody.

Austin

^ permalink raw reply	[relevance 0%]

* Re: Calling a File for Encryption from outside of the Main Ada-95 Holding Folder.
  2013-09-05 11:33  1%             ` Simon Wright
@ 2013-09-05 15:46  0%               ` Austin Obyrne
  2013-09-05 16:00  0%               ` Austin Obyrne
  1 sibling, 0 replies; 200+ results
From: Austin Obyrne @ 2013-09-05 15:46 UTC (permalink / raw)


On Thursday, September 5, 2013 12:33:32 PM UTC+1, Simon Wright wrote:
> Austin Obyrne <austin.obyrne@hotmail.com> writes: > I have tried Word Pad also and iit works equally well - but as you say > the file extension .doc is taboo - must not be used - .dat is fine It's not the file extension, it's the contents of the file! (I realise that many people would have trouble making the distinction). > Summarising. > > Users can use 'Notepad' with .dat file extension say > Users can use 'Wordpad' with .dat file extension It would be more normal to use .txt > If users insist on using MS Word then it must go through the AdaGIDE > editor with a .dat file extension (if any). Or Notepad, or Wordpad .. what you are doing is Copying the contents of the Word document, and Pasting them into an editor which doesn't understand Word's style and format information and only accepts the raw characters. Which is all that you are interested in. I don't think it's entirely reasonable from your users' point of view to only be able to deal with plain text files, though; for example, what about images? (.jpg, etc) which are going to give you the same problem. Perhaps you could consider reading the files using Ada.Streams.Stream_IO? Example use in procedure Output_Contents starting at line 182 of http://goo.gl/wcqkop

Many thanks Simon,

I think I will leave images for the present - just security of information will be all for now - frankly I dont know enough about images yet but anything that can be reduced to an alpahnumeric can be encrypted by my cipher.

Can I come back to you sometime in the future on this one.

Regards - Austinn

^ permalink raw reply	[relevance 0%]

* Re: Calling a File for Encryption from outside of the Main Ada-95 Holding Folder.
  @ 2013-09-05 11:33  1%             ` Simon Wright
  2013-09-05 15:46  0%               ` Austin Obyrne
  2013-09-05 16:00  0%               ` Austin Obyrne
  0 siblings, 2 replies; 200+ results
From: Simon Wright @ 2013-09-05 11:33 UTC (permalink / raw)


Austin Obyrne <austin.obyrne@hotmail.com> writes:

> I have tried Word Pad also and iit works equally well - but as you say
> the file extension .doc is taboo - must not be used - .dat is fine

It's not the file extension, it's the contents of the file! (I realise
that many people would have trouble making the distinction).

> Summarising.
>
> Users can use 'Notepad' with .dat file extension say
> Users can use 'Wordpad' with .dat file extension

It would be more normal to use .txt

> If users insist on using MS Word then it must go through the AdaGIDE
> editor with a .dat file extension (if any).

Or Notepad, or Wordpad .. what you are doing is Copying the contents of
the Word document, and Pasting them into an editor which doesn't
understand Word's style and format information and only accepts the raw
characters. Which is all that you are interested in.

I don't think it's entirely reasonable from your users' point of view to
only be able to deal with plain text files, though; for example, what
about images? (.jpg, etc) which are going to give you the same
problem. Perhaps you could consider reading the files using
Ada.Streams.Stream_IO?

Example use in procedure Output_Contents starting at line 182 of
http://goo.gl/wcqkop


^ permalink raw reply	[relevance 1%]

* Re: Private function w/ Tagged return-type.
  2013-07-29 20:54  1% Private function w/ Tagged return-type Shark8
@ 2013-07-29 21:20  0% ` Adam Beneschan
  0 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2013-07-29 21:20 UTC (permalink / raw)


On Monday, July 29, 2013 1:54:40 PM UTC-7, Shark8 wrote:
> Given the following:
> 
> 
> 
> with Ada.Streams;
> package example is
>     Type Subject is tagged private;
>     function Create return Subject;
> private
>         function Input(
> 		    Stream : not null access Ada.Streams.Root_Stream_Type'Class)
> 	return  Subject is (Create);
> 
> ---- private, moved here, will work.
> 
>     Type Subject is tagged null record
>       with Input => Input;
> 
>     function Create return Subject is (null record);
> end example;
> 
> yields the following error message:
> 
>      private function with tagged result must override visible-part function
>      move subprogram to the visible part (RM 3.9.3(10))
> 
> Yet, the given paragraph says:
> 
>    For an abstract type declared in a visible part, an abstract primitive subprogram shall not be declared in the private part, unless it is overriding an abstract subprogram implicitly declared in the visible part. For a tagged type declared in a visible part, a primitive function with a controlling result or a controlling access result shall not be declared in the private part, unless it is overriding a function implicitly declared in the visible part.
> 
> Is the error correct? 'Input, 'Output, 'Read & 'Write are implicitly created due to the stream operations/attributes, though arguably they are not functions/subprograms.

Well, no matter which way you argue, the T'Input function does not have the name "Input" and will not be overridden by a function named "Input".

You can put your Input function in a nested package to avoid the error, since that will make it non-primitive.

                                 -- Adam

^ permalink raw reply	[relevance 0%]

* Private function w/ Tagged return-type.
@ 2013-07-29 20:54  1% Shark8
  2013-07-29 21:20  0% ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2013-07-29 20:54 UTC (permalink / raw)


Given the following:

with Ada.Streams;
package example is
    Type Subject is tagged private;
    function Create return Subject;
private
        function Input(
		    Stream : not null access Ada.Streams.Root_Stream_Type'Class)
	return  Subject is (Create);

---- private, moved here, will work.
    
    Type Subject is tagged null record
      with Input => Input;

    function Create return Subject is (null record);
end example;

yields the following error message:
     private function with tagged result must override visible-part function
     move subprogram to the visible part (RM 3.9.3(10))

Yet, the given paragraph says:
   For an abstract type declared in a visible part, an abstract primitive subprogram shall not be declared in the private part, unless it is overriding an abstract subprogram implicitly declared in the visible part. For a tagged type declared in a visible part, a primitive function with a controlling result or a controlling access result shall not be declared in the private part, unless it is overriding a function implicitly declared in the visible part.

Is the error correct? 'Input, 'Output, 'Read & 'Write are implicitly created due to the stream operations/attributes, though arguably they are not functions/subprograms.

I should think that it would be perfectly appropriate to place the declarations of the functions you're assigning to 'Read/'Write/'Input/'Output into the private portion of the package.

^ permalink raw reply	[relevance 1%]

* Interresting, possibly buggy behavior in GNAT generics w/ expression function.
@ 2013-03-28 17:34  1% Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2013-03-28 17:34 UTC (permalink / raw)


Lately I've been interested in perhaps getting Ada as a script-tag language, much like JavaScript. I figured I'd need a DOM library or somesuch and was looking into XMLAda (which, oddly fails compile on DOTNET-Gnat and seems oblivious to --target=JVM) so I was tinkering with it in native-code hoping to be able to get to a point where I could seek-out and alter attributes [for a node] on a DOM-Document and was surprised to find there's no functionality for altering attributes via XMLAda DOM-package (at least nothing obvious).

So I decided to play around and see about my own DOM-library (which I would rather not do, as there are several DOM-ish Ada packages about) and found this interesting tidbit: behavior changes when the parameter of image is changed from positive to natural. {Actually it only happens when Attribute_Values is instantiated with Integer[-type].}
----------------------------------------------------------------------------
With Ada.Containers.Indefinite_Vectors, Ada.Strings.Fixed;
Use  Ada.Containers;

Generic
    Attribute_Name : String;
    Type Attribute_Values is (<>);

    With Function Img(Value : Attribute_Values) Return String is Attribute_Values'Image;
    With Package Units is New Indefinite_Vectors(
		Index_Type => Positive,
		Element_Type => String );

    Attribute_Units : Units.Vector:= Units.Empty_Vector;

Package Generic_Attribute_Set is

    Type Attribute(Has_Units : Boolean:= Attribute_Units.Length /= 0) is record
	Value : Attribute_Values;
	case Has_Units is
	When True  => Unit : Positive;
	When False => Null;
	end case;
    end record;

    -- The 'Image Attribute, when applied to numeric types, leaves a leading
    -- space for non-negative numbers (for uniform columnuar display); this is
    -- undesirable for our use, so we wrap it in a call to trim.
    Function Image(Value : Attribute_Values) Return String is
	( Ada.Strings.Fixed.Trim(Img(Value), Side => Ada.Strings.Left) );
    
    -- Getting the string stored in the position for out units-vector is a
    -- simple index into the proper position in the vector containing the units.
    Function Image(Value : Positive) Return String is
      ( --if Value not in positive then "" else 
        Units.Constant_Reference( Attribute_Units, Value ) );
    
    Function To_String( Attr : Attribute ) Return String is
      ( Attribute_Name & "=""" & 
	 Image(Attr.Value) & (if Attr.Has_Units then Image(Attr.Unit) else "") &
	 '"'
      );
    
End Generic_Attribute_Set;
----------------------------------------------------------------------------
With
Generic_Attribute_Set,
Ada.Streams,
Ada.Text_IO.Text_Streams,
Ada.Containers.Indefinite_Vectors;

Procedure Test is
    Package Units is New Ada.Containers.Indefinite_Vectors(
		Index_Type => Positive,
		Element_Type => String );

    Use Units;
    Screen : Units.Vector:= Vector'("en" & "ex") & Vector'("px" & "%");
    
    Type J is (Alpha, Beta, 'K', Fred);
    
    Package Margins is new Generic_Attribute_Set(
	Attribute_Name   => "margin-left",
	Attribute_Values => Integer,
	Units            => Units,
	Attribute_Units  => Screen);
Begin
    Declare
      Use Margins;
      K : Attribute;
    begin
	K.Value:= 88; --J'Succ(Beta);
	K.Unit:= 4;
	Ada.Text_IO.Put_Line( To_String(K) );
    end;
End Test;
----------------------------------------------------------------------------

As I understand it this shouldn't *ever* happen because in the generic there's supposed to be no knowledge of what the parameters are actually instantiated with.


^ permalink raw reply	[relevance 1%]

* Re: [Ann] Ada Web Application 0.3.0 is available
  @ 2013-03-02  5:54  1% ` shyam.laximan
  0 siblings, 0 replies; 200+ results
From: shyam.laximan @ 2013-03-02  5:54 UTC (permalink / raw)


Hi Stephane,

I am trying to install aws on windows xp. I have downloaded the awa-all-030 tar ball , have cygwin on my system. I have launched these 2 commands with no problems


1) ./configure --enable-xmlada --enable-aws

2) cd xmlada && make && make install


but his command below   actually caused problem .. can you help


cd aws && make prefix="/usr/local" setup build install

// error 
gcc -c -gnat05 -gnatwcfijkmRuv -gnaty3abcefhiIklmnoprstx -Wall -O2 -gnatn aws-services-web_block-registry.adb
aws-services-web_block-context.adb:36:12: missing "with Ada.Streams;"
gprbuild: *** compilation phase failed
makefile:251: recipe for target `build-native' failed
make: *** [build-native] Error 4



^ permalink raw reply	[relevance 1%]

* Re: Ada Containers
  @ 2012-10-07 22:00  1% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2012-10-07 22:00 UTC (permalink / raw)


rwilco19@gmail.com writes:

> Can someone please explain to me the difference between
> Ada.Containers.Hashed_Tables and Ada.Containers.Hashed_Maps, and when
> you might want to use a Hashed_Table over a Hashed_Map?

Ada.Containers.Hash_Tables, as you noted.

Hashed_Maps is in the Standard, Hash_Tables is not; it's part of
AdaCore's implementation (and maybe others, for all I know).

GCC 4.7.0 says for Hashed_Maps

   with Ada.Iterator_Interfaces;

   private with Ada.Containers.Hash_Tables;
   private with Ada.Finalization;
   private with Ada.Streams;

   generic
      type Key_Type is private;
      type Element_Type is private;

      with function Hash (Key : Key_Type) return Hash_Type;
      with function Equivalent_Keys (Left, Right : Key_Type) return Boolean;
      with function "=" (Left, Right : Element_Type) return Boolean is <>;

   package Ada.Containers.Hashed_Maps is

and you will see that Hash_Tables is withed privately (i.e., it's only
used in the private part, "not specified by the language").

A further clue: the comment at the start of Hash_Tables says "This
package declares the hash-table type used to implement hashed
containers."



^ permalink raw reply	[relevance 1%]

* Re: Endianness and Record Specification
  @ 2012-09-21 22:18  2% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2012-09-21 22:18 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:

> At first I was thinking I could do:
>
> if Standard'Default_Bit_Order = 1 then
>   -- defined Little endian rec spec
> else
>   -- define Bit endian rec spec
> end if;
>
> But, the compiler doesn't let me do that... :-)
>
> I would think I should be able to somehow use the Default_Bit_Order to
> define some sort of relative byte position, depending on the system
> endianness, but I'm drawing a blank and hoping someone might have a
> quick example they could provide.

The way I've approached this is to declare an unrepresented type for the
main program to use, and then make a local, derived, represented type
inside a bit-order-dependent conditional.

Below, the type Local_Status is very local, but it works with a wider
scope, and may lead to improved performance by avoiding
packing/unpacking.

This assumes it's OK to have the conversion only at the edges of the
program.

   Big_Endian : constant Boolean
     := System."=" (System.Default_Bit_Order, System.High_Order_First);

   function To_Stream_Element (S : Status) return Ada.Streams.Stream_Element
   is
      type Local_Status is record
         LI : Leap_Indicator;
         VN : Version;
         M : Mode;
      end record;
      V : constant Local_Status := (LI => S.LI, VN => S.VN, M => S.M);
   begin
      if Big_Endian then
         declare
            type Host_Status is new Local_Status;
            for Host_Status use record
               LI at 0 range 0 .. 1;
               VN at 0 range 2 .. 4;
               M  at 0 range 5 .. 7;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Host_Status,
                                             Ada.Streams.Stream_Element);
         begin
            return Convert (Host_Status (V));
         end;
      else
         declare
            type Host_Status is new Local_Status;
            for Host_Status use record
               LI at 0 range 6 .. 7;
               VN at 0 range 3 .. 5;
               M  at 0 range 0 .. 2;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Host_Status,
                                             Ada.Streams.Stream_Element);
         begin
            return Convert (Host_Status (V));
         end;
      end if;
   end To_Stream_Element;

   function To_Status (S : Ada.Streams.Stream_Element) return Status
   is
   begin
      if Big_Endian then
         declare
            type Host_Status is record
               LI : Leap_Indicator;
               VN : Version;
               M : Mode;
            end record;
            for Host_Status use record
               LI at 0 range 0 .. 1;
               VN at 0 range 2 .. 4;
               M  at 0 range 5 .. 7;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
                                             Host_Status);
            V : constant Host_Status := Convert (S);
         begin
            return (LI => V.LI, VN => V.VN, M => V.M);
         end;
      else
         declare
            type Host_Status is record
               LI : Leap_Indicator;
               VN : Version;
               M : Mode;
            end record;
            for Host_Status use record
               LI at 0 range 6 .. 7;
               VN at 0 range 3 .. 5;
               M  at 0 range 0 .. 2;
            end record;
            for Host_Status'Size use 8;
            function Convert
            is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
                                             Host_Status);
            V : constant Host_Status := Convert (S);
         begin
            return (LI => V.LI, VN => V.VN, M => V.M);
         end;
      end if;
   end To_Status;



^ permalink raw reply	[relevance 2%]

* Re: Should Inline be private in the private part of a package spec?
  2012-08-22 16:48  0%                                       ` Georg Bauhaus
@ 2012-08-22 17:44  1%                                         ` Dmitry A. Kazakov
  2012-08-22 21:18  0%                                           ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2012-08-22 17:44 UTC (permalink / raw)


On Wed, 22 Aug 2012 18:48:03 +0200, Georg Bauhaus wrote:

> On 22.08.12 16:30, Dmitry A. Kazakov wrote:
> 
>>> As always, the question is inefficient for what and for whom.
>> 
>> For the network and the peers. The measures for both can be easily
>> provided.
> 
> Well, that would depend on the specifics of "network" and its mode
> of use, wouldn't it?

There exist pretty general measures, e.g. number of bits, FLOPs, QoS and so
on.

>>>> 2. fails to capture the structure (e.g. recursive, interlinked structures)
>>>
>>> ?
>> 
>> Take Containers.Doubly_Linked_Lists as an example. The closure object of a
>> list is the structure in question.
> 
> "closure object" = ?

Linked list is not an object. An object could be a closure of the list upon
the relation predecessor-successor, e.g. a set of linked nodes.
 
> <l>
>  <it id = "one"           f="two" />
>  <it id = "two"   b="one" f="three" />
>  <it id = "three" b="two" />
> </l>

Which speaks for itself.

>>>> 6. requires complex, resource consuming, vulnerable infrastructure like
>>>> parsers
>>>
>>> Yes, there are cases where such parsers are needed, and even more
>>> of such things. For example, if you run Google.
>> 
>> Remember that the case in question is "exchanging structured data," not
>> running Google.
> 
> Google is the biggest thing on earth that exchanges data with
> just about everything outside microwave ovens.

This is why XML would not require complex, resource consuming, vulnerable
parsers?

>>>> 7. is not redundant and at the same time absolutely permissive (requires
>>>> complex validation of itself)
>>>
>>> Another set of unqualified word ({"redundant", ... })
>> 
>> http://en.wikipedia.org/wiki/Redundancy_%28engineering%29
> 
> (That's still unqualified, but as you say, redundancy may refer
> to layers. But there is more.)
> 
> The purpose of "syntactic excess" of XML is about the same as in Ada:

Not at all. Ada's redundancy is here to reduce influence of certain class
of programming errors. Ada is not proposed for exchanging structured data
between computers. Ada is a programming language. XML in this context plays
the role of a protocol to exchange above mentioned data. The nature of
errors which may appear upon such data exchange, their behavior has close
to nothing in common to the typo errors programmers do when they write Ada
code.

If you want to promote XML to a programming language that would be a
different beast, though no less ugly one.

>>> You don't have to write parser infrastructure when you
>>> can use XML.
>> 
>> 1. I don't need parser if I don't use XML.
> 
> I need to write many parsers if I can't use XML. I use data not
> generated by our programs.

In that case this is irrelevant to the issue. Other programs use formats
they do. If that requires parsing that is their problem. Two wrongs do not
make one right.

>> 3. Serialization is much simpler without XML. See Ada.Streams.
> 
> Is Ada's serialization easier for you, the 1 writer, or easier for
> the N unknown readers out there who might not be using Ada?

It is irrelevant whether they use Ada. Relevant is the architecture of the
protocol. A protocol similar to one of Ada streams deploy does not need
parsing.

>> Safety could be against
>> 
>> 1. intentional misuse
> 
> I don't see how any source of data could protect against misuse of data
> once data have left the "building".

http://en.wikipedia.org/wiki/Digital_signature

>> 2. unintentional errors
> 
> ?

E.g. typo errors. Baiting, when you type some garbage to let the compiler
to make a suggestion etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 1%]

* Re: Should Inline be private in the private part of a package spec?
  @ 2012-08-24  9:56  1%                                                       ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-08-24  9:56 UTC (permalink / raw)


On 24.08.12 06:48, Randy Brukardt wrote:
> "Georg Bauhaus" <rm.dash-bauhaus@futureapps.de> wrote in message 
> news:50361675$0$6582$9b4e6d93@newsspool3.arcor-online.net...
>> On 23.08.12 12:13, Dmitry A. Kazakov wrote:
>>> Ada is not proposed for exchanging structured data.
>>
>> XML is proposed for exchanging data between unknown endpoints,
>> for reasons similar to those that have produced Ada and its syntax.
> 
> Data should never be exchanged with "unknown endpoints", because there is 
> then no way to judge the reliability of the data. (And there are lots of 
> people who would like to corrupt it.)

The argument is bogus, because it assumes "known endpoints" send more
reliable data just because they are known. If you know the origin,
you still do not know what will be input.
If you assume criminals, than knowledge of criminal techniques
forces all I/O to be written assuming counterfeit.
Examples of failing security setups are readily available.
This has little to do with deciphering Ada.Streams or deciphering
XML documents.

The argument is also bogus if it implies that programs should
never read any input unless they know with certainty what will
be input. This excludes research programs that must try find
signals in noise, search patterns in the chaos, or look for
needles in the hay stack.


> Ergo, XML is proposed to solve a problem which simply should never arise.

More like a generalization of a very special case...




^ permalink raw reply	[relevance 1%]

* Re: Should Inline be private in the private part of a package spec?
  2012-08-22 17:44  1%                                         ` Dmitry A. Kazakov
@ 2012-08-22 21:18  0%                                           ` Georg Bauhaus
    0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2012-08-22 21:18 UTC (permalink / raw)


On 22.08.12 19:44, Dmitry A. Kazakov wrote:
> On Wed, 22 Aug 2012 18:48:03 +0200, Georg Bauhaus wrote:
>
>> On 22.08.12 16:30, Dmitry A. Kazakov wrote:
>>
>>>> As always, the question is inefficient for what and for whom.
>>>
>>> For the network and the peers. The measures for both can be easily
>>> provided.
>>
>> Well, that would depend on the specifics of "network" and its mode
>> of use, wouldn't it?
>
> There exist pretty general measures, e.g. number of bits, FLOPs, QoS and so
> on.

In the set called "and so on", information retrieval programs will
be efficient at all once they can interpret a data item to be an object
for which FLOPs make any sense. That's easier to see when there is
markup than when the program needs to guess if some four octets
could be a float.

>>>>> 2. fails to capture the structure (e.g. recursive, interlinked structures)
>>>>
>>>> ?
>>>
>>> Take Containers.Doubly_Linked_Lists as an example. The closure object of a
>>> list is the structure in question.
>>
>> "closure object" = ?
>
> Linked list is not an object. An object could be a closure of the list upon
> the relation predecessor-successor, e.g. a set of linked nodes.

So the closure could be mapped to ... what if not an object?

>> <l>
>>   <it id = "one"           f="two" />
>>   <it id = "two"   b="one" f="three" />
>>   <it id = "three" b="two" />
>> </l>
>
> Which speaks for itself.

Indeed, it shows that you can have the kind of structures you wanted;
I'll gladly add recursive structure � la Ada; for now,

   l'(it'(id => one, f => two, others => <>),
      it'(id => two, f => three, b => one),
      it'(id => three, b => two, others => <>);

Stream this aggregate to a C++ program outside your project ...


>>>>> 6. requires complex, resource consuming, vulnerable infrastructure like
>>>>> parsers
>>>>
>>>> Yes, there are cases where such parsers are needed, and even more
>>>> of such things. For example, if you run Google.
>>>
>>> Remember that the case in question is "exchanging structured data," not
>>> running Google.
>>
>> Google is the biggest thing on earth that exchanges data with
>> just about everything outside microwave ovens.
>
> This is why XML would not require complex, resource consuming, vulnerable
> parsers?

XML will not require complex, resource consuming, vulnerable parsers
once applications need not input non-XML data, such as Excel files
or HTML pages.


>> The purpose of "syntactic excess" of XML is about the same as in Ada:
>
> Not at all. Ada's redundancy is here to reduce influence of certain class
> of programming errors.

For example, Ada has named brackets in place of overloaded brackets
in many places. Like XML.

> Ada is not proposed for exchanging structured data
> between computers.

It is, however, required to say how to exchange structured program
source text between compilers.

> Ada is a programming language. XML in this context plays
> the role of a protocol to exchange above mentioned data.

No. It is a markup language for tagging data in text documents.
We have been here before.

> The nature of
> errors which may appear upon such data exchange, their behavior has close
> to nothing in common to the typo errors programmers do when they write Ada
> code.

When programmers correct errors that the compilers have found,
some of the are strictly syntax errors, others are of a more
grammatical nature. Source text not being a stream of octets
makes correcting Ada source text easier. Similarly for XML.


>>>> You don't have to write parser infrastructure when you
>>>> can use XML.
>>>
>>> 1. I don't need parser if I don't use XML.
>>
>> I need to write many parsers if I can't use XML. I use data not
>> generated by our programs.
>
> In that case this is irrelevant to the issue.

Irrelevant to your issue, I guess, of exchanging data in a network
where all components know what's required to participate. The issues
other people face have to do with mutual, deliberate lack of information,
and with non-coordination. If inscrutable serializing is added on
top of that, parties end up with trial and error. That's a lot less so
when they at least use  XML.


> A protocol similar to one of Ada streams deploy does not need
> parsing.

An exchange of data using streams does not work without agreements
on the stream's content; streams from 'Write are not usually
self-documenting. That's a lot less so with XML, therefore XML
is a suitable choice in situations without agreements.


>>> Safety could be against
>>>
>>> 1. intentional misuse
>>
>> I don't see how any source of data could protect against misuse of data
>> once data have left the "building".
>
> http://en.wikipedia.org/wiki/Digital_signature

Party A   1 <----> *   Party B

Party A provides data together with a signature.
The signature says that what was sent was really sent by A.
How does a signature prevent misusing what was sent?
(How can a signed kitchen knife prevent its use as a weapon?)
The recipient does not learn anything except that the origin is A.
The recipient cannot validate the structure using a signature.
The recipient is free to use information in ways not foreseen.

No accessible piece of data in whichever shape of form can
be protected from being used in any way.

Being able to interpret data is a consequence of assigning
meaning to its parts. A and B may have differing views on that.

There are networks without an arbiter. Then, if things work for
both A and B, then they are both right.


>>> 2. unintentional errors
>>
>> ?
>
> E.g. typo errors. Baiting, when you type some garbage to let the compiler
> to make a suggestion etc.

XML does not only provide for error recovery, as do other ways of
exchanging data. (E.g. through bracket naming, or through a
redundant amount of syntax; some markup is redundant in that an
SGML/XML processor could infer it without running into ambiguity).
It can also have good effects on producers of XML insofar as they can
employ ubiquitous tools to make sure they are really producing
XML documents.

Many do.




^ permalink raw reply	[relevance 0%]

* Re: Should Inline be private in the private part of a package spec?
  2012-08-22 14:30  1%                                     ` Dmitry A. Kazakov
@ 2012-08-22 16:48  0%                                       ` Georg Bauhaus
  2012-08-22 17:44  1%                                         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2012-08-22 16:48 UTC (permalink / raw)


On 22.08.12 16:30, Dmitry A. Kazakov wrote:

>> As always, the question is inefficient for what and for whom.
> 
> For the network and the peers. The measures for both can be easily
> provided.

Well, that would depend on the specifics of "network" and its mode
of use, wouldn't it?

>>> 2. fails to capture the structure (e.g. recursive, interlinked structures)
>>
>> ?
> 
> Take Containers.Doubly_Linked_Lists as an example. The closure object of a
> list is the structure in question.

"closure object" = ?

<l>
 <it id = "one"           f="two" />
 <it id = "two"   b="one" f="three" />
 <it id = "three" b="two" />
</l>

>>> 3. lacks even basic data types (everything is string, not even weakly
>>> typed)
>>
>> ?
> 
> Compare XML to Ada or C. The latter languages have elementary data types
> which can be used in algebraic operations constructing new types.

Many type definitions will be possible using the respective part of XML
technology (XSD, or Relax NG with suitable choices). If one wishes to
use them. This does not yield Ada data types, but it does yield data
with loads of information about the types, including Ada style range
constraints. Reuse of types in other types is possible.

But I would not want all those types, because my interpretation
of data might be justifiably different.

>>> 6. requires complex, resource consuming, vulnerable infrastructure like
>>> parsers
>>
>> Yes, there are cases where such parsers are needed, and even more
>> of such things. For example, if you run Google.
> 
> Remember that the case in question is "exchanging structured data," not
> running Google.

Google is the biggest thing on earth that exchanges data with
just about everything outside microwave ovens.

>>> 7. is not redundant and at the same time absolutely permissive (requires
>>> complex validation of itself)
>>
>> Another set of unqualified word ({"redundant", ... })
> 
> http://en.wikipedia.org/wiki/Redundancy_%28engineering%29

(That's still unqualified, but as you say, redundancy may refer
to layers. But there is more.)

The purpose of "syntactic excess" of XML is about the same as in Ada:
put a left bracket at the start of a thing, and put a right bracket
at the end of a thing, possibly named:

  title: begin ... end title;
  package Foo is  ... end Foo;


  <title>...</title>
  <div id="Foo"> ... </div>

Unlike HTML, and like Ada, XML allows for some redundancy by making
sure that for each left bracket there is a right bracket in the text.
Most right brackets in XML tend to be named brackets, just like in Ada.
Both are unlike Ada's streamed data.


>> You don't have to write parser infrastructure when you
>> can use XML.
> 
> 1. I don't need parser if I don't use XML.

I need to write many parsers if I can't use XML. I use data not
generated by our programs.

> 2. I need to write the application layer serializing and deserializing
> object in any case.

OK.

> 3. Serialization is much simpler without XML. See Ada.Streams.

Is Ada's serialization easier for you, the 1 writer, or easier for
the N unknown readers out there who might not be using Ada?



> Safety could be against
> 
> 1. intentional misuse

I don't see how any source of data could protect against misuse of data
once data have left the "building".

> 2. unintentional errors

?


[rant about more than one standards-conforming implementation
of XML tools.]



^ permalink raw reply	[relevance 0%]

* Re: Should Inline be private in the private part of a package spec?
  @ 2012-08-22 14:30  1%                                     ` Dmitry A. Kazakov
  2012-08-22 16:48  0%                                       ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2012-08-22 14:30 UTC (permalink / raw)


On Wed, 22 Aug 2012 15:12:41 +0200, Georg Bauhaus wrote:

> On 22.08.12 09:32, Dmitry A. Kazakov wrote:
>> On Tue, 21 Aug 2012 23:35:35 +0200, Pascal Obry wrote:
>> 
>>> Dmitry,
>>>
>>>> The problem of transformation XML documents does not exist. I don't see why
>>>> data exchange needs that. I don't see why any transformations would be
>>>> necessary between systems.
>>>
>>> You don't see why because you seem to try hard to deny XML any benefit.
>> 
>> It is not a hard try. Yes, I have an opinion on XML because in my job
>> (automation systems and embedded) XML became a real plague. I asked others
>> to put up a practical case where XML might be useful, technically useful,
>> rather than per popularity vote or legacy. Nobody proposed any.
>> 
>>> Exchanging structured data is an important point.
>> 
>> It is an important problem, yes, but XML is poor for that. XML
>> 
>> 1. is extremely inefficient
> 
> As always, the question is inefficient for what and for whom.

For the network and the peers. The measures for both can be easily
provided.

>> 2. fails to capture the structure (e.g. recursive, interlinked structures)
> 
> ?

Take Containers.Doubly_Linked_Lists as an example. The closure object of a
list is the structure in question.

>> 3. lacks even basic data types (everything is string, not even weakly
>> typed)
> 
> ?

Compare XML to Ada or C. The latter languages have elementary data types
which can be used in algebraic operations constructing new types.

>> 6. requires complex, resource consuming, vulnerable infrastructure like
>> parsers
> 
> Yes, there are cases where such parsers are needed, and even more
> of such things. For example, if you run Google.

Remember that the case in question is "exchanging structured data," not
running Google.
 
>> 7. is not redundant and at the same time absolutely permissive (requires
>> complex validation of itself)
> 
> Another set of unqualified word ({"redundant", ... })

http://en.wikipedia.org/wiki/Redundancy_%28engineering%29

You could argue that redundancy is not required for a layer running over a
safe transmission channel, but then what is the purpose of the abundance of
XML's syntactic excesses? You cannot have both.

>>> Before XML we were
>>> using many format and we had to write parsers for all those formats in
>>> every languages. Now with XML (and the corresponding xsd, or wsdl) it is
>>> possible to parse (and *validate*) any data set coming from any
>>> applications.
>> 
>> And it is still so with XML, because XML considered for data exchange is
>> not of the application level.
> 
> You don't have to write parser infrastructure when you
> can use XML.

1. I don't need parser if I don't use XML.

2. I need to write the application layer serializing and deserializing
object in any case.

3. Serialization is much simpler without XML. See Ada.Streams.

>> It is just a very ugly
> 
> What does "ugly" mean, technically?

Technically ugly means inefficient.

>> and unsafe
> 
> Another claim. XML may have been called robust (in that the
> brackets are named, e.g., not overloaded). Has it ever been
> called safe?

Safety could be against

1. intentional misuse

2. unintentional errors

>> The application level is still to
>> develop and XML is no relief, it just complicates things.
> 
> A problem that XML-based setups solve is when they greatly
> simplify the combinatorial explosion of some ad-hoc variety
> of mutually semi-compatible ways of exchanging data.

Huh, XML indeed simplifies combinatorial explosion in many possible
meanings of this word. There is a multitudes of XML representations,
equivalent or almost equivalent variants which make versioning and
validation difficult, at best. There is a multitude of XML tools to buy, to
validate, to train personnel, to maintain, to scrape. There is a multitude
of network traffic, disk space, CPU time lost due to XML. Most of mentioned
is more than O(n). Some could be O(exp n). So, yes, combinatorial
explosion, shit hitting the fan...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 1%]

* Re: Using 'Base
  2012-07-21 16:26  2% Using 'Base Simon Wright
@ 2012-07-26 17:21  0% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2012-07-26 17:21 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> I've been working on a binding to msgpack[1]; progress so far at [2],
> for booleans, integer, and modular types.
>
> Looking at the read-integer spec, I have
>
>    with Ada.Streams;
>    generic
>       type Integer_Type is range <>;
>    function Message_Pack.Integer_Reader
>      (From : not null access Ada.Streams.Root_Stream_Type'Class)
>      return Integer_Type'Base;
>
> and I _think_ that the point of returning the 'Base of the formal type
> is that any Constraint_Errors will happen in user code during
> assignment of the function result. The idea was copied from the
> Generic Elementary Functions, but I may well have got the reason
> wrong. And, also, I may still raise CE internally if the value
> received from the wire won't fit in Integer_Type'Base.

Quoting from the Ada 95 Rationale Part 3 Chapter A[3],

   "The Ada 95 version uses Float_Type'Base as a type mark in
   declarations; this was not available in Ada 83. Thus the formal
   parameter types and result types of the functions are of the
   unconstrained (base) subtype of the generic formal type Float_Type,
   eliminating the possibility of range violations at the interface."

So I was correct.

> Is there any point in a similar declaration for write-integer? At
> present I have

But I still don't see why this is needed for _parameters_; if I supply
an out-of-range value for the generic formal type, shoudn't I be warned
at the call?

>     with Ada.Streams;
>     generic
>        type Integer_Type is range <>;
>     procedure Message_Pack.Integer_Writer
>       (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
>        Item : Integer_Type'Base);
>
> (again, cf Generic Elementary Functions).
>
> [1] http://msgpack.org/
> [2] git://git.code.sf.net/u/simonjwright/msgpack-ada/code

[3]
http://www.adaic.org/resources/add_content/standards/95rat/rat95html/rat95-p3-a.html#3,
a bit over half way down



^ permalink raw reply	[relevance 0%]

* Using 'Base
@ 2012-07-21 16:26  2% Simon Wright
  2012-07-26 17:21  0% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2012-07-21 16:26 UTC (permalink / raw)


I've been working on a binding to msgpack[1]; progress so far at [2],
for booleans, integer, and modular types.

Looking at the read-integer spec, I have

   with Ada.Streams;
   generic
      type Integer_Type is range <>;
   function Message_Pack.Integer_Reader
     (From : not null access Ada.Streams.Root_Stream_Type'Class)
     return Integer_Type'Base;

and I _think_ that the point of returning the 'Base of the formal type
is that any Constraint_Errors will happen in user code during assignment
of the function result. The idea was copied from the Generic Elementary
Functions, but I may well have got the reason wrong. And, also, I may
still raise CE internally if the value received from the wire won't fit
in Integer_Type'Base.

Is there any point in a similar declaration for write-integer? At
present I have

    with Ada.Streams;
    generic
       type Integer_Type is range <>;
    procedure Message_Pack.Integer_Writer
      (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
       Item : Integer_Type'Base);

(again, cf Generic Elementary Functions).

[1] http://msgpack.org/
[2] git://git.code.sf.net/u/simonjwright/msgpack-ada/code



^ permalink raw reply	[relevance 2%]

* Re: xor
  @ 2012-03-30 21:53  1%                                 ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2012-03-30 21:53 UTC (permalink / raw)


On 12-03-30 02:41 , Randy Brukardt wrote:
> "Niklas Holsti"<niklas.holsti@tidorum.invalid>  wrote in message
> news:9ti9k2FjcvU1@mid.individual.net...
>> On 12-03-29 02:25 , Randy Brukardt wrote:
>>> "Niklas Holsti"<niklas.holsti@tidorum.invalid>   wrote in message
>>> news:9tgqomFflrU1@mid.individual.net...
>>>> On 12-03-28 18:23 , Michael Moeller wrote:
>>> ...
>>>>> I don't want to push your helpfulness to far, but I still don't
>>>>> know whether there is any means to determine the size of a file
>>>>> from within Ada other than using a C subroutine calling fstat.
>>>>
>>>> Two ways:
>>>>
>>>> - Ada.Directories.Size, given the file name.
>>>> - Ada.Direct_IO.Size, given an open (Direct_IO) file.
>>>
>>> Actually, three ways:
>>
>> Ok, I showed two ways, but did not mean that there aren't other ways.
>>
>>> Ada.Stream_IO.Size, given an open (Stream_IO) file.
>>
>> If "positioning is not supported" for the stream file, the result of
>> Ada.Stream_IO.Size is implementation defined. Positioning is probably
>> supported for the kinds of files the OP uses now, but it is a bit of trap
>> for possible future uses of the program, for example if the program is
>> later used in a shell pipeline. A pipe probably does not support
>> positioning.
>
> I'm pretty sure that if "positioning is not supported" for a particular
> stream file, none of the other mechanisms will provide any useful answers,
> either. That's especially true as most Ada compilers use a common I/O system
> to implement all of these packages, so the effects will be similar on all of
> them.
>
> File for which "positioning is not supported" are likely to be things like
> sockets, pipes, and devices. Those won't have a meaningful size no matter
> how they're accessed.

I agree, but I think it is much more likely that Ada.Streams will 
encounter such a file, than is the case for Ada.Directories or 
Ada.Direct_IO. Also, I think that Ada.Direct_IO.Open should raise 
Use_Error for such files (but this does not seem to be required in the RM).

> In any case, your point is really just another argument for not depending
> upon the size at all; depending on the sort of file, it may not even be a
> meaningful concept. So depending on the size decreases the utility and
> reusability of your code.

Agreed.

> That said, the OP knows that and it surely is
> their decision how to write their code.

And now the OP has several ways to find the Size, including some 
warnings about when these ways may not work (and fstat would not work 
either).

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 1%]

* Re: xor
       [not found]                                 ` <tdadna1MV6uj5O7SnZ2dnUVZ_jidnZ2d@earthlink.com>
@ 2012-03-29  7:43  1%                               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-03-29  7:43 UTC (permalink / raw)


On Wed, 28 Mar 2012 16:49:14 -0400, Dennis Lee Bieber wrote:

> 	The Stream_IO system (which I've never used myself) is an attempt to
> map Ada I/O onto a UNIX-style "stream" and allow for putting diverse
> element types into a single stream.

Stream_IO provides an implementation of Ada.Streams backed by files. There
are streams backed by memory, by sockets etc.

Considering Stream_IO, as Randy already pointed out, it is likely the most
efficient way to handle files.

> I believe that, for example, writing
> a "string" will result in a length value first, then <length>
> characters.

Yes, if String'Output is used. When String'Write is, then no bounds are
written.

> 	I believe my last job mostly used Text_IO in conjunction with 'image
> and 'value attributes to convert between text file and internal binary.

In many cases Stream_IO is a better choice over Text_IO, e.g. if you want
to handle file encoding, line endings etc.

Ideally, Text_IO should do it for you. But in reality, it should actually
be Wide_Wide_IO, and it is not to expect that its implementation would
really talk to the OS in order to determine the encoding and that the OS is
capable to do it properly, and the Wide_Wide_IO would really convert
anything as it reads and writes. It is also not to expect that
LF/CR/EOF-mess would be handled properly.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 1%]

* Re: xor
  @ 2012-03-27 22:01  1%             ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-03-27 22:01 UTC (permalink / raw)


On 27.03.12 23:44, Michael Moeller wrote:
> dealing with ciphers
> the size of file is well known in advance and must be verified in any event.
> In addition sometimes we'll only pick certain parts of a pretty huge file
> and we never hit EOF.


Just in case you'll have to read blocks, and while Ada.Streams
should be most efficient, another convenient and also venerable
method uses an instance Direct_IO, instantiated for blocks.
You can set the file position to the block you need.

with Ada.Direct_IO;
with Interfaces;

procedure Position is

    -- Read "xyz.bin", second block, where
    -- $ perl -e "print 'x' x 512, 'y' x 512, 'z' x 512" > xyz.bin

    subtype Byte is Interfaces.Unsigned_8;

    type Block_Index is range 0 .. 511;
    type Block is array (Block_Index) of Byte;

    package Block_IO is new Ada.Direct_IO (Block);

    -- second block should be all 'y's; in terms of Byte:
    Y : constant Byte := Byte'Val (Character'Pos ('y'));

    -- a virtual character not occuring in input:
    Rubbish: constant Byte := Byte'Val (Character'Pos ('*'));

    Input : Block_IO.File_Type;
    Data : Block := Block'(Block_Index => Rubbish);

    use Block_IO;
begin
    Open (Input, Name => "xyz.bin", Mode => In_File);
    Set_Index (Input, To => 2);
    Read (Input, Item => Data);
    Close (Input);

    if Data /= Block'(Block_Index => Y) then
       raise Program_Error;
    end if;
end Position;




^ permalink raw reply	[relevance 1%]

* Re: xor
  2012-03-27 20:09  0%       ` xor Michael Moeller
    @ 2012-03-27 20:13  2%         ` Jeffrey Carter
  2 siblings, 0 replies; 200+ results
From: Jeffrey Carter @ 2012-03-27 20:13 UTC (permalink / raw)


On 03/27/2012 01:09 PM, Michael Moeller wrote:
>
> I have to read in what in C is called an unsigned byte, which in fact is
> a stream of bytes without any interpretation as a symbol. Just a number
> from 0 to 255.

There are several things in Ada that correspond to an unsigned byte on a 
byte-oriented machine: Interfaces.Unsigned_8 (ARM B.2), 
System.Storage_Elements.Storage_Element (13.7.1), and Ada.Streams.Stream_Element 
(13.13.1). And, of course, any user-defined type that is "mod 2 ** 8".

Usually you want to read a bunch of these at once. For the most general case of 
that, you read into an Ada.Streams.Stream_Element_Array, using the Read 
operation in Ada.Streams.

-- 
Jeff Carter
"My mind is a raging torrent, flooded with rivulets of
thought, cascading into a waterfall of creative alternatives."
Blazing Saddles
89



^ permalink raw reply	[relevance 2%]

* Re: xor
  2012-03-25 19:26  1%     ` xor Niklas Holsti
@ 2012-03-27 20:09  0%       ` Michael Moeller
                             ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Michael Moeller @ 2012-03-27 20:09 UTC (permalink / raw)




On Sun, 25 Mar 2012, Niklas Holsti wrote:

> On 12-03-25 18:16 , Michael Moeller wrote:
>> Thank you for your quick answer.
>> 
>> Can I use Unsigned_Byte_T to read in a byte from a file
>> as in C? I haven't looked into this yet.
>
> C has several ways to "read in a byte from a file", depending on the type of 
> the file and how you specify which byte you want to read. Can you be more 
> specific?

I have to read in what in C is called an unsigned byte, which in fact is
a stream of bytes without any interpretation as a symbol. Just a number
from 0 to 255.

In addition it would be nice to call something like 'fstat' to get the 
size of file in advance instead of checking every byte for EOF.

>
> If you mean reading an 8-bit octet from a "binary file" -- that is, not a 
> text file -- you can use the Ada library packages Ada.Sequential_IO or 
> Ada.Direct_IO, depending on your needs. These are generic packages, so you 
> must instantiate them for the type of data, for example Unsigned_Byte_T.
>
> If the file contains a mixture of different kinds of "binary" data, for 
> example both 8-bit data and 16-bit data, or more complex structures, you 
> should use the Ada "stream" facility from Ada.Streams.Stream_IO. The stream 
> facility helps you handle things like different endianness, padding, packing, 
> unusual encodings, and so on.
>
> The stream facility does not use generics; instead, it uses a combination of 
> tagged types and the special "stream attribute" operations T'Read, T'Write, 
> et cetera, which you can define differently for each type, T, that is present 
> in your file. For example, your 'Read operation for a 16-bit integer will 
> specify whether the integer is stored in little-endian or big-endian order in 
> the file (by reading two 8-bit integers, using 'Read for the 8-bit type, in 
> the corresponding order).
>
> The stream technique takes a bit of study to understand, but it works very 
> well, especially if the file has a mixture of different complex structures of 
> data, or if the file is created by a different language or computer and is 
> not in the "native" form for your Ada compiler.
>
> -- 
> Niklas Holsti
> Tidorum Ltd
> niklas holsti tidorum fi
>      .      @       .
>
Perhaps it will be more save to leave the C-procedures alone and to
call them from within Ada instead. I don't know whether this will be 
easier. However, I'll give Sequential_IO and Direct_IO a try.

Regards,
Michael




^ permalink raw reply	[relevance 0%]

* Re: xor
  @ 2012-03-25 19:26  1%     ` Niklas Holsti
  2012-03-27 20:09  0%       ` xor Michael Moeller
  0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2012-03-25 19:26 UTC (permalink / raw)


On 12-03-25 18:16 , Michael Moeller wrote:
> Thank you for your quick answer.
>
> Can I use Unsigned_Byte_T to read in a byte from a file
> as in C? I haven't looked into this yet.

C has several ways to "read in a byte from a file", depending on the 
type of the file and how you specify which byte you want to read. Can 
you be more specific?

If you mean reading an 8-bit octet from a "binary file" -- that is, not 
a text file -- you can use the Ada library packages Ada.Sequential_IO or 
Ada.Direct_IO, depending on your needs. These are generic packages, so 
you must instantiate them for the type of data, for example Unsigned_Byte_T.

If the file contains a mixture of different kinds of "binary" data, for 
example both 8-bit data and 16-bit data, or more complex structures, you 
should use the Ada "stream" facility from Ada.Streams.Stream_IO. The 
stream facility helps you handle things like different endianness, 
padding, packing, unusual encodings, and so on.

The stream facility does not use generics; instead, it uses a 
combination of tagged types and the special "stream attribute" 
operations T'Read, T'Write, et cetera, which you can define differently 
for each type, T, that is present in your file. For example, your 'Read 
operation for a 16-bit integer will specify whether the integer is 
stored in little-endian or big-endian order in the file (by reading two 
8-bit integers, using 'Read for the 8-bit type, in the corresponding order).

The stream technique takes a bit of study to understand, but it works 
very well, especially if the file has a mixture of different complex 
structures of data, or if the file is created by a different language or 
computer and is not in the "native" form for your Ada compiler.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 1%]

* gnat serial communication
@ 2012-01-06 13:30  1% Rolf
  0 siblings, 0 replies; 200+ results
From: Rolf @ 2012-01-06 13:30 UTC (permalink / raw)


I am having a hard time getting back to programming with GNAT

I installed GNAT GPL 2011 on a windows XP SP3 computer together with
GTK-Ada.

The current task is to simply display the incoming data from a serial
line to the console. The following program always fails displaying the
message:

raised GNAT.SERIAL_COMMUNICATIONS.SERIAL_ERROR : set: cannot get comm
state ( 6)

with GNAT.Serial_Communications;     use GNAT.Serial_Communications;
with Ada.Text_IO;                    use Ada.Text_IO;
with Ada.Streams;                    use Ada.Streams;

procedure Read_Ser is
   P_Voltage : Serial_Port;
   Voltage_Buffer : Stream_Element_Array(1..11);
   Voltage_Last   : Stream_Element_Offset;
begin
   Open (P_Voltage, Name (11));
   Set (P_Voltage, Rate => B19200);

end Read_Ser;


The corresponding code in GNAT.Serial_Communications is

     Success := GetCommState (HANDLE (Port.H.all),
Com_Settings'Access);

      if Success = Win32.FALSE then
         Success := CloseHandle (HANDLE (Port.H.all));
         Port.H.all := 0;
         Raise_Error ("set: cannot get comm state");
      end if;

Other terminal programs (HTerm, Bry_Terminal, etc.) connect to the
port without problem can display the incoming data. Does anybody know
what might be problem here?

Rolf



^ permalink raw reply	[relevance 1%]

* Re: Writing Data to a file
  @ 2011-12-15 18:32  2% ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-12-15 18:32 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:
> I have code that imports the unix 'write' function in order to write a
> stream of byte data.
>
> I had thought that replacing this call with the POSIX.IO.Write would
> make more sense, so that I was using more of a standard method.
>
> Unfortunately, I cannot access the write function within POSIX.IO, so
> I'm stuck with using the Write procedures.
>
> I have the following code, but I'm not sure that I'm doing this the
> right way...
>
> declare
>   Buf_Last : Stream_Element_Count;
>   Buf_Addr : System.Address := AREA_PTR + Storage_Offset(READ_OFFSET);
>   Buf : Stream_Element_Array( 1 .. Stream_Element_Count( WRITE_OFFSET
> - READ_OFFSET) );
>   for Buf'Address use Buf_Addr;
> begin
>   POSIX.IO.Write( File=>FileHandle, Buffer=>Buf, Last=>Buf_Last);
> end;
>
> The original code, using the imported function was:
>
> C_WRITE( File => FileHandle, Buffer=> (Q_AREA_PTR +
> Storage_Offset(READ_OFFSET), Num_Bytes=> (WRITE_OFFSET -
> READ_OFFSET));
>
> having to use the declare section to overlay the Stream_Element_Array
> onto the memory segment of the buffer seems much more complicated; so
> I feel like there is likely an easier way to do this, using standard
> Ada, and not having to import the C write function.
>
> Anyone have any suggestions?

with Ada.Streams.Stream_IO;

declare
   File : Ada.Streams.Stream_IO.File_Type;
   Stream : Ada.Streams.Stream_IO.Stream_Access;
begin
   Ada.Streams.Stream_IO.Open (File => File,
                               Mode => Ada.Streams.Stream_IO.Out_File,
                               Name => "my_output.bin");
   Stream := Ada.Streams.Stream_IO.Stream (File);
   Ada.Streams.Write (Stream => Stream,
                      Item => Buf (1 .. Write_Offset - Read_Offset));
end;

See ARM A.12.1 and 13.13.

The problem you may (or may not) face is converting a POSIX file
descriptor (File_Handle) to a Ada.Streams.Stream_IO.File_Type.  If you
know the name of the file, then the problem disappears, as above.

Note that you have not specified what it is that Buf is supposed to
contain; you seem to assume that an explicit conversion to
Stream_Element_Array is necessary.  It is not; given a stream you might
as well use the stream-oriented attributes (ARM 13.13.2):

package Data is
   type T is private;
private
   -- omitted
end Data;

with Ada.Streams.Stream_IO;
with Data;

declare
   -- as above
   Item : Data.T;
begin
   Data.T'Output (Stream, Item);  -- emits bounds and discriminants
   Data.T'Write (Stream, Item); -- does not emit bounds or discriminants
end;

-- 
Ludovic Brenta.



^ permalink raw reply	[relevance 2%]

* Re: Does Ada support endiannes?
  @ 2011-12-15 13:01  1%             ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2011-12-15 13:01 UTC (permalink / raw)


Gerd <GerdM.O@t-online.de> writes:

> The problem space requires integers (signed), so using unsigned is not
> the right option.
>
> Could you please explain: What do you think how the data send from 68k
> to x86 will be converted from one data layout to the other? Will it
> happen "magically" on the wire? I think, conversion must be done
> explicit either on one side or on the other side, and this requires
> some code.
>
> Currently I use the htonl ntohl functions for it, which (as stated
> above) is not a good choice as it limits the allowed values to
> unsigned.

Some code I wrote -- not quite the same problem -- which handles 8-byte
signed quantities and conversion to/from wire format, and works just
fine on i386, x86_64, powerpc, is

   type SNTP_Timestamp is delta 2.0 ** (-32) range -2.0 ** 31 .. 2.0 ** 31;
   for SNTP_Timestamp'Size use 64;

   subtype Timestamp_Slice is Ada.Streams.Stream_Element_Array (1 .. 8);

   function To_Timestamp_Slice
     (T : SNTP_Timestamp) return Timestamp_Slice is
      function Convert
      is new Ada.Unchecked_Conversion (SNTP_Timestamp,
                                       Timestamp_Slice);
      Tmp : constant Timestamp_Slice := Convert (T);
   begin
      if Big_Endian then
         return Tmp;
      else
         return (1 => Tmp (8),
                 2 => Tmp (7),
                 3 => Tmp (6),
                 4 => Tmp (5),
                 5 => Tmp (4),
                 6 => Tmp (3),
                 7 => Tmp (2),
                 8 => Tmp (1));
      end if;
   end To_Timestamp_Slice;


   function To_SNTP_Timestamp (T : Timestamp_Slice) return SNTP_Timestamp is
      function Convert is new Ada.Unchecked_Conversion (Timestamp_Slice,
                                                        SNTP_Timestamp);
   begin
      if Big_Endian then
         return Convert (T);
      else
         return Convert ((1 => T (8),
                          2 => T (7),
                          3 => T (6),
                          4 => T (5),
                          5 => T (4),
                          6 => T (3),
                          7 => T (2),
                          8 => T (1)));
      end if;
   end To_SNTP_Timestamp;

No real possibility of validation of this data type at the conversion
level, of course.

I think the chance of using wierd machines where this doesn't work is
pretty low.

And don't forget you can come a cropper because of compiler changes:
previous to Ada 2005, GNAT's representation of Ada.Calendar.Time used
the Unix epoch, so a conversion based on that seemed a pretty safe bet.



^ permalink raw reply	[relevance 1%]

* Re: Stream_Element_Array
  2011-09-15 20:48  1%                         ` Stream_Element_Array Dmitry A. Kazakov
@ 2011-09-16  0:20  0%                           ` Alexander Korolev
  0 siblings, 0 replies; 200+ results
From: Alexander Korolev @ 2011-09-16  0:20 UTC (permalink / raw)


On Sep 16, 12:48 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 15 Sep 2011 11:58:21 -0700 (PDT), Alexander Korolev wrote:
> > On Sep 15, 12:20 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> >> On Wed, 14 Sep 2011 14:29:41 -0700 (PDT), Alexander Korolev wrote:
> >>> "In your case the other end is not the memory but the wire"
> >>> I am not sure I undestand you complitly. What's wrong, at least for
> >>> now, to build \ construct in memory the Buffer (Stream_Element_Array)
> >>> with full command (according the format I posted) inside and after
> >>> that send it over any stream (including GNAT.Serial, Socket etc)
> >>> derived from Root_Stream_Type. Basicly, I don't need even a Type -
> >>> I am using it just get Unsigned_16 serialized into Stream Elements.
>
> >> Yes, but in most cases it does not work so straightforwardly. You usually
> >> need headers, checksums etc. The point is that you have more layers of the
> >> protocol than just raw values over stream of octets. This is why you use
> >> stream rather as a transport for packets/messages and often more upper
> >> levels too (state machine etc). The idea is to always encapsulate each
> >> level into a data type. It saves much time later.
>
> >>> That's it. It's kind of hadcrafting. I also can override My_Type'Write
> >>> attribute and send to Serial port ... Your approach is to create a new
> >>> stream actully, which will take into account the PROTOCOL specifics.
> >>> Absolutly agree with that. But what is wrong with manual approach I am
> >>> implementing.
>
> >> It is not wrong, it is just might not work because protocols are more
> >> complex (layered) than this simple model.
>
> > 1. Can not disagree again - layers, state machines is "must" part.
> > 2. So far got some interim results with serialization of the Type
> >    in Volatile Stream. The Last set to 3? It looks I am getting
> >    there but no confidence so far.
>
> Volatile Stream has a bug in its implementation. Last is actually "Next".
>
> Anyway, here is how I do such stuff:
>
>    with Volatile_Streams;  use Volatile_Streams;
>    with Ada.Streams;       use Ada.Streams;
>    with Interfaces;        use Interfaces;
>
>    package Frame_Streams is
>       Protocol_Error : exception;
>       --
>       -- Implements frame I/O layer over the stream transport.
>       -- In this case the transport is memory-resident stream.
>       --
>       type Frame_Stream (Size : Stream_Element_Count) is
>          tagged limited private;
>          -- Send frame, Data is the frame body
>       procedure Send
>                 (  Stream : in out Frame_Stream;
>                    Data   : Stream_Element_Array
>                 );
>          -- Receive frame, Data is the frame body, Last its last item
>          -- Protocol_Error is propagated upon protocol errors
>       procedure Receive
>                 (  Stream : in out Frame_Stream;
>                    Data   : out Stream_Element_Array;
>                    Last   : out Stream_Element_Offset
>                 );
>    private
>       Max_Frame_Size : constant := 256;
>       type Frame_Stream  (Size : Stream_Element_Count) is
>          new Memory_Resident_Stream (Size) with
>       record
>          Output : Stream_Element_Array (1..Max_Frame_Size);
>       end record;
>    end Frame_Streams;
>
>    package body Frame_Streams is
>       procedure Send
>                 (  Stream : in out Frame_Stream;
>                    Data   : Stream_Element_Array
>                 )  is
>          Sum : Unsigned_8 := 0;
>       begin
>          if Data'Length + 4 > Stream.Output'Length then
>             raise Constraint_Error with "Packet is too large";
>          end if;
>          Stream.Output (1) := 0;
>          Stream.Output (2) := Stream_Element'Val (Data'Length / 256);
>          Stream.Output (3) := Stream_Element'Val (Data'Length mod 256);
>          Stream.Output (4..3 + Data'Length) := Data;
>          for Index in Stream_Element_Offset
>              range 2..3 + Data'Length
>          loop
>             Sum := Sum + Stream_Element'Pos (Stream.Output (Index));
>          end loop;
>          Stream.Output (4 + Data'Length) := Stream_Element'Val (Sum);
>          Stream.Write (Stream.Output (1..4 + Data'Length));
>       end Send;
>
>       procedure Receive
>                 (  Stream : in out Frame_Stream;
>                    Data   : out Stream_Element_Array;
>                    Last   : out Stream_Element_Offset
>                 )  is
>          Length : Stream_Element_Offset;
>          Sum    : Unsigned_8;
>          Input  : Stream_Element_Array (1..2);
>       begin
>          Stream.Read (Input (1..1), Last);
>          if Last /= 2 then
>             raise Protocol_Error with "Frame header expected";
>          elsif Input (1) /= 0 then
>             raise Protocol_Error with "Wrong leading byte";
>          end if;
>          Stream.Read (Input (1..2), Last);
>          Length := Stream_Element'Pos (Input (1)) * 256
>                  + Stream_Element'Pos (Input (2));
>          if Last /= 3 then
>             raise Protocol_Error with "Unexpected end of stream";            
>          elsif Length > Data'Length then
>             raise Protocol_Error with "Frame is too large";
>          end if;
>          Sum := Stream_Element'Pos (Input (1))
>               + Stream_Element'Pos (Input (2));
>          Stream.Read (Data (Data'First..Data'First + Length - 1), Last);
>          if Last /= Data'First + Length then
>             raise Protocol_Error with "Unexpected end of stream";
>          end if;
>          Stream.Read (Input (1..1), Last);
>          if Last /= 2 then
>             raise Protocol_Error with "Unexpected end of stream";
>          end if;
>          Last := Data'First + Length - 1;
>          for Index in Data'First..Last loop
>             Sum := Sum + Stream_Element'Pos (Data (Index));
>          end loop;
>          if Sum /= Stream_Element'Pos (Input (1)) then
>             raise Protocol_Error with "Checksum error";
>          end if;
>       end Receive;
>    end Frame_Streams;
>
> To be used as follows:
>
>    with Ada.Text_IO;     use Ada.Text_IO;
>    with Frame_Streams;  use Frame_Streams;
>
>    procedure Put (Data : Stream_Element_Array) is
>    begin
>       for Index in Data'Range loop
>          Put (Stream_Element'Image (Data (Index)));
>          Put (' ');
>       end loop;
>    end Put;
>
>    S : aliased Frame_Stream (1024);
>    Buffer : Stream_Element_Array (1..4);
>    Last   : Stream_Element_Offset;
> begin
>    S.Send ((1, 2, 3, 4));
>    Put_Line ("Written:" & Stream_Element_Count'Image (S.Extent));
>    S.Receive (Buffer, Last);
>    Put_Line ("Read:");
>    Put (Buffer (1..Last));
> end;
>
> Note that is in its turn is frame I/O layer. Upon it you will have another
> layer and so on up to the application layer.
>
> P.S. It is a bit simplified, if there are many transports layers, the frame
> layer would take the actual transport as a discriminant (access to
> Root_Stream'Class) or a generic parameter. In your case it would be an
> overkill.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thanks. Will help.




^ permalink raw reply	[relevance 0%]

* Re: Stream_Element_Array
  @ 2011-09-15 20:48  1%                         ` Dmitry A. Kazakov
  2011-09-16  0:20  0%                           ` Stream_Element_Array Alexander Korolev
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2011-09-15 20:48 UTC (permalink / raw)


On Thu, 15 Sep 2011 11:58:21 -0700 (PDT), Alexander Korolev wrote:

> On Sep 15, 12:20�pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Wed, 14 Sep 2011 14:29:41 -0700 (PDT), Alexander Korolev wrote:
>>> "In your case the other end is not the memory but the wire"
>>> I am not sure I undestand you complitly. What's wrong, at least for
>>> now, to build \ construct in memory the Buffer (Stream_Element_Array)
>>> with full command (according the format I posted) inside and after
>>> that send it over any stream (including GNAT.Serial, Socket etc)
>>> derived from Root_Stream_Type. Basicly, I don't need even a Type -
>>> I am using it just get Unsigned_16 serialized into Stream Elements.
>>
>> Yes, but in most cases it does not work so straightforwardly. You usually
>> need headers, checksums etc. The point is that you have more layers of the
>> protocol than just raw values over stream of octets. This is why you use
>> stream rather as a transport for packets/messages and often more upper
>> levels too (state machine etc). The idea is to always encapsulate each
>> level into a data type. It saves much time later.
>>
>>> That's it. It's kind of hadcrafting. I also can override My_Type'Write
>>> attribute and send to Serial port ... Your approach is to create a new
>>> stream actully, which will take into account the PROTOCOL specifics.
>>> Absolutly agree with that. But what is wrong with manual approach I am
>>> implementing.
>>
>> It is not wrong, it is just might not work because protocols are more
>> complex (layered) than this simple model.
> 
> 1. Can not disagree again - layers, state machines is "must" part.
> 2. So far got some interim results with serialization of the Type
>    in Volatile Stream. The Last set to 3? It looks I am getting
>    there but no confidence so far.

Volatile Stream has a bug in its implementation. Last is actually "Next".

Anyway, here is how I do such stuff:

   with Volatile_Streams;  use Volatile_Streams;
   with Ada.Streams;       use Ada.Streams;
   with Interfaces;        use Interfaces;

   package Frame_Streams is
      Protocol_Error : exception;
      --
      -- Implements frame I/O layer over the stream transport.
      -- In this case the transport is memory-resident stream.
      --
      type Frame_Stream (Size : Stream_Element_Count) is
         tagged limited private;
         -- Send frame, Data is the frame body
      procedure Send
                (  Stream : in out Frame_Stream;
                   Data   : Stream_Element_Array
                );
         -- Receive frame, Data is the frame body, Last its last item
         -- Protocol_Error is propagated upon protocol errors
      procedure Receive
                (  Stream : in out Frame_Stream;
                   Data   : out Stream_Element_Array;
                   Last   : out Stream_Element_Offset
                );
   private
      Max_Frame_Size : constant := 256;
      type Frame_Stream  (Size : Stream_Element_Count) is
         new Memory_Resident_Stream (Size) with
      record
         Output : Stream_Element_Array (1..Max_Frame_Size);
      end record;
   end Frame_Streams;

   package body Frame_Streams is
      procedure Send
                (  Stream : in out Frame_Stream;
                   Data   : Stream_Element_Array
                )  is
         Sum : Unsigned_8 := 0;
      begin
         if Data'Length + 4 > Stream.Output'Length then
            raise Constraint_Error with "Packet is too large";
         end if;
         Stream.Output (1) := 0;
         Stream.Output (2) := Stream_Element'Val (Data'Length / 256);
         Stream.Output (3) := Stream_Element'Val (Data'Length mod 256);
         Stream.Output (4..3 + Data'Length) := Data;
         for Index in Stream_Element_Offset
             range 2..3 + Data'Length
         loop
            Sum := Sum + Stream_Element'Pos (Stream.Output (Index));
         end loop;
         Stream.Output (4 + Data'Length) := Stream_Element'Val (Sum);
         Stream.Write (Stream.Output (1..4 + Data'Length));
      end Send;

      procedure Receive
                (  Stream : in out Frame_Stream;
                   Data   : out Stream_Element_Array;
                   Last   : out Stream_Element_Offset
                )  is
         Length : Stream_Element_Offset;
         Sum    : Unsigned_8;
         Input  : Stream_Element_Array (1..2);
      begin
         Stream.Read (Input (1..1), Last);
         if Last /= 2 then
            raise Protocol_Error with "Frame header expected";
         elsif Input (1) /= 0 then
            raise Protocol_Error with "Wrong leading byte";
         end if;
         Stream.Read (Input (1..2), Last);
         Length := Stream_Element'Pos (Input (1)) * 256
                 + Stream_Element'Pos (Input (2));
         if Last /= 3 then
            raise Protocol_Error with "Unexpected end of stream";            
         elsif Length > Data'Length then
            raise Protocol_Error with "Frame is too large";
         end if;
         Sum := Stream_Element'Pos (Input (1))
              + Stream_Element'Pos (Input (2));
         Stream.Read (Data (Data'First..Data'First + Length - 1), Last);
         if Last /= Data'First + Length then
            raise Protocol_Error with "Unexpected end of stream";
         end if;
         Stream.Read (Input (1..1), Last);
         if Last /= 2 then
            raise Protocol_Error with "Unexpected end of stream";
         end if;
         Last := Data'First + Length - 1;
         for Index in Data'First..Last loop
            Sum := Sum + Stream_Element'Pos (Data (Index));
         end loop;
         if Sum /= Stream_Element'Pos (Input (1)) then
            raise Protocol_Error with "Checksum error";
         end if;
      end Receive;
   end Frame_Streams;

To be used as follows:

   with Ada.Text_IO;     use Ada.Text_IO;
   with Frame_Streams;  use Frame_Streams;

   procedure Put (Data : Stream_Element_Array) is
   begin
      for Index in Data'Range loop
         Put (Stream_Element'Image (Data (Index)));
         Put (' ');
      end loop;
   end Put;

   S : aliased Frame_Stream (1024);
   Buffer : Stream_Element_Array (1..4);
   Last   : Stream_Element_Offset;
begin
   S.Send ((1, 2, 3, 4));
   Put_Line ("Written:" & Stream_Element_Count'Image (S.Extent));
   S.Receive (Buffer, Last);
   Put_Line ("Read:");
   Put (Buffer (1..Last));
end;

Note that is in its turn is frame I/O layer. Upon it you will have another
layer and so on up to the application layer.

P.S. It is a bit simplified, if there are many transports layers, the frame
layer would take the actual transport as a discriminant (access to
Root_Stream'Class) or a generic parameter. In your case it would be an
overkill.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 1%]

* Re: Stream_Element_Array
  2011-09-14  9:09  0%   ` Stream_Element_Array Alexander Korolev
@ 2011-09-14  9:40  0%     ` Dmitry A. Kazakov
    0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2011-09-14  9:40 UTC (permalink / raw)


On Wed, 14 Sep 2011 02:09:15 -0700 (PDT), Alexander Korolev wrote:

> On Sep 14, 12:31�pm, Simon Wright <si...@pushface.org> wrote:
>> Alexander Korolev <antonovkab...@gmail.com> writes:
>>> I have a Type
>>
>>> type Message_Header is
>>> � � record
>>> � � � �-- Components � � � � � � � � �-- � 8 bit
>>> � � � �Length � �: Unsigned_16; � �-- 16 bit �(MSB)
>>> � � � �-- other components � � � � �-- � 8 bit
>>> � � end record;
>>
>>> How I could split the Lenght component on two subsequent
>>> Stream_Element ( 8-bit)?
>>
>>> Command: Stream_Element_Array (1 .. 64);
>>
>> I think the best way is using unchecked conversion. Below adds the
>> complication of converting to network byte order if not already so:
>>
>> � �subtype Two_Byte_Slice is Ada.Streams.Stream_Element_Array (1 .. 2);
>>
>> � �Big_Endian : constant Boolean
>> � � �:= System."=" (System.Default_Bit_Order, System.High_Order_First);
>>
>> � �function To_Two_Byte_Slice (S : Unsigned_16) return Two_Byte_Slice is
>> � � � function Convert is new Ada.Unchecked_Conversion (Unsigned_16,
>> � � � � � � � � � � � � � � � � � � � � � � � � � � � � Two_Byte_Slice);
>> � � � Tmp : constant Two_Byte_Slice := Convert (S);
>> � �begin
>> � � � if Big_Endian then
>> � � � � �return Tmp;
>> � � � else
>> � � � � �return (1 => Tmp (2),
>> � � � � � � � � �2 => Tmp (1));
>> � � � end if;
>> � �end To_Two_Byte_Slice;
>>
>> � �Command (11 .. 12) := To_Two_Byte_Slice (42);
> 
> Thanks Simon
> I'll try your code anyway.
> -- I thought I might made the issue more complex
> The Unsigned_16 came from transformation of the Header_Type component
> by Interfaces.Unsigned_16 (Last).
> It means I have Last: Stream_Element_Count (8 bit) set correctly.
> -- (Note For Per: I can not send the lenth to target stream because
> the whole
> -- message (stream_element_array) assembled needs further computation
> over + one transformation
> -- (staffing - something like replace 111 with 444 + 555 if 111
> occures in some components of the message including
> -- the letgh ) after the computation as an external dev requirement

Here is the pattern I am using:

   Put (Destination : in out Stream_Element_Array;
      Index : in out Stream_Element_Offset;
      Data : <the data type>
   );

   Get (Source : Stream_Element_Array;
      Index : in out Stream_Element_Offset;
      Data : out <the data type>
   );

Index indicates the position to start at. It is advanced after the put/get
elements of the buffer.

You fill the output buffer using consequent calls to Put. Then send its
filled slice Buffer (Buffer'First..Index - 1) to the hardware.

The opposite direction works similarly. You take data from the input buffer
with consequent calls to Get.

Get and Put for composite types are implemented in terms of Get and Put of
integral types. Note that their representations need not to correspond to
the hardware layouts. You are free to use Ada types best suitable to the
application.

P.S. Do not use representation clauses or unchecked conversion, I *do* mean
it:
      -- Little endian implementation of Get for Unsigned_16
   procedure Get
             (  Source : Stream_Element_Array;
                Index  : in out Stream_Element_Offset;
                Data   : out Unsigned_16
             )  is
   begin
      Data := Stream_Element'Pos (Source (Index)) +
              Stream_Element'Pos (Source (Index + 1));
      Index := Index + 2;
   end Get;

P.P.S. Stream element might be not the best choice if you are communicating
with the external world. You could also consider taking Unsigned_8 and an
array built upon it, because in most cases the hardware talks in octets.
That does not change the pattern, of course.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Stream_Element_Array
  2011-09-14  8:31  1% ` Stream_Element_Array Simon Wright
@ 2011-09-14  9:09  0%   ` Alexander Korolev
  2011-09-14  9:40  0%     ` Stream_Element_Array Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Alexander Korolev @ 2011-09-14  9:09 UTC (permalink / raw)


On Sep 14, 12:31 pm, Simon Wright <si...@pushface.org> wrote:
> Alexander Korolev <antonovkab...@gmail.com> writes:
> > I have a Type
>
> > type Message_Header is
> >     record
> >        -- Components                  --   8 bit
> >        Length    : Unsigned_16;    -- 16 bit  (MSB)
> >        -- other components          --   8 bit
> >     end record;
>
> > How I could split the Lenght component on two subsequent
> > Stream_Element ( 8-bit)?
>
> > Command: Stream_Element_Array (1 .. 64);
>
> I think the best way is using unchecked conversion. Below adds the
> complication of converting to network byte order if not already so:
>
>    subtype Two_Byte_Slice is Ada.Streams.Stream_Element_Array (1 .. 2);
>
>    Big_Endian : constant Boolean
>      := System."=" (System.Default_Bit_Order, System.High_Order_First);
>
>    function To_Two_Byte_Slice (S : Unsigned_16) return Two_Byte_Slice is
>       function Convert is new Ada.Unchecked_Conversion (Unsigned_16,
>                                                         Two_Byte_Slice);
>       Tmp : constant Two_Byte_Slice := Convert (S);
>    begin
>       if Big_Endian then
>          return Tmp;
>       else
>          return (1 => Tmp (2),
>                  2 => Tmp (1));
>       end if;
>    end To_Two_Byte_Slice;
>
>    Command (11 .. 12) := To_Two_Byte_Slice (42);

Thanks Simon
I'll try your code anyway.
-- I thought I might made the issue more complex
The Unsigned_16 came from transformation of the Header_Type component
by Interfaces.Unsigned_16 (Last).
It means I have Last: Stream_Element_Count (8 bit) set correctly.
-- (Note For Per: I can not send the lenth to target stream because
the whole
-- message (stream_element_array) assembled needs further computation
over + one transformation
-- (staffing - something like replace 111 with 444 + 555 if 111
occures in some components of the message including
-- the letgh ) after the computation as an external dev requirement




^ permalink raw reply	[relevance 0%]

* Re: Stream_Element_Array
  @ 2011-09-14  8:34  1%   ` Alexander Korolev
  0 siblings, 0 replies; 200+ results
From: Alexander Korolev @ 2011-09-14  8:34 UTC (permalink / raw)


On Sep 14, 9:29 am, Per Sandberg <per.sandb...@bredband.net> wrote:
> Why not just:
>    Message_Header'Write(Output_Stream,My_Message_Header)
> That would serialize the Data into the stream.
>
> If the target stream is a blocked message why not do
>    Message_Header'Write(Buffer_Stream,My_Message_Header)
>    Buffer_Stream'Write(Output_Stream,Buffer_Stream)
>
> And the Buffer_Stream is a stream of the kind found in:
>    http://sourceforge.net/projects/ada-spread/
>          spread-memory_streams.*
> or
>
> https://github.com/persan/zeromq-Ada
>     zmq-utilities-memory_streams.ad
>
> Which now is part of fedora15
> /Per
>
> On 09/14/2011 05:13 AM, Alexander Korolev wrote:
>
>
>
> > I have a Type
>
> > type Message_Header is
> >      record
> >         -- Components                  --   8 bit
> >         Length    : Unsigned_16;    -- 16 bit  (MSB)
> >         -- other components          --   8 bit
> >      end record;
>
> > How I could split the Lenght component on two subsequent
> > Stream_Element ( 8-bit)?
>
> > Command: Stream_Element_Array (1 .. 64);
>
> > Thanks

Thanks Per

I've just tried with GNAT a similar to your suggestion aproach

In_Memory_Stream:Volatile_Streams.Memory_Resident_Stream (Size =>
128);
Message_Length:Stream_Element_Array(1..2);
Last:Stream_Element_Count;
Msg_Header_Instance:Message_Header;

Begin

Message_Header'Write(In_Memory_Stream, Msg_Header_Instance);
--  writes to meomory
read (In_Memory_Stream,Message_Length,Last);
-- retreives Message_Length wich is Stream_Element_Array -- and the
Last
-- I left only one component in Message_Header - the Lengh, expected
-- the Last = 2, and Message_Length instance filled in after read
(...).
--
End;

Complaints on compilation: "expected access to
Ada.Streams.Root_Stream_Type'Access"



^ permalink raw reply	[relevance 1%]

* Re: Stream_Element_Array
    @ 2011-09-14  8:31  1% ` Simon Wright
  2011-09-14  9:09  0%   ` Stream_Element_Array Alexander Korolev
  1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2011-09-14  8:31 UTC (permalink / raw)


Alexander Korolev <antonovkablog@gmail.com> writes:

> I have a Type
>
> type Message_Header is
>     record
>        -- Components                  --   8 bit
>        Length    : Unsigned_16;    -- 16 bit  (MSB)
>        -- other components          --   8 bit
>     end record;
>
> How I could split the Lenght component on two subsequent
> Stream_Element ( 8-bit)?
>
> Command: Stream_Element_Array (1 .. 64);

I think the best way is using unchecked conversion. Below adds the
complication of converting to network byte order if not already so:

   subtype Two_Byte_Slice is Ada.Streams.Stream_Element_Array (1 .. 2);


   Big_Endian : constant Boolean
     := System."=" (System.Default_Bit_Order, System.High_Order_First);


   function To_Two_Byte_Slice (S : Unsigned_16) return Two_Byte_Slice is
      function Convert is new Ada.Unchecked_Conversion (Unsigned_16,
                                                        Two_Byte_Slice);
      Tmp : constant Two_Byte_Slice := Convert (S);
   begin
      if Big_Endian then
         return Tmp;
      else
         return (1 => Tmp (2),
                 2 => Tmp (1));
      end if;
   end To_Two_Byte_Slice;


   Command (11 .. 12) := To_Two_Byte_Slice (42);




^ permalink raw reply	[relevance 1%]

* Re: Address and bit mask
  @ 2011-08-31  8:35  2%           ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-08-31  8:35 UTC (permalink / raw)


milouz wrote:
> On Aug 30, 5:14 pm, Adam Beneschan <a...@irvine.com> wrote:
>
>> If the reason you want to do address arithmetic is something else,
>> though, you're welcome to ask about it, but rather than giving us C
>> code with no context and asking us how to translate it, please give us
>> a bigger-picture description of what you're trying to accomplish
>
> Ok, so I'll try to be more precise.
> I have to parse a list of chunks which are 4 bytes aligned. Each chunk
> is like this:
>
>   [ size |    data     ]
>
> The 'size' field is a 32-bit unsigned integer and it's the size of the
> whole chunk.
> The 'data' field has various lenght (>= 1 byte).
>
> I can solve that problem in a C-ish style, but I wonder what is the
> proper way to solve that problem in Ada.

If the chunks are contiguous in memory (or, better yet, in a file), my
first reaction would be to construct a stream and then use
Interfaces.Unsigned_32'Read to read the sizes and
Interfaces.Unsigned_X'Read to read the data.  Something like:

with Ada.Streams.Stream_IO;
with Interfaces;

procedure Parse (File_Name : in String) is
   File : Ada.Streams.Stream_IO.File_Type;
begin
   Ada.Streams.Stream_IO.Open (File => File,
                               Mode => Ada.Streams.Stream_IO.In_Mode,
                               Name => File_Name);
   Parse (Ada.Streams.Stream_IO.Stream (File));
end Parse;

procedure Parse (Stream : in Ada.Streams.Stream_IO.Stream_Access) is
   Length : Interfaces.Unsigned_32;
   Alignment : constant := 4;
   Padding_Byte : Interfaces.Unsigned_8;
begin
   Interfaces.Unsigned_32'Read (Stream, Length);
   declare
      Data : Ada.Streams.Stream_Element_Array
               (1 .. Ada.Streams.Stream_Element_Count (Length));
      Last : Ada.Streams.Stream_Element_Offset;
   begin
      Ada.Streams.Read (Stream, Data, Last);
      if Last < Length then
         raise Program_Error with "not enough data in the stream";
      end if;
      -- process Data here
   end;
   -- Now read as many padding bytes as necessary to reach the next
alignment
   -- boundary
   if Length mod Alignment /= 0 then
      for J in 1 .. Alignment - Length mod Alignment loop
         Interfaces.Unsigned_8'Read (Stream, Padding_Byte);
      end loop;
   end if;
end Parse;

--
Ludovic Brenta.
The Chief Legal Officer globally achieves the industry-standard
baseline starting point.



^ permalink raw reply	[relevance 2%]

* Re: What is the best method for transmitting objects/tagged records?
  2011-06-09  0:49  0%     ` Randy Brukardt
@ 2011-06-09  1:12  1%       ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2011-06-09  1:12 UTC (permalink / raw)


On Jun 8, 7:49 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> "Shark8" <onewingedsh...@gmail.com> wrote in message
>
>
> >(WITH-ing Ada.Streams is fine because it is a Pure package.)
>
> Right, but you don't need to use Ada.Tags (or anything tags) in order to
> stream tagged types. Just use the provided T'Class'Input and T'Class'Output
> attributes. For those to have portable results, you need to specify your
> external tag values for your tagged types (we previously discussed that).
>
>                                             Randy.

Oh!
{ I assume you mean something like Function Parse( Input :
stream_type ) Return Hierarchy_Parent'Class; no? }

So I was right in that I need to redefine my interfaces.

I currently have a task; which cannot return values as a function
would, and therefore cannot be used to
directly initialize an class-wide variable.

What I'm going to have to do then, is 'hide' the task in the body;
something like this:
Package Parser is

Task Type Parser_Task is
 -- Get Text and get_Token do essentially the same thing; in my setup
 -- I would like to try the tokenizing on client- and server-side
 -- to compare the efficiencies of the two.
 --
 -- Sorry about the poor naming & invalid code; I'm just typing up
psudeocode.
 Entry Get_Token(Token_Stream : Access stream); -- reads a token
 Entry Get_Text( Text_Stream : access stream ); -- read text-stream
 Entry Get_Tag(  The_Tag : Out Tag  );
 Entry Get_Object( The_Object : Out Object'Class );
End Parser_Task;

[...]
The_Parser : Parser_Task;
[...]

Function Pars( Input : Access Ada.Streams.Stream'Class ) Return
Object'Class is
 T : Tag;
begin

The_Parser.Get_Text( Input );
The_Parser.Get_Tag( T );

-- use dispatching construction
Declare
 This_Object : Object'Class:= Dispatch( T );
Begin
 The_Parser.Get_Object( This_Object );
 Return This_Object;
End;

end Parse;

End parser;



^ permalink raw reply	[relevance 1%]

* Re: What is the best method for transmitting objects/tagged records?
  2011-06-08 23:16  1%   ` Shark8
@ 2011-06-09  0:49  0%     ` Randy Brukardt
  2011-06-09  1:12  1%       ` Shark8
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2011-06-09  0:49 UTC (permalink / raw)


"Shark8" <onewingedshark@gmail.com> wrote in message 
news:fb72e599-968f-4850-abf7-1ed1fc8e50c3@d1g2000yqm.googlegroups.com...
On Jun 7, 1:06 pm, tmo...@acm.org wrote:
>> >> marshalling/unmarshalling part of a Partition Communication Subsystem?
>>
>> >I think that's what it amounts to, yes.
>>
>> Sending an object over a comm link differs from writing to/reading from
>> disk only in timing.
>
>Which is exactly why using tags and streams is a good idea.
>The main problem is that the package that defines the tag-type is not
>WITH-able by packages that are Remote_Types / Remote_Interfaces.
>
>So, even a function that has a parameter-footprint of
>"Procedure ( Tag : In Out Ada.Tags.Tag )" is invalid
>
>(WITH-ing Ada.Streams is fine because it is a Pure package.)

Right, but you don't need to use Ada.Tags (or anything tags) in order to 
stream tagged types. Just use the provided T'Class'Input and T'Class'Output 
attributes. For those to have portable results, you need to specify your 
external tag values for your tagged types (we previously discussed that).

                                            Randy.







^ permalink raw reply	[relevance 0%]

* Re: What is the best method for transmitting objects/tagged records?
  @ 2011-06-08 23:16  1%   ` Shark8
  2011-06-09  0:49  0%     ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2011-06-08 23:16 UTC (permalink / raw)


On Jun 7, 1:06 pm, tmo...@acm.org wrote:
> >> marshalling/unmarshalling part of a Partition Communication Subsystem?
>
> >I think that's what it amounts to, yes.
>
>   Sending an object over a comm link differs from writing to/reading from
> disk only in timing.

Which is exactly why using tags and streams is a good idea.
The main problem is that the package that defines the tag-type is not
WITH-able by packages that are Remote_Types / Remote_Interfaces.

So, even a function that has a parameter-footprint of
"Procedure ( Tag : In Out Ada.Tags.Tag )" is invalid

(WITH-ing Ada.Streams is fine because it is a Pure package.)





^ permalink raw reply	[relevance 1%]

* Re: Reading the while standard input into a String
  2011-06-06 10:31  0%       ` Ludovic Brenta
@ 2011-06-06 12:07  0%         ` Natasha Kerensikova
  0 siblings, 0 replies; 200+ results
From: Natasha Kerensikova @ 2011-06-06 12:07 UTC (permalink / raw)


Hello,

On 2011-06-06, Ludovic Brenta <ludovic@ludovic-brenta.org> wrote:
> Ludovic Brenta wrote on comp.lang.ada:
>> Natasha Kerensikova wrote on comp.lang.ada:
>>> However I thought that something similar to C's fread(), which can use
>>> efficient bulk memory copy, would be better than a loop of single
>>> character read (even when buffered in memory).
>>
>> How about:
>>
>> procedure Read_In_Chunks (Stream : in out
>> Ada.Streams.Root_Stream_Type'Class;
>>                           Result : out
>> Ada.Strings.Unbounded.Unbounded_String) is
> [...]
>
> I think I'm guilty of premature optimization.  I'd be curious to know
> whether Read_In_Chunks is actually faster than simply reading one
> character at a time and appending it to Result.  Only a benchmark
> could tell for sure.

The problem with benchmarks is that they are highly dependant on platform
and situation.

For what it's worth, I tried on my development system (Ubuntu Lucid),
using 1 KiB chunk size to read 10 MiB on random data, alternating calls
to each test program, 10 times each discarding the result (to warm up
caches) and then 10 times each gathering the results.

I got 100-160 ms spent in system mode for both, 90-110 ms in user mode
for your reader, and 440-490 ms in user mode for mine.

Using on-the-fly concatenation of 10 times the original 10 MiB file,
piped into the test programs, I get roughly the same ranges times ten.

So it looks like your optimization was justiified after all.



Thanks a lot for the idea,
Natasha



^ permalink raw reply	[relevance 0%]

* Re: Reading the while standard input into a String
  2011-06-06 10:27  2%     ` Ludovic Brenta
@ 2011-06-06 10:31  0%       ` Ludovic Brenta
  2011-06-06 12:07  0%         ` Natasha Kerensikova
  0 siblings, 1 reply; 200+ results
From: Ludovic Brenta @ 2011-06-06 10:31 UTC (permalink / raw)


Ludovic Brenta wrote on comp.lang.ada:
> Natasha Kerensikova wrote on comp.lang.ada:
>> However I thought that something similar to C's fread(), which can use
>> efficient bulk memory copy, would be better than a loop of single
>> character read (even when buffered in memory).
>
> How about:
>
> procedure Read_In_Chunks (Stream : in out
> Ada.Streams.Root_Stream_Type'Class;
>                           Result : out
> Ada.Strings.Unbounded.Unbounded_String) is
[...]

I think I'm guilty of premature optimization.  I'd be curious to know
whether Read_In_Chunks is actually faster than simply reading one
character at a time and appending it to Result.  Only a benchmark
could tell for sure.

--
Ludovic Brenta.



^ permalink raw reply	[relevance 0%]

* Re: Reading the while standard input into a String
  @ 2011-06-06 10:27  2%     ` Ludovic Brenta
  2011-06-06 10:31  0%       ` Ludovic Brenta
  0 siblings, 1 reply; 200+ results
From: Ludovic Brenta @ 2011-06-06 10:27 UTC (permalink / raw)


Natasha Kerensikova wrote on comp.lang.ada:
> On 2011-06-06, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
>> I'd rather process the input one fixed-length chunk at a time and
>> discard each chunk after processing (possibly by recycling the in-
>> memory buffer for the next chunk).
>
> I would do so if online processing was an option. However in the program
> containing code similar to what I posted, I cannot do any processing
> before reaching the end of input, because the processed format allows
> forward references, so references have to be gathered in a first pass on
> the whole input, before doing a second pass where dereference can take
> place.

OK, fair enough.

>> Note that reading one character at a time from a stream is quite fast
>> since streams normally use the operating system's buffered IO. Adding
>> a second layer of buffering inside your program is probably counter-
>> productive.
>
> That second layer of buffer was actually meant to reduce the number of
> Ada.Strings.Unbounded.Append calls (and the expensive reallocations that
> go with them).

Actually, Ada.Strings.Unbounded.Append itself has mechanisms to reduce
memory reallocations.  But I see your point.

> However I thought that something similar to C's fread(), which can use
> efficient bulk memory copy, would be better than a loop of single
> character read (even when buffered in memory).

How about:

procedure Read_In_Chunks (Stream : in out
Ada.Streams.Root_Stream_Type'Class;
                          Result : out
Ada.Strings.Unbounded.Unbounded_String) is
   Chunk : Ada.Streams.Stream_Element_Array (1 .. 1024);
   Chunk_As_String : String (1 .. 1024);
   for Chunk_As_String'Address use Chunk'Address;
   Last : Natural;
begin
   loop
      Ada.Streams.Read (Stream => Standard_Input,
                        Item   => Chunk,
                        Last   => Last);
      exit when Last = Chunk'First - 1; -- end of stream reached
      Ada.Strings.Unbounded.Append (Result, Chunk_As_String (1 ..
Last));
      exit when Last < Chunk'Last; -- end of stream reached
   end loop;
end Read_In_Chunks;

--
Ludovic Brenta.



^ permalink raw reply	[relevance 2%]

* Re: Why no socket package in the standard ?
  @ 2011-05-25 15:12 14%   ` Tero Koskinen
  0 siblings, 0 replies; 200+ results
From: Tero Koskinen @ 2011-05-25 15:12 UTC (permalink / raw)


Hi,

On Tue, 24 May 2011 06:11:43 +0000 (UTC) tmoran@acm.org wrote:

> > Except (I just looked at the source) I personally don't enjoy bindings
> > which end to introduce C like namings [*] in Ada. Things like PF_INET,
> > IPPROTO_IP or SOL_SOCKET looks really strange for an Ada source;
> 
> A thicker binding is NC sockets ("Not Claw", derived from Claw.Sockets).
> It's nc.zip at www.adaworld.com, look there under
> Ada Projects/Ada Internet Projects/Internet Protocols
> It's for Windows but IIRC the WSAStartup and WSACleanup should be
> the only Windows specific things.

Here is a diff which allows the package to compile on OpenBSD/amd64.
(It includes also some filename upper/lower case corrections, so
 the diff is pretty big.)

The example programs still segfault. I guess the datastructure
definitions are incorrect.

diff -r f734a2862510 -r 2cca25a3f5f4 GETJPG.ADB
--- a/GETJPG.ADB	Tue Dec 21 19:45:44 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
--- Sample program using NC.Sockets
--- It goes to the San Jose State weathercam and downloads to pic.jpg
--- a picture of the current skyline in San Jose, California
--- Copyright 2003 tmoran@acm.org anyone may use for any purpose
-with Ada.Streams,
-     Ada.Streams.Stream_IO,
-     Ada.Text_IO,
-     Nc.Sockets;
-procedure Getjpg is
-  use type Ada.Streams.Stream_Element_Offset;
-
-  Buffer  : Ada.Streams.Stream_Element_Array(1 .. 5000);
-  Last    : Ada.Streams.Stream_Element_Offset;
-  F       : Ada.Streams.Stream_IO.File_Type;
-  Socket  : Nc.Sockets.Socket_Type;
-  Length  : Ada.Streams.Stream_Element_Offset := 0;
-  type States is (Start, Seen_CR1, Seen_LF1, Seen_CR2, In_Data);
-  subtype Header is States range Start .. Seen_Cr2;
-  State   : States := Start;
-
-  procedure Write is
-    use Ada.Streams;
-    C : Character;
-    Watch_For : constant array(Header) of Character
-      := (Start => Ascii.CR, Seen_CR1 => Ascii.LF, Seen_LF1 => Ascii.CR,
-          Seen_CR2 => Ascii.LF);
-  begin
-    if State = In_Data then
-      Stream_IO.Write(F, Buffer(1 .. Last));
-      Length := Length + Last;
-      return;
-    end if;
-    for I in 1 .. Last loop
-      C := Character'Val(Stream_Element'Pos(Buffer(I)));
-      Ada.Text_IO.Put(C);
-      if C = Watch_For(State) then
-        State := States'succ(State);
-        if State = In_Data then
-          Stream_Io.Create(F, Stream_Io.Out_File, "pic.jpg");
-          if I < Last then
-            Stream_Io.Write(F, Buffer(I + 1 .. Last));
-            Length := Last - I;
-          end if;
-          exit;
-        end if;
-      else
-        State := Start;
-      end if;
-    end loop;
-  end Write;
-
-  procedure Stop is
-  begin
-    Ada.Text_IO.Put_Line(Ada.Streams.Stream_Element_Offset'Image(Length)
-                         & " file pic.jpg written");
-    if Ada.Streams.Stream_IO.Is_Open(F) then
-      Ada.Streams.Stream_IO.Close(F);
-    end if;
-  end Stop;
-
-begin
-  Nc.Sockets.Open(Socket, "metsun1.met.sjsu.edu", 80, Timeout => 20.0);
-  Nc.Sockets.Put_Line(Socket, "GET /cam_directory/latest.jpg HTTP/1.0");
-  Nc.Sockets.Put_Line(Socket, "");
-  loop
-    Nc.Sockets.Input(Socket, Timeout => 10.0, Item => Buffer, Last => Last);
-    exit when Last < Buffer'First;
-    Write;
-  end loop;
-  Nc.Sockets.Close(Socket);
-  Stop;
-exception
-  when Nc.Not_Found_Error =>
-    Stop;
-end Getjpg;
diff -r f734a2862510 -r 2cca25a3f5f4 NC.ADS
--- a/NC.ADS	Tue Dec 21 19:45:44 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-with Interfaces.C;
-package NC is
-  type Short is new Interfaces.C.Short;
-  type Int is new Interfaces.C.Int;
-  subtype Natural_Int is Int range 0 .. Int'last;
-  type UInt is new Interfaces.C.Unsigned;
-  type DWord is new Interfaces.C.Unsigned_Long;
-
-  type Byte is range 0 .. 255;
-  for Byte'size use 8;
-  type Word is mod 2**16;
-  for Word'size use 16;
-
-  Windows_Error,
-  Not_Valid_Error,
-  Already_Valid_Error,
-  Not_Found_Error : Exception;
-  type Lpcstr is access all Interfaces.C.Char;
-end NC;
diff -r f734a2862510 -r 2cca25a3f5f4 getjpg.adb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getjpg.adb	Wed Dec 22 18:05:52 2010 +0200
@@ -0,0 +1,75 @@
+-- Sample program using NC.Sockets
+-- It goes to the San Jose State weathercam and downloads to pic.jpg
+-- a picture of the current skyline in San Jose, California
+-- Copyright 2003 tmoran@acm.org anyone may use for any purpose
+with Ada.Streams,
+     Ada.Streams.Stream_IO,
+     Ada.Text_IO,
+     Nc.Sockets;
+procedure Getjpg is
+  use type Ada.Streams.Stream_Element_Offset;
+
+  Buffer  : Ada.Streams.Stream_Element_Array(1 .. 5000);
+  Last    : Ada.Streams.Stream_Element_Offset;
+  F       : Ada.Streams.Stream_IO.File_Type;
+  Socket  : Nc.Sockets.Socket_Type;
+  Length  : Ada.Streams.Stream_Element_Offset := 0;
+  type States is (Start, Seen_CR1, Seen_LF1, Seen_CR2, In_Data);
+  subtype Header is States range Start .. Seen_Cr2;
+  State   : States := Start;
+
+  procedure Write is
+    use Ada.Streams;
+    C : Character;
+    Watch_For : constant array(Header) of Character
+      := (Start => Ascii.CR, Seen_CR1 => Ascii.LF, Seen_LF1 => Ascii.CR,
+          Seen_CR2 => Ascii.LF);
+  begin
+    if State = In_Data then
+      Stream_IO.Write(F, Buffer(1 .. Last));
+      Length := Length + Last;
+      return;
+    end if;
+    for I in 1 .. Last loop
+      C := Character'Val(Stream_Element'Pos(Buffer(I)));
+      Ada.Text_IO.Put(C);
+      if C = Watch_For(State) then
+        State := States'succ(State);
+        if State = In_Data then
+          Stream_Io.Create(F, Stream_Io.Out_File, "pic.jpg");
+          if I < Last then
+            Stream_Io.Write(F, Buffer(I + 1 .. Last));
+            Length := Last - I;
+          end if;
+          exit;
+        end if;
+      else
+        State := Start;
+      end if;
+    end loop;
+  end Write;
+
+  procedure Stop is
+  begin
+    Ada.Text_IO.Put_Line(Ada.Streams.Stream_Element_Offset'Image(Length)
+                         & " file pic.jpg written");
+    if Ada.Streams.Stream_IO.Is_Open(F) then
+      Ada.Streams.Stream_IO.Close(F);
+    end if;
+  end Stop;
+
+begin
+  Nc.Sockets.Open(Socket, "metsun1.met.sjsu.edu", 80, Timeout => 20.0);
+  Nc.Sockets.Put_Line(Socket, "GET /cam_directory/latest.jpg HTTP/1.0");
+  Nc.Sockets.Put_Line(Socket, "");
+  loop
+    Nc.Sockets.Input(Socket, Timeout => 10.0, Item => Buffer, Last => Last);
+    exit when Last < Buffer'First;
+    Write;
+  end loop;
+  Nc.Sockets.Close(Socket);
+  Stop;
+exception
+  when Nc.Not_Found_Error =>
+    Stop;
+end Getjpg;
diff -r f734a2862510 -r 2cca25a3f5f4 nc-sockets-alt_gethostbyname.adb
--- a/nc-sockets-alt_gethostbyname.adb	Tue Dec 21 19:45:44 2010 +0200
+++ b/nc-sockets-alt_gethostbyname.adb	Wed Dec 22 18:05:52 2010 +0200
@@ -10,7 +10,7 @@
     end loop;
     Result.P_Hostent := NC.Sockets.B_Helper.gethostbyname(Result.C_Name(0)'unchecked_access);
     if Result.P_Hostent = null then
-      Result.Error := NC.Sockets.B_Helper.WSAGetLastError;
+      Result.Error := 0;
     end if;
     Result.Output_Ready:=True;
     while not Result.Fini loop
diff -r f734a2862510 -r 2cca25a3f5f4 nc-sockets.adb
--- a/nc-sockets.adb	Tue Dec 21 19:45:44 2010 +0200
+++ b/nc-sockets.adb	Wed Dec 22 18:05:52 2010 +0200
@@ -32,6 +32,10 @@
   use Claw.Sockets.Low_Level;
 
   System_Control : System_Controls;
+  function WSAGetLastError return Error_Codes is
+  begin
+     return 0;
+  end WSAGetLastError;
 
   procedure Get_Error_Code(Info       : in out Host_Info_Type;
                            Error_Code :    out Error_Codes) is
@@ -212,8 +216,10 @@
 
       C_Name_Length : Size_T := Claw.sockets.Alt_Gethostbyname.C_Name_Type'length;
 
-      function Get_Last_Error return Claw.DWord;
-      pragma Import (StdCall, Get_Last_Error, "GetLastError");
+      function Get_Last_Error return Claw.DWord is
+      begin
+         return 0;
+      end Get_Last_Error;
 
     begin
 
@@ -489,19 +495,13 @@
       if Is_Running then
         Error := 0;
       else
-        Error := WSAStartup(16#0101#, wsadata'access);
-        if Error = 0 then
-          Is_Running := True;
-        end if;
+        Is_Running := True;
       end if;
     end Make_Running;
 
     procedure Make_Stopped is
     begin
       if not Is_Running then return;end if;
-      if WSACleanup = Socket_Error then
-        raise Claw.windows_error;  -- to be caught by Shut_Down
-      end if;
       Is_Running := False;
     end Make_Stopped;
   end Winsock_Systems;
diff -r f734a2862510 -r 2cca25a3f5f4 nc-sockets.ads
--- a/nc-sockets.ads	Tue Dec 21 19:45:44 2010 +0200
+++ b/nc-sockets.ads	Wed Dec 22 18:05:52 2010 +0200
@@ -8,7 +8,7 @@
 
 package NC.Sockets is
   package Claw renames NC;
-  pragma Link_With("libwsock32.a");
+  -- pragma Link_With("libwsock32.a");
     --
     -- Edit History:
     --
@@ -746,13 +746,13 @@
       Host_Address_List_Ptr : Host_Address_List_Ptr_Type; -- h_addr_list
   end record;
   for Hostents use record
-      Host_Name_Ptr at 0 range 0 .. 31;
-      Host_Alias_Ptr_List at 4 range 0 .. 31;
-      Host_Address_Kind at 8 range 0 .. 15;
-      Host_Address_Length at 10 range 0 .. 15;
-      Host_Address_List_Ptr at 12 range 0 .. 31;
+      Host_Name_Ptr at 0 range 0 .. 63;
+      Host_Alias_Ptr_List at 8 range 0 .. 63;
+      Host_Address_Kind at 16 range 0 .. 15;
+      Host_Address_Length at 18 range 0 .. 15;
+      Host_Address_List_Ptr at 20 range 0 .. 63;
   end record;
-  for Hostents'size use 16*8;
+  for Hostents'size use 224;
 
   type Hostent_Ptr_Type is access all HOSTENTs;
 
@@ -782,9 +782,9 @@
     Last_Error_Code : Error_Codes := 0;
   end record;
   for W_Host_Info_Type use record
-    Hostent at 0 range 0 .. 16*8-1;
-    Data_Area at 16 range 0 .. (MAXGETHOSTSTRUCT-16)*8-1;
-    Last_Error_Code at MAXGETHOSTSTRUCT range 0 .. 31;
+    Hostent at 0 range 0 .. 224-1;
+    Data_Area at 32 range 0 .. (MAXGETHOSTSTRUCT-16)*8-1;
+    Last_Error_Code at (MAXGETHOSTSTRUCT+32) range 0 .. 31;
   end record;
 
   procedure Copy_Host_Info(Source : in W_Host_Info_Type;
@@ -800,16 +800,15 @@
   package Low_Level is
     use type Claw.Int;
 
-    function WSAGetLastError return Error_Codes;
-    pragma Import(Stdcall, WSAGetLastError, "WSAGetLastError");
+    -- function WSAGetLastError return Error_Codes;
 
     function gethostbyname(name: NC.lpcstr) return Hostent_Ptr_Type;
-    pragma Import(Stdcall, gethostbyname, "gethostbyname");
+    pragma Import(C, gethostbyname, "gethostbyname");
 
     function gethostbyaddr(addr: access Network_Address_Type;
                            len : Claw.Int := Network_Address_Type'size/8;
                            kind : Claw.Int := PF_Inet) return Hostent_Ptr_Type;
-    pragma Import(Stdcall, gethostbyaddr, "gethostbyaddr");
+    pragma Import(C, gethostbyaddr, "gethostbyaddr");
 
     WSADescription_Len : constant := 256;
     WSASys_Status_Len  : constant := 128;
@@ -829,21 +828,13 @@
         szSystemStatus at 261 range 0 .. 129*8-1;
         iMaxSockets    at 390 range 0 .. 15;
         iMaxUdpDg      at 392 range 0 .. 15;
-        lpVendorInfo   at 394 range 0 .. 31;
+        lpVendorInfo   at 394 range 0 .. 63;
     end record;
-    for WSADatas'size use 398*8;
-
-    function WSAStartup (wVersionRequired : NC.word;
-                         lpWSAData      : access WSADatas)
-             return Error_Codes;
-    pragma Import(Stdcall, WSAStartup, "WSAStartup");
-
-    function WSACleanup return Claw.Int;
-    pragma Import(Stdcall, WSACleanup, "WSACleanup");
+    for WSADatas'size use 3216;
 
     function gethostname(Name : NC.lpcstr;
                          Length : Claw.Int) return Claw.Int;
-    pragma Import(Stdcall, gethostname, "gethostname");
+    pragma Import(C, gethostname, "gethostname");
 
     type Address_Family_Type is new Claw.short;
     AF_INET : constant Address_Family_Type := 2;
@@ -851,7 +842,7 @@
     type Network_Port_Type is new NC.word; -- network byte order
 
     function htons(hostshort: Port_Type) return Network_Port_Type;
-    pragma Import(Stdcall, htons, "htons");
+    pragma Import(C, htons, "htons");
 
     type SOCKADDR_INs is record
       Family  : Address_Family_Type := AF_INET;
@@ -863,32 +854,32 @@
     for SOCKADDR_INs use record
       Family  at 0 range 0 .. 15;
       Port    at 2 range 0 .. 15;
-      Address at 4 range 0 .. 31;
-      Extra   at 8 range 0 .. 8*8-1;
+      Address at 4 range 0 .. 63;
+      Extra   at 12 range 0 .. 8*8-1;
     end record;
-    for SOCKADDR_INs'size use 16*8;
+    for SOCKADDR_INs'size use 160;
 
     function Connect(S      : Socket_Handles;
                      Name   : access SOCKADDR_INs;
                      Length : Claw.Int := SOCKADDR_INs'size/8)
              return Claw.Int;
-    pragma Import(Stdcall, Connect, "connect");
+    pragma Import(C, Connect, "connect");
 
     function Bind(S       : Socket_Handles;
                   Address : access SOCKADDR_INs;
                   Length  : Claw.Int := SOCKADDR_INs'size/8)
              return Claw.Int;
-    pragma Import(Stdcall, Bind, "bind");
+    pragma Import(C, Bind, "bind");
 
     function Listen(S   : Socket_Handles;
                     Q_Length : Claw.Int) return Claw.Int;
-    pragma Import(Stdcall, Listen, "listen");
+    pragma Import(C, Listen, "listen");
 
     function Accept_function(S       : Socket_Handles;
                              Address : access SOCKADDR_INs;
                              Length  : access Claw.Int)
                return Socket_Handles;
-    pragma Import(Stdcall, Accept_function, "accept");
+    pragma Import(C, Accept_function, "accept");
 
     type Protocol_Type is new Claw.Int;
     Ipproto_TCP : constant Protocol_Type := 6;
@@ -898,7 +889,7 @@
                              Kind    : Sock_Type;
                              Protocol: Protocol_Type)
                return Socket_Handles;
-    pragma Import(Stdcall, Socket_function, "socket");
+    pragma Import(C, Socket_function, "socket");
 
     FD_SETSIZE : constant := 64;
 
@@ -932,10 +923,10 @@
                              Exceptions_FD_Set : access FD_SET_Type;
                              Timeout           : access Timeval_Type)
              return Claw.Int;
-    pragma Import(Stdcall, Select_function, "select");
+    pragma Import(C, Select_function, "select");
 
     function closesocket(s: Socket_Handles) return Claw.Int;
-    pragma Import(Stdcall, closesocket, "closesocket");
+    pragma Import(C, closesocket, "close");
 
     function recv(
                 s    : Socket_Handles;
@@ -943,7 +934,7 @@
                 Len  : Claw.Int;
                 Flags: Claw.Int)
                return Claw.Int;
-    pragma Import(Stdcall, recv, "recv");
+    pragma Import(C, recv, "recv");
 
     function recvfrom(
                 s    : Socket_Handles;
@@ -953,7 +944,7 @@
                 Name   : access SOCKADDR_INs;
                 Length : access Claw.Int)
                return Claw.Int;
-    pragma Import(Stdcall, recvfrom, "recvfrom");
+    pragma Import(C, recvfrom, "recvfrom");
 
     function send(
                 s    : Socket_Handles;
@@ -961,7 +952,7 @@
                 Len  : Claw.Int;
                 Flags: Claw.Int)
                return Claw.Int;
-    pragma Import(Stdcall, send, "send");
+    pragma Import(C, send, "send");
 
     function sendto(
                 s    : Socket_Handles;
@@ -971,7 +962,7 @@
                 Name   : access SOCKADDR_INs;
                 Length : Claw.Int := SOCKADDR_INs'size/8)
                return Claw.Int;
-    pragma Import(Stdcall, sendto, "sendto");
+    pragma Import(C, sendto, "sendto");
 
     type Event_Type is new Claw.uint;
     FD_READ_Event    : constant Event_Type := 1;
@@ -984,12 +975,12 @@
     function getpeername(s : Socket_Handles;
                          Address: access SOCKADDR_INs;
                          Length  : access Claw.Int) return Claw.Int;
-    pragma Import(Stdcall, getpeername, "getpeername");
+    pragma Import(C, getpeername, "getpeername");
 
     function getsockname(s : Socket_Handles;
                          Address: access SOCKADDR_INs;
                          Length  : access Claw.Int) return Claw.Int;
-    pragma Import(Stdcall, getsockname, "getsockname");
+    pragma Import(C, getsockname, "getsockname");
 
     type ioctl_cmd_type is new Claw.DWord;
 
@@ -998,7 +989,7 @@
     function ioctlsocket(s   : Socket_Handles;
                          cmd : ioctl_cmd_type;
                          arg : access Claw.DWord) return Claw.Int;
-    pragma Import(Stdcall, ioctlsocket, "ioctlsocket");
+    pragma Import(C, ioctlsocket, "ioctl");
 
   end Low_Level;
 
diff -r f734a2862510 -r 2cca25a3f5f4 nc.ads
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nc.ads	Wed Dec 22 18:05:52 2010 +0200
@@ -0,0 +1,19 @@
+with Interfaces.C;
+package NC is
+  type Short is new Interfaces.C.Short;
+  type Int is new Interfaces.C.Int;
+  subtype Natural_Int is Int range 0 .. Int'last;
+  type UInt is new Interfaces.C.Unsigned;
+  type DWord is new Interfaces.C.Unsigned_Long;
+
+  type Byte is range 0 .. 255;
+  for Byte'size use 8;
+  type Word is mod 2**16;
+  for Word'size use 16;
+
+  Windows_Error,
+  Not_Valid_Error,
+  Already_Valid_Error,
+  Not_Found_Error : Exception;
+  type Lpcstr is access all Interfaces.C.Char;
+end NC;


-- 
Tero Koskinen - http://iki.fi/tero.koskinen/



^ permalink raw reply	[relevance 14%]

* Re: Why no socket package in the standard ?
  @ 2011-05-24 22:54  2%       ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2011-05-24 22:54 UTC (permalink / raw)


Le Wed, 25 May 2011 00:39:58 +0200, Georg Bauhaus  
<rm.dash-bauhaus@futureapps.de> a écrit:
> - if Ada was to standardize a binding, then that's new.
>    Something standard that is not about an abstraction,
That's about abstraction, otherwise socket could be defined atop of Ada  
streams (defining pipes over Ada streams, would be OK as an example, but  
defining sockets above Ada streams, would not).

>    but
>    rather about including some historic incident like BSD
>    sockets, in the language description.
Where do you think Unicode (now partially supported by Ada) is rooted ?  
Answer : one of the topmost code page at sometime.

> - it seems completely sufficient to agree, outside the standard,
>    on an API that can be used with any Ada compiler.  No
>    standardization  is needed at all.
OK. Let say it is not required, so "not" may be an option. But to answer  
the topic, you should now give an answer to why this should not. If  
"don't" is an option, "do" is still an option too.

> - Wait. We *do* have Ada Posix binding with an ISO number; since
>    Posix sockets do the trick, there is no need to add them to Ada.
Bringing all of POSIX just to get sockets, is too heavy. And sockets can  
live without POSIX (in some extent, even POSIX could live without sockets,  
which is not a major part of this standard, as far as I understand it).


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.
“ c++; /* this makes c bigger but returns the old value */ ” [Anonymous]



^ permalink raw reply	[relevance 2%]

* Re: GNAT.Serial_Communications
  2011-04-15 18:01  1%               ` GNAT.Serial_Communications Jeffrey Carter
@ 2011-04-16 10:21  0%                 ` tonyg
  0 siblings, 0 replies; 200+ results
From: tonyg @ 2011-04-16 10:21 UTC (permalink / raw)


On Apr 15, 7:01 pm, Jeffrey Carter
<spam.jrcarter....@spam.not.acm.org> wrote:
> On 04/15/2011 09:32 AM, tonyg wrote:
>
> >        for count in
> > 1..Ada.Streams.Stream_Element_Offset(The_String'Length) loop
> >           Return_Value(count) :=
> > character'pos(The_String(Integer(count)));
>
> You assume that The_String'First = 1, which will not be the case if you pass a
> slice with a different lower bound. However, that will cause Constraint_Error
> (unless you have turned off this check), which does not seem to be the problem.
>
> >        Return Return_Value(1..The_String'Length);
>
> I see no reason for the slice.
>
> You should be able to replace the body of String_To_Stream with a simple
> Unchecked_Conversion:
>
> with Ada.Streams;
> with Ada.Text_IO;
> with Ada.Unchecked_Conversion;
>
> procedure Stream_Convert is
>     subtype String3 is String (1 .. 3);
>
>     From : constant String3 := "abc";
>
>     subtype Stream3 is Ada.Streams.Stream_Element_Array (1 .. From'Length);
>
>     function To_Stream is new Ada.Unchecked_Conversion (Source => String3,
> Target => Stream3);
>
>     To : Stream3;
> begin -- Stream_Convert
>     To := To_Stream (From);
>
>     Output : for I in To'range loop
>        Ada.Text_IO.Put (Item => To (I)'Img);
>     end loop Output;
> end Stream_Convert;
>
> --
> Jeff Carter
> "Unix and C are the ultimate computer viruses."
> Richard Gabriel
> 99

I did that because I got a bit paranoid with the way ada handles
strings after finding out something new in the way its handles them. I
used to think that a slice's indexes changed when it went through a
procedure or functions paramaters but came unstuck by it. Thanks for
the code, I'll give it a try once I get this naughty serial port
sorted.



^ permalink raw reply	[relevance 0%]

* Re: GNAT.Serial_Communications
  2011-04-15 16:32  2%             ` GNAT.Serial_Communications tonyg
@ 2011-04-15 18:01  1%               ` Jeffrey Carter
  2011-04-16 10:21  0%                 ` GNAT.Serial_Communications tonyg
  0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2011-04-15 18:01 UTC (permalink / raw)


On 04/15/2011 09:32 AM, tonyg wrote:
>        for count in
> 1..Ada.Streams.Stream_Element_Offset(The_String'Length) loop
>           Return_Value(count) :=
> character'pos(The_String(Integer(count)));

You assume that The_String'First = 1, which will not be the case if you pass a 
slice with a different lower bound. However, that will cause Constraint_Error 
(unless you have turned off this check), which does not seem to be the problem.

>        Return Return_Value(1..The_String'Length);

I see no reason for the slice.

You should be able to replace the body of String_To_Stream with a simple 
Unchecked_Conversion:

with Ada.Streams;
with Ada.Text_IO;
with Ada.Unchecked_Conversion;

procedure Stream_Convert is
    subtype String3 is String (1 .. 3);

    From : constant String3 := "abc";

    subtype Stream3 is Ada.Streams.Stream_Element_Array (1 .. From'Length);

    function To_Stream is new Ada.Unchecked_Conversion (Source => String3, 
Target => Stream3);

    To : Stream3;
begin -- Stream_Convert
    To := To_Stream (From);

    Output : for I in To'range loop
       Ada.Text_IO.Put (Item => To (I)'Img);
    end loop Output;
end Stream_Convert;

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99



^ permalink raw reply	[relevance 1%]

* Re: GNAT.Serial_Communications
  @ 2011-04-15 16:32  2%             ` tonyg
  2011-04-15 18:01  1%               ` GNAT.Serial_Communications Jeffrey Carter
  0 siblings, 1 reply; 200+ results
From: tonyg @ 2011-04-15 16:32 UTC (permalink / raw)


On Apr 15, 2:58 pm, tonyg <tonytheg...@gmail.com> wrote:
> On Apr 14, 6:52 pm, Chris Moore <zmo...@ntlworld.com> wrote:
>
>
>
> > On 13/04/2011 22:12, tonyg wrote:
>
> > > Its actually blocking on top of the write. Also I've discovered after
> > > much experimentation that the writes are not doing the job when it
> > > does not block up. Usually it blocks up after 3-4 write attempts. I
> > > expect I need to discover what is happening at the other end of the
> > > wire, but its my first experience of using a serial port for anything.
>
> > > I suspect there is an option I am not engaging in the setting up of
> > > the port. I am using the gpl version so I was thinking there could be
> > > a bug that is not in the gnat pro version, but I don't want to be a
> > > bad craftsman :) and gnat are usually pretty much on top of stuff like
> > > that from previous experience, but then again its a relatively new
> > > addition to the gnat compiler and no ones perfect. But.... its usually
> > > me.....
>
> > I suspect it's the speed setting.  Serial ports default to 9600 baud
> > which is slow so you're filling the buffers up with the first few writes
> > as they're unable to get the data out quick enough and then they start
> > to block cos there's nowhere to put the data.
>
> > > Saying that though I am successfully reading from the port the
> > > incoming messages although they do appear in sections and I have to
> > > keep re reading the port to get the full message...
>
> > This is how serial interfaces usually work.  The lowest level read
> > function returns the number of bytes actually read.
>
> I found the problem. Its very embarassing and completely my own fault!
> Basically I did not have the write access to the usb port! I am using
> ubuntu for this. Just to let those who are interested know.

Actually this is not the problem I spoke too soon. Minicom will talk
and read the correct values.
However gnat will read correctly but not write to the port properly,
but its not hanging anymore so thats a plus. I just cannot see why
minicom would write the string correctly to the port but when I write
the string to the port through gnat.serial_communication it does not
work!!

      GNAT.Serial_Communications.Write(Port   => The_Port,
                        Buffer =>
String_To_Stream(Broadcast_Message));

  function String_To_Stream ( The_String : in String) return
Ada.Streams.Stream_Element_Array is

      Return_Value :
Ada.Streams.Stream_Element_Array(1..The_String'length);

   begin
      Put (" Start of Data out  :- ");
      for count in
1..Ada.Streams.Stream_Element_Offset(The_String'Length) loop
         Return_Value(count) :=
character'pos(The_String(Integer(count)));
         int_io.Put(Integer(Return_Value(count)));
      end loop;
      Put (" End of Data out ");
	Put_Line (The_String);

      Return Return_Value(1..The_String'Length);
   end String_To_Stream;

Is there anything you can see thats wrong there ?



^ permalink raw reply	[relevance 2%]

* Re: Parser interface design
  @ 2011-04-08 11:16  1% ` Brian Drummond
  0 siblings, 0 replies; 200+ results
From: Brian Drummond @ 2011-04-08 11:16 UTC (permalink / raw)


On Wed, 06 Apr 2011 10:11:46 +0000, Natasha Kerensikova wrote:

> Hello,
> 
> before wasting too much time of anybody, I want to make it clear that
> I'm asking about interface design in Ada which might actually never turn
> up into real code. I'm still unsure about ever writing Ada code, and how
> bad my previous thread went playing no small part in that. However I'm
> still curious about how this particular problem might be solved in Ada.
> 
> I wrote a while back a C library to parse Markdown text. I call "parser"
> the code that takes a text assumed to be formatted in Markdown as input,
> and communicates in a still-to-be-defined way with another component,
> which I call "renderer", and which outputs the same text but using
> another formatting, for example HTML or PDF.
> 
> The problem on which I want your opinion is designing the interface
> between the parser and the renderer. The point is to be able to "plug"
> may renderer into the parser, and thereby obtain a different kind of
> output, with as little code rewrite as possible (hence the idea of
> refactoring the "parser" into a re-usable part).

One approach to the renderer : streaming I/O.

I don't know if it's the right approach for your problem, but Ada's 
stream I/O is flexible and capable of interesting things.

Ada.Streams allows you to overload your own Read and Write procedures for 
existing types, and define them for new types.

I have played with this a little, though not for your specific purpose.

It looks as if it ought to be possible to create PDF_Stream, HTML_Stream, 
RTF_Stream etc and output to any or all of them.

Sketch of one possible approach, where HTML_Stream, PDF_Stream are 
derived from the root stream class somehow... 
NOt tested : this may not work for multiple types of stream.

-- expose only this to the parser
type style is (none, bold, italic);

type formatted_string is record
   format : style;
   content : bounded_string;
end record;
(Or use discriminants for arbitrary string length.
It is up to the parser to supply formatted_strings)

type element is (ruler, page_break);

-- the rest is internal to the renderer

type V_String_Array is array (style) of V_String;
-- see Barnes p.402 on v-strings and ragged arrays

html_tags : constant V_String_Array := (+"", +"<b>", ...);
html_end_tags : constant V_String_Array := (+"", +"</b>", ...);

procedure write_formatted_string (stream : HTML_Stream; 
                                  f_string : formatted_string) is
begin
   write(html_tags(f_string.format));
   write(f_string.content);
   write(html_tags(f_string.format));
end write_html_formatted_string;

procedure write__element(stream : HTML_Stream) is ...

procedure write_formatted_string (stream : PDF_Stream; 
                                  f_string : formatted_string) is ...

for formatted_string'write use write_formatted_string;
for element'write use write_element; 

(then stream I/o as normal. Possibly open the correct stream type 
according to the supplied filename extension?)

My previous experiment with streams is described at

http://groups.google.com/group/comp.lang.ada/browse_thread/
thread/9642027a78f96963/8449fae50ece601f?q=group:comp.lang.ada
+insubject:newbie+author:brian_drummond%40btconnect.com#8449fae50ece601f

Here, I was trying to use generic Write procedures to write many (two in 
the example!) different enumerations, with control over how each 
enumeration appeared over the outputs. I ran into difficulties, and had 
to use renames to overcome them.

You may have some similar difficulty overloading procedures to write  
e.g. the formatted_string to different types of stream. It may be 
possible to resolve this by instantiating generic procedures, and 
renaming, as in my example above.

- Brian




^ permalink raw reply	[relevance 1%]

* Re: Text parsing package
  2011-03-28 10:18  0%       ` Yannick Duchêne (Hibou57)
@ 2011-03-28 12:08  0%         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-03-28 12:08 UTC (permalink / raw)


On Mon, 28 Mar 2011 12:18:38 +0200, Yannick Duch�ne (Hibou57) wrote:

> Le Mon, 28 Mar 2011 10:15:52 +0200, Dmitry A. Kazakov  
> <mailbox@dmitry-kazakov.de> a �crit:
>>>> 3. As others have mentioned, it is a good idea to abstract the source
>>>> formats in order to be able to parse files, strings, streams etc.
>>> And Ada already provides a root for that: Ada.Streams.Root_Stream_Type
>>
>> Unfortunately Root_Stream_Type is not an interface and string cannot be
>> inherited from. So in the effect you would need a special root.
> I meant implementing a concrete Root_Stream_Type using a string as source.  
> You would have an open method, getting a string or any kind of reference  
> to string, just not as a filename this time. But wonder about efficiency  
> (because of the tagged type), which is important for such low-level and  
> heavily iterated stuff.

Another problem is that it would be difficult to use. Mix-in does not work
because String cannot be a discriminant. You would have a nasty
access-to-string one or have to copy the whole string into the stream
object.

>> Yes, it would be nice to have structured multiple co-routines as an
>> alternative to FSM. There are some cases where tasks look like an  
>> overkill.
> I remember I made that wish too (can't remember what was said to advocate  
> against it).

The reason is always same, if there is nobody from ARG personally
interested in the concept, it will be blindly rejected. Here I mean not the
implementation, but merely a serious consideration of possible ways to
approach the problem. Alone this require much mental work.

> Let's hope for Ada 2017 or Ada 2022.

I doubt it. This is a "serious" issue, not a patch or yet another kludge.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Text parsing package
  2011-03-28  8:15  0%     ` Dmitry A. Kazakov
@ 2011-03-28 10:18  0%       ` Yannick Duchêne (Hibou57)
  2011-03-28 12:08  0%         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2011-03-28 10:18 UTC (permalink / raw)


Le Mon, 28 Mar 2011 10:15:52 +0200, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:
>>> 3. As others have mentioned, it is a good idea to abstract the source
>>> formats in order to be able to parse files, strings, streams etc.
>> And Ada already provides a root for that: Ada.Streams.Root_Stream_Type
>
> Unfortunately Root_Stream_Type is not an interface and string cannot be
> inherited from. So in the effect you would need a special root.
I meant implementing a concrete Root_Stream_Type using a string as source.  
You would have an open method, getting a string or any kind of reference  
to string, just not as a filename this time. But wonder about efficiency  
(because of the tagged type), which is important for such low-level and  
heavily iterated stuff. Buffering with systematic batch input/output may  
still be option to reach efficiency, even with a tagged stream type (batch  
often help efficiency I feel).

The advantage is that this would be clean to use, as this may be used  
every where something expect a standard Ada Stream. The disadvantage may  
be the above.

Also can be done with generics, but will not try to advocate it, as when I  
used it, I was not happy with that in the end.

> Yes, it would be nice to have structured multiple co-routines as an
> alternative to FSM. There are some cases where tasks look like an  
> overkill.
I remember I made that wish too (can't remember what was said to advocate  
against it). Let's hope for Ada 2017 or Ada 2022.

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.
“ c++; /* this makes c bigger but returns the old value */ ” [Anonymous]



^ permalink raw reply	[relevance 0%]

* Re: Text parsing package
  2011-03-28  0:15  1%   ` Yannick Duchêne (Hibou57)
@ 2011-03-28  8:15  0%     ` Dmitry A. Kazakov
  2011-03-28 10:18  0%       ` Yannick Duchêne (Hibou57)
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2011-03-28  8:15 UTC (permalink / raw)


On Mon, 28 Mar 2011 02:15:31 +0200, Yannick Duchêne (Hibou57) wrote:

> Le Wed, 23 Mar 2011 09:32:10 +0100, Dmitry A. Kazakov  
> <mailbox@dmitry-kazakov.de> a écrit:
>> 1. Don't use unbounded strings. That is an unnecessary overhead.
> Yes, better limit the maximum size of literals.

The literal size is limited by the maximal line length

>> 3. As others have mentioned, it is a good idea to abstract the source
>> formats in order to be able to parse files, strings, streams etc.
> And Ada already provides a root for that: Ada.Streams.Root_Stream_Type

Unfortunately Root_Stream_Type is not an interface and string cannot be
inherited from. So in the effect you would need a special root.

>> 6. You should decide what drives the parser. In your case it is the caller.
>> That is not a good idea in most cases, because the caller rarely knows what
>> to expect next. A better choice is semantic call-backs from the parser to
>> the caller. Abstract primitive operations is IMO the best implementation of
>> such callbacks.

> What “drives”, is not just a question rising with parsers, it is rising  
> every where. Here, if Ada had something like a Yield, this would be nice  
> too.

Yes, it would be nice to have structured multiple co-routines as an
alternative to FSM. There are some cases where tasks look like an overkill.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Text parsing package
  @ 2011-03-28  0:15  1%   ` Yannick Duchêne (Hibou57)
  2011-03-28  8:15  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2011-03-28  0:15 UTC (permalink / raw)


Le Wed, 23 Mar 2011 09:32:10 +0100, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:
> 1. Don't use unbounded strings. That is an unnecessary overhead.
Yes, better limit the maximum size of literals.

> 3. As others have mentioned, it is a good idea to abstract the source
> formats in order to be able to parse files, strings, streams etc.
And Ada already provides a root for that: Ada.Streams.Root_Stream_Type

> 6. You should decide what drives the parser. In your case it is the  
> caller.
> That is not a good idea in most cases, because the caller rarely knows  
> what
> to expect next. A better choice is semantic call-backs from the parser to
> the caller. Abstract primitive operations is IMO the best implementation  
> of
> such callbacks.
What “drives”, is not just a question rising with parsers, it is rising  
every where. Here, if Ada had something like a Yield, this would be nice  
too. Otherwise, yes, the callback is a good choice and may allow  
optimization, especially if some kind of seeking into the source is an  
expected option (the parser can then efficiently skip what is not  
relevant; on the opposite, if the caller drives, then no such optimization  
is possible).


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.
“ c++; /* this makes c bigger but returns the old value */ ” [Anonymous]



^ permalink raw reply	[relevance 1%]

* Re: Little tutorial about streams
    2011-03-05  1:08  1% ` Shark8
@ 2011-03-05  1:35  1% ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2011-03-05  1:35 UTC (permalink / raw)


"mockturtle" <framefritti@gmail.com> wrote in message 
news:fba7e41d-288d-419a-ae55-86c2fd954903@glegroupsg2000goo.googlegroups.com...
> Dear all,
> I'm back.  First of all, thank you to everyone for your comments.  Let me 
> do a cumulative answer. I am afraid that this will make this post a bit 
> long.
...
>> ---- on Mar 1 2011 Randy Brukardt wrote
>>
>> It might make sense to mention that you can also specify these 
>> subprograms
>> with an aspect clause in Ada 2012
>
> I did not know about this.  Do you have a reference?

The draft standard and Rationale are the best references. But the rationale 
isn't close to done at this point (I've only seen a draft of Chapter 1 to 
date) and isn't public anyway. The current draft of the standard gives the 
syntax (see http://www.ada-auth.org/standards/ada12.html for the whole 
draft; specifically see 
http://www.ada-auth.org/standards/12rm/html/RM-13-3-1.html for the aspect 
syntax). The next draft will have essentially all of the details (probably 
available in April).

Anyway, the basic idea is that aspect clauses can be given as part of 
declarations. The "definition" is not resolved or evaluated until the entity 
declared by the declaration is frozen (formally until the end of the 
enclosing declaration list), so these are automatically "forward" 
references. For instance, you could have:

    type A_Type is ....
        with Read => My_Read,
               Write => My_Write;

   procedure My_Read (Stream : not null access 
Ada.Streams.Root_Stream_Type'Class;
                                     Item : out A_Type);

   procedure My_Write (Stream : not null access 
Ada.Streams.Root_Stream_Type'Class;
                                     Item : in A_Type);

This notation is most valuable for subprograms (since it sidesteps the 
problems of overloading that cause problems for pragmas and attribute 
definition clauses), but it is general and works on almost any declaration. 
(There are a few obscure things that are technically declarations -- like 
goto labels -- that don't allow aspect clauses.)

Just one of the good things coming in Ada 2012.

                                  Randy.





^ permalink raw reply	[relevance 1%]

* Re: Little tutorial about streams
  @ 2011-03-05  1:08  1% ` Shark8
  2011-03-05  1:35  1% ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Shark8 @ 2011-03-05  1:08 UTC (permalink / raw)


I was debating on whether or not to submit to you a little 'toy' LISP
interpreter I've started. I've only got the reading and writing here,
no eval or special-forms like 'if', but since they're Stream-based it
might be appropriate.


---------------------------------
-- Lisp Interpreter in Ada.
-- By Joey Fish

---------------
-- LISP.ADS  --
---------------
With
Ada.Containers.Indefinite_Vectors,
Ada.Streams;

Package LISP is

 
-----------------------------------------------------------------------
   --	In LISP a List is defined as either a single element or an	--
   --	element followed by a lisr; as a consequence of this
definition	--
   --	there is no such thing as an "Empty List."			--
 
-----------------------------------------------------------------------


   Type List is Private;
   -- ToDo: Add primitive functions for list construction/
manipulation.
   -- ToDo: Add primitive functions for determining if it is an
executable list.

Private
   -- Alias Ads.Streams.Root_Stream_Type for ease of use.
   SubType Stream_Root is Ada.Streams.Root_Stream_Type;

   -- Element_Type describes the possible types of an Atom
   --	Note: Empty_Type is the NULL-element.
   Type Element_Type is
     ( Empty_Type, Boolean_Type, Integer_Type, Real_Type,
String_Type );

   -- Type Atom is a record containing the type and value of an
element.
   Type Atom( Element : Element_Type:= Empty_Type ) is record
      Case Element is
         When Empty_Type	=> Null;
         When Boolean_Type	=> Boolean_Value : Boolean:= False;
         When Integer_Type	=> Integer_Value : Integer:= 0;
         When Real_Type		=> Real_Value	 : Float  := 0.0;
         When String_Type	=> Is_Name	 : Boolean:= False;
				   String_Value	 : Not Null Access String;
      End Case;
   end record;

   Procedure Write_Atom( Stream	: Not Null Access Stream_Root'Class;
			 Item	: In Atom
                       );

   For Atom'Write Use Write_Atom;

   Type Atom_Array is Array (Positive Range <>) of Atom;
   Type Elementry_List( Terminal : Boolean:= True ) is record
      Head : Atom:=		( Element => Empty_Type );
      Case Terminal is
	When False => Tail : Not Null Access Elementry_List;
	When True  => Null;
      End Case;
   end record;

   Procedure Append( Head : In Out Elementry_List; Tail : In
Elementry_List );
   Function  Convert( List : Elementry_List ) Return Atom_Array;
   Function  Convert( List : Atom_Array ) Return Elementry_List;

   Procedure Write_EList( Stream	: Not Null Access Stream_Root'Class;
			  Item		: In Elementry_List
                       );
   Procedure Read_EList( Stream	: Not Null Access Stream_Root'Class;
			 Item	: Out Elementry_List
                       );


   For Elementry_List'Read  Use Read_EList;
   For Elementry_List'Write Use Write_EList;

   Type List_Element_Type is ( Atom_Element, EList_Type,
Recursive_List );
   Type List_Element( Element : List_Element_Type:= Atom_Element ) is
record
      Case Element is
	When Atom_Element	=> Atom_Data	: Atom;
	When EList_Type		=> EList_Data	: Elementry_List;
	When Recursive_List	=> RList_Data	: Not Null Access List;
      end case;
   end record;
   Function As_List( Input : in List_Element ) Return List;

   Package Elements is New Ada.Containers.Indefinite_Vectors
	( Index_Type => Positive, Element_Type => List_Element );

   Type List is Tagged record
      Data : Elements.Vector:= Elements.Empty_Vector;
   end record;

   Procedure Write_List( Stream	: Not Null Access Stream_Root'Class;
			  Item	: In List
                       );
   Procedure Read_List( Stream	: Not Null Access Stream_Root'Class;
			 Item	: Out List
                       );

   For List'Read  Use Read_List;
   For List'Write Use Write_List;


End LISP;

---------------
-- LISP.ADB  --
---------------

With
Ada.Strings.Fixed;

Package Body LISP is

   FALSE_Text	: Constant String:= Boolean'Image( False );
   TRUE_Text	: Constant String:= Boolean'Image( True  );
   NULL_Text	: Constant String:= "NULL";

   Function Trim_Image( Input : In Float ) Return String is
      Use Ada.Strings, Ada.Strings.Fixed;
   Begin
      Return Result: String:=
        Trim( Side => Left, Source => Float'Image( Input ) );
   End Trim_Image;


   ------------------
   --  WRITE_ATOM  --
   ------------------
   Procedure Write_Atom(	Stream	: Not Null Access Stream_Root'Class;
				Item	: In Atom ) is
      Text : Access String;
   begin
      Case Item.Element is
	 When Empty_Type	=>
		Text:= New String'( NULL_Text );
         When Boolean_Type	=>
		Text:= New String'( Boolean'Image(Item.Boolean_Value) );
         When Integer_Type	=>
		Text:= New String'( Integer'Image(Item.Integer_Value) );
         When Real_Type		=>
		Text:= New String'( Float'Image( Item.Real_Value ) );
         When String_Type	=>
            If Not Item.Is_Name then
		Text:= New String'( '"' & Item.String_Value.All & '"' );
            else
		Text:= New String'( Item.String_Value.All );
            end if;
      End Case;
      String'Write(	Stream, Text.All	);
   end Write_Atom;


   --------------
   --  Append  --
   --------------
   Procedure Append( Head : In Out Elementry_List; Tail : In
Elementry_List ) is
   begin
      If Head.Terminal then
         Declare
            Result : Elementry_List:= Elementry_List'( Terminal =>
False,
		Head => Head.Head, Tail => New Elementry_List'(Tail) );
            For Result'Address Use Head'Address;
         Begin		-- Here the initialization of Result changes the value
            Null;	-- of Head because they are overlaid; further, we
are
         End;		-- guarenteed that the sizes are both the same because
      else		-- Elementry_List is a simple varient record and cannot
         Declare	-- be extended because it is not a tagged-type.
            This : Access Elementry_List:= Head.Tail;
         Begin
            While Not This.Terminal loop	-- If Head is not terminal
then
               This:= This.Tail;		-- we must traverse the list
            end loop;				-- until the end to append Tail.
            Append( This.All, Tail );
         End;
      end if;
   end Append;

   Function  Convert( List : Elementry_List ) Return Atom_Array is

      Function Get_Element( Item : Elementry_List ) Return Atom_Array
is
      begin
         if Item.Terminal then
            Return Result : Atom_Array:= ( 1 => Item.Head );
         else
            Return Result : Atom_Array:= Atom_Array'( 1 => Item.Head )
		& Get_Element( Item.Tail.All );
         end if;
      end Get_Element;

   begin
      Return Get_Element( List );
   end Convert;

   Function Create( Input : Atom ) Return Elementry_List is
   begin
      Return Result: Elementry_List:= ( Terminal => True, Head =>
Input );
   end;


   Function  Convert( List : Atom_Array ) Return Elementry_List is
   begin
      if List'Length = 0 then
         Raise Program_Error;
      end if;

      Declare
	Working : Elementry_List:= Create( Input => List(List'First) );
      Begin
	For Index in Positive'Succ(List'First)..List'Last loop
            Append( Head => Working, Tail => Create( List(Index) ) );
	end loop;
       Return Working;
      End;
   end Convert;


   ---------------------------------------------------
   --  Elementry_List's  'Read & 'Write Attributes  --
   ---------------------------------------------------

   Procedure Write_EList( Stream	: Not Null Access Stream_Root'Class;
			  Item		: In Elementry_List
                       ) is

   begin
      Character'Write( Stream, '(' );		-- When saving to a Stream
every
      Declare					-- elementry-list begins with an
         This : Elementry_List:= Item;		-- opening parenthisis,
followed
      Begin					-- by list of Atoms (whitespace
         List:					-- separated), terminated by a
         loop					-- closing parenthisis.
            Atom'Write( Stream, This.Head );
            Exit List When This.Terminal;
            This:= This.Tail.All;
            Character'Write( Stream, ',' );
         end loop List;
         Character'Write( Stream, ')' );
      End;
   end Write_EList;

   Procedure Read_EList( Stream	: Not Null Access Stream_Root'Class;
			 Item	: Out Elementry_List
                        ) is
      Function Parse_Atom( S : String ) Return Atom is
         Function Get_Type_Indicator(Input : String) Return
Element_Type is
            SubType Digit is Character Range '0'..'9';
         begin
            Case Input(Input'First) is		-- A floating-point numeric is
               When Digit =>			-- distinguished from an integer
                  For Index in Input'Range loop	-- by the decimal
point or the
                     Case Input(Index) is	-- exponent notation.
                        When 'e' | 'E' | '.' => Return Real_Type;
                        When Others => null;
                     End case;
                  end loop;
                  Return Integer_Type;
               When Others =>
                  if Input = NULL_Text then	-- NULL, TRUE, & FALSE are
texts
                     Return Empty_Type;		-- which are not String_Type.
                  elsif Input = TRUE_Text or Input = FALSE_Text then
                     Return Boolean_Type;
                  else				-- Everything else, however, is
                     Return String_Type;	-- either a String_Type or a
                  end if;			-- name. Strings start w/ '"'.
            end case;
         end Get_Type_Indicator;

       Use Ada.Strings, Ada.Strings.Fixed;			-- Parse_Atom
         Input : String:= Ada.Strings.Fixed.Trim( S, Both );	-- starts
here.
      begin
         Return Result : Atom(Get_Type_Indicator(Input)) do
            Case Result.Element is
            When Empty_Type	=> Null;
            When String_Type	=>
               Result.Is_Name:= Input(Input'First) = '"';
               if Not Result.Is_Name then
               Result.String_Value:= New String'(
		  Input(Positive'Succ(Input'First)..Positive'Pred(Input'Last))
						);
               else
                  Result.String_Value:= New String'(Input);
               end if;
            When Integer_Type	=> Result.Integer_Value:=
Integer'Value(Input);
            When Real_Type	=> Result.Real_Value:= Float'Value(Input);
            When Boolean_Type	=> Result.Boolean_Value:= Input =
TRUE_Text;
            End case;
         End Return;
      end Parse_Atom;

         WhiteSpace : Constant Array(Character) Of Boolean:=
           ( ASCII.VT | ASCII.HT | ASCII.LF | ASCII.CR | ' ' => True,
             Others => False );

	Type Index_Vector is Array (Positive Range <>) of Positive;
	Seperators	: Not Null Access Index_Vector:=
					New Index_Vector'( 2..1 => 1 );
	Working		: Not Null Access String:= New String'( "" );
	C		: Character;
	Result		: Elementry_List;
	In_String	: Boolean:= False;
	Is_Terminated	: Boolean:= False;

   begin
      Loop
	Character'Read( Stream, C );
	Case C is
	 When '"'	=>	In_String:= Not In_String;
				Is_Terminated:= False;
         When ')'	=>	Exit When Not In_String;
         When Others	=>
	    If WhiteSpace(C) then
		if Is_Terminated then
			GoTo Bypass;
		else
			Is_Terminated:= True;
		end if;
	    else
		Is_Terminated:= False;
	    end if;
	End Case;
	Working:= New String'( Working.All & C );	-- We update "working."
	if WhiteSpace(C) then			-- and delimit with whitespace.
	   Seperators:= New Index_Vector'( Seperators.All & Working'Last );
	end if;
	<<Bypass>>
	Null;
      End Loop;

	-- We simulate a terminating space by appending one more
	-- than the last index to Seperators.
	Seperators:= New Index_Vector'(Seperators.All & (Working'Last+1));

      Declare
	-- We use one more than Working'First to ignore the '(' that starts
	-- this list, just like we terminated the string just before
	-- copying the trailing ')' into Working.
	Start : Positive:= Working'First+1;
	Stop  : Positive;
      Begin
	for Index in Seperators'Range loop	-- Here is where we create an
	    Stop:= Seperators( Index )-1;	-- atom from every interval we
	    Append(Result,			-- recorded in "seperators".
		(Terminal => True, Head => Parse_Atom(Working(Start..Stop)))
		  );
	    Start:= Seperators( Index )+1;
	end loop;
      End;
					-- And we return everything we
      Item:= Result.Tail.All;		-- previously appended to result.
   end Read_EList;

   ---------------
   --  As_List  --
   ---------------
   Function As_List( Input : in List_Element ) Return List is
   Begin
      Return Result : List do
         Case Input.Element is
            When Atom_Element	=> Result.Data.Append( New_Item =>
Input );
            When Recursive_List	=> Result:= Input.RList_Data.All;
            When EList_Type	=>
               Declare
		Data : Elementry_List:= Input.EList_Data;
               Begin
		loop
		   Result.Data.Append( New_Item => (Atom_Element, Data.Head) );
		   Exit When Data.Terminal;
		   Data:= Data.Tail.All;
		end loop;
               End;
         End Case;
      End Return;
   End As_List;



   Procedure Write_List( Stream	: Not Null Access Stream_Root'Class;
			  Item	: In List
                       ) is
      SubType ELIST is Elementry_List;
   begin
      Character'Write( Stream, '(' );
      Declare
         Procedure Process_Data( Position : Elements.Cursor ) is
            Item : List_Element Renames Elements.Element( Position );
         begin
            Case Item.Element is
            When Atom_Element	=> Atom'Write( Stream, Item.Atom_Data );
            When EList_Type	=> ELIST'Write(Stream, Item.EList_Data);
            When Recursive_List	=> List'Write( Stream,
Item.RList_Data.All );
            end case;
         end Process_Data;
      Begin
         Item.Data.Iterate( Process_Data'Access );
      End;
      Character'Write( Stream, ')' );
   end Write_List;

   Procedure Read_List( Stream	: Not Null Access Stream_Root'Class;
			 Item	: Out List
                      ) is
   begin
      null;
   end Read_List;


End LISP;



^ permalink raw reply	[relevance 1%]

* Re: Ann: Little tutorial about streams
  @ 2011-02-28 20:32  2% ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-02-28 20:32 UTC (permalink / raw)


mockturtle writes:
> Dear.all,

> remembering my initial difficulties with streams (I self-taught Ada,
> using few tutorials and lots of experiments before landing to the RM),
> I decided to write a page (my first one, so be patient :-) of the
> Wikibook with a little stream tutorial
>
> http://en.wikibooks.org/w/index.php?title=Ada_Programming/Input_Output/Stream_Tutorial
>
> As said in the page, the goal is to give to the reader an intuitive
> idea about how streams work so, in order to not hide the forest with
> too many leaves, some of the finest details have been omitted.  A
> subpage of the above page has a fairly complex example that is not
> complete yet, but I plan to complete it soon.
>
> The page is not linked yet with the book body.  I was thinking to add
> a link to it in the "Input Output" page as soon as the subpage with
> the example is in a good state.
>
> Any feedback [especially positive one :-) :-) :-) :-)] is appreciated.

Your page is great.  How's that for positive criticism :)

I've made a couple edits which you are, of course, free to revert.  I
(think I) have generally improved the style of the prose but not changed
the basic structure of the tutorial.

Now I have specific suggestions for further improvement:

* Between the sections "Abstract streams" and "Serialization functions",
  it would be nice to have a section on "Predefined concrete streams"
  discussing, in particular Ada.Text_IO.Text_Stream, so that beginners
  can start writing to the console using streams.

* In the section about Ada.Text_IO.Text_Streams, explain that this is
  much faster than Ada.Text_IO and why (hint: ARM A.10.4, A.12.2(7))

* Your first example of a serialization function, procedure
  Example.Print, seems too complicated.  But that may be on purpose, so
  I have not changed it.  Here is a simpler implementation:

  package body Example is
     procedure Print (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                      Item   : in  Int) 
     is
        -- Convert Item to String (with no trailing space)
        Value  : String := Trim(Int'Image(Item), Left);
        
        -- Convert Value'Length to String (with no trailing space)
        Len    : String := Trim(Integer'Image(Value'Length), Left);
     begin 
        String'Write (Stream, Len & 'i' & Value);
     end Print;
  end Example;

Thank you for taking the initiative writing this nice tutorial.  I think
it really helps lower the bar for novices.

-- 
Ludovic Brenta.



^ permalink raw reply	[relevance 2%]

* Re: How do I write directly to a memory address?
  @ 2011-02-08 20:52  1%                           ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2011-02-08 20:52 UTC (permalink / raw)


On Feb 8, 1:27 pm, Hyman Rosen <hyro...@mail.com> wrote:
> On 2/8/2011 3:11 PM, Shark8 wrote:> No, that's not it. What is 'it' is that the C programmers  treated
>
>  > Ada as if it were C and the result was, as expected, bad Ada.
>
> It is my understanding that Ada proponents believe that
> using Ada results in better programs than using C.

First off, I purposely did not say (or even imply) that using
Ada "automagically" makes one a better programmer, or
that it makes the programs themselves better.

Let me put it a different way: pneumatic tires are a pretty
good development; they can absorb shock to some
degree as well as allowing a measure of protection
from damage to the wheels {rim/hub} and in so doing
help minimize the cost of when you eventually run into
some road hazard.... but there is NOTHING preventing
you from going out and letting all the air out of your tires
and experiencing the same wheel-cost as the old
covered-wagons, no?

IOW, Ada could have all the most wonderful features and
helps possible but if one never uses them then they do
no good whatsoever to that person.

> But when presented with a program written in Ada that is not
> demonstrably better, that program is removed from the set
> of Ada programs under consideration by virtue of having
> been written by "C people". That is precisely the "no true
> Scotsman" fallacy.

Again, I was not dismissing any program in itself, or even
class of programs, and therefore the "No True Scotsman"
fallacy CANNOT apply to what I presented.

What is interesting, however, is some of the replies to
shown examples of Ada I've written to those well-versed
in C/C++ but unfamiliar with Ada. If you're interested I
have a LISP interpreter* I would otherwise post to show
some of the the "wows" I've gotten; and I'm not doing
anything too spectacular things like having my
overwriting the S_Expression type's 'read and 'write
attributes so I could do something like:

   Ada.Text_IO.Put_Line( "Begin Run:" );
   Open( Input, In_File, Name => "Temp.Txt" );
   Declare
      In_Stream	: Access Ada.Streams.Root_Stream_Type'Class:=
	Ada.Text_IO.Text_Streams.Stream( Input );
      Use LISP;
   Begin
      S_Expression'Read( In_Stream, S );
      -- Here's where EVAL would go.
      S_Expression'Write( Out_Stream, S );
   End;
   Ada.Text_IO.Put_Line( "" );
   Ada.Text_IO.Put_Line( "End Run." );
   Close( Input );

*Not working, I still have to implement the atomic-level
functions, the special-forms cases {like 'if'}, and the
Eval function.

> > The reverse is less true, I think. If you give an Ada  Programmer
>
>  > a "must do" in C, AND he applied the theory/ideology of Ada
>  > {specifically contract enforcement & rejection/culling of bad
>  > values}, then the result would NOT be "bad C"... would it?
>
> In other words, training in a certain style of programming leads
> to better programs. Sure, that's plausible.

More than plausible. I've had professors able to spot that I'd been
'trained' in Pascal from reading my C-code. "Trained" here actually
being self-taught with little more than the compiler and the user's
manual for the compiler.



^ permalink raw reply	[relevance 1%]

* Re: problems with interfacing c
  @ 2011-01-28  9:41  1%     ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-01-28  9:41 UTC (permalink / raw)


Staszek Goldstein wrote on comp.lang.ada:
> I am sending a solution to a problem to a site managing programming contests, and
> the stdin is in fact redirected to some text file with data. I do not know how
> big the data file will be, I know only the upper limit. Quick reading of the data is the
> key to success, and the two lines of C work very well for the purpose. I have not
> tried your solution, is it not going to cause constraint_error when it meets the end of the
> file?

If you really read from Standard_Input, there is no upper limit to the
size of the file, so you should not depend on one. i.e. your program
should work if you say:

$ yes | my_program

The proper way to read a potentially infinite amount of data from
Standard_Input is to read one character at a time, buffer the input
for processing, and discard the buffer from time to time so your
program runs in constant memory. The points in time where you discard
the buffer depend on the algorithm.

Like Dmitry, I strongly suggest you use Ada.Streams, not Ada.Text_IO,
because the latter is much slower (it does a lot of unnecessary
bookkeeping behind the scenes).

Here is a small example where I process the input buffer whenever it
is full and then discard it. I also do that when I reach the end of
the input stream. Note that I have not compiled this example, so it
may contain (intentional :)) bugs.

with Ada.IO_Exceptions;
with Ada.Text_IO;
with Ada.Strings.Bounded;
procedure My_Program is
   Current_Input : constant Ada.Text_IO.Text_Streams.Stream_Access :=
     Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Current_Input);
   package Buffers is new Ada.Strings.Bounded.Generic_Bounded_Length
(Max => 100_000);

   procedure Process_And_Discard (Buffer : in out
Buffers.Bounded_String) is
   begin
      -- actual processing left as an exercise for the reader :)
      Buffers.Delete (Source => Buffer, From => 1, Through =>
Buffers.Max_Length);
   end Process_And_Discard;

   Buffer : Buffers.Bounded_String;
begin
   loop
      declare
          C : Character;
      begin
          Character'Read (Current_Input, C);
          if Buffers.Length (Buffer) = Buffers.Max_Length then --
buffer is full
             Process_And_Discard (Buffer);
          end if;
          Buffers.Append (Source => Buffer, New_Item => C);
      exception
          when Ada.IO_Exceptions.End_Error => -- end of stream reached
             Process_And_Discard (Buffer); -- process whatever we read
last
             exit;
      end;
   end loop;
end My_Program;

> The other question is - how to use the C bindings properly in such a case?

Don't.

--
Ludovic Brenta.



^ permalink raw reply	[relevance 1%]

* Re: An Example for Ada.Execution_Time
  2010-12-30 23:51  1%     ` BrianG
@ 2011-01-01  0:07  1%       ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2011-01-01  0:07 UTC (permalink / raw)


"BrianG" <briang000@gmail.com> wrote in message 
news:ifj5u9$rr5$1@news.eternal-september.org...
> Randy Brukardt wrote:
>> "BrianG" <briang000@gmail.com> wrote in message 
>> news:ifbi5c$rqt$1@news.eternal-september.org...
>> ...
>>>    >Neither Execution_Time or Execution_Time.Timers provides any value
>>>    >that can be used directly.
>>
>> This seems like a totally silly question. Giving this some sort of 
>> religious importance is beyond silly...
>>
>>                                    Randy.
>
>
> Apparently, asking how a package, defined in the standard, was intended to 
> be used is now a silly question, and asking for an answer to the question 
> I originally asked (which was to clarify a previous response, not to 
> provide an example of use) is a religious debate.  I need to revise my 
> definitions.

But you didn't ask how a package defined in the standard was intended to be 
used. You asked why you have to use another package (Ada.Real_Time) in order 
for it to be useful. And you've repeated that over and over and over like it 
was meaningful in some way. But that is pretty much the definition of a 
silly question. It's just the way the package was defined, and it doesn't 
matter beyond having to add one additional "with" clause.

And that's pretty much irrelevant. In real Ada programs, there are many with 
clauses in the average compilation unit. In Janus/Ada, the number of withs 
averages 20 or so, and Claw programs are much higher than that. One could 
reduce those numbers by putting everything into a few massive packages, but 
those would be unweldy, poorly encapuslated, and close to unmaintainable.

The need to add one extra with to use a real-time package just falls into 
the noise. Probably it would have been better to offer the option of 
retrieving a value in terms of Duration, but it is just not a significant 
difference.

The answer to the "how do you use" question is simple and has been provided 
many times: use "-" to get a Time_Span, operate on that, and why that would 
be a problem to you or anyone else is beyond my comprehension.

> I won't claim to be an expert on the RM, but I don't recall any other 
> package (I did look at the ones you mention) that define a private type 
> but don't provide operations that make that type useful (for some 
> definition of 'use').  Ada.Directories doesn't require Ada.IO_Exceptions 
> to use Directory_Entry_Type or Search_Type; Ada.Streams.Stream_IO doesn't 
> require Ada.Streams (or Ada.Text_IO) to Create/Open/Read/etc. a File_Type. 
> The only thing provided from a CPU_Time is a count in seconds, or another 
> private type.

Here I completely disagree. If you plan to do anything *practical* with the 
Ada.Directories types, you'll have to use another package (at least 
Ada.Text_IO) to do something with the results. (Indeed, that is true of 
*all* Ada packages -- you have to do I/O somewhere or the results are 
irrelevant.  And you are wrong about Stream_IO.Read; you have to use a 
Stream_Element_Array in order to do that, and that is in Ada.Streams, not in 
Stream_IO.

In any case, I'm done wasting my time answering this question. It's obvious 
that you have lost you mind vis-a-vis this question, and there is no reason 
to waste any more time if/until you get it back. Do not feed the troll (even 
if the troll is someone that is otherwise reasonable).

                                                    Randy.





^ permalink raw reply	[relevance 1%]

* Re: An Example for Ada.Execution_Time
  2010-12-29  3:10  1%   ` Randy Brukardt
@ 2010-12-30 23:51  1%     ` BrianG
  2011-01-01  0:07  1%       ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: BrianG @ 2010-12-30 23:51 UTC (permalink / raw)


Randy Brukardt wrote:
> "BrianG" <briang000@gmail.com> wrote in message 
> news:ifbi5c$rqt$1@news.eternal-september.org...
> ...
>>    >Neither Execution_Time or Execution_Time.Timers provides any value
>>    >that can be used directly.
> 
> This seems like a totally silly question. 
> 
> Giving this some sort of religious importance is beyond 
> silly...
> 
>                                    Randy.


Apparently, asking how a package, defined in the standard, was intended 
to be used is now a silly question, and asking for an answer to the 
question I originally asked (which was to clarify a previous response, 
not to provide an example of use) is a religious debate.  I need to 
revise my definitions.

I won't claim to be an expert on the RM, but I don't recall any other 
package (I did look at the ones you mention) that define a private type 
but don't provide operations that make that type useful (for some 
definition of 'use').  Ada.Directories doesn't require Ada.IO_Exceptions 
to use Directory_Entry_Type or Search_Type; Ada.Streams.Stream_IO 
doesn't require Ada.Streams (or Ada.Text_IO) to Create/Open/Read/etc. a 
File_Type.  The only thing provided from a CPU_Time is a count in 
seconds, or another private type.

Since D.16 defines CPU_Time as if it were a numeric value, is it too 
much to ask why a conversion to some form of numeric value wasn't 
provided?  Perhaps either a "-" or To_Duration  (and before anyone 
mentions duplicating the existing function, look at all of the 
Open/Close/Create/etc. for all the *_IO File_Types)?  I wasn't asking 
for anything to be changed, merely "why" - because I originally thought 
there might be some use that I hadn't foreseen.  Apparently not.

(Give the RM definition, making it a child of Real_Time might make it 
seem more logical, I guess, but since CPU_Time is not really a time, and 
is not related to "real time" that doesn't seem to make any sense.  I 
would think that would be all the more reason not to relate it to 
Ada.Real_Time.)

--BrianG

-- don't ask me
-- I'm just improvising
--   my illusion of careless flight
-- can't you see
--   my temperature's rising
-- I radiate more heat than light



^ permalink raw reply	[relevance 1%]

* Re: An Example for Ada.Execution_Time
  @ 2010-12-29  3:10  1%   ` Randy Brukardt
  2010-12-30 23:51  1%     ` BrianG
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2010-12-29  3:10 UTC (permalink / raw)


"BrianG" <briang000@gmail.com> wrote in message 
news:ifbi5c$rqt$1@news.eternal-september.org...
...
> I asked for:
>    >> An algorithm comparison program might look like:
>    >>
>    >> with Ada.Execution_Time ;
>    >> with Ada.Execution_Time.Timers ;
>    >Given the below program, please add some of the missing details to
>    >show how this can be useful without also "with Ada.Real_Time".
>    >Neither Execution_Time or Execution_Time.Timers provides any value
>    >that can be used directly.

This seems like a totally silly question. There are a lot of well-designed 
packages in Ada that don't do anything useful without at least one or more 
other packages. Indeed, if you consider "Standard" to be a separate package 
(and it is), there are hardly any packages that *don't* require some other 
package to be useful.

More to the point, you probably need Ada.IO_Exceptions to use 
Ada.Directories effectively (use of any package without error handling is 
toy use); Ada.Streams.Stream_IO require use of Ada.Streams (a separate 
package, which you will need separate use clauses for even if you get it 
imported automatically); Ada.Strings.Maps aren't useful for anything unless 
you combine them with one of the string handling packages, and so on.

Perhaps you would have been happier if Ada.Execution_Time had been a child 
of Ada.Real_Time (exactly as in the string case), but this wouldn't change 
anything.

The odd thing is that Duration is defined in Standard, rather than some more 
appropriate package. Giving this some sort of religious importance is beyond 
silly...

                                   Randy.





^ permalink raw reply	[relevance 1%]

* Re: Newbie-ish question about generics and Ada.Streams
  2010-12-27 18:59  1% ` Robert A Duff
@ 2010-12-27 23:26  1%   ` Brian Drummond
  0 siblings, 0 replies; 200+ results
From: Brian Drummond @ 2010-12-27 23:26 UTC (permalink / raw)


On Mon, 27 Dec 2010 13:59:27 -0500, Robert A Duff <bobduff@shell01.TheWorld.com>
wrote:

>Brian Drummond <brian_drummond@btconnect.com> writes:
>
>> Comments welcome, but the specific points I am unhappy with are:
>> ...[3 things]
>
>It's reasonable to be unhappy about these things.
>There are no better workarounds than the ones
>you have already discovered.

Thanks.

>But why don't you use Shape'Image, possibly with
>a call to To_Lower?

Because that would restrict the output to file, which I wanted to control. 
(It could be an actual toy block, if the target was Lego Mindstorms!)

It would certainly work for this example though - ditto the string pointers.
This was only intended as a simple example to illustrate the issue.

The real case involves binary data, not text; and under some 
circumstances I must perform manipulations such as endian swaps. (Otherwise I
could simply use the appropriate representation for the enumeration, and allow
the default Integer'Write to take care of it.)

Thanks,

- Brian



^ permalink raw reply	[relevance 1%]

* Re: Newbie-ish question about generics and Ada.Streams
  2010-12-27 17:23  3% Newbie-ish question about generics and Ada.Streams Brian Drummond
@ 2010-12-27 18:59  1% ` Robert A Duff
  2010-12-27 23:26  1%   ` Brian Drummond
  0 siblings, 1 reply; 200+ results
From: Robert A Duff @ 2010-12-27 18:59 UTC (permalink / raw)


Brian Drummond <brian_drummond@btconnect.com> writes:

> Comments welcome, but the specific points I am unhappy with are:
> ...[3 things]

It's reasonable to be unhappy about these things.
There are no better workarounds than the ones
you have already discovered.

But why don't you use Shape'Image, possibly with
a call to To_Lower?

Or, in your tables mapping enums to strings, use
pointers, so you can make the strings exactly
the right length, instead of blank padding them?
Most likely, your enums will be in a library package
spec, so there's no need to Unchecked_Deallocate
the strings.

- Bob



^ permalink raw reply	[relevance 1%]

* Newbie-ish question about generics and Ada.Streams
@ 2010-12-27 17:23  3% Brian Drummond
  2010-12-27 18:59  1% ` Robert A Duff
  0 siblings, 1 reply; 200+ results
From: Brian Drummond @ 2010-12-27 17:23 UTC (permalink / raw)


Season's greetings!

In between rounds of turkey, I have been trying to learn a bit more about generics, though it still
feels as if I am pushing on a rope.

In particular, I have been trying to use generic procedures for stream access for a large set of
similar data types (enumerations) where I want a specific representation in the output file. This
means attaching the Read and Write procedures - instantiated generics - to the types using
representation clauses.

Which (as I understand it) has to be done before the types are frozen....

I hope the example below is clear...

Comments welcome, but the specific points I am unhappy with are:

(1) The incomplete procedure declarations, with deferred implementation. 
I suspect there is no way around this, as long as I need to freeze the type 
before the procedure body.

(2) The second generic parameter - the named array type. It feels like I am missing 
something obvious here, and there ought to be a way to avoid adding this clutter.

(3) Instantiating the generic under a different name, and renaming to match the incomplete
declaration. Is this (a) necessary, (b) Gnat-specific, or (c) something stupid on my part?

Thanks,
- Brian


with Ada.Text_Io.Text_Streams;
with Ada.Streams;

procedure try_generics is

-- We have multiple enumerations...
type shape is (circle, square);
type colour is (red, green, blue);

-- and we want to control how they are written to a stream
procedure colour_write (Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			what : in colour);
procedure shape_write (Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			what : in shape);
for colour'write use colour_write;
for shape'write use shape_write;

-- In this example, we use an array of strings indexed by the enumerations.
-- shapes : constant array(shape) of string(1 .. 7) := ("circle ", "square ");
-- but... generics (below) seem picky about using named vs anonymous subtypes
subtype name is string(1 .. 7);
type shape_names is array(shape) of name;
type colour_names is array(colour) of name;
-- appears to freeze the types; write procedures or representation clauses after this are "too late"
shapes : constant shape_names := ("circle ", "square ");
colours : constant colour_names := ("red    ", "green  ", "blue   ");

-- Example body of a write procedure...
--procedure colour_write (Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			what : in colour) is
--begin
--   String'write(Stream, colours(what));
--end colour_write;

-- That would get repetitive, so let's use a generic...
   generic
      type Item_Type is (<>);
      type Item_Names(<>) is array(Item_Type) of name;
      -- Feels as if the Item_Names type declaration ought to be unnecessary...
      Names : Item_Names;
   procedure Enum_Write(Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			Item : in Item_Type);

   procedure Enum_Write(Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			Item : in Item_Type) is
   begin
      String'Write(Stream, Names(Item));
   end Enum_Write;

-- And instantiate it. First attempt...
--procedure shape_write is new Enum_Write(Item_Type => shape, 
			Item_Names => shape_names, Names => shapes);
--try_generics.adb:12:01: missing body for "shape_write"
--try_generics.adb:43:11: instantiation cannot provide body for "shape_write"

-- So instantiate it under a different name, and rename it...
procedure shape_writer is new Enum_Write(Item_Type => shape, 
			Item_Names => shape_names, Names => shapes);
procedure shape_write(Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			what : in shape) renames shape_writer;
procedure colour_writer is new Enum_Write(Item_Type => colour, 
			Item_Names => colour_names, Names =>colours);
procedure colour_write (Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
			what : in colour) renames colour_writer;
-- That duplication is ugly ... can this be simplified?

-- Now we can use the enumerations in a toy block
type toy_block is record
   my_colour : colour;
   my_shape : shape;
end record;

-- and output the block to a stream
my_block : constant toy_block := (my_colour => red, my_shape => square);
Stdout : Ada.Text_Io.Text_Streams.Stream_Access :=
Ada.Text_Io.Text_Streams.Stream(Ada.Text_Io.Current_Output);
begin
   toy_block'write(Stdout, my_block); 
end try_generics;





^ permalink raw reply	[relevance 3%]

Results 1-200 of ~1000   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2010-12-27 17:23  3% Newbie-ish question about generics and Ada.Streams Brian Drummond
2010-12-27 18:59  1% ` Robert A Duff
2010-12-27 23:26  1%   ` Brian Drummond
2010-12-27 18:26     An Example for Ada.Execution_Time anon
2010-12-28  2:31     ` BrianG
2010-12-29  3:10  1%   ` Randy Brukardt
2010-12-30 23:51  1%     ` BrianG
2011-01-01  0:07  1%       ` Randy Brukardt
2011-01-20 20:21     problems with interfacing c Stoik
2011-01-20 20:56     ` Dmitry A. Kazakov
2011-01-28  0:39       ` Stoik
2011-01-28  9:41  1%     ` Ludovic Brenta
2011-02-03  5:52     How do I write directly to a memory address? Syntax Issues
2011-02-07  9:00     ` Ludovic Brenta
2011-02-07 13:43       ` Georg Bauhaus
2011-02-07 13:56         ` Ludovic Brenta
2011-02-07 14:58           ` Georg Bauhaus
2011-02-07 16:54             ` Ludovic Brenta
2011-02-07 17:55               ` Georg Bauhaus
2011-02-08  8:04                 ` Ludovic Brenta
2011-02-08 10:10                   ` Georg Bauhaus
2011-02-08 10:14                     ` Ludovic Brenta
2011-02-08 18:30                       ` Jeffrey Carter
2011-02-08 18:47                         ` Hyman Rosen
2011-02-08 20:11                           ` Shark8
2011-02-08 20:27                             ` Hyman Rosen
2011-02-08 20:52  1%                           ` Shark8
2011-02-28 17:00     Ann: Little tutorial about streams mockturtle
2011-02-28 20:32  2% ` Ludovic Brenta
2011-03-04 20:58     mockturtle
2011-03-05  1:08  1% ` Shark8
2011-03-05  1:35  1% ` Randy Brukardt
2011-03-22 23:34     Text parsing package Syntax Issues
2011-03-23  8:32     ` Dmitry A. Kazakov
2011-03-28  0:15  1%   ` Yannick Duchêne (Hibou57)
2011-03-28  8:15  0%     ` Dmitry A. Kazakov
2011-03-28 10:18  0%       ` Yannick Duchêne (Hibou57)
2011-03-28 12:08  0%         ` Dmitry A. Kazakov
2011-04-06 10:11     Parser interface design Natasha Kerensikova
2011-04-08 11:16  1% ` Brian Drummond
2011-04-11 10:26     GNAT.Serial_Communications tonyg
2011-04-11 11:11     ` GNAT.Serial_Communications Brian Drummond
2011-04-13  7:49       ` GNAT.Serial_Communications tonyg
2011-04-13 14:12         ` GNAT.Serial_Communications Alex Mentis
2011-04-13 21:12           ` GNAT.Serial_Communications tonyg
2011-04-14 17:52             ` GNAT.Serial_Communications Chris Moore
2011-04-15 13:58               ` GNAT.Serial_Communications tonyg
2011-04-15 16:32  2%             ` GNAT.Serial_Communications tonyg
2011-04-15 18:01  1%               ` GNAT.Serial_Communications Jeffrey Carter
2011-04-16 10:21  0%                 ` GNAT.Serial_Communications tonyg
2011-05-24  1:22     Why no socket package in the standard ? Yannick Duchêne (Hibou57)
2011-05-24  6:24     ` georg bauhaus
2011-05-24 19:17       ` Yannick Duchêne (Hibou57)
2011-05-24 22:39         ` Georg Bauhaus
2011-05-24 22:54  2%       ` Yannick Duchêne (Hibou57)
2011-05-24  1:39     Yannick Duchêne (Hibou57)
2011-05-24  6:11     ` tmoran
2011-05-25 15:12 14%   ` Tero Koskinen
2011-06-05 16:20     Reading the while standard input into a String Natasha Kerensikova
2011-06-06  8:33     ` Ludovic Brenta
2011-06-06 10:08       ` Natasha Kerensikova
2011-06-06 10:27  2%     ` Ludovic Brenta
2011-06-06 10:31  0%       ` Ludovic Brenta
2011-06-06 12:07  0%         ` Natasha Kerensikova
2011-06-07 14:18     What is the best method for transmitting objects/tagged records? Shark8
2011-06-07 18:06     ` tmoran
2011-06-08 23:16  1%   ` Shark8
2011-06-09  0:49  0%     ` Randy Brukardt
2011-06-09  1:12  1%       ` Shark8
2011-08-29 15:46     Address and bit mask milouz
2011-08-29 19:41     ` Ludovic Brenta
2011-08-29 19:54       ` Adam Beneschan
2011-08-30  9:14         ` milouz
2011-08-30 15:14           ` Adam Beneschan
2011-08-31  7:45             ` milouz
2011-08-31  8:35  2%           ` Ludovic Brenta
2011-09-14  3:13     Stream_Element_Array Alexander Korolev
2011-09-14  5:29     ` Stream_Element_Array Per Sandberg
2011-09-14  8:34  1%   ` Stream_Element_Array Alexander Korolev
2011-09-14  8:31  1% ` Stream_Element_Array Simon Wright
2011-09-14  9:09  0%   ` Stream_Element_Array Alexander Korolev
2011-09-14  9:40  0%     ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 10:53           ` Stream_Element_Array Simon Wright
2011-09-14 12:48             ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 14:48               ` Stream_Element_Array Alexander Korolev
2011-09-14 15:08                 ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 17:16                   ` Stream_Element_Array Alexander Korolev
2011-09-14 20:13                     ` Stream_Element_Array Dmitry A. Kazakov
2011-09-14 21:29                       ` Stream_Element_Array Alexander Korolev
2011-09-15  8:20                         ` Stream_Element_Array Dmitry A. Kazakov
2011-09-15 18:58                           ` Stream_Element_Array Alexander Korolev
2011-09-15 20:48  1%                         ` Stream_Element_Array Dmitry A. Kazakov
2011-09-16  0:20  0%                           ` Stream_Element_Array Alexander Korolev
2011-12-12  8:57     Does Ada support endiannes? Gerd
2011-12-12 11:27     ` Dmitry A. Kazakov
2011-12-12 12:44       ` Gerd
2011-12-13 14:19         ` Gautier write-only
2011-12-14 16:16           ` Gerd
2011-12-14 20:16             ` Gautier write-only
2011-12-15 11:27               ` Gerd
2011-12-15 13:01  1%             ` Simon Wright
2011-12-15 18:13     Writing Data to a file awdorrin
2011-12-15 18:32  2% ` Ludovic Brenta
2012-01-06 13:30  1% gnat serial communication Rolf
2012-03-25 14:28     xor Michael Moeller
2012-03-25 14:01     ` xor Niklas Holsti
2012-03-25 15:16       ` xor Michael Moeller
2012-03-25 19:26  1%     ` xor Niklas Holsti
2012-03-27 20:09  0%       ` xor Michael Moeller
2012-03-27 19:44             ` xor Dmitry A. Kazakov
2012-03-27 21:16               ` xor Michael Moeller
2012-03-27 22:03                 ` xor Georg Bauhaus
2012-03-27 23:50                   ` xor Michael Moeller
     [not found]                     ` <bbedne9wdofZyu_SnZ2dnUVZ_hydnZ2d@earthlink.com>
2012-03-28 12:18                       ` xor Michael Moeller
2012-03-28 12:48                         ` xor Georg Bauhaus
2012-03-28 15:23                           ` xor Michael Moeller
2012-03-28 15:58                             ` xor Niklas Holsti
2012-03-28 23:25                               ` xor Randy Brukardt
2012-03-29  5:17                                 ` xor Niklas Holsti
2012-03-29 23:41                                   ` xor Randy Brukardt
2012-03-30 21:53  1%                                 ` xor Niklas Holsti
2012-03-28 14:07                         ` xor Dmitry A. Kazakov
2012-03-28 16:16                           ` xor Michael Moeller
2012-03-28 16:08                             ` xor Dmitry A. Kazakov
2012-03-28 17:36                               ` xor Michael Moeller
     [not found]                                 ` <tdadna1MV6uj5O7SnZ2dnUVZ_jidnZ2d@earthlink.com>
2012-03-29  7:43  1%                               ` xor Dmitry A. Kazakov
2012-03-27 19:50             ` xor Randy Brukardt
2012-03-27 21:44               ` xor Michael Moeller
2012-03-27 22:01  1%             ` xor Georg Bauhaus
2012-03-27 20:13  2%         ` xor Jeffrey Carter
2012-07-21 16:26  2% Using 'Base Simon Wright
2012-07-26 17:21  0% ` Simon Wright
2012-08-03 13:30     Should Inline be private in the private part of a package spec? Georg Bauhaus
2012-08-16 12:56     ` Dmitry A. Kazakov
2012-08-16 18:31       ` Georg Bauhaus
2012-08-16 19:58         ` Dmitry A. Kazakov
2012-08-17 18:41           ` Georg Bauhaus
2012-08-18  6:24             ` Dmitry A. Kazakov
2012-08-20 13:51               ` Georg Bauhaus
2012-08-20 14:15                 ` Dmitry A. Kazakov
2012-08-20 16:22                   ` Georg Bauhaus
2012-08-20 19:28                     ` Dmitry A. Kazakov
2012-08-21 11:49                       ` Georg Bauhaus
2012-08-21 13:12                         ` Dmitry A. Kazakov
2012-08-21 14:17                           ` Georg Bauhaus
2012-08-21 15:06                             ` Dmitry A. Kazakov
2012-08-21 16:18                               ` Georg Bauhaus
2012-08-21 19:18                                 ` Dmitry A. Kazakov
2012-08-21 21:35                                   ` Pascal Obry
2012-08-22  7:32                                     ` Dmitry A. Kazakov
2012-08-22 13:12                                       ` Georg Bauhaus
2012-08-22 14:30  1%                                     ` Dmitry A. Kazakov
2012-08-22 16:48  0%                                       ` Georg Bauhaus
2012-08-22 17:44  1%                                         ` Dmitry A. Kazakov
2012-08-22 21:18  0%                                           ` Georg Bauhaus
2012-08-23  7:23                                                 ` Dmitry A. Kazakov
2012-08-23  8:56                                                   ` Georg Bauhaus
2012-08-23 10:13                                                     ` Dmitry A. Kazakov
2012-08-23 11:39                                                       ` Georg Bauhaus
2012-08-24  4:48                                                         ` Randy Brukardt
2012-08-24  9:56  1%                                                       ` Georg Bauhaus
2012-09-21 18:16     Endianness and Record Specification awdorrin
2012-09-21 22:18  2% ` Simon Wright
2012-10-07 19:58     Ada Containers rwilco19
2012-10-07 22:00  1% ` Simon Wright
2013-02-15 22:22     [Ann] Ada Web Application 0.3.0 is available Stephane Carrez
2013-03-02  5:54  1% ` shyam.laximan
2013-03-28 17:34  1% Interresting, possibly buggy behavior in GNAT generics w/ expression function Shark8
2013-07-29 20:54  1% Private function w/ Tagged return-type Shark8
2013-07-29 21:20  0% ` Adam Beneschan
2013-09-04 11:10     Calling a File for Encryption from outside of the Main Ada-95 Holding Folder Austin Obyrne
2013-09-04 19:37     ` Austin Obyrne
2013-09-04 19:47       ` Eryndlia Mavourneen
2013-09-04 20:37         ` Austin Obyrne
2013-09-04 21:31           ` Austin Obyrne
2013-09-05  5:39             ` Simon Wright
2013-09-05  7:56               ` Austin Obyrne
2013-09-05 11:33  1%             ` Simon Wright
2013-09-05 15:46  0%               ` Austin Obyrne
2013-09-05 16:00  0%               ` Austin Obyrne
2013-09-14  1:39  1% How to use GNAT.Serial_Communications ? elbric0
2013-09-14  5:42  1% ` Simon Wright
2013-12-07 12:24     Will Ada-95 Programs Written in MS Windows Run in MacOS and Linux Without Some Tweaking Austin Obyrne
2013-12-07 13:16     ` Simon Wright
2013-12-07 14:01       ` Austin Obyrne
2013-12-07 17:18         ` Simon Wright
2013-12-07 18:26           ` Austin Obyrne
2013-12-08 17:17             ` Simon Wright
2013-12-10  6:37               ` Randy Brukardt
2013-12-11  0:34  1%             ` Simon Wright
2014-01-23 18:53  2% Binary and XML serialization of types hanslad
2014-01-23 19:15  1% ` adambeneschan
2014-02-09 19:59     Hello, and help with GNAT and Windows USB programming Gumpy
2014-02-09 21:00  2% ` björn lundin
2014-02-15 23:32  1% Pass a serial port as user data in a GTK callback handler? hreba
2014-02-16  7:45  1% ` Niklas Holsti
2014-02-17 16:13  0% ` adambeneschan
2014-04-06 16:22  1% Serial port configuration hreba
2014-04-06 18:57  0% ` Simon Wright
2014-04-07 11:44  0%   ` hreba
2014-05-16  7:37     Help with type definition hanslad
2014-06-27 22:05     ` hanslad
2014-06-28  7:26  1%   ` Shark8
2014-07-06 15:19     Ada's ranking of popularity at IEEE Spectrum Dan'l Miller
2014-07-06 19:41     ` sbelmont700
2014-07-08 17:25       ` Shark8
2014-07-08 23:03         ` sbelmont700
2014-07-27  2:01           ` David Thompson
2014-07-27 20:19  1%         ` sbelmont700
2014-07-27 20:08     A custom stream type Victor Porton
2014-07-27 20:39  2% ` Niklas Holsti
2014-07-28 13:41     On packages hierarchy Victor Porton
2014-07-28 16:03     ` Shark8
2014-07-28 16:35       ` Victor Porton
2014-07-28 23:24  1%     ` Shark8
2014-07-29 12:36  0%       ` Victor Porton
2014-07-29 18:44  1%         ` Shark8
2014-08-05 20:09     A bad counterintuitive behaviour of Ada about OO Victor Porton
2014-08-05 20:59     ` Dmitry A. Kazakov
2014-08-05 21:11       ` Victor Porton
2014-08-06  7:26         ` Dmitry A. Kazakov
2014-08-07  7:41           ` Maciej Sobczak
2014-08-07  8:50             ` Dmitry A. Kazakov
2014-08-08  7:54               ` Maciej Sobczak
2014-08-08  8:34  1%             ` Shark8
2014-11-10  9:30     What exactly is the licensing situation with Gnat? Hubert
2014-11-11 23:10     ` What exactly is the licensing situation with GNAT? David Botton
2014-11-11 23:25       ` Alan Jump
2014-11-12  0:50         ` David Botton
2014-11-12  1:15           ` Hubert
2014-11-12  1:24             ` David Botton
2014-11-12  8:12               ` Simon Wright
2014-11-12  8:35                 ` Hubert
2014-11-12  9:25                   ` Mark Carroll
2014-11-12  9:37                     ` Hubert
2014-11-12 10:31                       ` jm.tarrasa
2014-11-12 10:44                         ` Hubert
2014-11-12 22:53                           ` Randy Brukardt
2014-11-13  1:54                             ` Hubert
2014-11-13 21:57                               ` Randy Brukardt
2014-11-13 22:43                                 ` Jeffrey Carter
2014-11-14  1:36                                   ` Hubert
2014-11-14  8:51                                     ` Dmitry A. Kazakov
2014-11-14  9:02                                       ` Stan Mills
2014-11-14 10:14                                         ` Dmitry A. Kazakov
2014-11-14 10:38                                           ` Stan Mills
2014-11-14 13:35  1%                                         ` Dmitry A. Kazakov
2014-11-14 15:29                                               ` Things that OO programming lacks (was: What exactly is the licensing situation with GNAT?) G.B.
2014-11-14 16:32  1%                                             ` Things that OO programming lacks Dmitry A. Kazakov
2014-11-15 19:46  1%                                               ` Georg Bauhaus
2014-11-16 10:18  0%                                                 ` Dmitry A. Kazakov
2014-11-15 14:35  2% Ada.Containers warnings with gnat Björn Lundin
2014-11-15 18:01  1% ` Jeffrey Carter
2014-11-16 10:05  0%   ` Björn Lundin
2014-11-16 11:37  2%     ` Björn Lundin
2014-11-16 17:32  0%       ` Jeffrey Carter
2014-11-17  8:13  2%         ` Björn Lundin
2014-11-17 16:39  0%           ` Anh Vo
2015-02-02  5:50  1% Did I find mamory leak in Generic Image Decoder (GID) ? reinkor
2015-04-06 17:27  1% ANN: STM32F4 GNAT Run Time Systems 20150406 Simon Wright
2015-04-08  6:42     ANN: stream_tools 1.0.1 Per Sandberg
2015-04-08 21:41  2% ` Randy Brukardt
2015-04-26 20:18     Pipes-and-Filters dpt
2015-04-27  7:18  1% ` Pipes-and-Filters Dmitry A. Kazakov
2015-04-30 11:22     ANN: GCC 5.1.0 for Mac OS X Simon Wright
2015-04-30 12:23  1% ` Simon Wright
2015-08-24 14:16     Creating an empty file with Ada.Text_IO Maciej Sobczak
2015-08-24 16:15     ` Dmitry A. Kazakov
2015-08-25  8:20  2%   ` Maciej Sobczak
2015-08-25 15:26  1%     ` Maciej Sobczak
2015-08-25 16:18  1%       ` J-P. Rosen
2015-08-25 16:45  2%       ` G.B.
2015-11-22 21:40  2% GNAT.Serial_Communication and Streams rrr.eee.27
2015-11-22 21:52  1% ` Simon Wright
2015-11-22 21:54  1% ` Jeffrey R. Carter
2015-11-24  1:29  0%   ` Randy Brukardt
2015-11-24  8:28  0%   ` Dmitry A. Kazakov
2016-01-20  1:39     Out_File , excess line comicfanzine
2016-01-22 20:01  1% ` comicfanzine
2016-01-23 20:06  1% ` comicfanzine
2016-01-27  9:26  0%   ` Simon Wright
2016-01-27 20:28  0%     ` Dmitry A. Kazakov
2016-01-31  8:56     ` comicfanzine
2016-01-31 11:25       ` Simon Wright
2016-01-31 12:57  2%     ` Dmitry A. Kazakov
2016-02-07 22:45  1% ANN: Cortex GNAT RTS 20160207 Simon Wright
2016-03-14 17:42  1% ANN: Cortex GNAT RTS 20160314 Simon Wright
2016-05-22 14:20  1% ANN: Cortex GNAT RTS 20160522 Simon Wright
2016-08-12  4:05     How to write "Hello" to a text file without a line terminator Jerry
2016-08-12  7:23     ` Dmitry A. Kazakov
2016-08-12  7:44       ` Jerry
2016-08-12 17:34         ` Jeffrey R. Carter
2016-08-13  3:21           ` Jerry
2016-08-13  4:23             ` Jeffrey R. Carter
2016-08-13  9:12               ` AdaMagica
2016-08-13 18:03                 ` Jeffrey R. Carter
2016-08-14  7:58                   ` AdaMagica
2016-08-14  8:30                     ` Simon Wright
2016-08-14  8:54                       ` Dmitry A. Kazakov
2016-08-14  9:40  1%                     ` Simon Wright
2016-08-14 10:17  1%                       ` Dmitry A. Kazakov
2016-08-25 20:17     zLibAda vs ZipAda (which should I use, if any)? Aurele
2016-08-25 23:07     ` Aurele
2016-08-25 23:43       ` gautier_niouzes
2016-08-25 23:55         ` Aurele
2016-08-26  0:18           ` gautier_niouzes
2016-08-26  1:44             ` Aurele
2016-08-26 12:36               ` gautier_niouzes
2016-08-26 14:23                 ` Aurele
2016-08-26 15:16                   ` gautier_niouzes
2016-08-26 16:05                     ` Aurele
2016-08-26 23:04                       ` Aurele
2016-08-27  5:30                         ` gautier_niouzes
2016-08-27 11:52                           ` Aurele
2016-08-27 16:31  2%                         ` Aurele
2016-08-27 19:15  0%                           ` gautier_niouzes
2016-08-27 19:33  2% ` Aurele
2016-10-12 14:23  1% Gnat Sockets - UDP timeout too short ahlan
2016-11-04  8:48  0% ` ahlan.marriott
2017-07-09  6:54     How to check syntax with GNAT? Victor Porton
2017-07-13  5:47  1% ` Simon Wright
2017-07-24 15:41  1% Smart Pointers and Tagged Type Hierarchies Felix Krause
2017-07-24 21:24  0% ` Chris Moore
2017-08-02 13:43     T'Interface attribute Dmitry A. Kazakov
2017-08-03  4:46     ` Randy Brukardt
2017-08-03  7:26  1%   ` Dmitry A. Kazakov
2017-08-04 23:51  0%     ` Randy Brukardt
2017-08-29 20:28     win32 interfacing check (SetClipboardData) Xavier Petit
2017-08-30 16:04     ` Dmitry A. Kazakov
2017-08-30 18:41       ` Xavier Petit
2017-08-30 21:17         ` Dmitry A. Kazakov
2017-09-01 12:51           ` Xavier Petit
2017-09-01 13:10  1%         ` Dmitry A. Kazakov
2017-09-02  9:38  0%           ` Xavier Petit
2017-09-02 12:29  0%             ` Dmitry A. Kazakov
2017-09-03 11:01     quiz for Sequential_IO Read Frank Buss
2017-09-03 12:26  1% ` Dmitry A. Kazakov
2017-09-03 12:43  0%   ` Frank Buss
2017-09-03 13:11  0%     ` Dmitry A. Kazakov
2017-09-04 19:58  2%       ` Frank Buss
2017-09-04 20:55  0%         ` Dmitry A. Kazakov
2017-09-14  5:09     use Ada.Text_IO in main() or Package? Mace Ayres
2017-09-14  6:21     ` gautier_niouzes
2017-09-14  6:47       ` Mace Ayres
2017-09-14  7:13         ` gautier_niouzes
2017-09-14  9:37           ` Mace Ayres
2017-09-14  9:49  1%         ` gautier_niouzes
2017-09-16  6:40     NTP Anatoly Chernyshev
2017-09-16  9:29  1% ` NTP Dmitry A. Kazakov
2017-10-21  2:05  2% Finding the end of a stream from a socket Andrew Shvets
2017-10-21  8:44  0% ` Dmitry A. Kazakov
2017-10-21 13:45  0%   ` Andrew Shvets
2017-10-21 18:11         ` Dennis Lee Bieber
2017-10-21 19:19           ` Dmitry A. Kazakov
2017-10-22 12:26  2%         ` Andrew Shvets
2017-10-22 12:28  0%           ` Andrew Shvets
2017-10-22 13:28  0%           ` Dmitry A. Kazakov
2017-10-21 17:34  0%   ` Andrew Shvets
2017-10-21 19:18  0%     ` Andrew Shvets
2017-11-13 22:09     Unbounded_String'Write et al in GNAT Victor Porton
2017-11-14 15:05  1% ` Simon Wright
2018-02-21 23:57  1% article on acces types and dynamic serialization in Ada (2003) Mehdi Saada
2018-02-28 13:01     body stub not allowed in inner scope Mehdi Saada
2018-02-28 13:32     ` AdaMagica
2018-02-28 14:30       ` Mehdi Saada
2018-02-28 23:23         ` Randy Brukardt
2018-03-01 17:37  1%       ` Shark8
2018-03-25  4:04  2% TCP Server & Client Andrew Shvets
2018-03-25  8:22  1% ` Simon Wright
2018-03-25 19:17  0%   ` Andrew Shvets
2018-03-27 20:26  2% Overriding procedure as null gautier_niouzes
2018-03-28  0:08  0% ` Randy Brukardt
2018-05-10 17:45     AI12-0218: What is the portable representation clause for processing IETF packets on little-endian machines? Dan'l Miller
2018-05-10 19:24     ` Dan'l Miller
2018-05-10 20:32       ` Paul Rubin
2018-05-10 22:24         ` Dan'l Miller
2018-05-10 22:44           ` Niklas Holsti
2018-05-11  2:38             ` Dan'l Miller
2018-05-11  7:55  2%           ` Simon Wright
2019-02-06 23:10     Ada x <whatever> Datagram Sockets Rego, P.
2019-02-07  0:42     ` Jere
2019-02-07  5:28       ` Rego, P.
2019-02-07  6:00         ` Egil H H
2019-02-07  6:41  1%       ` Rego, P.
2019-02-07  7:23  0%         ` Egil H H
2019-02-08 19:41  2%           ` Rego, P.
2019-02-08 20:31  0%             ` Dmitry A. Kazakov
2019-02-07  8:28  0%         ` Dmitry A. Kazakov
2019-02-08  0:15               ` Randy Brukardt
2019-02-08  8:25                 ` Simon Wright
2019-02-09  1:01                   ` Randy Brukardt
2019-02-10 17:54                     ` Simon Wright
2019-02-11 23:19                       ` Randy Brukardt
2019-02-12 11:35  2%                     ` Simon Wright
2019-02-07 11:47  0%         ` Jere
2019-02-07 18:00               ` Jeffrey R. Carter
2019-02-08 20:35                 ` Rego, P.
2019-02-08 21:26  2%               ` Jeffrey R. Carter
2019-02-08 22:02  0%                 ` Rego, P.
2019-10-14 19:41     How to transfer Class-Wide object to a Task ? William FRANCK
2019-10-14 20:21     ` William FRANCK
2019-10-14 21:57  1%   ` Shark8
2019-10-15  5:43  0%     ` William FRANCK
2020-01-18  7:32     Creating several types from a base type and conversion Ken Roberts
2020-01-23 21:39     ` Optikos
2020-01-24 15:54  1%   ` Simon Wright
2020-01-20  8:07  1% HTTP Range Requests and streams gautier_niouzes
2020-01-20  8:34  0% ` Dmitry A. Kazakov
2020-04-02 13:58     Simple parse from https website Rego, P.
2020-04-02 14:42     ` Dmitry A. Kazakov
2020-04-02 14:48       ` Rego, P.
2020-04-02 17:16  1%     ` Dmitry A. Kazakov
2020-04-02 18:27  0%       ` Rego, P.
2020-07-04 17:00     General circular buffer example not tied to any specific type Daniel
2020-09-24  4:10     ` nimaopatel121
2020-09-24  4:39  1%   ` J-P. Rosen
2021-02-20 15:26     set_index and and end_of_file with just a stream reference Mehdi Saada
2021-02-20 16:04     ` Dmitry A. Kazakov
2021-02-20 16:22       ` Mehdi Saada
2021-02-20 16:30         ` Mehdi Saada
2021-02-20 17:59           ` Dmitry A. Kazakov
2021-02-20 19:08             ` Mehdi Saada
2021-02-23 17:21  1%           ` Shark8
2021-03-22 17:13     surprise data from Ada.Sequential_IO John Perry
2021-03-22 17:48  1% ` Dmitry A. Kazakov
2021-05-17 18:44  2% Better way to fill Storage_IO? Michael Hardeman
2021-05-17 19:14  1% ` Simon Wright
2021-05-17 19:23  0%   ` Michael Hardeman
2021-05-18 20:39  2%     ` Simon Wright
2021-05-19  7:17  0%       ` J-P. Rosen
2021-05-19  8:26  0%         ` Björn Lundin
2021-05-19 15:39  0%         ` Simon Wright
2021-05-17 20:20  0%   ` Dmitry A. Kazakov
2021-05-17 20:48  0%     ` Michael Hardeman
2021-05-18 14:00  0%       ` Per Sandberg
2021-05-18  9:08  0%     ` J-P. Rosen
2021-06-10  2:17     Is it possible to redirect text output to a String or Unbounded_String? Jerry
2021-06-10 21:12  1% ` Shark8
2021-06-11 13:30  1% ANN: Ada Resource Embedder for C, Ada and Go Stephane Carrez
2021-06-27 19:33  1% Hi! How I can make _indexed_ stream file Input/Output ? Thanks Daniel Norte Moraes
2021-06-28  1:36  0% ` Dennis Lee Bieber
2021-07-02 20:57  0% ` Shark8
2021-07-05  4:06  0%   ` zac brown
2021-07-05  4:06  0%     ` zac brown
2022-01-14 18:30  1% Usage of Stream Set_Index() function DrPi
2022-01-14 20:35  0% ` Niklas Holsti
2022-01-15 10:36  0%   ` DrPi
2022-12-31 12:11     Sockets, Streams, and Element_Arrays: Much confusion Mark Gardner
2022-12-31 13:11  1% ` Dmitry A. Kazakov
2022-12-31 13:50  0%   ` Mark Gardner
2022-12-31 14:16  0%     ` Dmitry A. Kazakov
2022-12-31 17:39  1% ` Simon Wright
2022-12-31 19:36  0%   ` Mark Gardner
2023-02-07 20:29     Broadcast / iterate to all Connection objects via Simple Components? A.J.
2023-02-08  9:55     ` Jeffrey R.Carter
2023-02-13  7:28       ` Emmanuel Briot
2023-02-13  8:30         ` Dmitry A. Kazakov
2023-02-13  8:44           ` Emmanuel Briot
2023-02-13 10:55             ` Dmitry A. Kazakov
2023-02-13 11:07               ` Emmanuel Briot
2023-02-13 16:40  1%             ` Jeremy Grosser <jeremy@synack.me>
2023-06-30 19:28  2% GNAT Community 2020 (20200818-93): Big_Integer Frank Jørgen Jørgensen
2023-06-30 21:07  1% ` Dmitry A. Kazakov
2023-08-18  7:18     Parameterised 'Image Attributes Rod Kay
2023-08-18  8:25     ` Luke A. Guest
2023-08-19  9:14       ` J-P. Rosen
2023-08-19 16:49         ` moi
2023-08-20  7:25           ` Randy Brukardt
2023-08-20  9:43             ` Dmitry A. Kazakov
2023-08-21 23:34               ` Randy Brukardt
2023-08-22  8:13                 ` Dmitry A. Kazakov
2023-08-23 10:20                   ` Stephen Davies
2023-08-23 16:16                     ` Dmitry A. Kazakov
2023-08-24 19:59                       ` Stephen Davies
2023-08-25  7:26                         ` Dmitry A. Kazakov
2023-08-25  9:04                           ` Stephen Davies
2023-08-25 13:02                             ` Dmitry A. Kazakov
2023-08-28  9:18                               ` Stephen Davies
2023-08-28 10:58                                 ` Dmitry A. Kazakov
2023-08-28 15:42                                   ` Stephen Davies
2023-08-28 16:09                                     ` Dmitry A. Kazakov
2023-08-28 17:33  1%                                   ` G.B.
2023-08-28 19:08  0%                                     ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox