comp.lang.ada
 help / color / mirror / Atom feed
* String view of file
@ 2022-11-21  8:30 Jesper Quorning
  2022-11-21 13:01 ` G.B.
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Jesper Quorning @ 2022-11-21  8:30 UTC (permalink / raw)


I like to ask about

Is it possible to write something like this with ADA

```Ada
package my_rw_file is new file
  (name => "whatever"
   ,mode => read_write
   ,implementation => standard -- or portable or fast
  );
package as_string is new. xxx(from => my_rw_file);

-- parse (as_string);
package data is new parse (as_string, format => markdown); -- or whatever
```

Sorry, im new to ada


Jesper Q

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
@ 2022-11-21 13:01 ` G.B.
  2022-11-21 13:48 ` Jeffrey R.Carter
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: G.B. @ 2022-11-21 13:01 UTC (permalink / raw)


On 21.11.22 09:30, Jesper Quorning wrote:
> I like to ask about
> 
> Is it possible to write something like this with ADA
> 
> ```Ada
> package my_rw_file is new file
>    (name => "whatever"
>     ,mode => read_write
>     ,implementation => standard -- or portable or fast
>    );
> package as_string is new. xxx(from => my_rw_file);
> 
> -- parse (as_string);
> package data is new parse (as_string, format => markdown); -- or whatever
> ```

Do you mean, gobble up a file into a string
and then parse that? Yes, that's possible
in a number of ways.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
  2022-11-21 13:01 ` G.B.
@ 2022-11-21 13:48 ` Jeffrey R.Carter
  2022-11-21 15:52   ` Niklas Holsti
  2022-11-21 15:18 ` Dmitry A. Kazakov
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Jeffrey R.Carter @ 2022-11-21 13:48 UTC (permalink / raw)


On 2022-11-21 09:30, Jesper Quorning wrote:
> 
> Is it possible to write something like this with ADA

"Ada" is a woman's name, not an acronymn.

> package my_rw_file is new file
>    (name => "whatever"
>     ,mode => read_write
>     ,implementation => standard -- or portable or fast
>    );
> package as_string is new. xxx(from => my_rw_file);
> 
> -- parse (as_string);
> package data is new parse (as_string, format => markdown); -- or whatever

If I presume that the '.' in the declaration of As_String is a typo, what you 
have here is a sequence of related generic pkg instantiations, so you can write 
this in Ada if you have the corresponding generic pkgs. I have no idea what the 
result would provide.

If you want to read the arbitrary contents of a file into a String, that's 
easily done:

with Ada.Directories;

package String_A_File is
    use type Ada.Directories.File_Size;

    function File_As_String (Name : in String) return String with
       Pre  => Ada.Directories.Exists (Name) and then
               Ada.Directories.Size (Name) <=
               Ada.Directories.File_Size (Integer'Last),
       Post => File_As_String'Result'First = 1 and
               File_As_String'Result'Last =
               Integer (Ada.Directories.Size (Name) );
end String_A_File;

with Ada.Sequential_IO;

package body String_A_File is
    function File_As_String (Name : in String) return String is
       subtype FAS is String (1 .. Integer (Ada.Directories.Size (Name) ) );

       package FAS_IO is new Ada.Sequential_IO (Element_Type => FAS);

       File   : FAS_IO.File_Type;
       Result : FAS;
    begin -- File_As_String
       FAS_IO.Open (File => File, Mode => FAS_IO.In_File, Name => Name);
       FAS_IO.Read (File => File, Item => Result;
       FAS_IO.Close (File => File);

       return Result;
    end File_As_String;
end String_A_File;

This presumes that Result will fit on the stack. If that's likely to be a 
problem, then you will need to use Unbounded_String and read the file Character 
by Character.

-- 
Jeff Carter
"I have a very small head and I had
better learn to live with it ..."
Edsger Dijkstra
158

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
  2022-11-21 13:01 ` G.B.
  2022-11-21 13:48 ` Jeffrey R.Carter
@ 2022-11-21 15:18 ` Dmitry A. Kazakov
  2022-11-21 16:11 ` Marius Amado-Alves
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Dmitry A. Kazakov @ 2022-11-21 15:18 UTC (permalink / raw)


On 2022-11-21 09:30, Jesper Quorning wrote:

> Is it possible to write something like this with ADA
> 
> ```Ada
> package my_rw_file is new file
>    (name => "whatever"
>     ,mode => read_write
>     ,implementation => standard -- or portable or fast
>    );
> package as_string is new. xxx(from => my_rw_file);
> 
> -- parse (as_string);
> package data is new parse (as_string, format => markdown); -- or whatever

