Compound data type

From Rosetta Code
Revision as of 19:56, 25 February 2007 by 74.56.102.15 (talk)
Task
Compound data type
You are encouraged to solve this task according to the task description, using any language you may know.

Task 1: Create a structure Point(int x, int y)

 - Its internal content is in byte machine format (C struct) compatible.
 - For instance, by using pack/unpack internally on some scripting language. 
 - For a given object point with x=1 and y=2,
   the byte stream should be on x86 32-bit machines: 
   [0x01 0x00 0x00 0x00 | 0x02 0x00 0x00 0x00]

Task 2: Create a structure MyData as described in ANSI C as follows:

 #pragma pack(1)
 typedef struct MyData
 {
   signed char         m_sch;   //  8-bit signed
   unsigned char       m_uch;   //  8-bit unsigned
   signed short        m_ss;    // 16-bit signed
   unsigned short      m_us;    // 16-bit unsigned
   signed long         m_sl;    // 32-bit signed
   unsigned long       m_ul;    // 32-bit unsigned
   signed long long    m_sll;   // 64-bit signed
   unsigned long long  m_ull;   // 64-bit unsigned
   signed int          m_si;    // register int signed (native)
   unsigned int        m_ui;    // register int unsigned (native)
   float               m_f;     // 32-bit floating point
   double              m_d;     // 64-bit floating point
   long double         m_ld;    // 80-bit or 128-bit floating point
 } MyData;

Ada

Tagged Type

Ada tagged types are extensible through inheritance. The reserved word tagged causes the compiler to create a tag for the type. The tag identifies the position of the type in an inheritance hierarchy.

type Point is tagged record
   X : Integer := 0;
   Y : Integer := 0;
end record;

Record Type

Ada record types are not extensible through inheritance. Without the reserved word tagged the record does not belong to an inheritance hierarchy.

type Point is record
   X : Integer := 0;
   Y : Integer := 0;
end record;

Parameterized Types

An Ada record type can contain a discriminant. The discriminant is used to choose between internal structural representations. Parameterized types were introduced to Ada before tagged types. Inheritance is generally a cleaner solution to multiple representations than is a parameterized type.

type Person (Gender : Gender_Type) is record
   Name   : Name_String;
   Age    : Natural;
   Weight : Float;
   Case Gender is
      when Male =>
         Beard_Length : Float;
      when Female =>
         null;
   end case;
end record;

In this case every person will have the attributes of gender, name, age, and weight. A person with a Male gender will also have a beard length.

BASIC

Interpeter: QuickBasic 4.5, PB 7.1

TYPE Point
  x AS INTEGER
  y AS INTEGER
END TYPE

C

Compiler: GCC, MSVC, BCC, Watcom

Libraries: Standard

 typedef struct Point
 {
   int x;
   int y;
 } Point;

C++

Compiler: GCC, Visual C++, BCC, Watcom

 // C++ style: typedef is not required
 struct Point
 {
   int x;
   int y;
 };
 // C style
 typedef struct Point
 {
   int x;
   int y;
 } Point;

C#

 // Implicit: [StructLayout(LayoutKind.Sequential, Pack = 1)]
 struct Point
 {
   public int x, y;
   public Point() { x = 0; y = 0; }
   public Point(int x0) { x = x0; y = 0; }
   public Point(int x0, int y0) { x = x0; y = y0; }
 }
 // Verbose version
 .class public sequential ansi sealed beforefieldinit Point
 extends [mscorlib]System.ValueType
 {
   public int x, y;
   public Point() { x = 0; y = 0; }
   public Point(int x0) { x = x0; y = 0; }
   public Point(int x0, int y0) { x = x0; y = y0; }
 }
 public static Point ReadFromFileStream(FileStream fs)
 {
   // Create a buffer
   byte[] buffer = new byte[Marshal.SizeOf(typeof(Point))]; 
   // Read bytes into the buffer...
   fs.Read(buffer, 0, Marshal.SizeOf(typeof(Point)) );
   // Make sure that the Garbage Collector does not move the buffer 
   GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned);
   // Marshal the bytes
   Point point = (Point)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Point)); 
   // Give control of the buffer back to the Garbage Collector 
   handle.Free(); 
   return point;
 }
 public static Point ReadFromBinaryReader(BinaryReader br)
 {
   //Read byte array
   byte[] buffer = br.ReadBytes(Marshal.SizeOf(typeof(Point)));
   //Make sure that the Garbage Collector doesn't move our buffer 
   GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
   //Marshal the bytes
   Point point = (Point)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Point));
   // Give control of the buffer back to the Garbage Collector 
   handle.Free(); 
   return point;
 }
 // Improve speed by using PointSize
 internal sealed class PointSize
 {
   public static int size;
   static PointSize()
   {
     size = Marshal.SizeOf(typeof(Point));
   }
   public static int Size
   {
     get
     {
       return size;
     }
   }
 }

