Null characters in strings

Morton, John John.Morton at navcanada.ca
Thu Sep 9 19:55:23 CEST 2010


My thanks once again.  Things are now gradually starting to come
together.

I should first clarify that we never manipulate the time field - it's
the precise 32-bit bit pattern (time) that gets sent to the outside
world that matters, not what gpc Pascal (or any language/compiler)
actually uses to hold the 32 bit time field.

I am not yet a gpc user and was unaware of the type casting approach.
(My last Pascal experience was some years ago and that was on
mainframe/mini-computers, not in the PC/Linux world.  Since then I've
worked in ADA and greatly liked that language.)  
Type casting is exactly the KISS approach I was looking/hoping for.  In
great preference to the fragile and potentially non-portable approaches
of variant records or the parameter mapping "trick" at the library
interface.

Also new to me are the gpc bitwise operators, thanks for mentioning
them.  They will be a great help in rewriting parts of our code. 
 
Once I get "Hello World" working I'll be spending some time with the
current gpc manual to see what else in gpc is new to me.  I expect I
will find other things in gpc that will be of immediate practical use to
us.  
Hopefully the manual also covers how to create GPC makefiles that use
individually compile multiple source files, persistent object files and
a separate user controllable linker step.

As surmised, the time taken to build a message is not (yet)
time-critical.  However "endian-ism" might (but shouldn't) become an
issue.  We do not manipulate the time and not care how the bytes are
actually stored because it's only the bit pattern of the "4 byte time
field" that matters when the message is sent.

The current conceptual model (without type casting) is:

GetSystemTime( X )       - return 32 bit time in X (as a 4 byte string)

Y = X + rest-of-message  - concatenate strings to get final message
string
SendMessage( Y )         - hardware sends the final message sting

As revised to use type casting (using the types at the end of this
message):

GetSystemTime( Z )       - return the time in Z (Z is defined as 32
bits) 
X = Char4( Z )           - cast the 32 bit time to a 4 byte string
Y = X + rest-of-message  - concatenate strings to get final message
string
SendMessage( Y )         - hardware sends the final message string

So why use a 4 byte string and not something else?  Everything else in
the application uses strings - which makes using a string the simplest
way for us to handle the 32 bit time field.

Comments?  Improvements?

Thanks.

BTW, My viewpoint is that if something can be done in an easily
understood (=KISS) manner using only standard gpc Pascal constructs
(i.e. without "tricks" or "virtuous" (=often obtuse) coding) it is
"pure" Pascal.  By those standards only the second version is "pure"
Pascal.

-----Original Message-----
From: gpc-owner at gnu.de [mailto:gpc-owner at gnu.de] On Behalf Of Frank
Heckenbach
Sent: September 7, 2010 08:03 PM
To: gpc at gnu.de
Subject: Re: Null characters in strings

Morton, John wrote:

> My thanks for confirming that writeln is not implemented using C's
> printf function (I can't remember where I got that idea) and that
gpc's
> writeln can send all 256 characters (absolutely necessary to handle
> binary time as a string).
> 
> On reflection I realize I have misstated our problem.  But I think I
> also have a work-around for it. 
> 
> The issue is that the supplied library returns the time as a 32 bit
> binary value.  The problem is essentially how to coerce the 32 bits
into
> a corresponding 4 character gpc string.  (BTW, they are the first 4
> bytes of every message sent by our application).
> 
> I had hoped that the coercion (effectively a type cast) would be easy
to
> accomplish within Pascal.  I then thought about variant records but
that
> did not seem feasible.  
> I have since realized that the conversion could be done where we
define
> the interface to the external routine.  In the Pascal function
> definition use a 4 character fixed length string for the time field
and
> have the linker map that string to the corresponding 32 bit value
field
> used by the library (probably by using pass-by-address, possibly
> pass-by-value).  
> Not a pure Pascal approach but a practical one - as long as you are
well
> aware of the pitfalls.  (In the "pure" approach the Pascal interface
> parameter would be a 32 bit unsigned value that gets converted/mapped
by
> Pascal to the corresponding 4 byte string).

The only "pure" Pascal approach would be converting the value to
single bytes using "div"/"mod" (GPC also supports bitwise "and" and
"shl"/"shr") and then to characters using "Chr". If it's not
time-critical, this might actually be worth considering, since it
avoids endianness issues.

With GPC, also type-casting should work. Something like this:

program Foo;

type
  Card32 = Cardinal attribute (Size = 32);
  Char4 = array [1 .. 4] of Char;

var
  a: Card32;
  b: Char4;

begin
  b := Char4 (a);
  a := Card32 (b);
end.

Variant records are sometimes abused(!) for this purpose, but I
don't recommend it.

Frank

-- 
Frank Heckenbach, f.heckenbach at fh-soft.de, http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE  D101 CD02 4C9D 0FE0
E5E8







More information about the Gpc mailing list