It is difficult to guess what you want to achieve. What it looks to me 
is a design opposite to the customary approach:

     abstract code source  (generic and/or tagged)
       /        |       \
      /         |        \
   string   text_file   stream

Since string and file cannot be derived, in a tagged case some mix-in is 
used.

The parser from simple-components has multi-line and single-line 
sources. A single-line source can be set on a string. Multi-line source 
is for files and streams.

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21 13:48 ` Jeffrey R.Carter
@ 2022-11-21 15:52   ` Niklas Holsti
  2022-11-21 16:42     ` Jeffrey R.Carter
  0 siblings, 1 reply; 14+ messages in thread
From: Niklas Holsti @ 2022-11-21 15:52 UTC (permalink / raw)


On 2022-11-21 15:48, Jeffrey R.Carter wrote:
> On 2022-11-21 09:30, Jesper Quorning wrote:
>>
>> Is it possible to write something like this with ADA
> 
> "Ada" is a woman's name, not an acronymn.
> 
>> package my_rw_file is new file
>>    (name => "whatever"
>>     ,mode => read_write
>>     ,implementation => standard -- or portable or fast
>>    );
>> package as_string is new. xxx(from => my_rw_file);
>>
>> -- parse (as_string);
>> package data is new parse (as_string, format => markdown); -- or whatever
> 
> If I presume that the '.' in the declaration of As_String is a typo, 
> what you have here is a sequence of related generic pkg instantiations, 
> so you can write this in Ada if you have the corresponding generic pkgs. 
> I have no idea what the result would provide.
> 
> If you want to read the arbitrary contents of a file into a String, 
> that's easily done:
> 
> with Ada.Directories;
> 
> package String_A_File is
>     use type Ada.Directories.File_Size;
> 
>     function File_As_String (Name : in String) return String with
>        Pre  => Ada.Directories.Exists (Name) and then
>                Ada.Directories.Size (Name) <=
>                Ada.Directories.File_Size (Integer'Last),
>        Post => File_As_String'Result'First = 1 and
>                File_As_String'Result'Last =
>                Integer (Ada.Directories.Size (Name) );
> end String_A_File;
> 
> with Ada.Sequential_IO;
> 
> package body String_A_File is
>     function File_As_String (Name : in String) return String is
>        subtype FAS is String (1 .. Integer (Ada.Directories.Size (Name) 
> ) );
> 
>        package FAS_IO is new Ada.Sequential_IO (Element_Type => FAS);
> 
>        File   : FAS_IO.File_Type;
>        Result : FAS;
>     begin -- File_As_String
>        FAS_IO.Open (File => File, Mode => FAS_IO.In_File, Name => Name);
>        FAS_IO.Read (File => File, Item => Result;
>        FAS_IO.Close (File => File);
> 
>        return Result;
>     end File_As_String;
> end String_A_File;
> 
> This presumes that Result will fit on the stack. If that's likely to be 
> a problem, then you will need to use Unbounded_String and read the file 
> Character by Character.


For the OP's benefit (Jeffrey of course knows this): an alternative to 
Unbounded_String is to allocate the Result string on the heap, and 
return an access to the heap string. With that method, you can still 
read the entire string with one call of FAS_IO.Read instead of Character 
by Character.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
                   ` (2 preceding siblings ...)
  2022-11-21 15:18 ` Dmitry A. Kazakov
@ 2022-11-21 16:11 ` Marius Amado-Alves
  2022-11-21 17:29 ` Qunying
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Marius Amado-Alves @ 2022-11-21 16:11 UTC (permalink / raw)


Use Ada.Sequential_IO (Character), load to an Unbounded_String, save from a String or Unbounded_String.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21 15:52   ` Niklas Holsti
@ 2022-11-21 16:42     ` Jeffrey R.Carter
  2022-11-21 17:29       ` Niklas Holsti
  0 siblings, 1 reply; 14+ messages in thread
