The Store Service Class
The service class
Store contains the methods needed to manage data organized into
hierarchical fields and records. When dealing with language processing, program storage must
be viewed as containing a wide variety of different structures: indexes, lists, fixed
records, long unformatted records, variable length strings, and so on. In addition, it may be
purely memory bound or it may be stored in a persistent file system. The role of this service
class is to provide a single interface for storing and retrieving information. It uses the
LongMemory service class to manage its storage; therefore, it is sufficiently robust
to allow for the management of large files in the multiple gigabyte size range, while
it is still efficient for use by purely memory bound applications.
Physically, a storage area consists of a series of relatively large fixed sized blocks whose
boundaries cannot be crossed without software support. It is this unalterable property of
persistent storage that must be dealt with explicitly if an efficient information management
system is desired. The manner in which these blocks are created, maintained, and accessed is
determined when the storage area is created or opened. At a logical level the storage area is
viewed as consisting of a simple sequence of binary words -- long memory. All information
is stored on a word boundary and all offsets are expressed in terms of words.
The primary aspect of the approach used to achieve very rapid access times is
semi-permanent pointers. These are implemented via the
PagingSystem service
class. The basic idea is that a page pointer is a valid memory pointer until the block
which it contains is swapped out of memory. Thus, these pointers can be used safely within
local blocks of code where efficiency is needed, even though they cannot be saved and reused
over longer stretches of code.
The field langRoot
Prototype
The
langRoot field specifies the root of the language components in language file
The field langStore
Prototype
The
langStore field specifies the language storage area provider number.
The field userStore
Prototype
The
userStore field specifies the user storage area provider number.
The method Store_AddGlobal
Prototype
int Store_AddGlobal(int root,int global);
The
Store_AddGlobal method adds the root offset of a component, indexed by its parent
to a global index maintained within the storage area. This entry declares that the child
component has global scope if and only if the parent component is an active reference.
Its parameters are:
Parameter | Description
|
root | Specifies the root offset of a component that may have global scope.
|
global | Specifies the offset of the parent external library or class whose active
reference status triggers the global scope of its component.
|
If all goes well, the method returns a one. If the global, root pair already exists,
the method returns a zero.
The method Store_ChangeParent
Prototype
void Store_ChangeParent(int iRoot,int parent)
The
Store_ChangeParent method changes the parent of a component. Given the referential
complexity of the languages being processed, the compilers sometimes have to guess which
branch of the symbol table a given component belongs to. This method allows the caller to
change the parent and thus the branch of a previously entered component. This can only
be applied to components that are not on the root branch. Its parameters are:
Parameter | Description
|
iRoot | Specifies the root offset of the component in storage as originally returned
by the Store_Vector method.
|
parent | Specifies the root offset of the new parent component.
|
The method Store_Close
Prototype
The
Store_Close method closes the current storage area if that area is currently open.
It does not change the currently selected storage area.
The method Store_Create
Prototype
int Store_Create(char* filename,int iUnit);
The
Store_Create method creates a storage area. It selects the indicated storage
unit and initializes it as a new empty area whose content will be optionally paged into a
specified file. Any information currently in the storage area will be lost. Until another
storage area is selected all storage requests will be directed to this currently selected
storage area. Its parameters are:
Parameter | Description
|
filename | Contains the name of that file (optionally without an extension), if the storage
is to be paged into a file. If the storage is to be purely memory-based, then
this parameter should be NULL.
|
iUnit | Specifies the unit number of the desired storage area. The current implementation
supports upto Store_MaxUnit areas, so this must contain a value between 1
and Store_MaxUnit.
|
If all goes well a one (true) is returned. If there is a problem creating the storage area
a zero (false) is returned.
The method Store_DeltaVector
Prototype
void* Store_DeltaVector(int root);
The
Store_DeltaVector method gives write access to the information vector associated
with the component whose root offset is specified. If there is any question about the type of
component being accessed or about the validity of the root offset value, use the
Store_GetObjectType method first (see the discussion there). Any changes made to the
information vector will be saved. Use the
Store_GetVector method if the vector is to
be examined only. The parameter of this method is:
Parameter | Description
|
root | Specifies the root offset of component in storage.
|
This method returns a semi-permanent void pointer to the information vector. The storage
algorithm guarantees that there are no block boundaries with the vector, so the return value
is normally cast to a structure type.
The method Store_FindFirstChild
Prototype
int Store_FindFirstChild(int* levels,int iRoot);
The
Store_FindFirstChild method initiates a depth first, or preorder, search of the
symbol tree. Its parameters are:
Parameter | Description
|
levels | Receives information used internally by the search algorithm. It must have at
least two plus the maximum levels in the tree entries. Normal code structures
have no more than four levels -- project, class, subprogram, and local variable.
Controls defined via forms can often be nested more deeply. A size of 20 is
always safe. Note that levels[0] always receives the current nesting
level.
|
iRoot | Specifies the first node to be visited. If it> is non-zero, then the node with
this offset is visited first. If it is zero, then the first node in the tree is
visited first.
|
See the description of the method
Store_FindNextChild for information on how the next
node visited is determined. This method returns the offset of the first node visited or zero,
if the symbol tree is empty.
The method Store_FindGlobal
Prototype
int Store_FindGlobal(int symbolRoot,int libRoot)
The
Store_FindGlobal method determines if there is a global component in an external
that has a specified component name, indicated via its unique symbol root offset.
Its parameters are:
Parameter | Description
|
symbolRoot | Specifies the symbol root offset. It is normally obtained via a call to
the Store_FindRoot method.
|
libRoot | Specifies the offset of the external.
|
If the return value is negative then there are no globals with the specified name. If the
return value is zero, then the indicated external has no global component with the
specified name. A positive value is the root of a public component in the current external
with the specified name.
The method Store_FindNextChild
Prototype
int Store_FindNextChild(int* levels);
The
Store_FindNextChild method continues a depth first, or preorder search, of the
symbol tree. Its parameter is:
Parameter | Description
|
levels | Receives information used internally by the search algorithm. It must have been
initialized by the Store_FindFirstChild method.
|
In a depth first search, a visit to a node is followed immediately by visits to all
descendants of the node. There is a simple recursive algorithm for describing a depth first
search.
void depth_first_tree_search(node v, int level, void* info)
{
node u;
visit(v,level,info);
level++;
for(each child u of v) depth_first_tree_search(u,level,info);
}
This method returns the offset of the next node visited or zero, if there are no more nodes
to visit. Note that
levels[0] is always the value of
level in the above
algorithm
The method Store_FindRoot
Prototype
int Store_FindRoot(CONST char* identifier);
The
Store_FindRoot method searches the base symbol table for a specified identifier and
returns its root. This root unique for each identifier. Its parameters is:
Parameter | Description
|
identifier | Contains the identifier to be searched for in the symbol table in null-terminated
form.
|
If a component with the specified identifier is found within the symbol table then the root
offset of that component is returned. If no component can be found in the table, then a zero
is returned. Note this is the root of the symbol, not the root of any component that is
identified by it.
The method Store_FindVector
Prototype
int Store_FindVector(CONST char* identifier,int parent);
The
Store_FindVector method finds an identified information vector within a specified
single branch in the hierarchical symbol table. Its parameters are:
Parameter | Description
|
identifier | Contains a null-terminated string with the identifier to be searched for in the
specified branch of the symbol table.
|
parent | Specifies which branch of the symbol table is to be searched. If it is the root
branch of the symbol table is to be searched, then it should be set to zero. If
a child branch of a parent component, then it should be set equal to the root
offset of that parent component.
|
If a component with the specified identifier is found within the specified branch, then the
root offset of that component is returned. If no component can be found in the branch, then
a zero is returned.
The method Store_FirstReference
Prototype
int* Store_FirstReference(int symbolRoot,void* PostSet);
The
Store_FirstReference method returns the first reference record for a given symbol
or for any symbol as stored earlier by the
Store_Reference method. This reference is
assumed to have the following content:
Seq | Description 0f content
|
0 | The offset of the component containing the reference
|
1 | The offset of the component being referenced
|
2 | The text record number in the host file of the reference
|
3 | The offset in the compiled code of the reference code
|
4 | The offset of the information file containing the subprogram
|
5 | If the reference treated the component as terminal then one, else zero
|
Its parameters are:
Parameter | Description
|
symbolRoot | Specifies the offset of the symbol for which references are desired. If it is
zero, then all references are returned sorted by symbol referenced.
|
PostSet | Receives the information needed to control the search. It is a small scratch
storage area which must be allocated by the caller. Its content should not be
used by the caller. This area must be passed to the Store_NextReference
method to obtain additional reference records.
|
Note that as many simultaneous searches as desired may be conducted so long as each search has
its own unique
PostSet allocated. If there is at least one reference record available,
then a semi-permanent pointer to that record is returned. If there is no reference to the
specified symbol, or at all, then a NULL is returned.
The method Store_GetDataName
Prototype
char* Store_GetDataName(void);
The
Store_GetDataName method gets the name of the storage area. When a file-based
storage area is created or opened its name is stored in the storage control structure.
Additionally, the
Store_SetName method can be used to supply an alternative name
or to supply an actual name to areas that have no supporting file. This method returns
that name as a null-terminated string. This string may be empty, but never NULL.
The method Store_GetFirst
Prototype
int Store_GetFirst(int parent);
The
Store_GetFirst method returns the first child of a parent component or of the root
branch. This is the first component entered for the parent. In general, using this method in
conjunction with the
Store_GetNext method, will generate the sequence of components
stored within some branch of the symbol table in their defined order. Its parameters is:
Parameter | Description
|
parent | Specifies the root offset of the parent component or zero if the first member of
the root branch in the symbol table is desired.
|
If there is a first child of the specified component then this method returns its root
offset. If there is no first child, then this method returns a zero.
The method Store_GetGlobals
Prototype
int Store_GetGlobals(int symbolRoot,int* globals,int nGlobal);
The
Store_GetGlobals method returns the global root pairs added to a symbol identifier
via the
Store_AddGlobal method. The description of that method contains a detailed
description of these pairs. Its parameters are:
Parameter | Description
|
symbolRoot | Specifies a root offset in the base symbol index as returned by the
Store_FindRoot method.
|
globals | Receives the pairs added to the specified symbol.
|
nGlobal | Specifies the length of the globals vector. No more than nGlobal
entries will be stored int globals.
|
The method returns the number of entries returned in the vector. This is two times the
number of pairs.
The method Store_GetHandle
Prototype
void* Store_GetHandle(void);
The
Store_GetHandle method gets the
LongMemory handle of the current storage
area. All storage areas are maintained within a
LongMemory area. Though most access
needs for that memory area are provided here, it is occasionally necessary to use the
LongMemory methods, or one of the specialized stream access methods directly.
This method returns the handle to the underlying
LongMemory instance, if the storage
area is open; else a NULL is returned.
The method Store_GetIdent
Prototype
char* Store_GetIdent(int root,int* nIdent)
The
Store_GetIdent method returns the identifier of a component that was placed in
storage using the
Store_Vector method. By definition, the "identifier" is the original
identifier that was associated with the component when it was first placed in the symbol
table. Its parameters are:
Parameter | Description
|
root | Specifies the root offset of component in storage as originally returned by the
Store_Vector method.
|
nIdent | returns the length of the identifier.
|
The method returns a semi-permanent character pointer to the identifier of the component.
The method Store_GetInfo
Prototype
int Store_GetInfo(int addr,int* info);
The
Store_GetInfo method reads the information vector stored at the address specified.
Its parameters are:
Parameter | Description
|
addr | Specifies the address of the information vector. That vector is stored along with
its length.
|
info | Receives the content of the information vector. It is up to the user to ensure
that it has sufficient room. See the method Store_GetLength to obtain its
length in advance.
|
The method returns the length of the information vector as stored in
info in bytes.
The method Store_GetLength
Prototype
int Store_GetLength(int offset);
The
Store_GetLength method returns length information about the storage areas of about
vectors store in that area. Its parameters is:
Parameter | Description
|
offset | Specifies what length information is wanted. If it is zero, then the length in
words of the currently selected storage area is returned. If it is not zero but
less than the number of possible storage units Store_MaxUnit, then the
length in words of that unit is returned. If it is greater than the possible
number of storage units, then the length in bytes of the information stored at
the specified offset is returned.
|
Regardless of the value of the parameter
offset, if the current storage area is empty,
then this method returns zero.
The method Store_GetMessage
Prototype
char* Store_GetMessage(int number,int* nString)
The
Store_GetMessage method gets a message stored in the global message cache.
Its parameters are:
Parameter | Description
|
number | Specifies number of the message.
|
nString | returns the length of the message.
|
If the message exists, the method returns a pointer to the message string. If the message
does not exist, then a NULL is returned.
The method Store_HasName
Prototype
int Store_HasName(int root);
The
Store_HasName method returns a one if a symbol has a separate name defined and
returns zero if it does not. Its parameter is:
Parameter | Description
|
root | Specifies the root offset of the symbol whose name status is needed.
|
The method Store_GetName
Prototype
char* Store_GetName(int root,int* nIdent);
The
Store_GetName method returns the name of a component that was placed in storage
using the
Store_Vector method or was set using the method
Store_SetName.
Its parameters are:
Parameter | Description
|
root | Specifies the root offset of component in storage.
|
nIdent | returns the length of the name.
|
The method returns a semi-permanent character pointer to the name of the component as it
was originally specified when the component was first entered into the symbol table or that
was entered later using
Store_SetName.
The method Store_GetNext
Prototype
int Store_GetNext(int child);
The
Store_GetNext method returns the next child of a parent component or of the root
branch. This is the next component entered for the parent. In general, using this method in
conjunction with the
Store_GetFirst method, will generate the sequence of components
stored within some branch of the symbol table in their defined order. Its parameter is:
Parameter | Description
|
child | Specifies the root offset of the current child component as returned by
Store_GetFirst or a previous call this method.
|
If there is a next child of the parent of the specified component, then this method returns
its root offset. If there is no next child, then this method returns a zero.
The method Store_GetObjectType
Prototype
int Store_GetObjectType(int root);
The
Store_GetObjectType method gets the object type of a component. Whenever a
component is entered into the symbol table via the
Store_Vector method it is assigned
an integer object type code. Each object type code has associated with it a fixed-length
information vector used to describe components of the specified type. Before accessing the
information vector for a component using either of the methods
Store_GetVector or
Store_DeltaVector, if there is any possible doubt about a root offset, it is good
practice to call this method first to make certain that the root offset is in fact well
formed and does in fact belong to a component of the expected type. Its parameter is:
Parameter | Description
|
root | Specifies the root offset of a component in storage.
|
If the root offset passed to this method has a value less than or equal to zero, then this
method displays the following message and returns a zero.
SYSERR#5001: Object Type requested for invalid root %root%
If the root offset passed to this method has a value that exceeds the maximum possible
offset, this method displays the following message and returns a zero.
SYSERR#5002: Object Type requested for invalid root %root%
If the root offset is not obviously malformed, then this method returns the object type code
as stored the symbol table entry at the specified root offset.
The method Store_GetParent
Prototype
int Store_GetParent(int root);
The
Store_GetParent method returns the root offset of the parent of a specified
component or a zero if the component is in the root branch of the symbol table. Its
parameter is:
Parameter | Description
|
root | Specifies the root offset of the component in storage as originally returned by
the Store_Vector method.
|
The method Store_GetString
Prototype
char* Store_GetString(int addr,int* nString);
The
Store_GetString method returns a semi-permanent pointer to a string in storage
that was previously saved using the
Store_String method. Note that the string is not
necessarily bounded by a null-byte. Its length is also returned by this method. Its
parameters are:
Parameter | Description
|
addr | Specifies the offset of the string in storage as returned by the
Store_String method.
|
nString | returns the length of the string.
|
The method returns a semi-permanent character pointer to the start of the string. The caller
can assume that there are no block-boundaries within the string.
The method Store_GetSymbols
Prototype
int Store_GetSymbols(char* identifier);
The
Store_GetSymbols method returns the root offset of a sequence that contains the
root offsets of all symbols whose identifier matches a specified one. The symbol table has a
tree structure. The symbols within the tree need be unique along one branch only. As a result
of this, there can be many duplicates in the symbol table. The roles of the symbol retrieval
methods are to search the symbol tree for the correct occurrence of an identifier given a
current parent context -- i.e., the typical question asked is "Does a given parent node have
a child with the specified identifier". This question must be asked for every parent in the
current scope in scope order. This turns out to be a very difficult problem. The simplest
approach is to go through each branch on the symbol table in current scope order and see if
the identifier can be found on that branch. But there are many branches, especially if a
global symbol is being sought, so this process can require many individual searches. To make
matters even worse, the required searches are string searches which require time consuming
string comparisons as opposed to simple integer comparisons. The approach used separates the
search into two parts. First there is a base index in the symbol table that contains one
entry for each unique symbol defined anywhere in the current code set. This is the only index
that uses string keys. Associated with this entry for each symbol there is a secondary index
that uses integer parent node roots as the key and the root of the actual information vector
for the identifier in its form within that parent. The parameter of this message is:
Parameter | Description
|
identifier | Contains the identifier whose entries are desired.
|
This method searches the base index for the specified identifier using the method
Store_FindRoot. If found, it returns the root offset of a sequence maintained there
that contains the root offsets of the symbols with that name stored in the order that they
were defined. If no symbol with the specified name is present, a zero is returned.
The method Store_GetVector
Prototype
void* Store_GetVector(int root);
The
Store_GetVector method gives readonly access to the information vector associated
with the component whose root offset is specified. If there is any question about the type of
component being accessed or about the validity of the root offset value, use the
Store_GetObjectType method first (see the discussion there). Any changes made to the
information will generally not be saved. Use the
Store_DeltaVector method if the
vector is to be changed. The parameter of this method is:
Parameter | Description
|
root | Specifies the root offset of the component in storage.
|
The method returns a semi-permanent void pointer to the information vector. The storage
algorithm guarantees that there are no block boundaries with the vector, so the return
value is normally cast to a structure type.
The method Store_IssueMessage
Prototype
int Store_IssueMessage(CONST char* format,int number,char* Strings[],int nString,int Values[],int nValue);
The
Store_IssueMessage method issues a stored message. It retrieves a patterned
message from a specified storage unit, combines it with the supplied string and integer
parameters, and then writes the completed message to the log file using a specified format.
Its parameters are:
Parameter | Description
|
format | Contains a printf-style format to be used.
|
number | Specifies the number of message to be used.
|
Strings | Contains the string values to be supplied.
|
nString | Specifies the number of string values.
|
values | Contains the integer values to be supplied.
|
nValue | Specifies the number of integer values.
|
If a message was actually written to the log file, then this method returns the length of
that message else it return 0.
The method Store_LinkedString
Prototype
int Store_LinkedString(char* String,int nString,int link);
The
Store_LinkedString method stores a character string preceded by its length and by
an integer link in such a way that no block boundaries are crossed. It is this convention
that makes it possible to use a semipermanent pointer to access the character string and its
associated link later. It has the following parameters:
Parameter | Description
|
String | Contains the character string to be stored. It need not be null-terminated as its
length is supplied explicitly.
|
nString | Specifies the length of character string being stored.
|
link | Specifies a simple value that is stored along with the string. Usually this will be
an offset of some other information previously stored in the area but may be any
integer value.
|
The methods within this
Store class do not make any assumptions about the content of
the
String or
link parameter therefore, they can be used to store any fixed
length byte sequence with an information associated integer value.
The method returns offset in the storage area of the string. This offset can be used later
to retrieve the string using the standard
Store_GetString method. This offset can also
be used later to obtain or change the link value using the methods
Store_LinkGet or
Store_LinkSet.
The method Store_LinkGet
Prototype
int Store_LinkGet(int addr);
The
Store_LinkGet method gets the string associated link for a string that was originally
stored by the
Store_LinkedString method using the offset returned by that method.
Its parameter is:
Parameter | Description
|
addr | Specifies the location of the string whose link is wanted. It must be the offset
returned by the Store_LinkedString method when the string and its link were
originally stored.
|
The method returns the value of the link as retrieved from the storage area. This may be the
original value or a value as changed by the
Store_LinkSet method.
The method Store_LinkSet
Prototype
void Store_LinkSet(int addr,int link);
The
Store_LinkSet method sets the string associated link for a string that was originally
stored by the
Store_LinkedString method using the offset returned by that method.
Its parameters are:
Parameter | Description
|
addr | Specifies the location of the string whose link is to be changed. It must be the
offset returned by the Store_LinkedString method when the string and its link
were originally stored.
|
link | Specifies the new link value to be associated with the string as returned by the
method Store_LinkGet.
|
The typical use of this method is to create linked lists. The user retains the locations of
the current first and last members of the list as it is being created. The link value of the
last member added is always originally set to zero. As new members are added the previous
member's link value is set to the location of the new member.
The method Store_Message
Prototype
void Store_Message(int number,char* String,int nString);
The
Store_Message method stores a message in the global message cache.
Its parameters are:
Parameter | Description
|
number | Specifies the number of the message.
|
String | Contains the actual message.
|
nString | Specifies the length of the message.
|
The method Store_NextReference
Prototype
int* Store_NextReference(void* PostSet);
The
Store_NextReference method finds the next reference to a symbol. Once a reference
search is started via
Store_FirstReference, this method is used to find successive
references. Note that when a symbol specific search is being performed, the references to
that symbol are followed by references to a later symbol. The caller must check the symbol
referenced entry if only one symbol's references are desired. Each reference record is
assumed to have the following content:
Seq | Description 0f content
|
0 | The offset of the component containing the reference
|
1 | The offset of the component being referenced
|
2 | The text record number in the host file of the reference
|
3 | The offset in the compiled code of the reference code
|
4 | The offset of the information file containing the subprogram
|
5 | If the reference treated the component as terminal then one, else zero
|
Its parameter is:
Parameter | Description
|
PostSet | Receives the information needed to control the search. It is a small scratch
storage area which must be allocated by the caller. Its content should not be
used by the caller. This area must be initialized with the
Store_FirstReference method.
|
If there is an additional reference record available, then a semi-permanent pointer to that
record is returned. If there is no additional reference, then a NULL is returned.
The method Store_Open
Prototype
int Store_Open(char* filename,int iUnit,int append);
The
Store_Open method opens an existing storage area. It selects the indicated storage
unit and initializes it with the contents of a existing file. Any information currently in
the storage area will be lost. Until another storage area is selected, all storage requests
will be directed to this currently selected storage area. Its parameters are:
Parameter | Description
|
filename | Contains the name of the file (without an extension) to be opened for the
storage area.
|
iUnit | Specifies the unit number of the desired storage area. The current implementation
supports upto Store_MaxUnit areas, so this integer must contain a value
between 1 and Store_MaxUnit.
|
append | Specifies the access permission for the file. If it is nonzero (true), then the
file is opened with read/write access permission. If zero (false), then the file
is opened for read only access.
|
If all goes well a one (true) is returned. If there is a problem opening the storage area
because the file does not exist zero (false) is returned.
The method Store_PostVector
Prototype
int Store_PostVector(char* identifier,int parent,int length,int type);
The
Store_PostVector method posts a component information vector. It is a secondary
method used to enter components into the hierarchical symbol table. To enter a symbol four
things must be known. First it must have a unique identifier relative to the parent of
the symbol. Second it must have a parent which can either be another symbol already entered
into storage or can be the root of the symbol hierarchy. Third it must have a information
storage vector length. A zero-filled area of storage is allocated to the component with the
specified length. Fourth. it must have an object type code, which specifies the type of
component being entered. This method checks first to see if the component is already present.
If not, it stores it. The parameters of this method are:
Parameter | Description
|
identifier | Contains the identifier of component in null-terminated form.
|
parent | Specifies root offset of the parent of the component, if the component is the
child of a previously stored component. If the component has no parent -- i.e., if
it belongs in the root of the symbol table then this should be set to zero.
|
length | Specifies the length of information vector to be allocated for use by this
component.
|
type | Specifies the component object type code to be assigned to the component table.
|
If there already is a component with the same identifier stored in the specified branch of
the symbol table, then its root address is returned; else the component is stored and then
the new root offset is returned.
The method Store_ReadFront
Prototype
int Store_ReadFront(void* info,int offset,int nFront);
The
Store_ReadFront method reads a front part of a long information vector that was
initially written using the method
Store_WriteInfo. A physical read is required since
these information vectors may cross block boundaries, thus making semi-permanent pointers
inappropriate. This method should be used when the information storage area receiving the
read in not necessarily large enough to contain the entire vector that is in storage.
Its parameters are:
Parameter | Description
|
info | Receives the information read. It must have sufficient room to contain
the nFront bytes.
|
offset | Specifies the starting offset of the information as originally returned by the
Store_WriteInfo method.
|
nFront | Specifies the maximum number of bytes to be read.
|
The method returns the number of bytes actually read.
The method Store_ReadInfo
Prototype
int Store_ReadInfo(void* info,int offset);
The
Store_ReadInfo method reads long information vectors that were initially written
using the method
Store_WriteInfo A physical read is required since these information
vectors may cross block boundaries, thus making semi-permanent pointers inappropriate.
Its parameters are:
Parameter | Description
|
info | Receives the information read. It must have sufficient room to contain the entire
vector (see Store_ReadFront).
|
offset | Specifies the starting offset of the information as originally returned by the
Store_WriteInfo method.
|
The method returns the length of the information vector read in bytes.
The method Store_Reference
Prototype
void Store_Reference(int* reference);
The
Store_Reference method stores a reference record. The storage area maintains a
sorted list of reference records sorted by the offset of the symbol being referenced. During
the compilation process symbols are encountered by a referencing component. This method is
used to order them by the component being referenced so that those references can be used
by the analyser and auditor. This method actually stores an individual reference record,
which is assumed to have the following content:
Seq | Description 0f content
|
0 | The offset of the component containing the reference
|
1 | The offset of the component being referenced
|
2 | The text record number in the host file of the reference
|
3 | The offset in the compiled code of the reference code
|
4 | The offset of the information file containing the subprogram
|
5 | If the reference treated the component as terminal then one, else zero
|
Note that the reference information allows the later retrieval not only of the referencing
pseudocode but also the actual source statement that generated the reference. Its parameter
is as follows:
Parameter | Description
|
reference | Contains the 6 integer values that describe a single reference stored within
the pcode created by a language compiler.
|
The method Store_RewriteInfo
Prototype
void Store_RewriteInfo(void* info,int nByte,int offset);
The method
Store_RewriteInfo rewrites long information vectors that were initially
written using the method
Store_WriteInfo. The number of bytes in the new vector may
not exceed the original length of this information. If they do, then the following system
error warning is displayed
SYSERROR#50003: Rewriting "current" bytes over "previous" bytes.
Its parameters are:
Parameter | Description
|
info | Contains the information to be written.
|
nByte | Specifies the length of the information.
|
offset | Contains the starting offset of the information as originally returned by the
Store_WriteInfo method.
|
The method Store_Select
Prototype
void Store_Select(int Unit);
The
Store_Select method selects one of the available storage areas as the current
storage area. All successive storage area accesses will be performed to this area until
another call to this method is made. Note that this method only selects the area, it does not
change it in any way. Its parameter is:
Parameter | Description
|
Unit | Specifies the unit sequence number of the desired storage area. It must have a
value between 1 and Store_MaxUnit.
|
The method Store_SeqClose
Prototype
void Store_SeqClose(void* sequence);
The
Store_SeqClose method closes a sequence in storage. This method is needed to close
any sequences accessed via the
Store_SeqCreate or
Store_SeqOpen methods. In
addition to closing these sequences, this method also frees the memory used to contain the
control structure. Its parameter is:
Parameter | Description
|
sequence | Specifies the handle to the sequence control structure.
|
The method Store_SeqCreate
Prototype
void* Store_SeqCreate(int BlockSize);
The
Store_SeqCreate method creates a sequence in the current storage area. A sequence
is an open ended list of entries. They are used frequently by the language processing system.
See the description of the
Sequence service class for more information. This method is
provided to simplify creating sequences within the current storage area. Sequences created
via this method must be closed with the
Store_SeqClose method to ensure that all
resources are properly closed. Its parameter is:
Parameter | Description
|
BlockSize | Specifies the size of each block within the sequence. It is normally a small
value like 8 or 16.
|
The method returns the handle for the created sequence.
The method Store_SeqOpen
Prototype
void* Store_SeqOpen(int seqRoot);
The
Store_SeqOpen method opens an existing sequence in the current storage area. A
sequence is an open ended list of entries. They are used frequently by the language
processing system. See the description of the
Sequence class for more information.
This method is provided to simplify opening sequences within the current storage area.
Sequences opened via this service must be closed with the
Store_SeqClose method to
ensure that all resources are properly closed. Its parameter is:
Parameter | Description
|
seqRoot | Specifies the root offset of the sequence in the storage area. It would have been
the value of the Sequence_GetRoot method for the sequence when it was
created.
|
The handle for the opened sequence is returned.
The method Store_SetCaseSensitive
Prototype
void Store_SetCaseSensitive(int on);
The
Store_SetCaseSensitive method sets the cases sensitivity of string keys. It does
not effect how they are stored, only how they are compared. Its parameter is:
Parameter | Description
|
on | Specifies how string keys are to be compared. If nonzero, there are case
sensitive; else they are case insensitive
|
The method Store_SetName
Prototype
void Store_SetName(int root,CONST char* Name,int nName);
The
Store_SetName method sets the name of a component or of the overall storage area.
Whenever a component is stored in the symbol table using the
Store_Vector method that
component is given an identifier by the caller. This identifier can then used to retrieve the
component, and by default is used by the author whenever references to the component are
being written. If references are to be authored with a alternate identifier (referred to as
the "name" of the component) then this method is used to associate that name with the
component. Alternatively the storage area itself is given the name of the file that
contains it when the area is either created or opened. This method can be used to
supply an alternative name or to supply an actual name to areas that have no supporting file.
Its parameters are as follows:
Parameter | Description of content
|
root | Specifies the root offset of component in storage as originally returned by the
Store_Vector method if a component name is being supplied. An offset value
of zero sets the storage area name.
|
name | Contains the name to be assigned to the component or area.
|
nName | Specifies the length of the name to be assigned. If it has a value of zero then
name parameter is assumed to be null-terminated and this method computes its
length.
|
The method Store_SetObjectType
Prototype
void Store_SetObjectType(int root,int objType);
The
Store_SetObjectType method sets the object type of a component. Whenever a
component is entered into the symbol table it is assigned and integer object type code. Each
object type code has associated with it a fixed-length information vector used to describe
components of the specified type. There are occasionally instances of components that are
misclassified when they are initially stored. This method allows the user to change the
object type code. Note that this method does not change the size of the information vector
associated with the component, so great care must be exercised in the use of this method.
See the method
Store_SwitchVectors for an alternative way of reclassifying
components. The parameters of this method are:
Parameter | Description
|
root | Specifies the root offset of the component in storage as originally returned by
the Store_Vector method.
|
objType | Specifies the new object type code to be assigned to the component.
|
The method Store_SetRawCharacters
Prototype
void Store_SetRawCharacters(int status);
The
Store_SetRawCharacters method sets the raw character flag which controls the check
for the VB6 terminating type characters. Its parameter is:
Parameter | Description
|
status | Specifies the status of the check. If it is zero, then the check will be made.
If not zero, then the check will not be made.
|
The method Store_SetString
Prototype
void Store_SetString(int addr,char* string,int length);
The
Store_SetString method sets the content of an existing string. There are
occasionally situations where a string is edited without changing its length. In this case,
this method can be used to restore the string content. Do not use this method if the length
of the string has increased, simply use
Store_String to rewrite it and to obtain a new
offset. Its parameters are:
Parameter | Description
|
addr | Specifies the offset of the string in storage as returned by the
Store_String method.
|
string | Contains the new value of the string.
|
length | Specifies the length of the string.
|
It is up to the user to ensure that this length does not exceed the length of the string
when it was initially stored.
The method Store_String
Prototype
int Store_String(char* String,int nString);
The
Store_String method stores a character string preceded by its length in such a way
that no block boundaries are crossed. It is this convention that makes it possible to use a
semipermanent pointer to access the character string later. Obviously the length of string
must be less than the pagesize being used in the underlying physical storage of the blocks.
Its parameters are:
Parameter | Description
|
String | Contains the character string to be stored. It need not be null-terminated as its
length is supplied explicitly.
|
nString | Specifies the length of character string being stored.
|
The method returns the offset in the storage area of the string. This offset can be used
later to retrieve the string.
The method Store_SwitchVectors
Prototype
void Store_SwitchVectors(int root1,int root2);
The
Store_SwitchVectors method switches the information associated with one component
with that associated with another. Its parameters are:
Parameter | Description
|
root1 | Specifies the root offset of the first component of the switch.
|
root2 | Specifies the root offset of the second component of the switch.
|
The method Store_Unit
Prototype
The
Store_Unit method returns the value of the current storage unit. This is the
unit number of the currently selected storage area. It has a value between 1 and
Store_MaxUnit.
The method Store_Vector
Prototype
int Store_Vector(CONST char* identifier,int parent,int length,int type);
The
Store_Vector method stores a component information vector. It is the primary
method used to enter components into the hierarchical symbol table. To enter a symbol four
things must be known. First, it must have a unique identifier relative to the parent of
the symbol. Second, it must have a parent, which can either be another symbol already entered
into storage or can be the root of the symbol hierarchy. Third, it must have a information
storage vector length. A zero-filled area of storage is allocated to the component with the
specified length. Fourth. it must have an object type code, which specifies the type of
component being entered. Its parameters are:
Parameter | Description
|
identifier | Contains the identifier of the component in null-terminated form. It must be
unique relative to its parent.
|
parent | Specifies root offset of the parent of the component, if the component is the
child of a previously stored component. If the component has no parent, if it
belongs in the root of the symbol table, then this parameter should be zero.
|
length | Specifies the length of information vector to be allocated for use by this
component.
|
type | Specifies the component object type code to be assigned to the component.
|
If there already is a component with the same identifier stored in the specified branch of
the symbol table, then a zero is returned by this method; else the nonzero root offset of
the component is returned. It is this root offset which must be used to manipulate or
retrieve any information for the component.
The method Store_WriteInfo
Prototype
int Store_WriteInfo(void* info,int nByte);
The
Store_WriteInfo method writes long information vectors into storage. There is no
limit to the length of this information. Since block boundaries may occur within the storage
area used, semi-permanent pointers should not be used to access the record, rather the
methods
Store_ReadInfo and
Store_RewriteInfo should be used. Its parameters
are:
Parameter | Description
|
info | Contains the information to be written.
|
nByte | Specifies the length of the information.
|
If the number of bytes to be written is not well-formed -- i.e., is less than or equal to
zero, this method displays the following message and returns a zero.
SYSERR#5004: Empty or negative length (%nbyte%) record being written.
Else, the method returns the offset in the start of the storage area for the information.
This offset can be used later to retrieve the information.
The method Store_ZeroFirst
Prototype
void Store_ZeroFirst(int parent);
The
Store_ZeroFirst method zeros the offset of the first child of a nonterminal
component in the symbol table. This causes this component to be terminal. Its parameter is:
Parameter | Description
|
parent | Specifies the root offset of the component whose status is to be changed.
|