Friday, January 21, 2011

Getting Java Class Version using Python

Getting Java class version is actually quite straightforward once we can understand the Java class format. For more information, see this link.

import struct, os, sys

java_versions = {'45.3' : '1.0',
                 '45.3' : '1.2',
                 '46.0' : '1.2',
                 '47.0' : '1.3',
                 '48.0' : '1.4',
                 '49.0' : '1.5',
                 '50.0' : '1.6'}

def __print_error(msg):
    print "Error:", msg
    sys.exit(1)
    
def get_java_version(class_file):
    if not os.path.exists(class_file):
        __print_error(class_file + " doesn't exist")
    
    f = open(class_file, 'rb')
    if (not struct.unpack('!i', f.read(4)) ==
        struct.unpack('!i', '\xca\xfe\xba\xbe')):
        __print_error("Invalid Java class file")
    minor = str(struct.unpack('!H', f.read(2))[0])
    major = str(struct.unpack('!H', f.read(2))[0])
    version = major + "." + minor      
    return java_versions[version]
                         
if __name__ == "__main__":
    if not len(sys.argv) == 2: __print_error("Invalid arguments")
    print get_java_version(sys.argv[1])

The most important thing to note here is that. The first 4 bytes (signed int) is the magic number, the next two bytes (unsigned short) is the minor version, and the next two bytes after that is the major version (unsigned short). This can also be easily coded in Java by using DataInputStream.

Thursday, January 20, 2011

Forward Declarations in C++

Using forward declarations in C++ can help to speed up the compilation time.

X.h
#ifndef X_H_
#define X_H_

class Y;

class X
{
public:
    X();
    void doYStuff(Y& y) const;
    void sayHello() const;
    virtual ~X();
};

#endif /* X_H_ */
Here we can use forward declare Y because we don't use any of the Y's members.

X.cpp
#include "X.h"
#include "Y.h"
#include <iostream>
using namespace std;

X::X()
{
}

X::~X()
{
}

void X::sayHello() const
{
    cout << "I'm X!" << endl;
}

void X::doYStuff(Y& y) const
{
    y.sayHello();
}
Here we need to include Y because we use the Y's member.

Y.h
#ifndef Y_H_
#define Y_H_

class X;

class Y
{
public:
    Y();
    void doXStuff(X& x) const;
    void sayHello() const;
    virtual ~Y();
};

#endif /* Y_H_ */
Here we can use forward declare X because we don't use any of the X's members.

Y.cpp
#include "Y.h"
#include "X.h"
#include <iostream>
using namespace std;

Y::Y()
{
}

Y::~Y()
{
}

void Y::sayHello() const
{
    cout << "I'm Y!" << endl;
}


void Y::doXStuff(X& x) const
{
    x.sayHello();
}
Here we need to include X because we use the X's member.

Main.cpp
#include <iostream>
#include "X.h"
#include "Y.h"
using namespace std;

int main()
{
    X x;
    Y y;

    x.doYStuff(y); // I'm Y!
    y.doXStuff(x); // I'm X!

    return 0;
}

Understanding C++ Type Casting

C++ has 4 different types of casting.
1. const_cast
This cast can used to cast away the the constant.
2. static_cast
This cast can be used to add constant, perform implicit conversion, and to convert from base-class to derived-class.
3. dynamic_cast
This cast can used to convert from derived-class to base-class.
4. reinterpret_cast
This cast can be used to perform conversion from one pointer to another unrelated pointer. This cast is normally used for low-level stuff and not portable.

Person.h
#ifndef PERSON_H_
#define PERSON_H_

#include <string>
using namespace std;

class Person
{
public:
    Person(string name);
    void sayHello() const;
    virtual ~Person();
protected:
    string name;
};

#endif /* PERSON_H_ */

Person.cpp
#include <iostream>
#include "Person.h"
using namespace std;

Person::Person(string name) : name(name)
{
    cout << "Person constructor is being called" << endl;
}

Person::~Person()
{
    cout << "Person destructor is being called" << endl;
}

void Person::sayHello() const
{
    cout << "Hello, " << this->name << endl;
}

Employee.h
#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_

#include "Person.h"

class Employee : public Person
{
public:
    Employee(string name);
    void doWhatever() const;
    virtual ~Employee();
};

#endif /* EMPLOYEE_H_ */

Employee.cpp
#include <iostream>
#include "Employee.h"
using namespace std;

Employee::Employee(string name) : Person(name)
{
    cout << "Employee constructor is being called" << endl;
}

Employee::~Employee()
{
    cout << "Employee destructor is being called" << endl;
}

