Variable length raw-byte data 
Author Message
 Variable length raw-byte data

I'm trying to shim to a C library that returns some data as a length in
bytes and a pointer to the first byte. The length is not known at compile
time. Is there any way I can morph this into an array of mod 2**8? I'm
using the latest Linux GNAT.


Sat, 31 May 2003 03:38:23 GMT  
 Variable length raw-byte data
Try looking at Interfaces.C and Interfaces.C.Pointers.
If it's string data, look at Interfaces.C.Strings.
I've used this successfully to interface to C.

Or

In your interface routine, receive the pointer as an
address, and then unchecked convert it.

  type Byte is mod 2**8;

  type Byte_Array is array (positive range <>) of Byte;

  type Byte_Array_Pointer is access Byte_Array;

  buffer_Address : System.Address;
  buffer_Pointer : Byte_Array_Pointer;

begin
...
  status := Get_C_Stuff(length         => length,
                        buffer_Address => buffer_Address);

  if (length > 0) then
    declare
      subtype Constrained_Byte_Array is Byte_Array(1..length);
      function To_Buffer_Pointer is
        new Ada.Unchecked_Conversion(System.Address,Constrained_Byte_Array);
    begin
      buffer_Pointer := To_Buffer_Pointer(buffer_Address);
    end;
    ...
  end if;
...

Something like that.  (Constructive corrections only please!)
I haven't done it this way in a while.

Frank

Quote:
-----Original Message-----

Sent: Monday, December 11, 2000 2:38 PM

Subject: Variable length raw-byte data

I'm trying to shim to a C library that returns some data as a length in
bytes and a pointer to the first byte. The length is not known at compile
time. Is there any way I can morph this into an array of mod 2**8? I'm
using the latest Linux GNAT.
_______________________________________________
comp.lang.ada mailing list

http://ada.eu.org/mailman/listinfo/comp.lang.ada



Sat, 31 May 2003 11:30:12 GMT  
 Variable length raw-byte data
Often, you can receive the pointer as an address and use it for an
object.

type Byte_List is array (Positive range <>) of Unsigned_8;

C_Thing (Length, Pointer);

Use_Thing : declare
   Thing : Byte_List (1 .. Length);
   for Thing'Address use Pointer;
begin -- Use_Thing
   ...
end Use_Thing;

--
Jeff Carter
"I blow my nose on you."
Monty python & the Holy Grail



Sat, 31 May 2003 13:19:21 GMT  
 Variable length raw-byte data
Quote:
>Or
>In your interface routine, receive the pointer as an
>address, and then unchecked convert it.
> ...
>  type Byte_Array is array (positive range <>) of Byte;
>  buffer_Address : System.Address;
> ...
>      subtype Constrained_Byte_Array is Byte_Array(1..length);
>      function To_Buffer_Pointer is
>        new Ada.Unchecked_Conversion(System.Address,Constrained_Byte_Array);
> ...
>Something like that.  (Constructive corrections only please!)

  Instead of trying to use Unchecked_Conversion to change an address
