comp.lang.ada
 help / color / mirror / Atom feed
* A copy question....
@ 2001-10-15 10:40 Zebylon
  2001-10-15 11:21 ` Dale Stanbrough
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Zebylon @ 2001-10-15 10:40 UTC (permalink / raw)


If you have an system.address variable, an data length variable and an array
of Unsigned_32. How can you move the data ranging between the address and
the address+data_length into the array?

I.G.

Address               : System.address      := 0x0200_0000;
Data_Length       : Natural                       := 200; --bytes
Array                   : array range (integer 0..375) of Unsigned_32;

Is there some smart way of placing the data in the array...?






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

* Re: A copy question....
  2001-10-15 10:40 A copy question Zebylon
@ 2001-10-15 11:21 ` Dale Stanbrough
  2001-10-15 11:30   ` Dale Stanbrough
  2001-10-15 13:38   ` Ted Dennison
  2001-10-15 13:30 ` Mark Doherty
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-15 11:21 UTC (permalink / raw)


In article <9qedad$i1p$1@newstoo.ericsson.se>,
 "Zebylon" <sebastian.madunic@esavionics.se> wrote:

> If you have an system.address variable, an data length variable and an array
> of Unsigned_32. How can you move the data ranging between the address and
> the address+data_length into the array?
> 
> I.G.
> 
> Address               : System.address      := 0x0200_0000;
> Data_Length       : Natural                       := 200; --bytes
> Array                   : array range (integer 0..375) of Unsigned_32;
> 
> Is there some smart way of placing the data in the array...?


Convert the address to an access type using an instantiation of the 
generic

   System.Address_To_Access_Conversions.To_Pointer

and then dereference the pointer generated by the function...

   function Address_To_Int_Pointer is new
      To_Pointer (Int_Pointer);

...
   for i in Array'range loop
      Array (i) := Address_To_Int_Pointer (Address).all;
      Address := Address + Unsigned_32'Size/8;
      -- i think there is a constant somewhere i should use instead of 8
   end loop;

note that the "+" operator is from System.Storage_Elements

Alternatively you could dive into either the OS API, which could well 
have a block move instruction (realloc?), or call any relavent assembler 
instruction.

Dale



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

* Re: A copy question....
  2001-10-15 11:21 ` Dale Stanbrough
@ 2001-10-15 11:30   ` Dale Stanbrough
  2001-10-15 11:59     ` Petter Fryklund
  2001-10-15 13:38   ` Ted Dennison
  1 sibling, 1 reply; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-15 11:30 UTC (permalink / raw)


Dale Stanbrough wrote:

> Convert the address to an access type using an instantiation of the 
> generic
> 
>    System.Address_To_Access_Conversions.To_Pointer
> 
> and then dereference the pointer generated by the function...
> 
>    function Address_To_Int_Pointer is new
>       To_Pointer (Int_Pointer);
> 
> ...
>    for i in Array'range loop
>       Array (i) := Address_To_Int_Pointer (Address).all;
>       Address := Address + Unsigned_32'Size/8;
>       -- i think there is a constant somewhere i should use instead of 8
>    end loop;


Silly me. I didn't check the code. System.Address_To_Access_Conversion
is a generic package, not a package with a generic function.
You'll need to instantiate it as...
  
   package To_Int_Pointers is
      new System.Address_To_Access_Conversion (Int_Pointer);

and then you'll call the To_Pointer function in this package.


Dale



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

* Re: A copy question....
  2001-10-15 11:30   ` Dale Stanbrough
@ 2001-10-15 11:59     ` Petter Fryklund
  2001-10-15 21:04       ` Dale Stanbrough
  0 siblings, 1 reply; 14+ messages in thread
From: Petter Fryklund @ 2001-10-15 11:59 UTC (permalink / raw)


Wouldn't it be more efficient to let Int_Pointer point to an Array of
Unsigned_32 and instead of looping just assign the value by means of:

