www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - cast to void[]

reply Alberto <reda zioale.it> writes:
I have some problem casting a struct to void[]:

const ushort RSA_ENC_LEN =256;

struct RSAEncryptedData {
  ubyte encoding[RSA_ENC_LEN];
}

struct Signature {
  ubyte sig[RSA_ENC_LEN];
}

class RSA {
  ...
  Signature sign(void[] block, int type=Hash.SHA512);
  bool verifySig(void[] block, Signature sig, int type=Hash.SHA512);
  ...
}

int main() {
	ubyte[32] sessionkey;
	int ret;
	
	aes128 aes = new aes128(Bits256);
	aes.setRandomKey();
	sessionkey[0..$] = aes.getKey();

	RSA  rsatest = new RSA();
	RSAEncryptedData buf = rsatest.encryptWithPublicKey(sessionkey);
	
	// #1
	Signature sig = rsatest.sign(cast(void[])buf.encoding, Hash.SHA512);
	ret = rsatest.verifySig(cast(void[])buf.encoding, sig, Hash.SHA512);
	assert(ret == true);
	
	// #2
	void[] a;
	a.length = RSAEncryptedData.sizeof;
	memcpy(cast(void *)a, cast(void *)&buf, a.length);
	Signature sig2 = rsatest.sign(a, Hash.SHA512);
	ret = rsatest.verifySig(a, sig2, Hash.SHA512);	
	assert(ret == true);
	
	// #3
	Signature sig3 =
rsatest.sign(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]), Hash.SHA512);
	ret =
rsatest.verifySig(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]),
sig3, Hash.SHA512);
	assert(ret == true);

	return 0;
}

I got an Assertion failure on the 3 assert, where I have tried to cast
buf directly to void[].
In general, if I have something like this:

struct pippo {
   ushort a;
   ushort b;
   ubyte[170] c;
   uint d;
}

void do_something(void []);

What is the right way to pass pippo to do_something() ? something like #2 ?
Feb 12 2007
next sibling parent Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Alberto wrote:
 In general, if I have something like this:
 
 struct pippo {
    ushort a;
    ushort b;
    ubyte[170] c;
    uint d;
 }
 
 void do_something(void []);
 
 What is the right way to pass pippo to do_something() ? something like #2 ?

I came up with the following. It seems idiomatic to me, but there might be something smarter: struct pippo { ushort a; ushort b; ubyte[170] c; uint d; } void do_something(void[] foo) { pippo* p = cast(pippo*)foo.ptr; assert (p.d == 2); } void main() { pippo p; p.d = 2; do_something((&p)[0..pippo.sizeof]); } -- Remove ".doesnotlike.spam" from the mail address.
Feb 12 2007
prev sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Alberto wrote:
 I have some problem casting a struct to void[]:
 

 	// #3
 	Signature sig3 =
 rsatest.sign(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]), Hash.SHA512);
 	ret =
 rsatest.verifySig(cast(void[])((&buf)[0..RSAEncryptedData.sizeof]),
 sig3, Hash.SHA512);
 	assert(ret == true);

That RSAEncryptedData.sizeof should be 1, since you're slicing a value of type RSAEncryptedData*.
 
 	return 0;
 }
 
 I got an Assertion failure on the 3 assert, where I have tried to cast
 buf directly to void[].
 In general, if I have something like this:
 
 struct pippo {
    ushort a;
    ushort b;
    ubyte[170] c;
    uint d;
 }
 
 void do_something(void []);
 
 What is the right way to pass pippo to do_something() ? something like #2 ?

My preferred way is something like --- pippo somevar; // ... initialize do_something((&somevar)[0..1]); --- (The inner brackets may be superfluous, but I'm not sure. My rule of thumb in such cases is to always put them in there, because even if the code does exactly the same they make it more clear what's happening)
Feb 12 2007