into an access type (I presume that was meant here), use
System.Address_To_Access_Conversions.  That should work.  But a
System.Address need not be the same size as an access type (consider
various Intel memory models), and even an access to an unconstrained
array (which will involve an actual 'range being stored somewhere) and
an access to a constrained array (where the compiler might keep the
range somewhere else) may be different, and different from a
System.Address.

Quote:
>I'm trying to shim to a C library that returns some data as a length in
>bytes and a pointer to the first byte. The length is not known at compile

 type Data_Array is array(1 .. 10_000) of Byte; -- big enough constrained array
 type Data_Array_Ptr is access all Data_Array;
 P : aliased Data_Array_Ptr;
 N : aliased Natural;
 ...
 if C_Func(N'access, P'access) /= Failure then ...
 -- P.all(0 .. N) contains result

If Data_Array is not constrained, then a pointer to one, ie a
Data_Array_Ptr, must handle the range somewhere.  If it's a fat pointer,
it's unlikely C_Func will be so kind as to supply it correctly.  If it
points to a descriptor of some kind for the actual array, it's again
unlikely C_Func will return such a beast.



Sat, 31 May 2003 13:54:12 GMT  
 Variable length raw-byte data
Yes, I forgot about this.  I've used this several times
in the past with great success.

Frank

Quote:
-----Original Message-----

Often, you can receive the pointer as an address and use it for an
object.

type Byte_List is array (Positive range <>) of Unsigned_8;

C_Thing (Length, Pointer);

Use_Thing : declare
   Thing : Byte_List (1 .. Length);
   for Thing'Address use Pointer;
begin -- Use_Thing
   ...
end Use_Thing;

--
Jeff Carter
"I blow my nose on you."
Monty Python & the Holy Grail
_______________________________________________
comp.lang.ada mailing list

http://ada.eu.org/mailman/listinfo/comp.lang.ada



Sun, 01 Jun 2003 05:00:11 GMT  
 Variable length raw-byte data
Your right.  When I wrote the code that used Unchecked_Conversion,
it was on an HP-UX box with the Alsys Ada83 compiler that didn't
have System.Address_To_Access_Conversions.  The addresses there
did translate nicely to access types.

With Ada95, the only interfaces I've written to C have used the
Interfaces.C... packages.

Frank

Quote:
-----Original Message-----

  Instead of trying to use Unchecked_Conversion to change an address
into an access type (I presume that was meant here), use
System.Address_To_Access_Conversions.  That should work.  But a
System.Address need not be the same size as an access type (consider
various Intel memory models), and even an access to an unconstrained
array (which will involve an actual 'range being stored somewhere) and
an access to a constrained array (where the compiler might keep the
range somewhere else) may be different, and different from a
System.Address.



Sun, 01 Jun 2003 05:11:13 GMT  
 Variable length raw-byte data
In article


Quote:
> I'm trying to shim to a C library that returns some data as a
length in
> bytes and a pointer to the first byte. The length is not known
at compile
> time. Is there any way I can morph this into an array of mod
2**8? I'm
> using the latest Linux GNAT.

The important thing is to NEVER use pointers to unconstrained
arrays in such a case. this is asking for non-portable, peculiar
behavior.

A good type to use in this case is what we in GNAT-land call
big arrays:

   type byte is mod 2 ** 8;

   type memory is array (natural) of byte;
   type memptr is access memory;

Now it is almost certainly safe to use address_to_access
conversions to go between address and memptr.

Of course you have to be careful not to access the array
out of bounds, but that's going to be up to the calling
program anyway if the bounds don't come built in :-)

Sent via Deja.com
http://www.deja.com/



Sun, 01 Jun 2003 08:50:29 GMT  
 Variable length raw-byte data

Quote:
>The important thing is to NEVER use pointers to unconstrained
>arrays in such a case. this is asking for non-portable, peculiar
>behavior.

That's exactly why my example contained a pointer to the constrained
subtype.

Quote:
> A good type to use in this case is what we in GNAT-land call
> big arrays:

>   type byte is mod 2 ** 8;

>   type memory is array (natural) of byte;
>   type memptr is access memory;

So you're going to allocate 2GB to handle what might
be only 10 bytes (or even 1K or 10K).  That should
work well on a dedicated processor with 64 K of memory.

And again if you use a pointer to the constrained subtype,
you only allocate what you need.

Or are you saying, you will be kind and make sure you
don't go beyond the length value returned, instead of
letting Ada constraint checking make sure you don't do it.

Quote:
>Now it is almost certainly safe to use address_to_access
>conversions to go between address and memptr.

>Of course you have to be careful not to access the array
>out of bounds, but that's going to be up to the calling
>program anyway if the bounds don't come built in :-)

And you're going to depend on C to do this?


Sun, 01 Jun 2003 10:56:14 GMT  
 Variable length raw-byte data
Quote:

>In article


>> I'm trying to shim to a C library that returns some data as a
>length in
>> bytes and a pointer to the first byte. The length is not known
>at compile
>> time. Is there any way I can morph this into an array of mod
>2**8? I'm
>> using the latest Linux GNAT.

>The important thing is to NEVER use pointers to unconstrained
>arrays in such a case. this is asking for non-portable, peculiar
>behavior.

>A good type to use in this case is what we in GNAT-land call
>big arrays:

>   type byte is mod 2 ** 8;

>   type memory is array (natural) of byte;
>   type memptr is access memory;

>Now it is almost certainly safe to use address_to_access
>conversions to go between address and memptr.

AFAIR, address_to_access_conversions has only one generic parameter: the
Object.
So, you need to use the access type defined by the package.
Right or wrong ?

Related question: why it is so ? (why AAC doesn't have the same paramaters
as unchecked_conversion ?)

Tristan.



Sun, 01 Jun 2003 16:56:32 GMT  
 Variable length raw-byte data
Since Byte_List is unconstrained is there not a potential for problem here
with additional data associated with the type for bounds?

Quote:
> type Byte_List is array (Positive range <>) of Unsigned_8;

Would this be a better solution:

C_Thing (Length, Pointer)

declare
    type Byte_List is array (1 .. Length) of Unsigned_8;
    Thing : Byte_List;
    for Thing'Address use Pointer;

begin
   ...
end;

I frequently code the above as:

C_Thing (Length, Pointer)

declare
    type Byte_List is array (1 .. Length) of Unsigned_8;
    type Pointer_To_Byte_List is access all Byte_List;

    function To_Pointer_To_Byte_List is
       new Ada.Unchecked_Conversion (System.Address, Pointer_To_Byte_List);

    Thing : Pointer_To_Byte_List := To_Pointer_To_Byte_List
(Pointer'Address);
begin
 ...
end;

Is there a reason that using the for Thing'Address would be a better
solution then the second method?

David Botton



Sun, 01 Jun 2003 23:48:31 GMT  
 Variable length raw-byte data

Quote:

>C_Thing (Length, Pointer)

>declare
>    type Byte_List is array (1 .. Length) of Unsigned_8;
>    Thing : Byte_List;
>    for Thing'Address use Pointer;

Usually I add:
     pragma Convention(Byte_List, Thing);

Quote:
>Is there a reason that using the for Thing'Address would be a better
>solution then the second method?

Personally I suspect an array to be a complex data structure and am not sure
if the Unchecked_Conversion or the 'Address points really to the included
data with out the pragam above.

--
              http://www.tm.oneiros.de/calendar/2001/index.html



Sun, 01 Jun 2003 23:51:20 GMT  
 Variable length raw-byte data
In article

nctswash.navy.mil>,

Quote:
> So you're going to allocate 2GB to handle what
> might be only 10 bytes (or even 1K or 10K).  That
> should work well on a dedicated processor with 64 K
> of memory.

Well you sure missed the point here :-)

Of *course* you never allocate an instance of a
big array. in fact it is not a bad idea to add

  for big_string_ptr'storage_Size use 0;

to emphasize this. The ONLY way you create instances
of the pointer is by unchecked conversion.

Quote:

> And again if you use a pointer to the constrained
> subtype, you only allocate what you need.

Again, you never do any allocations.

Quote:

> Or are you saying, you will be kind and make sure
> you don't go beyond the length value returned,
> instead of letting Ada constraint checking make
> sure you don't do it.

Well remember that the case being discussed here
is one in which the bounds are not part of the value
in any case. If you know the bound BEFORE you look
at the value, then of course you can make a subtype
that is the right length, but this is not always
the case, the obvious example being a C-style
null-terminated string, and here of course, yes,
the program must be "kind" and make sure it does
not reference past the terminating zero byte.

Quote:
> >Now it is almost certainly safe to use
> >address_to_access conversions to go between
> >address and memptr.

> >Of course you have to be careful not to access the
> >array out of bounds, but that's going to be up to
> >the calling program anyway if the bounds don't
> >come built in :-)
> And you're going to depend on C to do this?

That's the point, you *can't* depend on C to do this.
And if you are importing the data from the C world,
you cannot depend on Ada to magically protect you
from inherently dangerous C data structures!

Sent via Deja.com
http://www.deja.com/



Sun, 01 Jun 2003 23:52:32 GMT  
 Variable length raw-byte data

Quote:

> In article

> nctswash.navy.mil>,

>> So you're going to allocate 2GB to handle what
>> might be only 10 bytes (or even 1K or 10K).  That
>> should work well on a dedicated processor with 64 K
>> of memory.

> Well you sure missed the point here :-)

