Welcome to MSDN Blogs Sign in | Join | Help

Demonstrating Object Serialization

Assuming you know the rules for Object Serialization, my aim in this article is to write an app in J# which does Object Serialization and then I shall decipher the serialized data.

 

Below is the app which does the object serialization. This app is inspired from :

 

// Demonstrates Object Serialization

 

import java.io.*;

import java.util.*;

 

class Store implements Serializable {

  private int n;

  public Store(int n) { this.n = n; }

  public String toString() { return Integer.toString(n); }

}

 

public class link implements Serializable {

  private static int next_int = 0;

  private Store[] d = {

    new Store(next_int++),

    new Store(next_int++),

    new Store(next_int++)

  };

  private link next;

  private char c;

  // Value of i == number of segments

  public link(int i, char x) {

    c = x;

    if(--i > 0)

      next = new link(i, (char)(x + 1));

  }

  public link() {}

 

  public static void main(String[] args) throws ClassNotFoundException, IOException {

    link w = new link(4, 'a');

 

    ObjectOutputStream out = new ObjectOutputStream(

      new FileOutputStream("link.out"));

 

    out.writeObject(w);

    out.close();

  }

}

 

 

Now using the app from my previous post, when I try to read the contents of the output file link.out, I get the following result:

 

 

>file_bytes.exe link.out

 

ac  ed  0  5  73  72  0  4  6c  69  6e  6b  c8  f1  6d  e  38  aa  2f  ca  2  0  3  43  0  1  63  5b  0  1  64  74  0  8  5b  4c  53  74  6f  72  65  3b  4c  0  4  6e  65  78  74  74  0  6  4c  6c  69  6e  6b  3b  78  70  0  61  75  72  0  8  5b  4c  53  74  6f  72  65  3b  29  20  b6  39  0  37  55  a0  2  0  0  78  70  0  0  0  3  73  72  0  5  53  74  6f  72  65  ee  f5  85  2f  82  b5  ab  5a  2  0  1  49  0  1  6e  78  70  0  0  0  0  73  71  0  7e  0  6  0  0  0  1  73  71  0  7e  0  6  0  0  0  2  73  71  0  7e  0  0  0  62  75  71  0  7e  0  4  0  0  0  3  73  71  0  7e  0  6  0  0  0  3  73  71  0  7e  0  6  0  0  0  4  73  71  0  7e  0  6  0  0  0  5  73  71  0  7e  0  0  0  63  75  71  0  7e  0  4  0  0  0  3  73  71  0  7e  0  6  0  0  0  6  73  71  0  7e  0  6  0  0  0  7  73  71  0  7e  0  6  0  0  0  8  73  71  0  7e  0  0  0  64  75  71  0  7e  0  4  0  0  0  3  73  71  0  7e  0  6  0  0  0  9  73  71  0  7e  0  6  0  0  0  a  73  71  0  7e  0  6  0  0  0  b  70 

Total no of bytes read :286

 

Now, let us decipher this data. I would use “à” as a notation for “implies”

 

 

ac ed à STREAM MAGIC

0 5  à STREAM VERSION

 

73 à Terminal constant for OBJECT

72 à Terminal constant for CLASSDESC

 

0  4 à length of the class name (“link”)

 

6c  69  6e  6b  à ‘l’  ‘i’  ‘n’  ‘k’

 

c8  f1  6d  e  38  aa  2f  ca  à serialVersionUID

 

2 à serializable flag

 

0  3 à No of serializable fields in class “link”

 

43 à  ‘C’ , primitive type code for Char

 

0  1 à length of the char field name i.e 1 here

 

63 à ‘c’ , name of the char field

 