Array (0 .. 199) := Address_To_Int_Pointer (Address).all (0 .. 199);





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

* Re: A copy question....
  2001-10-15 10:40 A copy question Zebylon
  2001-10-15 11:21 ` Dale Stanbrough
@ 2001-10-15 13:30 ` Mark Doherty
  2001-10-15 17:00 ` tmoran
  2001-10-16 23:00 ` David Botton
  3 siblings, 0 replies; 14+ messages in thread
From: Mark Doherty @ 2001-10-15 13:30 UTC (permalink / raw)


> If you have an system.address variable, an data length variable and an array
> of Unsigned_32. How can you move the data ranging between the address and
> the address+data_length into the array?

Take a look at: 
 for ... use (at) clause (ada83/95 syntax dependant), 
 pragma volatile and 
 pragma import.

in the lrm.

p.s. be careful with the sizes as you are impling 375*4 bytes of array
and 200 bytes of address space!



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

* Re: A copy question....
  2001-10-15 11:21 ` Dale Stanbrough
  2001-10-15 11:30   ` Dale Stanbrough
@ 2001-10-15 13:38   ` Ted Dennison
  1 sibling, 0 replies; 14+ messages in thread
From: Ted Dennison @ 2001-10-15 13:38 UTC (permalink / raw)


In article <dale-238AFE.21195615102001@mec2.bigpond.net.au>, Dale Stanbrough
says...
>
>In article <9qedad$i1p$1@newstoo.ericsson.se>,
> "Zebylon" <sebastian.madunic@esavionics.se> wrote:
>
>> If you have an system.address variable, an data length variable and an array
>> of Unsigned_32. How can you move the data ranging between the address and
>> the address+data_length into the array?
..
>Convert the address to an access type using an instantiation of the 
>generic

But a *really* smart Ada developer will never get him/herself into this
situation in the first place. Instead, you pick better types, that don't need to
be converted. In *rare* circumstances something like this may be unaviodable.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html

No trees were killed in the sending of this message. 
However a large number of electrons were terribly inconvenienced.



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

* Re: A copy question....
  2001-10-15 10:40 A copy question Zebylon
  2001-10-15 11:21 ` Dale Stanbrough
  2001-10-15 13:30 ` Mark Doherty
@ 2001-10-15 17:00 ` tmoran
  2001-10-16 10:09   ` Mark Doherty
  2001-10-16 23:00 ` David Botton
  3 siblings, 1 reply; 14+ messages in thread
From: tmoran @ 2001-10-15 17:00 UTC (permalink / raw)


with System,
     System.Storage_Elements,
     Interfaces;