From: Jeffrey R.Carter @ 2022-11-21 16:42 UTC (permalink / raw)


On 2022-11-21 16:52, Niklas Holsti wrote:
> 
> For the OP's benefit (Jeffrey of course knows this): an alternative to 
> Unbounded_String is to allocate the Result string on the heap, and return an 
> access to the heap string. With that method, you can still read the entire 
> string with one call of FAS_IO.Read instead of Character by Character.

I know it, and I deliberately reject it. Having access types in a pkg spec is 
poor design. Delegating the associated memory management and all its 
opportunities for error to the pkg client is very poor design.

If access types are used, they should be hidden and encapsulated with their 
memory management. This makes it easier to get the memory management correct. 
Since this is what using Unbounded_String does for you, I think it's better to 
use it than to expend extra effort doing something similar.

-- 
Jeff Carter
"I have a very small head and I had
better learn to live with it ..."
Edsger Dijkstra
158

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21 16:42     ` Jeffrey R.Carter
@ 2022-11-21 17:29       ` Niklas Holsti
  0 siblings, 0 replies; 14+ messages in thread
From: Niklas Holsti @ 2022-11-21 17:29 UTC (permalink / raw)


On 2022-11-21 18:42, Jeffrey R.Carter wrote:
> On 2022-11-21 16:52, Niklas Holsti wrote:
>>
>> For the OP's benefit (Jeffrey of course knows this): an alternative to 
>> Unbounded_String is to allocate the Result string on the heap, and 
>> return an access to the heap string. With that method, you can still 
>> read the entire string with one call of FAS_IO.Read instead of 
>> Character by Character.
> 
> I know it, and I deliberately reject it. Having access types in a pkg 
> spec is poor design. Delegating the associated memory management and all 
> its opportunities for error to the pkg client is very poor design.


I agree in general, but there are design trade-offs that depend on 
issues not made clear in the original question, such as the size of the 
file and the performance requirements. So I thought that the OP should 
know of the heap alternative, even if it has some poorer properties too.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
                   ` (3 preceding siblings ...)
  2022-11-21 16:11 ` Marius Amado-Alves
@ 2022-11-21 17:29 ` Qunying
  2022-11-21 21:43 ` Gautier write-only address
  2023-01-01 23:36 ` Jesper Quorning
  6 siblings, 0 replies; 14+ messages in thread
From: Qunying @ 2022-11-21 17:29 UTC (permalink / raw)


If you are using gnat with gnatcoll, then you may try its mmap facility, https://docs.adacore.com/gnatcoll-docs/mmap.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
                   ` (4 preceding siblings ...)
  2022-11-21 17:29 ` Qunying
@ 2022-11-21 21:43 ` Gautier write-only address
  2023-01-01 23:36 ` Jesper Quorning
  6 siblings, 0 replies; 14+ messages in thread
From: Gautier write-only address @ 2022-11-21 21:43 UTC (permalink / raw)


You may be interested by this:
https://github.com/zertovitch/zip-ada/blob/master/zip_lib/zip_streams.ads#L148
It can be actually used out of the context of Zip archives.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2022-11-21  8:30 String view of file Jesper Quorning
                   ` (5 preceding siblings ...)
  2022-11-21 21:43 ` Gautier write-only address
@ 2023-01-01 23:36 ` Jesper Quorning
  2023-01-02 18:57   ` Stephen Leake
  2023-01-03 16:37   ` Jeffrey R.Carter
  6 siblings, 2 replies; 14+ messages in thread
From: Jesper Quorning @ 2023-01-01 23:36 UTC (permalink / raw)


The original post was a bit of a mess, and I am not quite new to Ada. But I lack some skills regarding software construction and software engineering.

What I want goes something like this:
- Zero copy access to a (read-only) file.
- Get lines of file one by one as a stream of lines.
- Use a package instance as file representation.
- Stretch goal: Multiple implementations of File Instance (Standard, Fast, Compatible ..)

Refined version:
```Ada
package File
   is new File_Instance
    (Filename => "whatever",
      Implementation => Standard);
---
for Line of File.As_Line_Stream loop
   Parse (Line);
end loop;
```

I think Dewar has written something about string view of some data. I saw some tricky tricks in the GNAT.Snobol implementation. Links to papers anyone?