5b à ‘[‘ , object type code for array

 

0  1 à length of the array field name i.e 1 here

 

64 à ‘d’ , name of the array field

 

74 à Terminal constant for STRING

 

0  8 à Length of type name is 8

 

5b  4c  53  74  6f  72  65  3b  à ‘[‘  ‘L’  ‘S’  ‘t’  ‘o’  ‘r’  ‘e’  ‘;’ (field descriptor format)

 

4c à ‘L’ , object type code for object

 

0  4 à length of the object field name i.e 4 here

 

6e  65  78  74  à ‘n’  ‘e’  ‘x’  ‘t’

 

74 à Terminal constant for STRING

 

0  6 à Length of type name is 6

 

4c  6c  69  6e  6b  3b à ‘L’  ‘l’  ‘i’  ‘n’  ‘k’  ‘;’ (field descriptor format)

 

78  à Terminal constant for ENDBLOCKDATA

70  à Terminal constant for NULL (null reference for super class)

 

0  61  à char value is ‘a’

 

75  à Terminal constant for ARRAY

72  à Terminal constant for CLASSDESC

 

0  8 à Length of type name is 8

 

5b  4c  53  74  6f  72  65  3b  à ‘[‘  ‘L’  ‘S’  ‘t’  ‘o’  ‘r’  ‘e’  ‘;’ (field descriptor format)

 

29  20  b6  39  0  37  55  a0  à serialVersionUID

 

2 à serializable flag

 

0  0  à No of serializable fields in the array class

 

78  à Terminal constant for ENDBLOCKDATA

70  à Terminal constant for NULL (null reference for super class)

 

0  0  0  3  à No of fields in the array

 

73 à Terminal constant for OBJECT

72 à Terminal constant for CLASSDESC

 

0  5 à String length of “Store”

 

53  74  6f  72  65  à ‘S’  ‘t’  ‘o’  ‘r’  ‘e’

 

ee  f5  85  2f  82  b5  ab  5a  à serialVersionUID

 

2 à serializable flag for Store class

 

0  1 à No of serializable fields in Store class

 

49  à ‘I’ , primitive type code for integer

 

0  1 à length of the char field name i.e 1 here

 

6e à ‘n’ , name of the char field in Store class

 

78  à Terminal constant for ENDBLOCKDATA

70  à Terminal constant for NULL (null reference for super class)

 

0  0  0  0 à int value of the field ‘n’ ( which is 0 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  1 à int value of the field ‘n’ ( which is 1 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  2  à int value of the field ‘n’ ( which is 2 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  0  à handle to the link class

 

0  62  à char value is ‘b’

 

75 à Terminal constant for ARRAY

71 à Terminal constant for REFERENCE

 

0  7e  0  4  à handle to the array class

 

0  0  0  3  à No of fields in the array

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  3  à int value of the field ‘n’ ( which is 3 here )

 

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  4  à int value of the field ‘n’ ( which is 4 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  5  à int value of the field ‘n’ ( which is 5 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  0  à handle to the link class

 

0  63  à char value is ‘c’

 

75 à Terminal constant for ARRAY

71 à Terminal constant for REFERENCE

 

0  7e  0  4  à handle to the array class

 

0  0  0  3  à No of fields in the array

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  6  à int value of the field ‘n’ ( which is 6 here )

 

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  7  à int value of the field ‘n’ ( which is 7 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  8  à int value of the field ‘n’ ( which is 8 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  0  à handle to the link class

 

0  64  à char value is ‘d’

 

75 à Terminal constant for ARRAY

71 à Terminal constant for REFERENCE

 

0  7e  0  4  à handle to the array class

 

0  0  0  3  à No of fields in the array

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  9  à int value of the field ‘n’ ( which is 9 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  a  à int value of the field ‘n’ ( which is 10 here )

 

73 à Terminal constant for OBJECT

71  à Terminal constant for REFERENCE

 

0  7e  0  6  à handle to the Store class

 

0  0  0  b  à int value of the field ‘n’ ( which is 11 here )

 

70 à Terminal constant for NULL ( for the “next” member of this link object)

 

 

 

Posted by premk | 1 Comments

Display Raw Contents of a file

Sometimes you just want to see the raw contents of a file. This is especially useful when you don’t have any cool editor/program which can read that file and present the contents in some useful manner. Like you may want to see contents of a zipped file or contents of a file that contains serialized data of an object.

 

The following J# program reads the content of the file and outputs the same on the standard output console. All the bytes read are written in hex format. It also tells you the no of bytes read from the file.

 

 

 

import java.io.*;

 

public class file_bytes

{

      public static void main(String[] args) throws FileNotFoundException, IOException

      {

            FileInputStream fi = new FileInputStream(args[0]);

            int read_byte;

            int length = 0;

            while ((read_byte = fi.read()) != -1)

            {

                  System.out.print(Integer.toHexString(read_byte) + "  ");

                  length++;

            }

            System.out.print("\n");

            System.out.print("Total no of bytes read :" + length);

 

      }

} 

 

 

All you need to do is to compile this file using the J# compiler ( vjc.exe ) which would be usually present at the windir\Microsoft.NET\Framework\version where windir identifies your Windows directory and version is a version number identifying a specific version of the .NET Framework.

 

Then while executing the generated exe, give the complete path of the file whose contents you want to read.

 

For example, using notepad I created a file whose contents are simply :

Let us see what happens!

 

Suppose the file is stored as test.txt at C:\temp\

 

Now, if my exe created after compiling the above J# program is “file_bytes.exe”, then all I need to do is run my exe as :

 

file_bytes.exe "C:\\temp\\test.txt"

 

and I see the output as :

 

4c  65  74  20  75  73  20  73  65  65  20  77  68  61  74  20  68  61  70  70  65  6e  73  21

 

Total no of bytes read :24

 

Now, lets do something interesting here. I zipped the test.txt file using the WinZip and save it as test.zip at the same location.

 

Now if I run the my exe as :

file_bytes.exe "C:\\temp\\test.zip"

 

I see the output as :

 

 

50  4b  3  4  a  0  0  0  0  0  78  73  7c  34  ea  97  1  f7  18  0  0  0  18  0  0  0  8  0  0  0  74  65  73  74  2e  74  78  74  4c  65  74  20  75  73  20   73  65  65  20  77  68  61  74  20  68  61  70  70  65  6e  73  21  50  4b  2  14  0  a  0  0  0  0  0  78  73  7c  34  ea  97  1  f7  18  0  0  0  18  0   0  8  0  0  0  0  0  0  0  1  0  20  0  0  0  0  0  0  0  74  65  73  74  2e  74  78  74  50  4b  5  6  0  0  0  0  1  0  1  0  36  0  0  0  3e  0  0  0  0  0

 

Total no of bytes read :138

 

As you can see, this time contents of the file grew larger than what it was !

 

Check my next blog which would use this app to demonstrate Object Serialization.

Posted by premk | 3 Comments

IEEE-754 Floating point --> Special values and Ranges

As I mentioned in my previous blog, we shall now discuss details regarding range of values for IEEE-754 floating point numbers, Denormalized forms, NAN and a simple algorithms for conversion between IEEE-754 hexadecimal representations and decimal Floating-Point Numbers.

 

Let’s take a look at the special values in IEEE-754 floating point representation.

 

Special values:

 

Exponent field values of all 0s and all 1s are used to denote special values in this scheme

 Zero

Zero is represented with an exponent field of zero and a mantissa field of zero. Depending on the sign bit, it can be a positive zero or a negative zero. Thus, -0 and +0 are distinct values, though they are treated as equal.

 

 Infinity

Infinity is represented with an exponent of all 1s and a mantissa of all 0s. Depending on the sign bit, it can be a positive infinity(+¥) or negative infinity (-¥). The infinity is used in case of the saturation on maximum representable number so that the computation could continue.

 

 NaN

The value NaN (Not a Number) is used to represent a value that does not represent a real number. They are used in computations that generate undefined results so that with NaN the operations are defined for it to let the computations continue. NaN's are represented by a bit pattern with an exponent of all 1s and a non-zero mantissa. There are two categories of NaN: QNaN (Quiet NaN) and SNaN (Signalling NaN).

 

A QNaN is a NaN with the most significant fraction bit set (denotes indeterminate operations).

 

An SNaN is a NaN with the most significant fraction bit clear (denotes invalid operations).

 

 Denormalized

If the exponent is all 0s, and the mantissa is non-zero, then the value is treated as a denormalized number. The denormalized numbers does not have an assumed leading 1 before the binary point. For Single precision, this represents a number (-1)s × 0.m × 2-126, where s is the sign bit and m is the mantissa. For double precision, it represents as (-1)s × 0.m × 2-1022.

 

 

Thus, following are the values corresponding to a given representation:

(Note that b used in the table is the bias)

 

Sign(s)

Exponent (e)

Mantissa (m)

Range  for Single Precision values in binary

Range Name

1

11..11

10..00
:
11.11

 

__

QNaN

1

11..11

00..01
:
01..11

 

__

SNaN

1

11..11

00..00

 

< -(2-2-23) × 2127

-Infinity

(Negative Overflow)

1

11..10
:
00..01

11..11
:
00..00

-(2-2-23) × 2127
:
-2-126

Negative Normalized

-1.m × 2(e-b)

1

00..00

11..11
:
00..01

-(1-2-23) × 2-126
:
-2-149

Negative Denormalized
-0.m × 2(-b+1)

__

__

__

-2-150
:
< -0

Negative Underflow

1

00..00

00..00

-0

-0

0

00..00

00..00

+0

+0

__

__

__

> +0
:
2-150

Positive Underflow

0

00..00

00..01
:
11..11

2-149
:
 (1-2-23) × 2-126

Positive Denormalized
0.m × 2(-b+1)

0

00..01
:
11..10

00..00
:
01..11

2-126
:
(2-2-23) × 2127

Positive Normalized

1.m × 2(e-b)

0

11..11

00..00

> (2-2-23) × 2127

+Infinity

(Positvie Overflow)

0

11..11

00..01
:
01..11

 

__

SNaN

0

11..11

10..00
:
11.11

 

__

QNaN

 

 

Range:

 

As, mentioned in the table above, range for the positive normalized no for single precision float is

2-126  to (2-2-23) × 2127  . Note that the bias(b) here is 127.

 

Let’s see how did we arrive we arrive at these ranges. As mentioned table above, the positive normalized form would be represented as 1.m × 2(e-b)   where m is mantissa, e is exponent and b is bias.

 

Thus, smallest normalized no for single precision would come out as 1.0…0( all 0’s after decimal)  x 21-127 such that mantissa is 0 as and exponent is 1, thus:

 

1.0 x 21-127 à   2-126   

 

Now, the largest normalized no for single precision would come out as 1.1…..1( 23 1’s after decimal) x 2254-127 such that mantissa is all ones and exponent is also all 1s except the least significant bit(254), thus this no equals :

 

1……1( 24 ones)                                                224  - 1

-----------------------       x  2254-127         à        --------------     X   2127       à     (2-2-23) × 2127

              223                                                              223

 

Again as mentioned in the table above, range for the positive denormalized no for single precision float is 2-149  to  (1-2-23) × 2-126 .Note that the bias(b) here is 127 and denormalized form would be represented as: 0.m × 2(-b+1)

 

Thus, smallest denormalized no for single precision would come out as 0.00…..1 x 2-127+1 such that mantissa has all the bits as 0 except the least significant bit and exponent is anyways 0, thus:

 

0.00…..1 x 2-127+1 à   2-23  x  2-126  à  2-149 

 

And the largest denormalized no for single precision would come out as 0.11…..1 x 2-127+1 such that mantissa has all the bits as 1 and exponent is anyways 0, thus:

 

1……1( 23 ones)                                                223  - 1

-----------------------       x  2-127+1         à         --------------     X   2-126       à     (1-2-23) × 2-126

              223                                                              223

 

Similarly, you can derive the ranges for double precision floats as well. The following table shows the ranges for the single as well the double precision floats for their positive as well as negative values.

 

 

Single Precision

Double Precision

Normalized form

± 2-126 to (2-2-23)×2127

± 2-1022 to (2-2-52)×21023

Denormalized form

± 2-149 to (1-2-23)×2-126

± 2-1074 to (1-2-52)×2-1022

 

 

 

Algorithms:

 

Let’s take a look into an algorithm(written in C++) which takes a 32-bit integer (which contains the simple bit representation for a single precision float) and returns an equivalent float value.

 

     float single_float_from_storage_bits(int storagebits)

     {

         //Check the sign bit and assign the same to sign

         int sign = ((storagebits & 0x80000000) == 0) ? 1 : -1;

         // get the exponent value, bit postion 30 - 23

         int exponent = ((storagebits & 0x7f800000) >> 23);

         // get the mantissa value, bit position 22 - 00

         int mantissa = (storagebits & 0x007fffff);

         //if exponent is 0, it could be either 0 or denormalized form.

         if (exponent == 0)

         {

             // since matissa is also 0, definitely this is a 0

             if (mantissa == 0)

             {

                 // We would decide +ve or -ve 0 depending on sign

                 return (sign * 0.0f);

             }

             else

                 // else return the calculated denormalized value

                 return (float)(sign * mantissa * pow(2, -149));

             }

         //if exponent is all 1, then it could be either Infinity or NaN

         else if (exponent == 0xff) 

         {

             //if mantissa is 0, then it is +infnity or -infinity

             if (mantissa == 0)

             {

                 // Use sign to decide +infnity or -infinity

                 return ((sign == 0) ? -INFINITY : +INFINITY) ;

             }

             // Else its a NaN, you can also check SNaN or QNan here

             else return NaN;

         }

         // Now we are sure this is a Normalized no

         else

         {

             // add the implied 24th bit of mantissa here

             mantissa |= 0x00800000;

             // return the normalized form here

             return (float)(sign * mantissa * pow(2, exponent-150));

         }

     }

 

In a similar manner, you can do the vice versa, i.e given a single precision float, you can find out its storage bits representation layout.

Posted by premk | 5 Comments

IEEE Standard 754 for Floating Point Numbers

This article specifies how single precision (32 bit) and double precision (64 bit) floating point numbers are to be represented as per IEEE Standard 754.

 

Floating point Representation:

 

Floating-point representation represents real numbers in scientific notation. Scientific notation represents numbers as a base number and an exponent. For example, in decimal, 123.456 could be represented as 1.23456 × 102.

In binary, the number 1100.111 might be represented as 1.10111 × 23. Here, the value part i.e. 1.10111 is referred to as “mantissa” and the power part, i.e. 3 is called “exponent”. 2 here is referred as base of the exponent.

From the storage layout point of view, floating point numbers have three components: the sign, the exponent, and the mantissa.

IEEE floating point numbers come in two sizes, 32-bit single precision and 64-bit double precision numbers. The layouts for the parts of a floating point number are:

Single-Precision

Sign

Exponent

Fraction

Bit Positions

31

30-23

22-00

Number of bits

1

8

23

Bias

127

Double-Precision

Sign

Exponent

Fraction

Bit Positions

63

62-52

51-00

Number of bits

1

11

52

Bias

1023

 

The Sign

A zero in the sign bit indicates that the number is positive; a one indicates a negative number.

The Exponent

 

The exponent base 2 is implicit and is not stored. In order to keep things simple, the exponent is not stored as a signed number. To accomplish the same, a bias is added to the actual exponent in order to get the stored exponent. A single-precision number uses eight bits for the exponent, so it should be capable of storing exponents ranging from -127 through +127. But the value actually stored is the exponent plus the bias. Thus, the bias for single precision numbers is 127. Similarly, the bias for double precision numbers is 1023. This means that the value stored will range from zero to 255 for a single, and zero to 2047 for a double.

    For example, in case of single precision float, a stored exponent of 150 means that the actual exponent is 23.

    It also needs to be noted that exponents of having all the bits as 0 or having all the bits as 1 are used for special numbers.

 

The Mantissa

 

The mantissa represents the precision bits of the number. It has an implicit leading bit (1) and the fraction bits.

    To find out the value of the implicit leading bit, consider that a binary number can be expressed in scientific notation in different ways like 1.0011 x 23 or 100.11 x 21. Now, the mantissa is normalized so that the most significant digit is just to the left of the decimal point. Since in case of binary, the only possible non-zero digit is 1, the leading digit of 1 can be ignored, and does not need to be represented explicitly. As a result, the mantissa for example in case of single precision float has effectively 24 bits of resolution, by way of 23 fraction bits.

 

Thus,

 

  • The sign bit is 0 for positive, 1 for negative.
  • The exponent's base is two.
  • The exponent field contains bias plus the true exponent
  • The mantissa would always looks like 1.f, where f is the field of fraction bits.

 

Now, let’s see what goes into 32 bits of a single precision float when we assign 2865412.25 to it:

 

First, get the sign:

Since the sign of the number is positive, a 0 goes into the top bit.

Second, convert the number to binary:

2865412.25 is 1010111011100100000100. 01 in binary (2865412 converted to binary is 1010111011100100000100, and .25 decimal is .01 = {0 * 2-1  + 1 * 2-2 } in binary.)

Third, normalize the number:

We can normalize the binary to 1.01011101110010000010001 * 221

Fourth, store the exponent:

Adding in the bias, the exponent will be stored as 21 + 127 = 148, or 10010100 written in binary.

Fifth, store the mantissa

The mantissa is handled by dropping the most significant bit, leaving us with . 01011101110010000010001. Since, we can now take the next 23 bits allowed for mantissa, we have the mantissa as :

     0101 1101 1100 1000 0010 001

     or 2EE411 in hexadecimal.

 

 

Thus, the result is stored in 32-bits as :

 

Sign

Exponent

Mantissa

0

10010100

0101 1101 1100 1000 0010 001 

i.e 4A2EE411 in hex.

 

You can also visit the following link which provides visual tool to covert IEEE-754 hexadecimal representations to decimal Floating-Point Numbers and vice versa and gives awesome details of all the components:

 

http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html

 

Check my next blog which would contain details regarding range of values for IEEE-754 floating point numbers, Denormalized forms, NAN and some simple algorithms for conversion between IEEE-754 hexadecimal representations and decimal Floating-Point Numbers.

Posted by premk | 5 Comments

Some Insights into Delegates from J# perspective

It needs to be noted that the classes com.ms.lang.Delegate, System.Delegate or System.Multicast Delegate are all abstract classes. Hence, we cannot create instances of com.ms.lang or System.Delegate classes with the “new” keyword.

 

When we declare a delegate using the “delegate” keyword, compiler generates a non-abstract class derived from the com.ms.lang.Delegate type if @delegate is not used else from the class is derived from System.Delegate type. Since, this delegate is a non-abstract class, it can go as the upper level class. Also, now you can create their instances with the “new” keyword supplying them necessary instantiating parameters as required.

 

However, if you use syntax like:

 

com.ms.lang.Delegate del1;

System.Delegate del2;

 

They are only references to the corresponding types and hence cannot be used as the top level class. They need to go inside some class as its member. However, they can be definitely assigned the reference to delegate object whose delegate class was generated through the “delegate” keyword and that was instantiated with the new” keyword.

 

Last but not the least, Delegate class itself does not have a invoke method. This method is injected by the compiler while generating a non-abstract delegate class when it encounters the “delegate” keyword. Hence, the only way to create a delegate class (which is non-abstract) during compilation is to use the “delegate” keyword.

 

For example following code snippet works just fine.

 

 

 

// compiler would generate SampleDelegate as a non-abstract

// class derived from com.ms.lang.Delegate

delegate void SampleDelegate(int a, int b);

 

// commented since its just a refrence

// hence, cannot keep it here

/* com.ms.lang.Delegate del; */

 

 

public class test {

      com.ms.lang.Delegate del;

 

      public void greater( int a, int b ) {

            if (a > b)

                System.out.println("Greater");

            else

            System.out.println("Small");

      }

 

      public static void main(String args[])

      {

        test t = new test();

          // Commented as this would give error

          // since Delegate here is an abstract class

            /* t.del = new com.ms.lang.Delegate(); */

 

            t.del = new SampleDelegate(t.greater);

 

            // won't work b'se com.ms.lang.Delegate itself does not

            // have invoke member method, this method is generated

            // by the compiler into the newly generated class during  compilation

            /* t.del.invoke(21, 20); */

 

            ((SampleDelegate)(t.del)).invoke(21, 20);

            try

            {

                  t.del.dynamicInvoke(new Object[] { new Integer(21), new Integer(20) });

            }

            catch (Exception e)

            {

                  e.printStackTrace();

            }

      }

}              

 

 

You can also refer to the following link for more info on Delegates :

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/bjthedel.asp

 

Posted by premk | 1 Comments

Some differences between com.ms.lang.Delegate and System.Delegate type in J#

Firstly, instance “invoke” function has different case letters in them:

 

com.ms.lang.Delegate à invoke

System.Delegate à Invoke

 

Also, the static functions combine and Remove have different case letters:

 

com.ms.lang.Delegate à combine

com.ms.lang.Delegate à remove

 

System.Delegate àCombine

System.Delegate àRemove

 

Moreover, delegates of com.ms.lang.Delegate type are binded at runtime, while System.Delegates are binded at compile time (until we are not using

System.Delegate.CreateDelegate calls directly).

 

Hence, the following code snippet compiles fine but throws runtime exception for com.ms.lang.types saying :

 

java.lang.IllegalArgumentException: Error binding to target method

 

as there is no function named : “lower” here.

 

 

 

delegate void check(int a, int b);

 

public class test {

 

    public void greater( int a, int b ) {

        if (a > b)

            System.out.println("Greater");

        else

            System.out.println("Small");

    }

 

    public static void main(String args[])

    {

        test t = new test();

        check ch = new check(t, "lower");

        ch.invoke(21, 20);

    }

}

   

 

 

While the following code snippet gives the compiler error saying :

 

error VJS1223: Cannot find method 'lower(int, int)'

 

 

 

/**@delegate*/

delegate void check(int a, int b);

 

public class test

{

 

    public void greater(int a, int b)

    {

        if (a > b)

            System.out.println("Greater");

        else

            System.out.println("Small");

    }

 

    public static void main(String args[])

    {

        test t = new test();

        check ch = new check(t, "lower");

        ch.Invoke(21, 20);

    }

}

 

 

Posted by premk | 4 Comments

How to create System.Delegate in J#

Creating System.Delegate in J#

 

Single-cast Delegate

 

Single-cast delegate derived from System.Delegate are created using the @delegate directive. The default delegate in J# are the ones derived from com.ms.lang.Delegate(without using the @delegate directive). If one however wants to explicitly declare a delegate of the System.Delegate type, then the @delegate directive has to be used before the delegate definition.

For example, here SampleDelegate has been declared to be of type System.Delegate :

 

/**@delegate*/

delegate int SampleDelegate(int a, int b);

 

Muti-cast Delegate

 

It needs to be noted that Single-cast and multi-cast delegates of the com.ms.lang.Delegate type are different with respect to each other. However, in case of System.Delegate type, single-cast and multi-cast delegates are not separate entities and hence when declaring multicast delegate of the System.Delegate type there is no need to use the keyword “multicast” as in case of com.ms.lang.Delegate type.

 

Hence, syntax for the multicast delegate here still remains the same:

 

/**@delegate*/

delegate int SampleDelegate(int a, int b);

 

Hence, single-cast and multi-cast delegate of the System.Delegate are one and the same thing. Both can be a part of the link list and also their return values can be anything. In case return value is not void, the return value of the last called method is returned.

 

Hence, the following program works just fine:

 

/**@delegate*/

delegate int SampleDelegate(int a, int b);

 

public class test

{

      public int greater(int a, int b)

      {

            if (a > b)

                  System.out.println("Greater");

            else

                  System.out.println("Small");

 

            return a;

      }

 

      public int lower( int a, int b)

      {

            return b;

      }

 

      public static void main(String args[])

      {

            test t = new test();

 

            SampleDelegate ch3 = new SampleDelegate(t, "greater");

            SampleDelegate ch4 = new SampleDelegate(t, "lower");

 

            SampleDelegate ch6 = (SampleDelegate)System.Delegate.Combine(ch3, ch4);

 

            System.out.println(ch6.Invoke(3, 4));

      }

}

 

 

Posted by premk | 1 Comments

How to create com.ms.lang.Delegate in J#

Creating com.ms.lang.Delegate in J#

 

Single-cast Delegate

 

Single-cast Delegate derived from com.ms.lang.Delegate calls only one function. This delegate type represents objects that cannot be chained together in an invocation list.

   The Syntax for the single-cast delegate is shown below:

 

        delegate int TestDelegate (int a, int b);

 

As you can see, the “delegate” keyword is used to declare a Single cast delegate derived from com.ms.lang.Delegate. When compiler encounters the above statement, it will create a new class called TestDelegate which as said, would have been derived from com.ms.lang.Delegate.

 

 Since, this type of Delegate cannot be combined, hence combining it with any other delegate will throw an exception saying:

 

com.ms.lang.MulticastNotSupportedException: class check does not support multicasting

 

For example, following program would throw an exception as mentioned as above:

 

 

 

import com.ms.lang.*;

 

delegate void check(int a, int b);

 

public class test

{

      public void greater(int a, int b)

      {

            if (a > b)

                  System.out.println("Greater");

            else

                  System.out.println("Small");

      }

 

      public void lower( int a, int b)

      {

            return;

      }

 

      public static void main(String args[])

      {

            test t = new test();

            check ch = new check(t, "greater");

            check ch1 = new check(t, "lower");

            Delegate.combine(ch, ch1);

      }

}

 

   

 

Multicast Delegates

   

    Multicast Delegates derived from com.ms.lang.Delegates can be a part of the link list and always points to the head of the link list. The Syntax for the single-cast delegate is shown below:

 

    multicast delegate void TestDelegate (int a, int b);

 

As you can see “multicast” keyword along with “delegate” keyword is used while declaring a multicast delegate in J#. The return type of this muticast delegate cannot be anything else than void else VJ# compiler: vjc compiler would throw an error.

 

It needs to be noted that only delegates which are of the same type (i.e. which belongs to the same class) can be combined. You can also not combine a mutlicast and a single-cast delegate. For example, the following program would an exception saying:

 

java.lang.IllegalArgumentException: cannot combine Delegates of different types

   

 

 

import com.ms.lang.*;

 

multicast delegate void multi_check(int a, int b);

delegate void single_check(int a, int b);

 

public class test

{

      public void greater(int a, int b)

      {

            if (a > b)

                  System.out.println("Greater");

            else

                  System.out.println("Small");

      }

 

      public void lower( int a, int b)

      {

            return;

      }

 

      public static void main(String args[])

      {

            test t = new test();

            multi_check ch = new multi_check(t, "greater");

            single_check ch1 = new single_check(t, "lower");

            Delegate.combine(ch, ch1);

            ch.invoke(21, 20);

      }

}

 

Posted by premk | 1 Comments

Primer - Delegates in J#

Primer - Delegates in J#

 

In next couple of posts i will discuss about delegates in J# starting from basic introduction, different types, and finally discuss some examples around delegates.

 

Here is the first section of this primer...As always feel free to send in your comments, questions and feedback!

 

Delegates in J#

 

    Delegates are .NET version of the callback function. Unlike callback mechanism used in other platforms such as C/C++, delegates offer much more functionality. For example in Unmanaged C/C++, the address of a function is just a memory address. This address doesn’t carry along any information, such as the number of parameters the function expects, the types of these parameters, the functions return value type, and the functions calling convention. In short, unmanaged C/C++ callback functions are not type safe.

    However, Delegates in .NET ensures that the callback method is type safe and it also integrates the ability to call the multiple methods serially and support calling of static methods as well as instance methods.

 

    It needs to be noted that delegates are compiled into classes and hence the instances of delegates are treated like any other class instance.

 

Two Different Delegates types in J#

 

    It needs to be noted that in case of J# the binding of delegates is done at runtime (shall talk more on this later). It also needs to be noted that when we use the delegate and the multicast delegate keywords to declare single cast and multicast delegate in J#, the delegates that are created may be of the type com.ms.lang.Delegate or of the type System.Delegate depending on the declaration of the delegate.

 

In the next post, i will go in more details and talk about delegates derived from com.ms.lang.Delegate...

Posted by premk | 5 Comments

Who am I !

 

My name is Prem and I am working as a Software Design Engineer in Visual J# product team.

Visual J# is essentially one of the languages targeting .NET platform.

 

Visual J# is a powerful tool for Java-language developers who want to build applications and services on the Microsoft .NET Framework. Visual J# targets the new .NET Framework version 2.0 and is fully integrated with Visual Studio .NET.

 

I will try to share my thoughts, learning and experiences through my blogs.

 

Keep checking this out!

 

-Prem

 

Posted by premk | 0 Comments
 
Page view tracker