Thread overview
string to char[4] FourCC conversion
May 26, 2023
realhet
May 26, 2023
realhet
May 27, 2023
kdevel
May 26, 2023

Hello,

Is there a way to do it nicer/better/faster/simpler?

char[4] fourC(string s)
{
	uint res;//Zero initialized, not 0xff initialized.
	auto 	cnt = min(s.length, 4),
		p = cast(char[4]*)(&res);
	(*p)[0..cnt] = s[0..cnt];
	return *p;
}

I tried to use staticArray!(char, 4), on s.byChar, but failed.

I think I could do this using cast(char[4])(s.take(4).enumerate.map!"cast(uint)(a.value)<<<(a.index*8)".sum), but that seems no so effective. But at least that works in CT.

I hope there is a more clever way in the std library I couldn't imagine at the moment...

//I also tried an arithmetic version, but it's impossible to convert to char[4] except with using pointer casts...
uint fourCC(string s)
{ return s.take(4).enumerate.map!(a => a.value << cast(uint)a.index*8).sum; }
May 26, 2023

On 5/26/23 8:19 AM, realhet wrote:

>

Hello,

Is there a way to do it nicer/better/faster/simpler?

char[4] fourC(string s)
{
     uint res;//Zero initialized, not 0xff initialized.
     auto     cnt = min(s.length, 4),
         p = cast(char[4]*)(&res);
     (*p)[0..cnt] = s[0..cnt];
     return *p;
}

This worked for me:

char[4] fourC(string s)
{
    if(s.length >= 4)
        return s[0 .. 4];
    char[4] res = 0;
    res[0 .. s.length] = s;
    return res;
}

Supporting returning as a 4-char array even when the input has less than 4 makes it tricky. But not so bad.

-Steve

May 26, 2023

On Friday, 26 May 2023 at 13:18:15 UTC, Steven Schveighoffer wrote:

>

This worked for me:

char[4] fourC(string s)
{
    if(s.length >= 4)
        return s[0 .. 4];
    char[4] res = 0;
    res[0 .. s.length] = s;
    return res;
}

Sometimes I forget that the return does an implicit cast. And it looks inside the slice [..] if it constant or not. Lot of things going on under the hood...

Thank You!

May 27, 2023

On Friday, 26 May 2023 at 13:18:15 UTC, Steven Schveighoffer wrote:

>

[...]
This worked for me:

char[4] fourC(string s)
{
    if(s.length >= 4)
        return s[0 .. 4];

Silent truncation? Non-ASCII chars?

>
char[4] res = 0;

According to [1], [2] or [3] that should read

    char[4] res = ' ';
>
res[0 .. s.length] = s;
return res;

}

[1] Multimedia Programming Interface and Data Specifications 1.0
IBM Corporation and Microsoft Corporation
August 1991, p. 11
https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf

[2] http://ffmpeg.org/doxygen/trunk/raw_8c_source.html#l00050

[3] https://en.wikipedia.org/wiki/FourCC
"The byte sequence is usually restricted to ASCII printable characters, with space characters reserved for padding shorter sequences. [...] Some FourCCs however, do contain non-printable characters, and are not human-readable without special formatting for display; for example, 10bit Y'CbCr 4:2:2 video can have a FourCC of ('Y', '3', 10, 10) which ffmpeg displays as rawvideo (Y3[10] [10] / 0x0A0A3359), yuv422p10le."