> Of *course* you never allocate an instance of a
> big array. in fact it is not a bad idea to add

>   for big_string_ptr'storage_Size use 0;

> to emphasize this. The ONLY way you create instances
> of the pointer is by unchecked conversion.

That is an interesting trick.  Is it new for Ada 95 ?

Looking at the nearest (old) manual for VAX/DEC/Compaq Ada (83),
it says that if the value specified is zero the default value of
"no limit" will be used.  Of course that is in the blue type,
meaning a description specific to that compiler. Is their approach
now outlawed for Ada 95, or was it outlawed by an AI for Ada 83 ?



Mon, 02 Jun 2003 02:23:12 GMT  
 Variable length raw-byte data



Quote:
> Is their approach
> now outlawed for Ada 95, or was it outlawed by an
> AI for Ada 83 ?

It was considered to be a ramification in an Ada 83
AI. It is clearly wrong to treat 0 as unlimited in
this context (and silly, because the default if no
such clause is given should be unlimited, the whole
point of a storage size clause is to set a limit).

Sent via Deja.com
http://www.deja.com/



Mon, 02 Jun 2003 03:26:49 GMT  
 Variable length raw-byte data


    pragma Convention(Byte_List, Thing);

What on earth is that supposed to mean. I don't know
of any Ada compiler that supports the convention
Byte_List -- most certainly this is wrong or highly
non-portable, most likely the former, and I cannot
guess what you meant to be saying here!

Sent via Deja.com
http://www.deja.com/



Mon, 02 Jun 2003 03:34:00 GMT  
 
 [ 19 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Attempting to read variable length records as raw data

2. Processing variable length/variable data files

3. Variable Length Data Types

4. Returning variable length data from C extensions

5. Vstruct module: unpack heterogenous, variable-length binary data

6. Extract data from radius's raw data

7. PyObject *data - access to raw data?

8. Getting true length of a variable length record - IBM Mainframe

9. Finding Variable-Length Record Length

10. Garnet 3.0 under Redhat/CMUCL: Error in function C::BYTE-INTERPRET-BYTE: Unbound variable: OPAL::AGGRELIST

11. Reading binary file, convert raw bytes

12. Reading in a file as raw hex bytes?

 

 
Powered by phpBB® Forum Software