void Employee::doWhatever() const
{
    cout << "Whatever!" << endl;
}

Main.cpp
#include <iostream>
#include "Person.h"
#include "Employee.h"
using namespace std;

void testReinterpretCast()
{
    cout << "=== Testing reinterpret_cast ===" << endl;
    char* str = "Hello";
    int i = reinterpret_cast<int>(str);
    cout << i << endl; // will print garbage
    str = reinterpret_cast<char*>(i);
    cout << str << endl; // get the value back

    cout << endl;
}


void testDynamicCast()
{
    cout << "=== Testing dynamic_cast ===" << endl;

    // derived-class to base-class
    Employee* e = new Employee("Employee");
    Person* p = dynamic_cast<Person*>(e);
    p->sayHello();
    delete e;

    cout << endl;
}

void testStaticCast()
{
    cout << "=== Testing static_cast ===" << endl;

    // force implicit conversion
    double d = 10.20;
    int i = static_cast<int>(d);
    cout << i << endl;
    // add constant
    const int ci = static_cast<const int>(i);
    cout << ci << endl;

    Person* p = new Person("Person");
    p->sayHello();
    delete p;

    cout << endl;

    // base-class to derived-class
    Person* e = new Employee("Employee");
    e->sayHello();
    Employee* e1 = static_cast<Employee*>(e);
    e1->doWhatever();
    delete e;

    cout << endl;
}

void testConstCast()
{
    cout << "=== Testing const_cast ===" << endl;
    // remove the constant
    const char* cstr = "Hello";
    // char* str = cstr; // Won't compile!
    char* str = const_cast<char*>(cstr);
    cout << str << endl;

    cout << endl;
}

int main()
{
    testStaticCast();
    testConstCast();
    testDynamicCast();
    testReinterpretCast();

    return 0;
}

And this is the output.
=== Testing static_cast ===
10
10
Person constructor is being called
Hello, Person
Person destructor is being called

Person constructor is being called
Employee constructor is being called
Hello, Employee
Whatever!
Employee destructor is being called
Person destructor is being called

=== Testing const_cast ===
Hello

=== Testing dynamic_cast ===
Person constructor is being called
Employee constructor is being called
Hello, Employee
Employee destructor is being called
Person destructor is being called

=== Testing reinterpret_cast ===
4210901
Hello

Wednesday, January 12, 2011

SSH with Python

To use SSH with Python, we can use library like paramiko. That library depends on pycrypto, which is mostly a C library. Thus, we need to make sure that we have a C compiler. To install paramiko on Linux/Ubuntu, it's very straightforward.
sudo apt-get install python-paramiko
However, on Windows, we need a little bit of work. By default, distutils on Windows requires Visual Studio compiler.
1. Download Microsoft Visual Studio Express 2008.
2. Download Windows SDK and install the Windows Headers and Libraries.
pyconfig.h requires header files, such as basetsd.h that's available in Windows SDK.
3. Download pycryto library.
4. From the command line, go to pycrypto folder and type
python setup.py install
5. Download paramiko library.
6. From the command line, go to paramiko folder and type
python setup.py install

Below is the sample. The code is pretty self-explanotary.
import paramiko

def do_ssh(hostname, username, password):
    client = paramiko.SSHClient()
    try:
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(hostname, 22, username, password)
        stdin, stdout, stderr = client.exec_command('ls -l')
        print stdout.read()
    finally:
        client.close()

if __name__ == "__main__":
    do_ssh("hostname", "username", "password")

Wednesday, January 5, 2011

Dealing with Unsigned Types in Java

Suppose we need to create a binary file with structure like this
1 unsigned byte
1 unsigned short
1 unsigned int

In C, we can do it easily like below.
writec.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE* myfile;

    myfile = fopen("/tmp/writec.bin", "wb");
    if (!myfile)
    {
        printf("Unable to open the file!");
        return EXIT_FAILURE;
    }

    unsigned char x = 12;
    unsigned short y = 123;
    unsigned int z = 1234;
    fwrite(&x, sizeof(unsigned char), 1, myfile);
    fwrite(&y, sizeof(unsigned short), 1, myfile);
    fwrite(&z, sizeof(unsigned int), 1, myfile);

    fclose(myfile);

    return EXIT_SUCCESS;
}

To read such a file in Java can be quite tricky since the file has unsigned types. All data types in Java are signed, except for char. Here I'm gonna show you how to read such a file in Java.
ReadJava.java
package myproject;
 
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.nio.ByteOrder;
 
public class ReadJava {
 
