# Section 8.2.1.2:
$BINARY

###### abstract class $BINARY

#### Formal Definitions

This abstract class defines a state component which is a set of all instantiations of objects of any class sub-typing from this class in addition to the vdm model types used wherever this class name is used. Note that SAME has to be an instantiated class, not an abstract one.

types
SAME = object_type ;
$BINARY = set of object_type
state
multi : $BINARY
inv multi_types ==
forall obj in set multi_types & sub_type($BINARY,obj)

NOTE | See the important note about vdm state in the notes on vdm-sl usage in this specification.

This abstract class models the concept of those features of an object which permit conversion between a model value and some externally usable bit-pattern as a string of OCTETs. The features which sub-types must provide shall be consistent with the general identity -

<create>(Value.<binstr>) = Value

#### create

This create routine is required to convert the given storage into an object of the type of self. It is an error if the binary string is not exactly the correct number of octets to form an object or there is any internal inconsistency in the bit-patterns which enable an implementation to reject the bit-pattern as being valid. The value returned under error conditions must be void!

create | (
| storage : BINSTR
| ) : SAME

##### Formal Signature

Being a creation routine the signature does not have a 'self' argument. Note that the type of the returned value is optional, since it may not be possible to retrieve a model value from the given binary string.

create(store : BINSTR) res : [SAME]

##### Pre-condition

This pre-condition should ideally make use of the binstr feature specified later. Since that would involve specifying the result in a pre-condition this cannot be done.

pre len str > 0

##### Post-condition

post res = nil
or binstr(res) = store

Provided that the size of the storage argument is exactly the amount of storage required for an object of this class as would be produced by application of the binstr routine to the result, then storage is converted into an object of the class which is returned.

#### build

This routine presumes that the next binary sub-string starting at the current position of the cursor can be converted into a valid model value. If this is possible then the appropriate value is returned and the cursor has been moved over the portion of the binary string used. If conversion was not possible then void shall be returned and the string cursor will be in the same position as it was when this routine was called.

build | (
| cursor : BIN_CURSOR
| ) : SAME

##### Formal Signature

This routine is another form of creation and, as such, takes no self parameter. Since retrieval of a model value may fail, the return type is an optional type.

build(cursor : BIN_CURSOR) res : [SAME]

##### Pre-condition

prenot BIN_CURSOR.is_done(cursor)

##### Post-condition

post res = nil
or let str = binstr(res),
initial_posn = BIN_CURSOR.index(cursor~) in
size = BIN_CURSOR.index(cursor) - initial_posn + 1 in
BINSTR.substring(BIN_CURSOR.buffer(cursor),initial_posn,size) = str

Provided that the binary string referred to by the cursor has at least the number of storage units (after the initial cursor position) required to produce a value of this class then the number of storage units required are used to do so and the cursor is moved to the next position on the binary string. Conversion failure shall result in void being returned and the cursor position not being changed.

#### read

This routine is provided for those cases where some internal structure is provided in the binary string indicated by the cursor. Should the next item in the string be the Boolean value true then an attempt is made to build a model object from the subsequent octets in the string. If the next item is the Boolean value false then void will be returned.

read |
| cursor : BIN_CURSOR
| ) : SAME

##### Formal Signature

This routine is another form of creation and, as such, takes no self parameter. Since retrieval of a model value may fail, the return type is an optional type.

read(cursor : BIN_CURSOR) res : [SAME]

##### Pre-condition

prenot BIN_CURSOR.is_done(cursor)

##### Post-condition

Despite the apparent simplicity of this routine, the post-condition must cater for the following cases :-

1. The next item indicated by the original cursor position in the string is neither the Boolean value true nor the value false.
2. The next item indicated is a valid Boolean value false.
3. The next item indicated is a valid Boolean value true but there is either insufficient following octets to form a model value or the buffer contents do not form a valid model value.
4. The next item indicated is a valid Boolean value true and retrieval of a valid model value from subsequent octets is accomplished.

post let initial_posn = BIN_CURSOR.index(cursor~),
truth_val = BOOL.create(BIN_CURSOR.item(cursor))in
<span="tab1">(res = nil
<span="tab2">and ((truth_val = nil
<span="tab4">and BIN_CURSOR.index(cursor) = initial_posn)
<span="tab3">or (not truth_val
<span="tab4">and BIN_CURSOR.index(cursor) = initial_posn + 1)
<span="tab3">or (truth_val
<span="tab4">and BIN_CURSOR.index(cursor) = initial_posn)))
or let str = binstr(res),
size = BIN_CURSOR.index(cursor) - initial_posn in
BINSTR.substring(BIN_CURSOR.buffer(cursor),initial_posn + 1,size) = str

This routine returns the next object in the indicated buffer providing that the next item is the boolean value for true, otherwise, if the next item is the Boolean value for false it returns void having moved past the item in the string. If neither of these conditions holds then void is returned and the cursor position has not been altered.

#### binstr

This feature returns a binary string representation of the object in an object-dependent form.

binstr | : BINSTR

##### Formal Signature

binstr(self : SAME) res : BINSTR

##### Pre-condition

Since the argument is not an optional type this is vacuously true.

pre true

##### Post-condition

See also the definition of the create routine above.

post create(res) = self

This routine returns a sequence of storage units representing the model value which is suitable for conversion back into the same model value.

#### write

This write routine provides for the situation where a file is being composed in several places/threads in an executing program - by appending to it the binary string representation of self.

write | (
| fyle : BIN_FILE
| )

##### Formal Signature

##### Pre-condition

pre BIN_FILE.is_open(fyle)
and BIN_FILE.writable(fyle)
and not BIN_FILE.error(fyle)

##### Post-condition

For the purposes of input and output from/to a file it must be remembered that a binary file is viewed as a sequence of octets buffer with a current 'cursor' position, thus

post let initial_posn = BIN_FILE.position(fyle~),
finish_posn = BIN_FILE.position(fyle) in
(finish_posn - initial_posn + 1 = len binstr(self))
and not BIN_FILE.error(fyle)

This routine appends a binary string representation of self to the given file (which must be open for writing/appending).

| Language Index |  | Library Index |  | Basic Index

Comments or enquiries should be made to Keith Hopper. Page last modified: Wednesday, 22 November 2000. |