Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
September 09, 2011 How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Here is an example of what I am after: struct DATA { ubyte D1; ubyte D2; ubyte D3; ubyte D4; } void main() { ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b = (cast(DATA*)a.ptr)[0 .. 4]; auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; } I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault. |
September 09, 2011 Re: How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Posted in reply to teo | On 09/09/2011 05:19 PM, teo wrote: > Here is an example of what I am after: > > struct DATA > { > ubyte D1; > ubyte D2; > ubyte D3; > ubyte D4; > } > > void main() > { > ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, > 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; > auto b = (cast(DATA*)a.ptr)[0 .. 4]; > auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; > } > > I need to have a DATA[2][2]. That code compiles but gives me a > segmentation fault. If you actually want a dynamic DATA[2][] array of length 2, this works: auto b=(*(cast(DATA[2][2]*)a.ptr))[]; Otherwise: A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr); but note that this copies the data, because static arrays have value semantics. If you want to have refer the new array to the same location, you can use a union. void main(){ union Myunion{ ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; DATA[2][2] b; } Myunion myunion; assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); } |
September 09, 2011 Re: How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Fri, 09 Sep 2011 11:43:04 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote: > On 09/09/2011 05:19 PM, teo wrote: >> Here is an example of what I am after: >> >> struct DATA >> { >> ubyte D1; >> ubyte D2; >> ubyte D3; >> ubyte D4; >> } >> >> void main() >> { >> ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, >> 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; >> auto b = (cast(DATA*)a.ptr)[0 .. 4]; >> auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; >> } >> >> I need to have a DATA[2][2]. That code compiles but gives me a >> segmentation fault. > > If you actually want a dynamic DATA[2][] array of length 2, this works: > auto b=(*(cast(DATA[2][2]*)a.ptr))[]; > > Otherwise: > > A simple reinterpret cast should do: > auto b=*(cast(DATA[2][2]*)a.ptr); > > but note that this copies the data, because static arrays have value semantics. > > If you want to have refer the new array to the same location, you can use a union. > > void main(){ > union Myunion{ > ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, > 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; > DATA[2][2] b; > } > Myunion myunion; > assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); > } You can also use ref, but you have to use a function, as it's impossible to declare a ref local variable except as a function parameter. void main() { ubyte[16] a = ...; void foo(ref DATA[2][2] b) { ... } foo(*(cast(DATA[2][2]*)a.ptr)); } -Steve |
September 09, 2011 Re: How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | Timon Gehr:
> A simple reinterpret cast should do:
> auto b=*(cast(DATA[2][2]*)a.ptr);
I think this is enough:
auto b = cast(Data[2][2])a;
Bye,
bearophile
|
September 09, 2011 Re: How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Fri, 09 Sep 2011 17:43:04 +0200, Timon Gehr wrote: > On 09/09/2011 05:19 PM, teo wrote: >> Here is an example of what I am after: >> >> struct DATA >> { >> ubyte D1; >> ubyte D2; >> ubyte D3; >> ubyte D4; >> } >> >> void main() >> { >> ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, >> 0x01, >> 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; >> auto b = (cast(DATA*)a.ptr)[0 .. 4]; >> auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; >> } >> >> I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault. > > If you actually want a dynamic DATA[2][] array of length 2, this works: > auto b=(*(cast(DATA[2][2]*)a.ptr))[]; > > Otherwise: > > A simple reinterpret cast should do: > auto b=*(cast(DATA[2][2]*)a.ptr); > > but note that this copies the data, because static arrays have value semantics. > > If you want to have refer the new array to the same location, you can use a union. > > void main(){ > union Myunion{ > ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, > 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; > DATA[2][2] b; > } > Myunion myunion; > assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); > } Thank you Timon for the good explanation. Just one more question (I suspect the answer will be no, but let me ask): is it possible to directly cast to ubyte[][]? |
September 09, 2011 Re: How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Fri, 09 Sep 2011 13:10:41 -0400, bearophile wrote:
> Timon Gehr:
>
>> A simple reinterpret cast should do:
>> auto b=*(cast(DATA[2][2]*)a.ptr);
>
> I think this is enough:
> auto b = cast(Data[2][2])a;
>
> Bye,
> bearophile
That works. Thanks.
|
September 09, 2011 Re: How can I map bytes to a matrix of structures? | ||||
---|---|---|---|---|
| ||||
Posted in reply to teo | On 09/09/2011 10:25 PM, teo wrote: > On Fri, 09 Sep 2011 17:43:04 +0200, Timon Gehr wrote: > >> On 09/09/2011 05:19 PM, teo wrote: >>> Here is an example of what I am after: >>> >>> struct DATA >>> { >>> ubyte D1; >>> ubyte D2; >>> ubyte D3; >>> ubyte D4; >>> } >>> >>> void main() >>> { >>> ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, >>> 0x01, >>> 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; >>> auto b = (cast(DATA*)a.ptr)[0 .. 4]; >>> auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; >>> } >>> >>> I need to have a DATA[2][2]. That code compiles but gives me a >>> segmentation fault. >> >> If you actually want a dynamic DATA[2][] array of length 2, this works: >> auto b=(*(cast(DATA[2][2]*)a.ptr))[]; >> >> Otherwise: >> >> A simple reinterpret cast should do: >> auto b=*(cast(DATA[2][2]*)a.ptr); >> >> but note that this copies the data, because static arrays have value >> semantics. >> >> If you want to have refer the new array to the same location, you can >> use a union. >> >> void main(){ >> union Myunion{ >> ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, > 0x01, >> 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; >> DATA[2][2] b; >> } >> Myunion myunion; >> assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); >> } > > Thank you Timon for the good explanation. You are welcome. As bearophile suggests, those are nicer though: auto b=(cast(DATA[2][2]a); // static array auto b=(cast(DATA[2][2]a)[];// dynamic array > > Just one more question (I suspect the answer will be no, but let me ask): > is it possible to directly cast to ubyte[][]? Not directly, because you have to build some structure in memory. an ubyte[][] is an array of dynamic arrays. Each of those dynamic arrays is a 2 field struct consisting of a ptr and a length field. That data you have to construct manually. in case you wanted to turn the ubyte[16] a array to a ubyte[][] b array, with b.length and b[i].length equal to 4, this would probably do the job: ubyte[16] a=[ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b=new ubyte[][](4);// create a ubyte[][] array that can hold 4 ubyte[] values foreach(i,ref x;b) x=a[i*4 .. (i+1)*4]; // compute the values by slicing the original array |
Copyright © 1999-2021 by the D Language Foundation