Sorry for the late follow-up.


/Jesper

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2023-01-01 23:36 ` Jesper Quorning
@ 2023-01-02 18:57   ` Stephen Leake
  2023-01-03 16:37   ` Jeffrey R.Carter
  1 sibling, 0 replies; 14+ messages in thread
From: Stephen Leake @ 2023-01-02 18:57 UTC (permalink / raw)


Jesper Quorning <jesper.quorning@gmail.com> writes:

> The original post was a bit of a mess, and I am not quite new to Ada. But I lack some skills regarding software construction and software engineering.
>
> What I want goes something like this:
> - Zero copy access to a (read-only) file.

You can use gnatcoll mmap to get a memory-mapped view of a file. To get
a zero-copy string, you'll have to find the line boundaries yourself,
and use unchecked-conversion on a string pointer, or an address clause
on a local variable.

> - Get lines of file one by one as a stream of lines.

'stream' has a specific meaning in Ada; better say "collection of lines"
here.

You can define an iterator for your File type.

- Use a package instance as file representation. 

Why do you want to do this? The alternative is to define your own File
type, and provide an Open; then you can reuse that package for multiple
files. Closer to Ada standard practice for files.

- Stretch goal: Multiple implementations of File Instance (Standard, Fast, Compatible ..)

If you want to choose the implementation at compile time, you can use
separate bodies in implementation-specific directories, and choose the
directory in the project file.

If you want to chose the implementation at run time, you have to make
File a dispatching type. Then you pick the implementation via the
package name:

My_File : Files.Implementation_1.File;

> for Line of File.As_Line_Stream loop
>    Parse (Line);
> end loop;

You probably know that you can get close to this in standard Ada, at the
cost of a copy:

while not End_of_file (File) loop
   declare
      Line : get_line (file);
   begin
      Parse (line);
   end;
end loop;

An really aggressive optimizing compiler could get rid of the local
variable Line to avoid the copy, but it's not very likely.

This violates your requirement, but it could easily be that the copy is
very cheap; have you measured it in your actual application, and is
eliminating it worth the bother?

-- 
-- Stephe

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2023-01-01 23:36 ` Jesper Quorning
  2023-01-02 18:57   ` Stephen Leake
@ 2023-01-03 16:37   ` Jeffrey R.Carter
  2023-01-03 17:02     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 14+ messages in thread
From: Jeffrey R.Carter @ 2023-01-03 16:37 UTC (permalink / raw)


On 2023-01-02 00:36, Jesper Quorning wrote:
> 
> - Zero copy access to a (read-only) file.

So far as I know, any access to a file involves copying information from the 
external medium into memory, so this may be impossible.

-- 
Jeff Carter
"Any noun can be verbed."
Alan Perlis
"Verbing weirds language."
Calvin and Hobbes
206

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: String view of file
  2023-01-03 16:37   ` Jeffrey R.Carter
@ 2023-01-03 17:02     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry A. Kazakov @ 2023-01-03 17:02 UTC (permalink / raw)


On 2023-01-03 17:37, Jeffrey R.Carter wrote:
> On 2023-01-02 00:36, Jesper Quorning wrote:
>>
>> - Zero copy access to a (read-only) file.
> 
> So far as I know, any access to a file involves copying information from 
> the external medium into memory, so this may be impossible.

... in many cases copying drastically improves performance, e.g. 
caching, read ahead techniques etc.

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-01-03 17:02 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-21  8:30 String view of file Jesper Quorning
2022-11-21 13:01 ` G.B.
2022-11-21 13:48 ` Jeffrey R.Carter
2022-11-21 15:52   ` Niklas Holsti
2022-11-21 16:42     ` Jeffrey R.Carter
2022-11-21 17:29       ` Niklas Holsti
2022-11-21 15:18 ` Dmitry A. Kazakov
2022-11-21 16:11 ` Marius Amado-Alves
2022-11-21 17:29 ` Qunying
2022-11-21 21:43 ` Gautier write-only address
2023-01-01 23:36 ` Jesper Quorning
2023-01-02 18:57   ` Stephen Leake
2023-01-03 16:37   ` Jeffrey R.Carter
2023-01-03 17:02     ` 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