CASE in records
Author Message
CASE in records

Hey all

Could someone please explain me these piece of code:

tPolygonRec = Record
...
...
Case Integer of  { Cases for the various polygon types }
1 : (AB1, AB2, AB3 : UVCoord; Intensity : Byte);
2 : (AB4, AB5, AB6 : UVCoord; I1, I2, I3 : Byte);
3 : (AB7, AB8, AB9 : UVCoord);
4 : (UV1, UV2, UV3 : UVCoord);
5 : (AC1, AC2, AC3 : UVCoord; I_tensity : Byte);
6 : (AC4, AC5, AC6 : UVCoord; I4, I5, I6 : Byte);
7 : (AC7, AC8, AC9 : UVCoord; PT1, PT2, PT3 : UVCoord);
End;

-or-

Type Register = Record
Case Byte of
0  : (w1, w2  : Word);
1  : (b1, b2, b3, b4 : Byte);
End;

(I copied these pieces of code from somebody elses sources)

What i don't understand is the 'CASE' statements in these records. Can
someone please explain to me how i use 'CASE' in records and why this is

Grtnx
Xy

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Quote:
> Hey all

> Could someone please explain me these piece of code:

>   tPolygonRec = Record
>   ...
>   ...
>   Case Integer of  { Cases for the various polygon types }
>       1 : (AB1, AB2, AB3 : UVCoord; Intensity : Byte);
>       2 : (AB4, AB5, AB6 : UVCoord; I1, I2, I3 : Byte);
>       3 : (AB7, AB8, AB9 : UVCoord);
>       4 : (UV1, UV2, UV3 : UVCoord);
>       5 : (AC1, AC2, AC3 : UVCoord; I_tensity : Byte);
>       6 : (AC4, AC5, AC6 : UVCoord; I4, I5, I6 : Byte);
>       7 : (AC7, AC8, AC9 : UVCoord; PT1, PT2, PT3 : UVCoord);
>   End;

> -or-

> Type Register = Record
>     Case Byte of
>       0  : (w1, w2  : Word);
>       1  : (b1, b2, b3, b4 : Byte);
>   End;

> (I copied these pieces of code from somebody elses sources)

> What i don't understand is the 'CASE' statements in these records. Can
> someone please explain to me how i use 'CASE' in records and why this
is

> Grtnx
> Xy

There are bound to be better replies, as I'm not an expert.
These are also referred to as "Variant records".
It allows you to store different data-types or data-sizes within the
same record.
Your 2nd example allows a person to store either two words or four
bytes (same size) within the record, and Pascal chooses which one by
the type of the data you are storing there (byte or word).
In some implementations I think the size of each variant had to be the
same, or the larger ones came first. Your first example doesn't appear
to follow this restriction. But then again, I'm a UCSD Pascal
programmer... the only one left, I imagine :)

Sent via Deja.com http://www.deja.com/

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records
[variant records]

Quote:
> Your 2nd example allows a person to store either two words or four
> bytes (same size) within the record, and Pascal chooses which one by
> the type of the data you are storing there (byte or word).
> In some implementations I think the size of each variant had to be the
> same, or the larger ones came first. Your first example doesn't appear
> to follow this restriction. But then again, I'm a UCSD Pascal
> programmer... the only one left, I imagine :)

Variant records can have variants of different sizes; enough space is
allocated to store the largest. The type used is determined when the data is
read or written; this makes it easy to convert data between compatible
types.  For instance, TP has a variant record type for the registers; so you
can store data in the 8-bit registers and read it from the 16-bit registers,
or the other way around. Many other applications are possible. In
particular, it makes it possible to pass different but related types to a
single procedure or function, as in your polygon example. Each form needs
its own parameters and storage, but a single routine can handle them by
using the variant record.

--
______________________________________________________________________
The Scarlet Manuka,      |        Nitpickers' Party motto:
Pratchett Quoter At Large,  |  "He who guards his lips guards his
First Prophet of Bonni, is:  |  soul, but he who speaks rashly will

______________________________|_______________________________________

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

schreibt:

Quote:
>Type Register = Record
>    Case Byte of
>      0  : (w1, w2  : Word);
>      1  : (b1, b2, b3, b4 : Byte);
>  End;

Such a record contains all the listed items, but not all at the same time, or
not all with different values, since some of the items reside at the same
memory addresses. In the above example w1 shares 2 bytes with b1 and b2, w2
shares 2 more bytes with b3 and b4. The compiler will find out, which of the
cases will occupy the most bytes, and use that size for every instance of such
a record.