procedure Test is
  Address : System.Address
    := System.Storage_Elements.To_Address(16#0200_0000#);
  Data_Length: Natural := 200; --bytes
  type Dword_Arrays is array (Integer range <>) of Interfaces.Unsigned_32;
  Source  : Dword_Arrays(0 .. 49); -- 50*32=200*8
  for Source'Address use Address;
  Target  : Dword_Arrays(0 .. 375);
begin
  Target(Source'range) := Source;
end Test;



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

* Re: A copy question....
  2001-10-15 11:59     ` Petter Fryklund
@ 2001-10-15 21:04       ` Dale Stanbrough
  2001-10-16  2:34         ` Jeffrey Carter
  0 siblings, 1 reply; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-15 21:04 UTC (permalink / raw)


Petter Fryklund wrote:

> Wouldn't it be more efficient to let Int_Pointer point to an Array of
> Unsigned_32 and instead of looping just assign the value by means of:
> 
> Array (0 .. 199) := Address_To_Int_Pointer (Address).all (0 .. 199);

I hadn't thought of that! Certainly better notationally - probably
more efficient at the computer level as well.

Dale



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

* Re: A copy question....
  2001-10-15 21:04       ` Dale Stanbrough
@ 2001-10-16  2:34         ` Jeffrey Carter
  2001-10-16 11:15           ` Dale Stanbrough
  0 siblings, 1 reply; 14+ messages in thread
From: Jeffrey Carter @ 2001-10-16  2:34 UTC (permalink / raw)


Dale Stanbrough wrote:
> 
> > Array (0 .. 199) := Address_To_Int_Pointer (Address).all (0 .. 199);
> 
> I hadn't thought of that! Certainly better notationally - probably
> more efficient at the computer level as well.

The .all is not required. Note also that using
Address_To_Access_Conversions on an unconstrained array type is unlikely
to give the desired results. The compiler has no way to determine the
designated object's bounds. A constrained subtype is usually OK, but I
think using an address clause to locate an object of the desired type
and bounds is usually best.

-- 
Jeff Carter
"We call your door-opening request a silly thing."
Monty Python & the Holy Grail



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

* Re: A copy question....
  2001-10-15 17:00 ` tmoran
@ 2001-10-16 10:09   ` Mark Doherty
  2001-10-17  0:18     ` tmoran
  0 siblings, 1 reply; 14+ messages in thread
From: Mark Doherty @ 2001-10-16 10:09 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<mCEy7.18793$gT6.11921721@news1.rdc1.sfba.home.com>...

> with System,
>      System.Storage_Elements,
>      Interfaces;
> procedure Test is
>   Address : System.Address
>     := System.Storage_Elements.To_Address(16#0200_0000#);
>   Data_Length: Natural := 200; --bytes
>   type Dword_Arrays is array (Integer range <>) of Interfaces.Unsigned_32;
>   Source  : Dword_Arrays(0 .. 49); -- 50*32=200*8
>   for Source'Address use Address;
>   Target  : Dword_Arrays(0 .. 375);
> begin
>   Target(Source'range) := Source;
> end Test;

The use of 
>   for Source'Address use Address;
is not portable.
 
Rational would initialise Source to 0's (unless the Pragma Import is used).



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

* Re: A copy question....
  2001-10-16  2:34         ` Jeffrey Carter
@ 2001-10-16 11:15           ` Dale Stanbrough
  0 siblings, 0 replies; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-16 11:15 UTC (permalink / raw)


Jeffrey Carter wrote:

> The .all is not required. 

I would still put it in, as I think it makes the code clearer
(i much prefer Pascal's dereferencing syntax).


Dale



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

* Re: A copy question....
  2001-10-15 10:40 A copy question Zebylon
                   ` (2 preceding siblings ...)
  2001-10-15 17:00 ` tmoran
@ 2001-10-16 23:00 ` David Botton
  3 siblings, 0 replies; 14+ messages in thread
From: David Botton @ 2001-10-16 23:00 UTC (permalink / raw)


----- Original Message -----
From: "Zebylon" <sebastian.madunic@esavionics.se>
> Is there some smart way of placing the data in the array...?

This is my favorite method and if you don't need a copy, but just an easy
way to access the memory, you can just use the returned Pointer_To_The_Array
directly instead of copying it.

I think the compiler will likely figure out the best way to make the block
copy on the platform :-)


with GNAT.IO; use GNAT.IO;

with Ada.Unchecked_Conversion;

with System;
with Interfaces;

procedure Block is

   type My_Array is array (Integer range <>) of Interfaces.Unsigned_32;

   Stuff_In_Memory : My_Array (1 .. 200) := (others => 999);

   Address     : System.Address := Stuff_In_Memory (1)'Address;
   Data_Length : Natural := Stuff_In_Memory'Length;

   type The_Array is new My_Array (1 .. Data_Length);
   type Pointer_To_The_Array is access all The_Array;

   function To_Pointer_To_The_Array is
      new Ada.Unchecked_Conversion (System.Address, Pointer_To_The_Array);

   Copied_Array : The_Array := To_Pointer_To_The_Array (Address).all;
begin
   for N in Copied_Array'Range loop
      Put_Line (Copied_Array (N)'Img);
   end loop;
end Block;





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

* Re: A copy question....
  2001-10-16 10:09   ` Mark Doherty
@ 2001-10-17  0:18     ` tmoran
  2001-10-17  1:14       ` David Botton
  0 siblings, 1 reply; 14+ messages in thread
From: tmoran @ 2001-10-17  0:18 UTC (permalink / raw)


> The use of
> >   for Source'Address use Address;
> is not portable.
>
> Rational would initialise Source to 0's (unless the Pragma Import is used).
  It's not a portability problem, it's an error in the code I posted. :(
Most compilers of my acquaintance only initialize things with
initializers, and don't initialize simple arrays of integers.  But that
just demonstrates the disadvantages of not using a diversity of compilers.
Yes indeed there should be a Pragma Import.
  As I read the LRM, the array Source ought to be declared aliased, also.
  Speaking of portability,
>  function To_Pointer_To_The_Array is
>     new Ada.Unchecked_Conversion (System.Address, Pointer_To_The_Array);
is not portable, while
package System.Address_To_Access_Conversions
is specifically designed to do what you want.
> Put_Line (Copied_Array (N)'Img);
  The 'Img attribute is a "vendor special", 'Image would be portable.



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

* Re: A copy question....
  2001-10-17  0:18     ` tmoran
@ 2001-10-17  1:14       ` David Botton
  0 siblings, 0 replies; 14+ messages in thread
From: David Botton @ 2001-10-17  1:14 UTC (permalink / raw)


I was showing my "favorite" method. The use of the 'Img was part of the test
driver. It is a convenience that I am surprised has not been adopted by
other vendors.

I admit that since most of my Ada programming is with GNAT, I get lazy about
portability to other compilers.

Here is a more universal version:

with Ada.Text_IO; use Ada.Text_IO;

with System.Address_To_Access_Conversions;
with System;

with Interfaces;

procedure Block is

   type My_Array is array (Integer range <>) of Interfaces.Unsigned_32;

   Stuff_In_Memory : My_Array (1 .. 200) := (others => 999);

   Address     : System.Address := Stuff_In_Memory (1)'Address;
   Data_Length : Natural := Stuff_In_Memory'Length;
   -- Assuming of Unsigned_32s

   type The_Array is new My_Array (1 .. Data_Length);
   pragma Pack (The_Array);

   package Array_Copier is
      new System.Address_To_Access_Conversions (The_Array);

   Copied_Array : The_Array := Array_Copier.To_Pointer (Address).all;
begin
   for N in Copied_Array'Range loop
      Put_Line (Interfaces.Unsigned_32'Image (Copied_Array (N)));
   end loop;
end Block;




<tmoran@acm.org> wrote in message
news:t74z7.24114$gT6.15011939@news1.rdc1.sfba.home.com...
>   Speaking of portability,
> >  function To_Pointer_To_The_Array is
> >     new Ada.Unchecked_Conversion (System.Address, Pointer_To_The_Array);
> is not portable, while
> package System.Address_To_Access_Conversions
> is specifically designed to do what you want.
> > Put_Line (Copied_Array (N)'Img);
>   The 'Img attribute is a "vendor special", 'Image would be portable.





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

end of thread, other threads:[~2001-10-17  1:14 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-15 10:40 A copy question Zebylon
2001-10-15 11:21 ` Dale Stanbrough
2001-10-15 11:30   ` Dale Stanbrough
2001-10-15 11:59     ` Petter Fryklund
2001-10-15 21:04       ` Dale Stanbrough
2001-10-16  2:34         ` Jeffrey Carter
2001-10-16 11:15           ` Dale Stanbrough
2001-10-15 13:38   ` Ted Dennison
2001-10-15 13:30 ` Mark Doherty
2001-10-15 17:00 ` tmoran
2001-10-16 10:09   ` Mark Doherty
2001-10-17  0:18     ` tmoran
2001-10-17  1:14       ` David Botton
2001-10-16 23:00 ` David Botton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox