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
   char                m_str[80];  // 80 bytes ANSI string
   wchar_t             m_wstr[80]; // 80 wchar string (not sure if its UTF-16)
 } MyData;
 MyData foo = { -12, +12, -23456, +23456, -12345678, +12345678, -1234567890, +1234567890,
                  1, 2, 3.14159, 6.28318, 9.42477, "Hello world!", L"Hello world!" };

Ada

Compiler: GNAT GPL 2006

Task 1

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

Task 2

type Unsigned_8 is mod 2**8;
type Unsigned_16 is mod 2**16;
type Unsigned_32 is mod 2**32;
type Unsigned_64 is mod 2**64;
type Signed_8 is range -128..127;
type Signed_16 is range -(2**15)..(2**15 - 1);
type Signed_32 is range -(2**31)..(2**31 - 1);
type Signed_64 is range -(2**63)..(2**63 - 1);
type My_Data is record
   M_sch  : Signed_8;
   M_uch  : Unsigned_8;
   M_ss   : Signed_16;
   M_us   : Unsigned_16;
   M_sl   : Signed_32;
   M_ul   : Unsigned_32;
   M_sll  : Signed_64;
   M_ull  : Unsigned_63;
   M_si   : Integer;
   M_ui   : Unsigned_32;
   M_f    : Float;
   M_d    : Long_Float;
   M_ld   : Long_Long_Float;
   M_Str  : String(1..80);
   M_Wstr : Wide_String(1..80);
end record;

The Ada pragma Pack will compress the data, but may re-arrange the fields in memory. The only way to ensure a particular memory layout is to provide a representation clause. The representation clause allows the storage specification down to the bit level.

Word : constant := 4; -- storage element is byte, four elements per word
for My_Data use record
   M_sch at 0 * Word range 0..7;
   M_uch at 0 * Word range 8..15;
   M_ss  at 0 * Word range 16..31;
   M_us  at 1 * Word range 0..15;
   M_sl  at 1 * Word range 16..47;
   M_ul  at 2 * Word range 16..47;
   M_sll at 3 * Word range 16..79;
   M_ull at 5 * Word range 16..79;
   M_si  at 7 * Word range 16..47;
   M_ui  at 8 * Word range 16..47;
   M_F   at 9 * Word range 16..49;
   M_D   at 10 * Word range 18..81;
   M_Ld  at 12 * Word range 18..113; -- 96 bytes minimum
   M_Str at 15 * Word range 18..657;
   M_Wstr at 35 * Word range 18..1297;
end record;
Foo : My_Data :=(M_Sch => -12,         M_Uch => 12,
                 M_Ss  => -23456,       M_Us => 23456,
                 M_Sl  => -12345678,    M_Ul => 12345678,
                 M_Sll => -1234567890, M_Ull => 1234567890,
                 M_Si  => 1,            M_Ui => 2,
                 M_F   => 3.14159,      M_D  => 6.28318,
                 M_Ld  => 9.42477,      M_Str(1..12) => "Hello World!",
                 M_Wstr(1..12) => "Hello World!");

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


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;

OCaml TODO

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