Though all fields must have different names, and can be accessed at any time by
their unique name, only the fields of every single variant really occupy
different locations in memory.

First (intended) use:
Economic memory management. When you know, that at the same time you only want
to store one or two words, and in other situations up to four bytes, but never
both kinds at the same time, than you can use a record structure like above.
Then you can hold different values in all the members of the same case.

The Pascal syntax also allows for a tag value, like:
case v: integer of ...

Here v is the tag variable, here of type integer, which also becomes a member
of the record. The intention for this tag is, that you should store there the
number of the variant, which you want to fill with values. Before reading back
the values you can check, whether the record contains the values in the
expected variant format. A compiler could perform these checks automatically,
but almost no compiler really cares about the actual tag value.

Second (not portable) use:
When in the above record a value is written into w1, it can be read back using
w1, or also using b1 and b2, which would return the low and high byte of the
stored word. b1 has the same address in memory than w1, b2 the next higher
address. Likewise you can store 2 bytes into b1 and b2, and retrieve the
composed word as w1.

Since the low/high byte order depends on the machine architecture, you'll find
the bytes swapped, when using an Intel and Motorola processor (big/little
endian). More problems can arise from the alignment gaps, added by new
compilers. To omit such gaps, you should mark the record as "packed".

DoDi

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records
This information helped me alot, thnx..But i have only one question: When/Why do i
use "Case BYTE of", and when/why do i use "Case INTEGER of", or doesn't this make a
difference?

Grtnx,
Xy

Quote:

> schreibt:

> >Type Register = Record
> >    Case Byte of
> >      0  : (w1, w2  : Word);
> >      1  : (b1, b2, b3, b4 : Byte);
> >  End;

> Such a record contains all the listed items, but not all at the same time, or
> not all with different values, since some of the items reside at the same
> memory addresses. In the above example w1 shares 2 bytes with b1 and b2, w2
> shares 2 more bytes with b3 and b4. The compiler will find out, which of the
> cases will occupy the most bytes, and use that size for every instance of such
> a record.

> Though all fields must have different names, and can be accessed at any time by
> their unique name, only the fields of every single variant really occupy
> different locations in memory.

> First (intended) use:
> Economic memory management. When you know, that at the same time you only want
> to store one or two words, and in other situations up to four bytes, but never
> both kinds at the same time, than you can use a record structure like above.
> Then you can hold different values in all the members of the same case.

> The Pascal syntax also allows for a tag value, like:
>   case v: integer of ...

> Here v is the tag variable, here of type integer, which also becomes a member
> of the record. The intention for this tag is, that you should store there the
> number of the variant, which you want to fill with values. Before reading back
> the values you can check, whether the record contains the values in the
> expected variant format. A compiler could perform these checks automatically,
> but almost no compiler really cares about the actual tag value.

> Second (not portable) use:
> When in the above record a value is written into w1, it can be read back using
> w1, or also using b1 and b2, which would return the low and high byte of the
> stored word. b1 has the same address in memory than w1, b2 the next higher
> address. Likewise you can store 2 bytes into b1 and b2, and retrieve the
> composed word as w1.

> Since the low/high byte order depends on the machine architecture, you'll find
> the bytes swapped, when using an Intel and Motorola processor (big/little
> endian). More problems can arise from the alignment gaps, added by new
> compilers. To omit such gaps, you should mark the record as "packed".

> DoDi

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Quote:

>This information helped me alot, thnx..But i have only one question: When/Why do i
>use "Case BYTE of", and when/why do i use "Case INTEGER of", or doesn't this make a
>difference?

If there is no selector field then it makes no difference. If there is
selector field, then that of course changes the type of that field. One
must remember that the basic form is the one with the selector field.
The version without is basically a gimmick and is used for raw type
conversions.  (same stuff for which one uses absolute variables or
variable typecasts)

Osmo

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Quote:

>   You don't ever want to to use "Case Integer of" (in TP/BP), because
>the TP/BP implementations of Pascal support only the ranges of Byte and
>Char for the Case statement.

Incorrect. Turbo Pascal is a 16-bit compiler so it supports 16-bit vales
with case. Also the case in records has little to do with actual case
statement.

Osmo

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records
You don't ever want to to use "Case Integer of" (in TP/BP), because
the TP/BP implementations of Pascal support only the ranges of Byte and
Char for the Case statement.  There is a potential of having integer
values which exceed the Byte range being truncated and treated as their
"mod Byte) values.
In the case <ggg> below, this doesn't matter, because the Case
constant values are within the supported range...
Quote:
> This information helped me alot, thnx..But i have only one question: When/Why do i
> use "Case BYTE of", and when/why do i use "Case INTEGER of", or doesn't this make a
> difference?

