
     Notes on null and empty values for string fields in object templates


History:

  0.01  17-May-94  First release to Aquarius team for comment
  0.02  18-May-94  Added section on implementation in !ResEd
  0.03  31-May-94  Rewritten following Aquarius Team discussion


1  Summary

This document is an attempt to classify the various string fields which may
appear in object templates (or resource files) according to their behaviour
with respect to null and empty values.

As an example, consider the "help_message" field in a gadget. A null value
might mean "don't respond to help requests" or "respond in the same way as
the underlying window" - whereas an empty string might mean "respond with the
empty string" or "don't respond to help requests".


2  Definitions

A string field is "fixed-length" if a fixed number of bytes is allocated to
it inside the template (eg an object template's "name").


Other string fields are represented in two parts: a pointer and a buffer.

The pointer is a 32-bit value which is either null, or addresses the
buffer; the null value is 0.

The buffer contains a zero-terminated string, and has an associated length;
this length is known as the length of the string field (as opposed to the
length of the string field's value).


A string field is "constant" if the client application has no way to alter
its value at run-time. The name of the menu template associated with a window
template is an example of a constant string field, because its value does not
appear in the window object itself - it is, instead, replaced by the
corresponding menu object's ObjectId. Another example is the label associated
with a labelled box gadget: in this case, there is simply no method provided
to alter the label text at run-time.

A string field is "assignable" if the client application can alter its value
at run-time. An example is the text to be placed inside a menu entry.


The buffer associated with an assignable string field has a maximum length
which is itself held in an associated length field; for example, the 'title'
of a menu object is an assignable string field whose associated length field
is 'max_title'. It is never possible to alter this length at run-time.

The buffer's length constrains the size of string value that can be assigned
to the field at run-time. The length includes a zero terminator, and so an
assignable string field of length n can hold string values which contain at
most (n-1) characters.


A "null" string value is represented by a string field with a pointer value
of zero; only constant or assignable string fields can take null values.


The "empty" string value is the zero-length string consisting of a single
zero terminator byte.


3  Basic assumptions

Every string field either contains a zero-terminated string value, or a null
value. In particular, both fixed-length and non-null assignable string fields
always contain a zero byte somewhere.

  ResEd will ensure that this is true for resource files that it generates.

  Both ResEd and ToolBox modules will assume this is true of all resource
   files.


Any constant or assignable string field may contain a null value or an empty
string.

  Neither ResEd nor the ToolBox may assume that particular fields always
   contain non-null values, or never contain an empty string.


An assignable string field may contain the null string value even though its
length is non-zero; this allows the client to assign a non-null string to the
field at run-time. On the other hand, an assignable string field with zero
length must always contain the null value (and its value can never be altered
at run-time).

  Neither ResEd nor ToolBox modules should test for a null value by looking
   at the value of the associated length field.

  ResEd will allow the user to set the length of an assignable field to a
   non-zero value even if the field itself is set to the null value.


In summary, an assignable string field and its associated length field adhere
to the following constraints:

        state        value               length

  null value          null            >= 0
  empty string          ""            >= 1
  non-empty string       s            >= strlen(s)+1



4  Classifications


4.1  Fixed-length fields

There is only one fixed-length string field, being the "name" field of an
object template header.

The empty string is not a valid object template name, and so this field
should always contain a non-empty string.

  ResEd will ensure that this is so for resource files that it generates.

  Both ResEd and ToolBox modules will assume this is true of all resource
   files.


4.2  Optional constant and assignable fields

These are fields where a null value and the empty string have distinct
meanings; for example, the null value may indicate that the field is not
applicable, or that some default value should be used.

  ResEd will make sure that the user is able to set such a field to a null
   value as well as to an explicit (and possibly empty) string.


The following fields fall into this classification (where an asterisk
identifies those fields which are constant as opposed to assignable). The
column headed "Null" describes the meaning of a null value, and the column
headed "Empty" contains OK if the empty string is meaningful, and ERR if it
will cause an error when the template is used.

  Class/gadget type           Null                                     Empty
     and field

  Menu
    help_message      Supply system default menu help               No help

  Menu entry
    help_message      Supply menu help                              No help
    click_show*       Do not show object on click                       ERR
    submenu_show*     This entry has no submenu                         ERR

  Window
    help_message      Supply system default window help             No help
    pointer_shape     Do not change shape as pointer enters             ERR
    menu*             There is no window menu                           ERR
    title_validation* No title validation string                         OK

  Keyboard shortcut
    key_show*         Do not show object on key-press                   ERR

  All gadgets
    help_message      Supply underlying window's help               No help

  Action button
    click_show*       Do not show object on click                       ERR

  Writable field
    allowable         No validation string                               OK

  Draggable
    text              Icon has no text                                   OK
    sprite            Icon has no sprite                                 OK

  String set        
    allowable         No validation string                               OK

  Iconbar icon
    help_message      Supply system default iconbar help            No help
    sprite_name       Icon has no sprite                                 OK
    text              Icon has no text                                   OK
    menu*             Menu-click has no action                          ERR
    select_show*      Select-click has no action                        ERR
    adjust_show*      Adjust-click has no action                        ERR

  Colour menu
    title             Use default title                                  OK

  Colour Dbox
    title             Use default title                                  OK
    help_text*        Supply colour picker default help             No help

  DCS
    title             Use default title                                  OK
    message           Use default message                                OK
    window*           Use default window                                ERR

  File Info
    title             Use default title                                  OK
    filename*         Use default initial filename                       OK
    window*           Use default window                                ERR

  Font Menu
    ticked_font*      Use first font in list                 No ticked font

  Font Dbox 
    title             Use default title                                  OK
    initial_font*     Use first font in list                No initial font
    try_string*       Use default string                                 OK
    window*           Use default window                                ERR

  Print Dbox
    further_options*  No "set-up" dbox                                  ERR
    window*           Use default window                                ERR

  Prog Info
    title             Use default title                                  OK
    window*           Use default window                                ERR

  Quit
    title             Use default title                                  OK
    message           Use default message                                OK
    window*           Use default window                                ERR

  SaveAs
    title             Use default title                                  OK
    window*           Use default window                                ERR

  Scale view 
    title             Use default title                                  OK
    window*           Use default window                                ERR


4.3  Mandatory constant and assignable fields

These are fields where there is no natural way to distinguish between a null
value and an empty string value.

  ResEd will ensure that such fields have null values (since these occupy
   less space in a resource file), but will accept empty strings as valid
   when loading templates.

  The ToolBox will accept either null values or empty strings, and will treat
   both in the same way - whether implementing a default, or raising an
   error.

The following fields fall into this classification (where an asterisk
identifies those fields which are variable-length as opposed to extensible).

  Class/gadget type           Null or empty
     and field

  Menu              
    title                     No title

  Menu entry
    text                      Blank entry

  Window
    title_text                Blank title-bar

  Action button
    text                      Blank button

  Option button
    label                     No label

  Labelled box
    label*                    No label

  Label
    label*                    No label

  Radio button
    label                     No label

  Display field
    text                      Empty display field

  Writable field
    text                      Field initially empty; if length = 0, then the
                              user cannot enter any data.

  Popup menu
    menu*                     ERR

  String set
    string_set                ERR
    initial_string            No ticked menu entry initially

  Prog Info
    purpose*                  Blank field
    author*                   Blank field
    version*                  Blank field

  SaveAs
    filename*                 Blank field
  

5  Implementation issues


5.1  Representation inside ResEd

Object template names - the unique fixed-length field - are dealt with
specially inside the shell; ResEd ensures that valid non-empty names are
attached to all objects inside resource files.


The value of a constant or assignable string field is represented as a char*
value which may be NULL, or otherwise addresses a (possibly empty)
zero-terminated string held in malloc'd storage. Whenever the value changes,
the old string is free'd, and space for the new one is malloc'd.

The length associated with an assignable string field is always greater than
or equal to the length of the string value plus one, or may be zero when
the string value is NULL.


5.2  User interface

Examples are given of dialogue box components for changing the value of a
string field; '#' stands for an option button, and a string inside angle
brackets indicates a writable field.

5.2.1  Optional constant string field

   Example:         # Show object  <str>

If the option button is selected, the value is given by <str>, the (possibly
empty) content of the writable field.

If the option button is not selected, the writable field is faded and the
value is null.


5.2.2  Optional assignable string field

   Example:         # Text  <str>  Length  <n>

If the option button is selected, the value is given by <str>, the (possibly
empty) content of the first writable field. The length of the field is set to
max(n, strlen(str)+1).

If the option button is not selected, the writable field is faded and the
value is null. The length of the field is set to <n>, the content of the
Length writable (which is *not* faded).


5.2.3  Mandatory constant string field

   Example:         Text  <str>

If the content of the writable <str> is empty, the value is null; otherwise,
the value is set equal to <str>.


5.2.4  Mandatory assignable string field

   Example:         Text  <str>  Length  <n>

If the content of the writable <str> is empty, the value is null, and the
length of the field is set to <n> (which may be equal to zero).

Otherwise, the value is set equal to <str>, and the length of the field is
set to max(n, strlen(str)+1)).


5.3  Possible extension

In many cases, assignable fields can, in fact, be treated as constant
fields: for example, help text is not usually changed dynamically by the
client application, and so it is almost always right that the length of a
help text field is exactly equal to the length of its value plus one.

However, updating an object's help text in ResEd will only ensure that the
new length is greater than or equal to the old length: ResEd never implicitly
shortens the length of a field, just in case it was set to an upper bound
for a good reason.

One way to help the ResEd user would be to define a special value (-1) of the
length field to mean "when creating an object containing this field, allocate
exactly sufficient buffer space for the current value and no more"; note that
this would require changes to the Toolbox as well as to ResEd.

Another way would be to define option flags held with objects in the resource
file which were interpreted by ResEd alone; one flag would be needed for
each assignable field. If the user typed a special character into the length
field (say *), then the options flag would be set and the length would be
calculated only when the template was saved. When the template was reloaded,
the state of the flag would tell ResEd to fill in the length field with an
asterisk again.
