Clan x86

Technical (Development, Security, etc.) => General Programming => Topic started by: Joe on February 07, 2007, 03:13:26 AM

Title: Integer by reference..
Post by: Joe on February 07, 2007, 03:13:26 AM
Is there any easy way to pass an int or Integer by reference in Java? I want to but it won't let me. :(
Title: Re: Integer by reference..
Post by: d&q on February 07, 2007, 05:17:01 AM
Use an int array with one value? That's probably not the best method though..
Title: Re: Integer by reference..
Post by: Chavo on February 07, 2007, 10:20:21 AM
passing be reference/value isn't as black & white in java as it is in other languages, what are you trying to do?
Title: Re: Integer by reference..
Post by: Joe on February 07, 2007, 03:32:39 PM
filename, formula, and filetime should be byvalue and checksum, verhas, and exeinfo should be byreference.

exeinfo is already byreference, but my attempt to pass checksum and verhash as an object (Integer opposed to int) failed.

public void getVersionCheck(String filename, String formula, long filetime, Integer checksum, Integer verhash, String exeinfo) throws IOException
    {
        Socket s = getConnection();
        BufferedReader in = getReader(s);
        BufferedWriter out = getWriter(s);
       
BNLSPacket pkt = new BNLSPacket(BNLS_VERSIONCHECKEX2);
pkt.addDWord(getBnlsProductId(game)); // (DWORD) Product ID
pkt.addDWord(0); // (DWORD) Flags**
pkt.addDWord(0); // (DWORD) Cookie
pkt.addLong(filetime); // (ULONGLONG) Timestamp for version check archive
pkt.addNTString(filename); // (STRING) Version check archive filename.
pkt.addNTString(formula); // (STRING) Checksum formula.
out.write(pkt.getChars());
out.flush();

BNLSPacket inPkt = getNextPacket(in);
/*(BOOL) Success*
(DWORD) Version.
(DWORD) Checksum.
(STRING) Version check stat string.
(DWORD) Cookie.
(DWORD) The latest version code for this product.*/
inPkt.removeDWord();
verhash = inPkt.removeDWord();
checksum = inPkt.removeDWord();
exeinfo = inPkt.removeNTString();
   
    }