D TODO

Compiler: DMD,GDC

Forth TODO

Fortran TODO

IDL

point = {x: 6 , y: 0 } 
point.y = 7
print, point
;=> {       6       7}

Java TODO

// The byte structure format does not exist natively --> TODO.
public class Point
{
  public int x, y;
  public Point() { this(0); }
  public Point(int x0) { this(x0,0); }
  public Point(int x0, int y0) { x = x0; y = y0; }
  public static void main(String args[])
  {
    Point point = new Point(1,2);
    System.out.println("x = " + point.x );
    System.out.println("y = " + point.y );
  }
}

JavaScript TODO

 var point = new Object();
 point.x = 1;
 point.y = 2;

JSON TODO

 var point = {
   x:1,
   y:2
 };

Perl TODO

Interpeter: Perl

 # Please verify the code above... (from CPAN docs, not tested)
 # Using Inline::Struct with C code embedded
 use Inline C;
 my $point = new Inline::Struct::Point(1,2);
 
 __C__
 typedef struct Point 
 {
   int x;
   int y;
 };
 # Using Inline C, Struct
 use Inline C => <<'END', ENABLE => 'STRUCTS';
 struct Point {
   int x;
   int y;
 };
 END

 my $point = Inline::Struct::Point->new(1,2);
 print $point->x, $point->y, "\n";
 # Using bytes packed data with pack/unpack
 my $point = pack("ii", 1, 2);
 my ($x, $y) = unpack("ii", $point);
 # Using Win32::API::Struct
 use Win32::API;
 Win32::API::Struct->typedef( 'Point', qw(
   int x;
   int y;
 ));
 # Declarative
 my $point = new Win32::API::Struct->new( 'Point' );
 $point->{x} = 1;
 $point->{y} = 2;
 # Tie
 tie %point, 'Win32::API::Struct', 'Point';
 $point{x} = 1;
 $point{y} = 2;


 # Using C::DynaLib::Struct
 use C::DynaLib::Struct;
 Define C::DynaLib::Struct('Point', 'ii', [qw(x y)]);  
 # Using C::Include
 use C::Include qw(point.h -cache);
 my $point = $include->make_struct( 'Point' );
 point.h:
 #ifdef __PERL__
 // Anything that should be parsed by C::Include only
 #endif
 typedef struct Point { int x; int y; } Point;


 ### The code below does not create a "binary" like structure.
 # Using Class::Struct
 use Class::Struct;
 struct Point => [ x => '$', y => '$' ];
 my $point = new Point( x => 1, y => 2 );
 # Using a hash for storage
 my %point = ( x => 1, y => 2);

PHP TODO

 # Using pack/unpack 
 $point = pack("ii", 1, 2);
 $u = unpack("ix/iy", $point);
 echo $x;
 echo $y;
 list($x,$y) = unpack("ii", $point);
 echo $x;
 echo $y;

Tcl

This appears to be a sub-functionality of a proper associative array:

 array set point {x 4 y 5}
 set point(y) 7
 puts "Point is {$point(x),$point(y)}"
 # => Point is {4,7}

OCaml TODO

 type json point = < x: int; y: int >