> > >Type Register = Record
> > >    Case Byte of
> > >      0  : (w1, w2  : Word);
> > >      1  : (b1, b2, b3, b4 : Byte);
> > >  End;

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Ronkanen) schreibt:

Quote:
>Incorrect. Turbo Pascal is a 16-bit compiler so it supports 16-bit vales
>with case. Also the case in records has little to do with actual case
>statement.

This just reminds me on a similar discussion, in the BC3 beta test. The Ansi C
guidelines stated an "integral" expression for case statements, what was
misinterpreted by the compiler writers as "integer" expressions.

DoDi

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

schreibt:

Quote:
>When/Why do i
>use "Case BYTE of", and when/why do i use "Case INTEGER of", or doesn't this
>make a difference?

Simply try, or consult your compiler documentation. Delphi3 didn't even check
the case values against the type of the tag, but Delphi4 performs these checks.
Since most compilers imply no special relationship between the tag and the
various cases, no special conflicts should ever arise, or the compiler will
report...

DoDi

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Quote:

> Simply put:
> Type
>   tString = Record
>     Case Boolean Of
>       True: (AsStr :String);
>       False: (AsByte :Byte; AsChar :Array[0..253] Of Char);
>   End;
> In your program, you can either reference "tString.AsStr" as a string type,
> or reference it as "AsByte" and "AsChar" to get the length (AsByte) and it's
> contents (AsChar).  This means you can use the PChar routines on
> tString.AsChar (as long as you remember to update AsByte with the string
> length). You can empty the string by "tString.AsStr := '';" or

You'll also need to make sure that you write a terminating #0 byte each time
you modify the string, if you want to use it with PChar routines.

--
______________________________________________________________________
The Scarlet Manuka,      |        Nitpickers' Party motto:
Pratchett Quoter At Large,  |  "He who guards his lips guards his
First Prophet of Bonni, is:  |  soul, but he who speaks rashly will

______________________________|_______________________________________

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Quote:
>>   tString = Record
>>     Case Boolean Of
>>       True: (AsStr :String);
>>       False: (AsByte :Byte; AsChar :Array[0..253] Of Char);
>>   End;

>> In your program, you can either reference "tString.AsStr" as a string type,
>> or reference it as "AsByte" and "AsChar" to get the length (AsByte) and it's
>> contents (AsChar).  This means you can use the PChar routines on
>> tString.AsChar (as long as you remember to update AsByte with the string
>> length). You can empty the string by "tString.AsStr := '';" or

>You'll also need to make sure that you write a terminating #0 byte each time
>you modify the string, if you want to use it with PChar routines.

Now we are on this topic, does somebody have a unit for modula2 styled
array of char ?

This is zero terminated, except when the array is full (then length is
sizeof/high(x)), which allows the last char to be used for text.

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records
I can write the code for you quite quickly, but why would you want this
array style?

Quote:
> >>   tString = Record
> >>     Case Boolean Of
> >>       True: (AsStr :String);
> >>       False: (AsByte :Byte; AsChar :Array[0..253] Of Char);
> >>   End;

> >> In your program, you can either reference "tString.AsStr" as a string
type,
> >> or reference it as "AsByte" and "AsChar" to get the length (AsByte) and
it's
> >> contents (AsChar).  This means you can use the PChar routines on
> >> tString.AsChar (as long as you remember to update AsByte with the
string
> >> length). You can empty the string by "tString.AsStr := '';" or

> >You'll also need to make sure that you write a terminating #0 byte each
time
> >you modify the string, if you want to use it with PChar routines.

> Now we are on this topic, does somebody have a unit for modula2 styled
> array of char ?

> This is zero terminated, except when the array is full (then length is
> sizeof/high(x)), which allows the last char to be used for text.

Wed, 18 Jun 1902 08:00:00 GMT
CASE in records

Quote:
>I can write the code for you quite quickly, but why would you want this
>array style?

I can do it myself too, I just wondered if it already existed, and save some
work. Also, it has to be done/converted to Free Pascal, so BP internal asm
is useless.

I still have datafiles with records that contain strings in this format,
have ported the apps that generate them to Free Pascal, but want an
import and export function in the old format.

Pchar is possible, but the strings unit is quite limited, shortstring is too
short. Ansistring would be best, but I want a small TP compilable app too
:-)

Wed, 18 Jun 1902 08:00:00 GMT

 Page 1 of 1 [ 14 post ]

Relevant Pages