Title: Re: Integer by reference..
Post by: Sidoh on February 07, 2007, 04:22:57 PM
Here (http://www.yoda.arachsys.com/java/passing.html)'s a good article on this subject, Joe.  In short, I think you're going to have to find a different way to solve this problem.  You could invent a convoluted way to implement a "by reference" method (like deuce suggested, the only thing I can think of offhand is to have an object or an array of some sort), but I think you can come up with something better.
Title: Re: Integer by reference..
Post by: Chavo on February 07, 2007, 05:06:52 PM
You could encapsulate all your parameters in an object and then just pass references to that object.
Title: Re: Integer by reference..
Post by: Sidoh on February 07, 2007, 05:09:58 PM
Quote from: unTactical on February 07, 2007, 05:06:52 PM
You could encapsulate all your parameters in an object and then just pass references to that object.

I recommended that, but in a less elaborate way. :(

Like I said though, I don't think there's any non-convoluted way to do what you're wanting to do.
Title: Re: Integer by reference..
Post by: Chavo on February 07, 2007, 05:42:05 PM
encapsulation isn't a convoluted unless you do it in an ugly way like a one element array!
Title: Re: Integer by reference..
Post by: d&q on February 07, 2007, 06:26:19 PM
Quote from: unTactical on February 07, 2007, 05:42:05 PM
encapsulation isn't a convoluted unless you do it in an ugly way like a one element array!

:(
Title: Re: Integer by reference..
Post by: Chavo on February 07, 2007, 06:56:05 PM
lol, that wasn't a shot at you deuce, its just an ugly way
Title: Re: Integer by reference..
Post by: Warrior on February 07, 2007, 07:27:15 PM
put all your vars in a object then pass that by ref.

im a genius.
Title: Re: Integer by reference..
Post by: rabbit on February 07, 2007, 08:04:05 PM
Make a class that consists entirely of the value types you want to get back, and return that from the function.  That is what Java is made for.
Title: Re: Integer by reference..
Post by: MyndFyre on February 07, 2007, 10:16:26 PM
Quote from: rabbit on February 07, 2007, 08:04:05 PM
Make a class that consists entirely of the value types you want to get back, and return that from the function.  That is what Java is made for.

Heh.  I was thinking that myself.  I'm pretty sure that's what Sidoh was thinking, too.  And Warrior.  And unTactical.  ;)
Title: Re: Integer by reference..
Post by: rabbit on February 07, 2007, 11:14:19 PM
It's what anyone who's gotten past chapter 2 of "Java for Dummies" should think.
Title: Re: Integer by reference..
Post by: Sidoh on February 08, 2007, 02:53:21 PM
Quote from: unTactical on February 07, 2007, 05:42:05 PM
encapsulation isn't a convoluted unless you do it in an ugly way like a one element array!

Haha, it is for some situations.

Quote from: rabbit on February 07, 2007, 11:14:19 PM
It's what anyone who's gotten past chapter 2 of "Java for Dummies" should think.

You bug me.
Title: Re: Integer by reference..
Post by: rabbit on February 08, 2007, 07:54:06 PM
What?  That's the entire point of Java: an overabundance of objects.  You're not supposed to return a pointer, you're supposed to return an object.
Title: Re: Integer by reference..
Post by: kalaka on February 08, 2007, 07:58:22 PM
Quote from: rabbit on February 07, 2007, 11:14:19 PM
It's what anyone who's gotten past chapter 2 of "Java for Dummies" should think.
Crap, I knew I should've read chapter 2...
Title: Re: Integer by reference..
Post by: Sidoh on February 08, 2007, 08:38:05 PM
Quote from: rabbit on February 08, 2007, 07:54:06 PM
What?  That's the entire point of Java: an overabundance of objects.  You're not supposed to return a pointer, you're supposed to return an object.

I said "you bug me," not "I'm unable to decipher your hyperbole."
Title: Re: Integer by reference..
Post by: iago on February 08, 2007, 09:43:01 PM
If you need to return more than a single variable, then you probably have a design issue. 

I think it might work best like this (in general):

int val1, val2;
VersionDatachecker vd = new VersionDatachecker();
vd.go(list, of, variables);
val1 = vd.getVal1();
val2 = vd.getVal2();

That's likely a cleaner design, and more "proper", in many respects.

Creating an object to return a parameter value is a gross kludge. It was a killable offense back when I was a marker.
Title: Re: Integer by reference..
Post by: Joe on February 09, 2007, 04:17:21 AM
Here you go:

package versioning;

public class CheckRevisionResults
{

private int m_verhash;
private int m_checksum;
private byte[] m_statstring;

public CheckRevisionResults(int verhash, int checksum, byte[] statstring)
{
m_checksum = checksum;
m_verhash = verhash;
m_statstring = statstring;
}

public int getChecksum()
{
return m_checksum;
}

public int getVerhash()
{
return m_verhash;
}

public byte[] getStatstring()
{
return m_statstring;
}
}


getVersionCheck returns that.

By the way, I passed Lockdown with SEXP, in case anyone cares.
Title: Re: Integer by reference..
Post by: Chavo on February 09, 2007, 10:09:22 AM
Quote from: iago on February 08, 2007, 09:43:01 PM
If you need to return more than a single variable, then you probably have a design issue. 

Returning an object that acts as a data structure encapsulating a number of related variables IS returning a single variable (or at least a reference to one).  That's not a design issue... Writing 2 methods just to return 2 seperate values that you are going to combine anyway or that causes unnecessary copying of code is a bigger design problem than returning an object instead of a primitive ><

Quotent val1, val2;
VersionDatachecker vd = new VersionDatachecker();
vd.go(list, of, variables);
val1 = vd.getVal1();
val2 = vd.getVal2();
This makes sense when Val1 and Val2 are not dependent variables or are not going to be used in the same place.

Quoteint val1, val2;
VersionDatachecker vd = new VersionDatachecker();
vd.go(list, of, variables);
val1 = vd.getVal1();
val2 = vd.getVal2();
computeNewVal(val1, val2);
If I'm just passing those 2 variables into a new method, that's fine, it is more flexible (not more 'correct').  It is not incorrect to write a method such that:

Quoteint val1, val2;
VersionDatachecker vd = new VersionDatachecker();
vd.go(list, of, variables);
vallist = vd.getVariableList();
vallist = computeNewVals(vallist);
//or even better
computeNewVals(vd);

If you are writing a utility class and looking to maximize reusability, it makes sense to break things down, but that's hardly a design issue to not use Objects where its easier or makes sense.


Title: Re: Integer by reference..
Post by: nslay on February 09, 2007, 03:54:36 PM
Quote from: iago on February 08, 2007, 09:43:01 PM
If you need to return more than a single variable, then you probably have a design issue. 

I think it might work best like this (in general):

int val1, val2;
VersionDatachecker vd = new VersionDatachecker();
vd.go(list, of, variables);
val1 = vd.getVal1();
val2 = vd.getVal2();

That's likely a cleaner design, and more "proper", in many respects.

Creating an object to return a parameter value is a gross kludge. It was a killable offense back when I was a marker.

Just to expand on what unTactical said, as well as being a big C/C++/Fortran programmer (though I hate Fortran!), it is not only common to wish to return multiple pieces of data, but the ability to do so is built into all three of these languages.
While, C/C++ provide structs and classes, to "return" multiple pieces of data, Fortran actually defines a class of "subprogram" known as a "subroutine"
A subroutine is basically a C++ void function that accepts all references.
Here's a practical example where I want two pieces of data returned in fortran (95):
SUBROUTINE boxmuller(x,y)
  IMPLICIT NONE
  DOUBLE PRECISION, PARAMETER :: PI = 3.14159265359d0
  DOUBLE PRECISION, INTENT(OUT) :: x, y
  DOUBLE PRECISION :: u1, u2
  CALL RANDOM_NUMBER(u1)
  CALL RANDOM_NUMBER(u2)
  x = SQRT(-2.d0*LOG(u1))*COS(2.d0*PI*u2)
  y = SQRT(-2.d0*LOG(u1))*SIN(2.d0*PI*u2)
END SUBROUTINE boxmuller

This returns two independent variates distributed on N(0,1) generated from Box-Muller.

Here's a practical example in C
int tunman_getaddr( struct tunman *tn, struct sockaddr *addr, struct sockaddr *b
road ) {
        struct ifconf ifc;
        struct ifreq ifr;
        int s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
        if ( s == -1 ) return -1;
        memset( &ifc, 0, sizeof(ifc) );
        strncpy( ifr.ifr_name, tn->ifnam, sizeof( ifr.ifr_name ) );
        ifc.ifc_len = sizeof(ifr);
        ifc.ifc_req = &ifr;
        if ( ioctl( s, SIOCGIFCONF, &ifc ) == -1 ) {
                close( s );
                return -1;
        }
        close( s );
        memcpy( addr, &ifc.ifc_req->ifr_addr, sizeof(*addr) );
        memcpy( broad, &ifc.ifc_req->ifr_broadaddr, sizeof(*broad) );
        return 0;
}


In this example, I not only return an indicator for error, but I also return two pieces of information, an interface's IP address and broadcast address.  The ioctl() SIOCGIFCONF also returns a buffer of ifreqs that hold the interface's IP address and aliases.  These types of operations are very common in Unix...doing something like:
getipaddr("eth0", &ip);
getbroad("eth0",&broad);
getmask("eth0", &mask);
getstate("eth0", &up );
etc...is extremely redundant!
Title: Re: Integer by reference..
Post by: MyndFyre on February 09, 2007, 04:49:56 PM
Quote from: nslay on February 09, 2007, 03:54:36 PM
In this example, I not only return an indicator for error, but I also return two pieces of information, an interface's IP address and broadcast address.  The ioctl() SIOCGIFCONF also returns a buffer of ifreqs that hold the interface's IP address and aliases.  These types of operations are very common in Unix...doing something like:
getipaddr("eth0", &ip);
getbroad("eth0",&broad);
getmask("eth0", &mask);
getstate("eth0", &up );
etc...is extremely redundant!

Ahh, very true.  *HOWEVER*, the C language was developed before structured exception handling was really a standard (or at the very least, it wasn't considered a major feature of C).  It isn't appropriate in languages with SEH (except C++ apparently, probably because of its C roots) to return error codes.
Title: Re: Integer by reference..
Post by: Joe on February 09, 2007, 06:06:51 PM
Mine was somewhat the same idea. The way RCRS worked is each field was a different packet, but now that I'm using BNLS, it seemed impracticle to send the same packet three times over in the seperate functions.