Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can 4-character string literals and FourCC (aka OSType) values live together in peace and harmony?

Tags:

delphi

I'm working with RIFFCHUNK structures, declared (in the "foreign" modules) as (citing MMSystem and DirectShow9):

  type FOURCC = DWORD;                    { a four character code }

  type _riffchunk = record
    fcc: FOURCC;
    cb: DWORD;
  end;
  type RIFFCHUNK = _riffchunk;

My particular interest here is fcc field, which type resolves to LongWord. In the other hand, meaningful values for fcc are strings comprised by 4 ASCII printable single-byte characters. I'd like to avoid the following ugliness (citing MMSystem):

  const FOURCC_RIFF = $46464952;   { 'RIFF' }

... and use actual, self-explaining four character string literals for assignment and comparison.

What have I tried so far and got stuck shown below:

const idRIFF: packed array [1..4] of AnsiChar = 'RIFF';
var Chunk: RIFFCHUNK;
begin
  Chunk.fcc := FOURCC(idRIFF);  { works, but requires a typecast in implementation }

Since idRIFF isn't true constant, it cannot be used in declaration of properly typed symbol.

So, I'd like to ask an advice where to go further in this beautification affair?

Please note what FOURCC type is "foreign", so I cannot just redeclare it as character array.

like image 464
Free Consulting Avatar asked Nov 30 '13 15:11

Free Consulting


2 Answers

This declaration will treat FOURCC_RIFF as a constant using a string literal:

const
  FOURCC_RIFF_S : array[0..SizeOf(FOURCC)-1] of AnsiChar = 'RIFF';
var
  FOURCC_RIFF : FOURCC absolute FOURCC_RIFF_S;

If writable constant directive is on, that could be fixed by catching the compiler directive as well.

{$IFOPT J+}
  {$DEFINE UNDO_WRCONST}
  {$J-}
{$ENDIF}
const
  FOURCC_RIFF_S : array[0..SizeOf(FOURCC)-1] of AnsiChar = 'RIFF';
var
  FOURCC_RIFF : FOURCC absolute FOURCC_RIFF_S;
{$IFDEF UNDO_WRCONST}
  {$J+}
{$ENDIF}

No typecasting needed and compiler treats the value as a true constant.

var
  Chunk: RIFFCHUNK;
...
  Chunk.fcc := FOURCC_RIFF;
like image 54
LU RD Avatar answered Nov 15 '22 02:11

LU RD


The multimedia API defines MAKEFOURCC() and mmioFOURCC() macros, both of which convert 4 characters into a FOURCC value, eg:

Chunk.fcc := MAKEFOURCC('R', 'I', 'F', 'F'); 

Chunk.fcc := mmioMAKEFOURCC('R', 'I', 'F', 'F'); 

In case Delphi does not have an existing translation in the MMSystem unit (it should, but I cannot check right now), here is one:

function MAKEFOURCC(ch0, ch1, ch2, ch3: AnsiChar): LongWord;
begin
  Result := LongWord(Ord(ch0)) or (LongWord(Ord(ch1)) shl 8) or (LongWord(Ord(ch2)) shl 16) or (LongWord(Ord(ch3)) shl 24); 
end;
like image 21
Remy Lebeau Avatar answered Nov 15 '22 04:11

Remy Lebeau