    public static void main(String[] args) throws Exception {
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            fis = new FileInputStream("/tmp/writec.bin");
            bos = new ByteArrayOutputStream();
            byte[] bytes = new byte[128];
            int bytesRead;
            while ((bytesRead = fis.read(bytes, 0, bytes.length)) != -1) {
                bos.write(bytes, 0, bytesRead);
            }
            byte[] rawBytes = bos.toByteArray();
           
            int index = -1;
            int firstByte = 0;
            int secondByte = 0;
            int thirdByte = 0;
            int fourthByte = 0;
            short unsignedByte = 0;
            int unsignedShort = 0;
            long unsignedInt = 0;
           
            firstByte = (0x000000FF & ((int) rawBytes[++index]));
            unsignedByte = (short) ((firstByte) & 0xFF);
            System.out.println("unsigned byte=" + unsignedByte);
           
            firstByte = (0x000000FF & ((int) rawBytes[++index]));
            secondByte = (0x000000FF & ((int) rawBytes[++index]));
            if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
                unsignedShort = (int) ((firstByte | secondByte << 8) & 0xFFFF);
            } else {
                unsignedShort = (int) ((firstByte << 8 | secondByte) & 0xFFFF);
            }
            System.out.println("unsigned short=" + unsignedShort);
           
            firstByte = (0x000000FF & ((int) rawBytes[++index]));
            secondByte = (0x000000FF & ((int) rawBytes[++index]));
            thirdByte = (0x000000FF & ((int) rawBytes[++index]));
            fourthByte = (0x000000FF & ((int) rawBytes[++index]));
            if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
                unsignedInt = (long) (((firstByte | secondByte << 8 |
                    thirdByte << 16 | fourthByte << 24)) & 0xFFFFFFFFL);
            } else {
                unsignedInt = (long) (((firstByte << 24 | secondByte << 16 |
                    thirdByte << 8 | fourthByte)) & 0xFFFFFFFFL);
            }
            System.out.println("unsigned int=" + unsignedInt);
        } finally {
            if (bos != null) {
                bos.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
    }
}


Similarly, if we need to create such a file in Java, we can do the following.
WriteJava.java
package myproject;

import java.io.FileOutputStream;
import java.nio.ByteOrder;
 
public class WriteJava {
 
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("/tmp/writejava.bin");
       
        try {
            short unsignedByte = 0;
            int unsignedShort = 0;
            long unsignedInt = 0;
            int index = -1;
           
            byte[] rawBytes = new byte[7];
           
            unsignedByte = (short) (12 & 0XFF);
            rawBytes[++index] = (byte) ((unsignedByte & 0x00FF));
           
            unsignedShort = (int) (123 & 0XFFFF);
            if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
                rawBytes[++index] = (byte) ((unsignedShort & 0x000000FF));
                rawBytes[++index] = (byte) ((unsignedShort & 0x0000FF00) >> 8);
            } else {
                rawBytes[++index] = (byte) ((unsignedShort & 0x0000FF00) >> 8);
                rawBytes[++index] = (byte) ((unsignedShort & 0x000000FF));
            }
           
            unsignedInt = (long) (1234 & 0xFFFFFFFFL);
            if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
                rawBytes[++index] = (byte) ((unsignedInt & 0x000000FFL));
                rawBytes[++index] = (byte) ((unsignedInt & 0x0000FF00L) >> 8);
                rawBytes[++index] = (byte) ((unsignedInt & 0x00FF0000L) >> 16);
                rawBytes[++index] = (byte) ((unsignedInt & 0xFF000000L) >> 24);
            } else {
                rawBytes[++index] = (byte) ((unsignedInt & 0xFF000000L) >> 24);
                rawBytes[++index] = (byte) ((unsignedInt & 0x00FF0000L) >> 16);
                rawBytes[++index] = (byte) ((unsignedInt & 0x0000FF00L) >> 8);
                rawBytes[++index] = (byte) ((unsignedInt & 0x000000FFL));
            }
           
            fos.write(rawBytes);
        } finally {
            fos.close();
        }
    }
}

To read it in C, it's as easy as below.
readc.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE* myfile;

    myfile = fopen("/tmp/writejava.bin", "rb");
    if (!myfile)
    {
        printf("Unable to open the file!");
        return EXIT_FAILURE;
    }

    unsigned char x;
    unsigned short y;
    unsigned int z;
    fread(&x, sizeof(unsigned char), 1, myfile);
    fread(&y, sizeof(unsigned short), 1, myfile);
    fread(&z, sizeof(unsigned int), 1, myfile);

    printf("unsigned byte=%d\n", x);
    printf("unsigned short=%d\n", y);
    printf("unsigned int=%d\n", z);

    fclose(myfile);

    return EXIT_SUCCESS;
}