Be Sure To: Lock the block on the global heap (unless it is fixed).
Warnings: The bytes you delete must all be in the chunk. If
deleteOffset
and
deleteCount
indicate bytes that are not in the chunk, results are undefined.
Include: lmem.h
See Also: LMemReAlloc()
,
LMemInsertAt()
,
LMemDeleteAtHandles()
.
void LMemDeleteAtHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle ch, /* Handle of chunk to resize */ word deleteOffset, /* Offset within chunk of first * byte to be deleted */
word deleteCount); /* # of bytes to delete */
This routine is exactly like
LMemDeleteAt()
above, except that the chunk is specified by its global and chunk handles.
Be Sure To: Lock the block on the global heap (unless it is fixed).
Warnings: The bytes you delete must all be in the chunk. If
deleteOffset
and
deleteCount
indicate bytes that are not in the chunk, results are undefined.
Include: lmem.h
void * LMemDeref( optr chunk); /* optr to chunk to dereference */
This routine translates an optr into the address of the chunk. The LMem heap must be locked or fixed on the global heap. Chunk addresses can be invalidated by many LMem routines, forcing you to dereference the optr again.
Be Sure To: Lock the block on the global heap (unless it is fixed).
Include: lmem.h
See Also: LMemDerefHandles()
.
void * LMemDerefHandles( MemHandle mh, /* Handle of LMem heap's block */ ChunkHandle chunk); /* Handle of chunk to dereference */
This routine is exactly like
LMemDeref()
above, except that the chunk is specified by its global and chunk handles.
Be Sure To: Lock the block on the global heap (unless it is fixed).
Include: lmem.h
See Also: LMemDeref()
.
void LMemFree( optr chunk); /*optr of chunk to free */
This routine frees a chunk from an LMem heap. The chunk is added to the heap's free list. The routine is guaranteed not to compact or resize the heap; thus, all pointers within the block remain valid (except for pointers to data in the freed chunk, of course).
Be Sure To: Lock the block on the global heap (unless it is fixed).
Include: lmem.h
See Also: LMemFreeHandles()
.
void LMemFreeHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle chunk); /* Handle of chunk to free */
This routine is just like
LMemFree()
above, except that the chunk is specified by its global and chunk handles (instead of by an optr).
Be Sure To: Lock the block on the global heap (unless it is fixed).
Include: lmem.h
word LMemGetChunkSize( optr chunk); /* optr of subject chunk */
This routine returns the size (in bytes) of a chunk in an LMem heap. Since LMem chunks are dword-aligned, the chunk's size may be slightly larger than the size specified when it was allocated. The routine is guaranteed not to compact or resize the heap; thus, all pointers within the block remain valid.
Be Sure To: Lock the block on the global heap (unless it is fixed).
Include: lmem.h
See Also: LMemGetChunkSizeHandles()
.
word Routine( MemHandle mh, /* Handle of LMem heap */ ChunkHandle chunk); /* Handle of chunk in question */
This routine is just like
LMemGetChunkSize()
above, except that the chunk is specified by its global and chunk handles (instead of by an optr).
Be Sure To: Lock the block on the global heap (unless it is fixed).
Include: lmem.h
See Also: LMemGetChunkSize()
.
void LMemInitHeap( MemHandle mh, /* Handle of (locked or fixed) * block which will contain heap */
LMemType type, /* Type of heap to create */ LocalMemoryFlags flags, /* Record of LocalMemoryFlags */ word lmemOffset, /* Offset of first chunk in heap */ word numHandles, /* Size of starter handle table */ word freeSpace); /* Size of first free chunk * created */
This routine creates an LMem heap in a global memory block. The block must be locked or fixed in memory. The routine initializes the
LMemBlockHeader
, creates a handle table, allocates a single free chunk, and turns on the HF_LMEM flag for the block. The block will be reallocated if necessary to make room for the heap. The routine takes six arguments:
mh
type
LMemType
enumerated type, specifying the kind of block to create. For most applications, this will be LMEM_TYPE_GENERAL.
flags
LocalMemoryFlags
, specifying certain properties of the heap. Most applications will pass a null record.
lmemOffset
LMemBlockHeader
structure which begins every heap block. Any space between the
LMemBlockHeader
and the heap is left untouched by all LMem routines. Usually you can just pass sizeof(
LMemBlockHeader
) as this argument, or sizeof(
ObjLMemBlockHeader
) for object blocks.
numHandles
freeSpace
To destroy an LMem heap, call
MemFree()
to free the block containing the heap.
Structures: There are two special data types used by this routine:
LMemType
and
LocalMemoryFlags
.
LMem heaps are created for many different purposes. Some of these purposes require the heap to have special functionality. For this reason, you must pass a member of the
LMemType
enumerated type to specify the kind of heap to create. The following types can be used; other types exist but should not be used with
LMemInitHeap()
.
When an LMem heap is created, you must pass a record of flags to
LMemInitHeap()
to indicate how the heap should be treated. Most of the
LocalMemoryFlags
are only passed by system routines; the flags available for this routine are: LMF_HAS_FLAGS, LMF_DETACHABLE, LMF_NO_ENLARGE, LMF_RETURN_ERRORS. The flags can be read by examining the
LMemBlockHeader
structure at the beginning of the block. Ordinarily, general LMem heaps will have all flags cleared.
Tips and Tricks: If you want a fixed data space after the header, declare a structure whose first element is an
LMemBlockHeader
and whose other fields are for the data you will store in the fixed data space. Pass the size of this structure as the
LMemOffset
argument. You can now access the fixed data area by using the fields of the structure.
Be Sure To: Pass an offset at least as large as
sizeof(LMemBlockHeader)
. If you pass an offset that is too small, the results are undefined. Lock the block on the global heap before calling this routine (unless the block is fixed).
Warnings: The block may be relocated, if its initial size is too small to accommodate the heap. This is true even for fixed blocks. If the flag LMF_NO_ENLARGE is set, the block will never be relocated; however, you must make sure it starts out large enough to accommodate the entire heap.
Include: lmem.h
See Also: LMemBlockHeader
,
LMemType
,
LocalMemoryFlags
,
MemAlloc()
,
MemAllocLMem()
,
MemFree()
,
VMAllocLMem()
.
void LMemInsertAt( optr chunk, /* optr of chunk to resize */ word insertOffset, /* Offset within chunk of first byte * to be added */
word insertCount); /* # of bytes to add */
This routine inserts space in the middle of a chunk and zero-initializes the new space. The first new byte will be at the specified offset within the chunk.
Be Sure To: Lock the block on the global heap (unless it is fixed). Make sure the offset is within the specified chunk.
Warnings: This routine may resize or compact the heap; thus, all pointers to data within the block are invalidated.
You must pass an
insertOffset
that is actually within the chunk; if the offset is out-of-bounds, results are undefined.
Include: lmem.h
See Also: LMemReAlloc()
,
LMemDeleteAt()
,
LMemInsertAtHandles()
.
void LMemInsertAtHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle chunk, /* Chunk to resize */ word insertOffset, /* Offset within chunk of first byte * to be added */
word insertCount); /* # of bytes to add */
This routine is just like
LMemInsertAt()
above, except that the chunk is specified by its global and chunk handles (instead of by an optr).
Be Sure To: Lock the block on the global heap (unless it is fixed). Make sure the offset is within the specified chunk.
Warnings: This routine may resize or compact the heap; thus, all pointers to data within the block are invalidated.
You must pass an
insertOffset
that is actually within the chunk; if the offset is out-of-bounds, results are undefined.
Include: lmem.h
Boolean LMemReAlloc( optr chunk, /* optr of chunk to resize */ word chunkSize); /* New size of chunk in bytes */
This routine resizes a chunk in an LMem heap. The heap must be in a locked or fixed block. If the routine succeeds, it returns zero. If it fails (because the heap ran out of space and could not be expanded), it returns non-zero.
If the new size is larger than the original size, extra bytes will be added to the end of the chunk. These bytes will not be zero-initialized. The heap may have to be compacted or resized to accommodate the request; thus, all pointers to data within the block are invalidated.
If the new size is smaller than the old, the chunk will be truncated. The request is guaranteed to succeed, and the chunk will not be moved; neither will the heap be compacted or resized. Thus, all pointers to other chunks remain valid. Reallocating a chunk to zero bytes is the same as freeing it.
Be Sure To: Lock the block on the global heap (unless it is fixed).
Warnings: As noted, if the new size is larger than the old, the heap may be compacted or resized, invalidating pointers.
Include: lmem.h
See Also: LMemReAllocHandles()
,
LMemInsertAt()
,
LMemDeleteAt()
.
Boolean LMemReAllocHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle chunk, /* Handle of chunk to resize */ word chunkSize); /* New size of chunk in bytes */
This routine is just like
LMemReAlloc()
above, except that the chunk is specified by its global and chunk handles (instead of by an optr).
Be Sure To: Lock the block on the global heap (unless it is fixed).
Warnings: As noted, if the new size is larger than the old, the heap may be compacted or resized, invalidating pointers.
Include: lmem.h
WWFixedAsDWord LocalAsciiToFixed( const char * buffer, char ** parseEnd);
This routines converts a string like "12.345" to a fixed point number. The pointer pointed to by parseEnd will be returned pointing into the buffer after the last character parsed.
Include: localize.h
word LocalCalcDaysInMonth( word year, word month);
This routine computes the number of days in a given month.
sword LocalCmpStrings( const char * str1, const char * str2, word strSize);
This routine compares two strings to determine which comes first in a lexical (i.e. alphabetic) ordering. If the return value is negative, then str1 is earlier than str2 . If the return value is positive, then str1 is later than str2 . If the return value is zero, then the strings appear at the same place in alphabetical order.
Include: localize.h
sword LocalCmpStringsDosToGeos( const char * str1, const char * str2, word strSize, word defaultChar, LocalCmpStringsDosToGeosFlags flags);
This routine compares two strings to determine which comes first in lexical ordering. Either or both of these strings may be a DOS string. If the return value is negative, then str1 is earlier than str2 . If the return value is positive, then str1 is later than str2 . If the return value is zero, then the strings appear at the same place in alphabetical order.
Structures:
typedef ByteFlags LocalCmpStringsDosToGeosFlags; /* The following flags may be combined using | and &: * LCSDTG_NO_CONVERT_STRING_2, * LCSDTG_NO_CONVERT_STRING_1 */
Include: localize.h
sword LocalCmpStringsNoCase( const char * str1, const char * str2, word strSize);
This routine compares two strings to determine which comes first in a lexical (i.e. alphabetic) ordering. The comparison used is not case-sensitive. If the return value is negative, then str1 is earlier than str2 . If the return value is positive, then str1 is later than str2 . If the return value is zero, then the strings appear at the same place in alphabetical order.
Include: localize.h
sword LocalCmpStringsNoSpace( const char *str1, const char *str2, word strSize);
This routine compares two strings to determine which comes first in a lexical (i.e. alphabetic) ordering. The comparison ignores spaces. If the return value is negative, then str1 is earlier than str2 . If the return value is positive, then str1 is later than str2 . If the return value is zero, then the strings appear at the same place in alphabetical order.
sword LocalCmpStringsNoSpaceCase( const char *str1, const char *str2, word strSize);
This routine compares two strings to determine which comes first in a lexical (i.e. alphabetic) ordering. The comparison ignores spaces and is case-insensitive. If the return value is negative, then str1 is earlier than str2 . If the return value is positive, then str1 is later than str2 . If the return value is zero, then the strings appear at the same place in alphabetical order.
Boolean LocalCodePageToGeos( char * str, word strSize, /* Size of the string, in bytes */ DosCodePage codePage, word defaultChar);
This routine converts a DOS string to standard GEOS text using a specified code page. Any characters for which there is no GEOS equivalent will be replaced by the passed default character.
Include: localize.h
word LocalCodePageToGeosChar( word ch, DosCodePage codePage, word defaultChar);
This routine converts a DOS character to standard GEOS text using a specified code page. Any character for which there is no GEOS equivalent will be replaced by the passed default character.
Include: localize.h
word LocalCustomFormatDateTime( char * str, /* Buffer to save formatted text in */ const char * format, /* Format string */ const TimerDateAndTime *dateTime);
This routine takes a date or time and constructs a string using a custom format.
Include: localize.h
word LocalCustomParseDateTime( const char * str, DateTimeFormat format, TimerDateAndTime * dateTime);
This routine parses a date and time string by comparing it with the passed
DateTimeFormat
. It fills in the fields of the
TimerDateAndTime
structure. Any fields which are not specified in the format string will be filled with -1.
If the string parses correctly,
LocalCustomParseDateTime()
returns -1. Otherwise it reutrns the offset to the start of the text which did not parse correctly.
Include: localize.h
WWFixedAsDword LocalDistanceFromAscii( const char * buffer, DistanceUnit distanceUnits, MeasurementTypes measurementType);
This routine takes a function like "72 pt" and returns a number representing the distance. The returned answer represents the measure in points, inches, centimeters, or some other measure as specified by the passed unit.
Include: localize.h
word LocalDistanceToAscii( /* Length of string, including NULL */ char * buffer, /*Buffer to save formatted text in */ word value, DistanceUnit distanceUnits, MeasurementType measurementType);
This routine takes a distance and a set of units and returns a string containing a properly formatted distance.
Include: localize.h
Boolean LocalDosToGeos( char * str, word strSize, word defaultChar);
Convert a DOS string to GEOS text. Any characters for which there is no GEOS equivalent will be replaced by the passed default character.
Include: localize.h
word LocalDosToGeosChar( word ch, word defaultChar);
Convert a DOS character to GEOS text. Any characters for which there is no GEOS equivalent will be replaced by the passed default character.
Include: localize.h
word LocalDowncaseChar( word ch);
Return the lower case equivalent, if any, of the passed character.
Include: localize.h
void LocalDowncaseString( char * str, word size); /* Size of string, in bytes */
Convert the passed string to its all lower case equivalent.
Include: localize.h
void LocalFixedToAscii( char * buffer, WWFixedAsDWord value, word fracDigits);
This routine returns the ASCII expression of a fixed point number.
Include: localize.h
word LocalFormatDateTime( /* Length of returned string */ char * str, DateTimeFormat format, const TimerDateAndTime * dateTime);
This routine returns the string (e.g. "9:37") corresponding to the passed DateAndTime.
Include: localize.h
word LocalFormatFileDateTime( char *str, DateTimeFormat format, const FileDateAndTime *dateTime);
This utility routine provides a simple way to present a
FileDateAndTime
structure such as used with file-related operations.
Structures:
typedef struct { byte numberFormatFlags; /* NumberFormatFlags value */ byte decimalDigits; wchar thousandsSeparator; wchar decimalSeparator; wchar listSeparator; } LocalNumericFormat;
The first byte is a
NumberFormatFlags
field specifying whether or not to use a leading zero. The second byte is the number of digits to show after the decimal point.
Include: localize.h
Boolean LocalGeosToCodePage( char * str, word strSize, DosCodePage codePage, word defaultChar);
Convert a GEOS string to DOS text, using the specified code page. Any characters for which there is no DOS equivalent will be replaced by the passed default character.
Include: localize.h
word LocalGeosToCodePageChar( word ch, DosCodePage codePage, word defaultChar);
Convert a GEOS character to DOS text, using the specified code page. Any character for which there is no DOS equivalent will be replaced by the passed default character.
Include: localize.h
Boolean LocalGeosToDos( char * str, word strSize, word defaultChar);
Convert a GEOS string to DOS text. Any characters for which there is no DOS equivalent will be replaced by the passed default character.
Include: localize.h
word LocalGeosToDosChar( word ch, word defaultChar);
Convert a GEOS character to DOS text. Any character for which there is no DOS equivalent will be replaced by the passed default character.
Include: localize.h
DosCodePage LocalGetCodePage(void);
This routine returns the current code page, used by DOS to handle international character sets.
Include: localize.h
void LocalGetCurrencyFormat( LocalCurrencyFormat * buf, char * symbol);
This routine returns the current currency format and symbol.
Include: localize.h
void LocalGetDateTimeFormat( char * str, DateTimeFormat format);
This routine returns the user's preferred time and date formats.
Include: localize.h
word LocalGetLanguage(void); /* Returns a StandardLanguage value */
This routine returns the user machine's language.
MeasurementTypes LocalGetMeasurementType(void);
This routine returns the user preference between US and metric measurement systems.
Include: localize.h
void LocalGetNumericFormat( LocalNumericFormat * buf);
This routine returns the user's preferred format for numbers.
Include: localize.h
void LocalGetQuotes( LocalQuotes * quotes);
This routine returns the user's preferred quote marks.
Include: localize.h
Boolean LocalIsDateChar( word ch);
This routine returns true if the passed character could be part of a date or time.
Include: localize.h
Boolean LocalIsDosChar( word ch);
This routine returns true if the passed character is part of the DOS character set.
Include: localize.h
Boolean LocalIsNumChar( word ch);
This routine returns true if the passed character is a number or part of the number format.
Include: localize.h
Boolean LocalIsSymbol( word ch);
This routine returns true if the passed character is a symbol.
Include: localize.h
Boolean LocalIsTimeChar( word ch);
This routine returns true if the passed character is a number or part of the user's time format.
Include: localize.h
word LocalLexicalValue( word ch);
This routine returns the passed character's lexical value, useful when trying to sort strings alphabetically.
Include: localize.h
word LocalLexicalValueNoCase( word ch);
This routine returns the passed character's case-insensitive lexical value, useful when trying to sort strings alphabetically.
Include: localize.h
Boolean LocalParseDateTime( /* Returns FALSE on failure */ const char * str, DateTimeFormat format, TimerDateAndTime * dateTime);
This routine takes a string describing a date or time (e.g. "9:37") and parses it using the passed format.
Include: localize.h
void LocalSetCurrencyFormat( const LocalCurrencyFormat * buf, const char * symbol);
This routine changes the stored preferred currency format.
Include: localize.h
void LocalSetDateTimeFormat( const char * str, DateTimeFormat format);
This routine changes the stored preferred time and date format.
Include: localize.h
void LocalSetMeasurementType( MeasurementTypes meas);
This routine changes the stored preferred measurement type.
Include: localize.h
void LocalSetNumericFormat( const LocalNumericFormat * buf);
This routine changes the stored preferred number format.
Include: localize.h
void LocalSetQuotes( const LocalQuotes * quotes);
This routine changes the stored preferred quote marks.
Include: localize.h
word LocalStringLength( const char * str);
This routine returns the length (in characters) of a null-terminated string (not counting the null), even for multibyte character sets.
Include: localize.h
word LocalStringSize( const char * str);
This routine returns the size (in bytes) of a null-terminated string.
Include: localize.h
word LocalUpcaseChar( word ch);
This routine returns the upper case equivalent, if any, of the passed character.
Include: localize.h
void LocalUpcaseString( char * str, word size);
This routine converts the passed string to its all upper case equivalent.
Include: localize.h
void LogAddEntry( LogEntry *logEntry);
This function adds an entry to the Contact log. (The Contact log keeps track of what calls the user has sent to and received from each of their contacts; this is the function that logs a call.) The function takes on argument, a
LogEntry
structure.
typedef struct { NameOrNumber LE_number; dword LE_contactID; LogEntryType LE_type; LogEntryDirection LE_direction; dword LE_duration; DateAndTime LE_datetime; LogEntryFlags LE_flags; } LogEntry;
Normally, this function is invoked twice for each call--once at the start of the call, and again when the call is done.
When invlking the function at the start of the call, set up the
LogEntry
structure. Fill in the
LE_number
and/or
LE_contactID
fields if you know the contact's name, number, or
RecordID
number, Fill in the
LE_type
field with one of LET_CALL, LET_FAX, LET_SMS, LET_DATA_MAILBOX, LET_DATA_WWW, or LET_DATA_TELNET. Fill in the
LE_direction
field with one of LED_SENT, LED_RECEIVED, or LED_MISSED. The LE_duration should be zero. Fill in the
LE_datetime
field with the current date and time. (The
TimerGetDateAndTime()
function returns this information.) Leave the
LE_flags
field alone.
Keep the structure around after you call the routine; it will fill in some of the fields. Then when the call is complete, fill in the
LE_duration
field and invoke the function again. The
LE_duration
field should contain the call's duration in seconds. One way to compute this time is to call
TimerGetCount()
twice: once at the start of the call and once at the end. By subtracting the start time from the end time and dividing by 60, one can compute the number of seconds that passed.
Having invoked the function a second time, the program may safely free the
LogEntry
structure.
Include: contlog.goh
See Also: TimerGetDateAndTime()
,
TimerGetCount()
.
void LogDeleteAllEntries();
This function deletes all entries in the contact log.
Include: contlog.goh
void LogDestroy();
This function deletes the contact log's log file.
Include: contlog.goh
void MailboxAcknowledgeMessageReceipt( MailboxMessage msg);
This routine tells the Mailbox library that the application has taken control of the message msg. msg will be visually removed from the system inbox only when this function is called.
Warning:
When the mailbox receives a message targeted for an application, it sends that application the message MSG_META_MAILBOX_NOTIFY_MESSAGE_AVAILABLE
. Should the application not acknowledge the message with
MailboxAcknowledgeMessageReceipt()
and the application exits and restarts, the application will again be notified of the message's availability.
Include: mailbox.h
MailboxError MailboxBodyReformatted( MailboxMessage msg, MailboxDataFormat newFormat, MailboxMessageFlags newBodyFlags);
This routine changes the format indication of the message msg to newFormat and sets the MailboxMessageFlags
newBodyFlags to either MMF_BODY_DATA_VOLATILE
or MMF_DELETE_BODY_AFTER_TRANSMISSION
. This routine does not alter the contents of msg msg.If msg is invalid then a MailboxError
will be generated.
The MailboxDataFormat
structure is formatted as:
typedef struct { word MDF_id; /*GeoworksMailboxDataFormatID*/ ManufacturerID MDF_manuf; } MailboxDataFormat;
Warning:
MailboxBodyReformatted()
is used to change the format of msg in-place. To create a copy of a message in a new format, use
MailboxChangeBodyFormat()
.
Include: mailbox.h
MailboxError MailboxChangeBodyFormat( MailboxMessage msg, const MailboxChangeBodyFormatArgs *mcbfArgs);
This routine replaces the format and the body of the message msg with mcbfArgs. If msg is invalid or the body is in use, then a MailboxError
will be generated.
Warning:
MailboxChangeBodyFormat()
should be used when creating a copy of a message in a new format. To reformat the message in-place, use
MailboxBodyReformatted()
.
Include: mailbox.h
void MailboxChangeToMailboxDir(void);
This routine changes the application's current working directoryto the directory where the Mailbox library holds its message bodies and administrative files.
Warning: This is primarily intended for use by data and transport drivers.
Include: mailbox.h
Boolean MailboxCheckMediumAvailable( MediumType mediumType, word unitNum, MediumUnitType unitType);
If the transmission medium mediumType
exists, then this routine returns TRUE
(non-zero); otherwise, it returns FALSE
(zero). Since the Mailbox library cannot control the comings and goings of the different media, there is no guarantee that a medium which exists now will exist later.
For example, if a modem PCMCIA card is inserted, then
the DATA_MODEM medium will be available (and the unit number will be the
SERIAL_COMx constant by which the modem can be reached). When the PCMCIA card
is removed, then that medium will no longer be available and
MailboxCheckMediumAvailable()
will return FALSE
.
Warning: If unitType is a MUT_MEM_BLOCK
(a handle to other data), it means that the Mailbox library will take responsibility for freeing the memory block. In this case, the application should no longer reference the handle it passed in as the unit number.
Include: mailbox.h
Boolean MailboxCheckMediumConnected( MediumType mediumType, word unitNum, MediumUnitType unitType);
Sees if the Mailbox library has been told whether a connection over the specified transmission medium exists. The medium is not guaranteed to remain connected once this call returns, as the Mailbox library has no control over connections, usually. This routine returns non-zero if, while the call was in-progress, the medium using MediumType
mediumType, unit number unitNum (ignored if unitType is set to MUT_NONE
), and MediumUnitType
unitType were connected; otherwise, the routine returns zero.
Warning: If unitType is a MUT_MEM_BLOCK
(a handle to other data), it means that the Mailbox library will take responsibility for freeing the memory block. In this case, the application should no longer reference the handle it passed in as the unit number.
Include: mailbox.h
void MailboxDeleteMessage(MailboxMessage msg);
This routine lets the Mailbox library know that it is free to delete the message msg. This routine should only be called after the application has called
MailboxAcknowledgeMessageReceipt()
to acknowledge that it has finished handling the message.
Include: mailbox.h
void MailboxDoneWithBody( MailboxMessage msg, const void *appRef, word appRefSize);
This routine indicates that the body reference appRef returned by an earlier call to
MailboxGetBodyRef()
will no longer be used, so the data driver is free to close the file, etc. appRef points to the body of the message msg, and appRefSize refers to the size of this body, in bytes.
Warning: After calling this routine, no further use of the body via appRef may be made.
Include: mailbox.h
void MailboxDoneWithVMFile( VMFileHandle file);
Lets the Mailbox know that the application is done using the file file, a parameter which was returned from
MailboxGetVMFile()
. The Mailbox library is free to close file after this routine is called.
Include: mailbox.h
void MailboxFreeDriver( GeodeHandle driverHandle);
This routine unloads the driver driverHandle previously loaded by the Mailbox library.
Note that a call to
MailboxLoad...Driver()
should be balanced with a call to
MailboxFreeDriver()
.
See Also: MailboxLoadDataDriver()
MailboxLoadDataDriverWithError()
MailboxLoadTransportDriver()
Include: mailbox.h
VMFileHandle MailboxGetAdminFile(void);
Returns the handle of the main administrative VM file that is maintained by the Mailbox library.
Warning: The returned file should NOT be used for general storage of data. This routine is intended to allow applications that wish to
register a message without the aid of a MailboxSendControl
to
create the transData
argument required by the transport driver
they've chosen, should the driver expect something to be
allocated within the admin file.
Include: mailbox.h
This document is in Beta. Ride at your own risk. Mail us your comments and suggestions
MailboxError MailboxGetBodyFormat( MailboxMessage msg, MailboxDataFormat *dataFormat);
This routine gets the MailboxDataFormat
token of the message msg and copies it into dataFormat. It returns a MailboxError
if the routine is invalid.
Include: mailbox.h
MailboxError MailboxGetBodyMboxRefBlock( MailboxMessage msg, MemHandle *mboxRefHandle);
Fetches the opaque mailbox reference to the message body of message msg and stores it in the block mboxRefHandle. This returned block contains a mailbox reference structure specific to the Data Driver. Examples are:
/* for mailbox data drivers that use VMChains */ typedef { dword VMTMR_vmChain; TCHAR VMTMR_filename[]; } VMTreeMboxRef; /* for mailbox data drivers that use raw data files */ typedef { Boolean FMR_deleteAfterTransmit; word FMR_diskDataOffset; word FMR_diskDataLen; word FMR_filenameLen; byte FMR_filenameAndDiskData[]; /* start of null-terminated filename, * followed by diskData (at * FMR_diskDataOffset). */ } FileDDMboxRef;The routine returns
ME_INVALID_MESSAGE
if the message is invalid, or ME_NOT_ENOUGH_MEMORY
if the block of data could not be created.
Note: This routine is normally used by the mailbox drivers, not by applications.
Include: mailbox.h
MailboxError MailboxGetBodyRef( MailboxMessage msg, void *appRefBuf, word *appRefBufSize);
This routine retrieves the address of the message body of the message msg in the format understood and used by applications registering a message with the Mailbox library, the app-reference. The definitions of app-reference structures are defined in the documentation for each of the various communication methods, e.g. the SMS chapter. This reference to the body is copied into the buffer appRefBuf. appRefBufSize initially points to the size of this buffer in bytes, and then it is set to the number of bytes that were copied into the buffer. In the case of an error (msg is invalid, the library is unable to load the driver, there is insufficient memory, the app-ref buffer too small, there is no message body available) a MailboxError
will be generated.
Warning:
Each call to this routine must be matched by a call to
MailboxDoneWithBody()
.
Include: mailbox.h
MailboxError MailboxGetDestApp( MailboxMessage msg, GeodeToken *tokenBuf);
Gets the GeodeToken
for the destination application from the message msg and copies it into tokenBuf. This routine returns ME_INVALID_MESSAGE
if the passed MailboxMessage is invalid.
Include: mailbox.h
MailboxError MailboxGetEndBound( MailboxMessage msg, FileDateAndTime *dateTime);
Fetches the end bound of the message msg and copies it into dateTime. If the message is invalid, this routine returns ME_INVALID_MESSAGE
.
See Also: MailboxGetStartBound()
Include: mailbox.h
word MailboxGetFirstMediumUnit( MediumType mediumType, MediumUnitType *unitType);
Puts the first available unit of the indicated MediumType
mediumType into unitType. This should be used when a transport driver just wants to use a particular medium but doesn't care which one. This routine returns the unit number.
Warning:
Do not call this for a medium that doesn't use unit numbers. You will generate a fatal-error in the error-checking version, and won't get any additional information in the non-error-checking version (since the return will be MUT_NONE
whether there's an available unit or not). Use
MailboxCheckMediumAvailable()
instead. Also remember, if unitType is a handle to other memory because it is a MUT_MEM_BLOCK
, it will be your responsibility to free the associated memory block.
Include: mailbox.h
MailboxError MailboxGetMessageFlags( MailboxMessage msg, MailboxMessageFlags *flags);
Retrieves the MailboxMessageFlags
for the message msg and copies them into flags. If the message is invalid, ME_INVALID_MESSAGE
is returned.
Include: mailbox.h
MailboxError MailboxGetNumTransAddrs( MailboxMessage msg, word *numAddresses);
Retrieves the number of transport addresses bound to the message msg and stores that number in numAddresses. If msg is in the inbox, then numAddressess is set to zero. If the number of addresses can't be obtained, then the routine returns ME_INVALID_MESSAGE
.
See Also: MailboxGetTransAddr()
Include: mailbox.h
MailboxError MailboxGetStartBound( MailboxMessage msg, FileDateAndTime *dateTime);
Fetches the start bound of the message msg and copies it into dateTime. If the message is invalid, this routine returns ME_INVALID_MESSAGE
.
See Also: MailboxGetEndBound()
Include: mailbox.h
MailboxError MailboxGetStorageType( MailboxMessage msg, MailboxStorage *storage);
This routine gets the MailboxStorage
token for the message msg and copies it into storage. If the message is invalid, ME_INVALID_MESSAGE
is returned.
Include: mailbox.h
MailboxError MailboxGetSubjectBlock( MailboxMessage msg, MemHandle *subjHandle);
Retrieves the null-terminated subject/summary of the message msg and copies it into a global memory block, then puts the associated MemHandle
into subjHandle. Returns ME_INVALID_MESSAGE
if msg is invalid or ME_NOT_ENOUGH_MEMORY
if there isn't sufficient memory to create the block.
Include: mailbox.h
MailboxError MailboxGetSubjectLMem( MailboxMessage msg, MemHandle lmemBlock, ChunkHandle *subjectChunk);
Retrieves the subject/summary of the message msg and copies it into a local memory block lmemBlock, and puts the ChunkHandle
for this null-terminated subject into subjectChunk. Returns ME_INVALID_MESSAGE
if msg is invalid or ME_NOT_ENOUGH_MEMORY
if there isn't sufficient memory to create the block.
Include: mailbox.h
Boolean MailboxGetTransAddr( MailboxMessage msg, word addrNumber, void *addressBuffer, word *bufSizePtr);
This routine retrieves the addrNumber-th transport address from the message msg and copies the address into addressBuffer. bufSizePtr should initially point to the size of the buffer in bytes and, if the routine works successfully, it will be set to the number of bytes that were actually copied into addressBuffer. If the addrNumber is invalid because it is either too large or the message doesn't exist, then bufSizePtr will be set to zero. If the buffer isn't large enough to store the address, then bufSizePtr is set to the number of bytes required. The routine returns zero (FALSE
) if an error occurred, otherwise it returns non-zero.
See Also: MailboxGetNumTransAddrs()
MailboxGetUserTransAddrLMem()
MailboxSetTransAddr()
Include: mailbox.h
MailboxError MailboxGetTransData( MailboxMessage msg, dword *transData);
Puts the 32-bit transport data registered with the message msg into transData. If msg is an invalid message then the routine returns ME_INVALID_MESSAGE
.
See Also: MailboxSetTransData()
Include: mailbox.h
MailboxError MailboxGetUserTransAddrLMem( MailboxMessage msg, word addrNumber, MemHandle lmemBlock, ChunkHandle *addrChunk);
Retrieves a user-readable transport address from a message. The input parameters are the message msg, the address number addrNumber, and the handle of the lmem block lmemBlock in which to place the string. The routine copies the null-terminated string into this block, and sets addrChunk to point to the string's chuck. There are three errors that could occur: if addrNumber is not valid, ME_ADDRESS_INVALID
is returned; if msg is not valid, ME_INVALID_MESSAGE
is returned; and if there is insufficient memory to create the chunk, ME_NOT_ENOUGH_MEMORY
is returned;
See Also:MailboxGetTransAddr()
Include: mailbox.h
This document is in Beta. Ride at your own risk. Mail us your comments and suggestions
VMFileHandle MailboxGetVMFile( word expectedNumBlocks, word *vmStatusp);
This routine obtains the handle of a writable VM file in which data can be stored. The file is managed by the Mailbox library, so the data stored in it can be passed off to the library without being marked as MMF_BODY_DATA_VOLATILE
.
Parameters:
Returns: If successful, this routine returns a VMFileHandle
to a writable VM File. If it fails, it returns NullHandle
and sets vmStatusp.
Include: mailbox.h
void MailboxGetVMFileName( VMFileHandle file, FileLongName *namep);
Gets the name of a VM file file which was previously opened by the Mailbox library. This file resides in the Mailbox library's spool directory. namep is a buffer in which to place the file's FileLongName
, a null-terminated file name.
Warning:
MailboxGetVMFileName()
is used primarily by data storage drivers to obtain a persistent reference to the body of a message since file handles aren't preserved across shutdowns or file closes.
Include: mailbox.h
GeodeHandle MailboxLoadDataDriver( MailboxStorage storage, GeodeLoadError *error);
MailboxLoadDataDriver()
loads the specified data storage driver.
Parameters:
MailboxStorage
token of the requested data storage driver.GeodeLoadError
should the driver not load properly.
Return: If this routine is successful, it returns the handle of the loaded driver. Otherwise, the error is put into error.
This driver should be unloaded using
MailboxFreeDriver()
.
Include: mailbox.h
GeodeHandle MailboxLoadDataDriverWithError( MailboxStorage storage, GeodeLoadError *error);
MailboxLoadDataDriverWithError()
loads the specified data storage driver. If the driver can't be loaded then the error message error will be used to prompt the user to make the driver available, with the option to retry the load.
Parameters:
MailboxStorage
token of the requested data storage driver.
MailboxLoadDataDriver()
.Return: If this routine is successful, it returns the handle of the loaded driver. Otherwise, the error is put into error.
This driver should be unloaded using
MailboxFreeDriver()
.
Include: mailbox.h
GeodeHandle MailboxLoadTransportDriver( MailboxTransport transport, GeodeLoadError *error);
MailboxLoadTransportDriver()
loads the transport driver with the MailboxTransport
token transport and returns the handle of the driver. If the driver can't be loaded, then the GeodeLoadError
is put into error.
The driver should be unloaded using
MailboxFreeDriver()
.
Include: mailbox.h
VMFileHandle MailboxOpenVMFile( FileLongName *namep, word *vmStatusp);
Reopens a VM file that was previously returned by
MailboxGetVMFileName()
, and whose name namep was obtained through MailboxGetVMFileName
. If successful, the routine returns a VMFileHandle
to the VMFile
. If there is an error, this routine returns NullHandle
with vmStatusp
filled in with the appropriate VMStatus
value.
Warning:
Any call to this routine must be matched with a call to
MailboxDoneWithVMFile()
.
Include: mailbox.h
void MailboxPushToMailboxDir();
This routine performs a
FilePushDir()
followed by a
MailboxChangeToMailboxDir()
.
Include: mailbox.h
MailboxError MailboxRegisterMessage( MailboxRegisterMessageArgs *mrmArgs, MailboxMessage *msg);
The routine registers a message with the system. A message consists of the information the system needs to properly process that message, the MailboxRegisterMessageArgs
mrmArgs, and the body data of the message itself, msg. The body data are copied, if necessary, or simply taken-possession-of by the system.
You can find examples of filling in MailboxRegisterMessageArgs
in the chapters that discuss the various communication methods, such as
the SMS chapter.
Include: mailbox.h
MailboxError MailboxSetTransAddr( MailboxMessage msg, word addrNumber, const void *newAddress, word addrSize);
Sets the opaque transport address of the addrNumber-th address for the message msg to newAddress, replacing the existing one. addrSzie is the size of the new address buffer, in bytes. This routine returns ME_INVALID_MESSAGE
if msg is invalid or ME_NOT_ENOUGH_MEMORY
if there is not enough memory.
Warning: The new address may not differ from the old address in its significant address bytes. This is not intended to allow arbitrary redirection of a message, but simply for transport drivers to record their progress for a particular address in the insignificant portion of the address.
See Also: MailboxGetTransAddr()
Include: mailbox.h
MailboxError MailboxGetTransData( MailboxMessage msg, dword transData);
This routine replaces the 32-bit transport data registered with the message msg with transData. If the message is invalid then the routine returns ME_INVALID_MESSAGE
; if successful, it returns ME_SUCCESS
.
Warning:
The caller is responsible for freeing any resources referred to by the previous dword
transport data since the Mailbox library places absolutely no interpretation on the transData
, and thus cannot know what needs to be freed when one transData
dword replaces another.
See Also: MailboxGetTransAddr()
Include: mailbox.h
MailboxError MailboxStealBody( MailboxMessage msg, void *appRefBuf, word *appRefBufSize);
This routine lets an application take possession of the body of the message msg. It puts the app-reference to the body in appRefBuf. The app-reference structure defined for each communication mode is defined in the documentation for that communication mode, e.g.
the SMS chapter.
The application is responsible for destroying the data associated with this app-reference. If the message body is within a VM file, the application is responsible for calling
MailboxDoneWithVMFile()
after freeing the data that make up the body. The parameters for this routine are the message msg, a pointer appRefBuf to an app-reference, and a word appRefBufSize that points to the size of appRefBuf, in bytes. appRefBufSize is then filled with the number of bytes that are put into appRefBuf.
The possible errors are ME_INVALID_MESSAGE, ME_NOT_ENOUGH_MEMORY, ME_CANNOT_LOAD_DATA_DRIVER, ME_CANNOT_LOAD_TRANSPORT_DRIVER, ME_APP_REF_BUF_TOO_SMALL, ME_CANNOT_OPEN_MESSAGE_FILE,
and ME_CANNOT_READ_MESSAGE_FILE
.
Include: mailbox.h
WWFixed MakeWWFixed(number);
This macro casts a floating-point or integer number to a
WWFixed
value.
Include: geos.h
void * malloc( size_t blockSize); /* # of bytes to allocate*/
The
malloc()
family of routines is provided for Standard C compatibility. If a geode needs a small amount of fixed memory, it can call one of the routines. The kernel will allocate a fixed block to satisfy the geode's
malloc()
requests; it will allocate memory from this block. When the block is filled, it will allocate another fixed malloc-block. When all the memory in the block is freed, the memory manager will automatically free the block.
When a geode calls
malloc()
, a section of memory of the size specified will be allocated out of its malloc-block, and the address of the start of the memory will be returned. The memory will
not
be zero-initialized. If the request cannot be satisfied,
malloc
will return a null pointer. The memory is guaranteed not to be moved until it is freed (with
free()
) or resized (with
realloc()
). When GEOS shuts down, all fixed blocks are freed, and any memory allocated with
malloc()
is lost.
Using too many fixed blocks degrades the memory manager's performance, slowing the whole system. For this reason, applications should not use
malloc
-family routines if they can possibly be avoided. They are provided only to simplify porting of existing programs; however, applications should make every effort to use the GEOS memory management and LMem routines instead. If you must use the
malloc
-family routines, use them sparingly, and free the memory as quickly as possible.
Tips and Tricks: You can allocate memory in another geode's malloc-block by calling
GeoMalloc()
. However, that block will be freed when the other geode exits.
Warnings: All memory allocated with
malloc()
is freed when GEOS shuts down.
Include: stdlib.h
See Also: calloc()
,
free()
,
GeoMalloc()
,
realloc()
.
word ManufacturerFromFormatID(id); ClipboardItemFormatID id;
This macro extracts the word-sized manufacturer ID (of type
ManufacturerIDs
) from a
ClipboardInfoFormatID
argument.
MemHandle MemAlloc( word byteSize, /* Size of block in bytes */ HeapFlags hfFlags, /* Type of block */ HeapAllocFlags haFlags); /* How to allocate block */
This routine allocates a global memory block and creates an entry for it in the global handle table. The properties of the block are determined by the
HeapFlags
record passed; the way the block should be allocated is determined by the
HeapAllocFlags
record. Both sets of flags are described below. The routine returns the block's handle. If it could not allocate the block, it returns a null handle. The block allocated may be larger than the size requested, as the block size is rounded up to the next even paragraph (one paragraph equals sixteen bytes).
HeapFlags
are stored in the block's handle table entry. They can be retrieved with the routine
MemGetInfo()
; some of them can be changed with the routine
MemModifyFlags()
. The following flags are available:
LMemInitHeap()
and
VMAllocLMem()
; applications should not need to set this flag.
HeapAllocFlags
indicate how the block should be allocated and initialized. They are not stored and can not be retrieved. Some of the flags can be passed with
MemReAlloc()
. The following flags are available:
MemReAlloc()
to cause new memory to be zero-initialized.
MemDeref()
. This flag may be passed to
MemReAlloc()
.
MemReAlloc()
.If necessary, this routine will automatically compact the heap to find enough space to allocated the desired sized block.
Include: heap.h
See Also: MemAllocSetOwner()
,
MemReAlloc()
,
MemDeref()
.
MemHandle MemAllocLMem( LMemType type, /* type of LMem block */ word headerSize); /* size of header structure */
This routine allocates and initializes a local memory block; it can be used to simplify this procedure from the two-step process of
MemAlloc()
followed by
LMemInitHeap()
. Pass an LMem type indicating what will be stored in the block, along with the size of the header structure to use. If the block is to have the standard header, pass zero in
headerSize
.
This routine returns the handle of the unlocked, newly allocated block. The block will contain two LMem handles and 64 bytes allocated for the LMem heap.
Include: lmem.h
See Also: LMemInitHeap()
.
MemHandle MemAllocSetOwner( GeodeHandle owner, /* Handle of block's owner */ word byteSize, /* Size of block in bytes */ HeapFlags hfFlags, /* Type of block */ HeapAllocFlags haFlags); /* How to allocate block */
This routine is the same as
MemAlloc()
except that you can specify the owner of the global memory block created.
Include: heap.h
See Also: MemAlloc()
.
void MemDecRefCount( MemHandle mh); /* handle of affected block */
This routine decrements the reference count of a global memory block (the reference count is stored in HM
_otherInfo
). If the reference count reaches zero,
MemDecRefCount()
will free the block.
Warnings: This routine assumes that a reference count is stored in HM
_otherInfo
. You may only use this routine if the block has had a reference count set up with
MemInitRefCount()
.
Include: heap.h
void * MemDeref( MemHandle mh); /* Handle of locked block to dereference */
This routine takes one argument, the handle of a global memory block; it returns the address of the block on the global heap. If the block has been discarded, or if the handle is not a memory handle, it returns a null pointer. It gets this information by reading the block's handle table entry; it does not need to actually access the block.
Note that if the handle is of an unlocked, moveable block,
MemDeref()
will return the block's address with out any warning; however, the address will be unreliable, since the memory manager can move the block at any time.
Include: heap.h
Tips and Tricks: This is very useful when you allocate a fixed or locked block, and need to get the block's address without calling
MemLock()
.
Warnings: This routine, if given an unlocked, moveable block, will return the pointer without a warning, even though that block may move at any time.
See Also: MemGetInfo()
,
MemModifyFlags()
.
void MemDowngradeExclLock( MemHandle mh); /* handle of affected block */
An application that has an exclusive lock on a block may downgrade it to a shared lock with this routine. It does not otherwise affect the block.
Include: heap.h
void MemFree( MemHandle mh); /* handle of block to be freed */
This routine frees a global memory block. The block can be locked or unlocked.
Include: heap.h
Warnings: The routine does not care whether other threads have locked the block. If you try to free a bad handle, routine may fatal-error.
word MemGetInfo( /* return value depends on flag passed */ MemHandle mh, /* Handle of block to get info about */ MemGetInfoType info); /* Type of information to get */
MemGetInfo()
is a general-purpose routine for getting information about a global memory block. It gets the information by looking in the block's handle table entry; it does not need to access the actual block. It returns a single word of data; the meaning of that word depends on the value of the
MemGetInfoType
variable passed. The following types are available:
HeapFlags
record for the block. The lower byte is the number of locks currently on the block.
MemDeref()
is preferable.
HM_otherInfo
word. This word is used in different ways for different types of handles.Include: heap.h
Warnings: If the handle is not a global memory block handle, results are unpredictable (the routine will read inappropriate data from the handle table entry).
See Also: MemDeref()
,
MemModifyFlags()
,
MemModifyOtherInfo()
,
HandleModifyOwner()
.
void MemIncRefCount( MemHandle mh); /* handle of affected block */
This routine increments the reference count of a global memory block (the reference count is stored in HM
_otherInfo
).
Warnings: This routine assumes that a reference count is stored in HM
_otherInfo
. You may only use this routine if the block has had a reference count set up with
MemInitRefCount()
.
Include: heap.h
void MemInitRefCount( MemHandle mh, /* handle of affected block */ word count); /* initial reference count */
This routine sets up a reference count for the specified global memory block. The passed count is stored in the HM
_otherInfo
field of the block's handle-table entry.
Warnings: This routine overwrites the HM
_otherInfo
field. Since the semaphore routines (
HandleP()
and
HandleV()
and the routines which use them) use this field, you cannot use both the semaphore routines and the reference count routines on the same block.
Include: heap.h
void * MemLock( MemHandle mh); /* Handle of block to lock */
This routine locks a global memory block on the global heap. If the block is swapped, the memory manager swaps it back into the global heap; it then increments the lock count (up to a maximum of 255). The block will not be moved, swapped, or discarded until the lock count reaches zero. This routine returns a pointer to the start of the block, or a null pointer if block has been discarded. To get the address of a block without locking it, use
MemDeref()
.
Include: heap.h
Warnings: If you try to lock a bad handle, the routine may fatal-error. This routine does not check for synchronization problems; if the block is used by several threads, you should use the synchronization routines.
Never Use Situations:
Never lock a fixed block.
See Also: MemDeref()
.
void * MemLockExcl( MemHandle mh); /* Handle of block to grab */
If several different threads will be accessing the same global memory block, they should use data-access synchronization routines.
MemLockExcl()
belongs to one such set of routines. Often, several threads will need access to the same block; however, most of the time, they will not need to change the block. There is no synchronization problem if several threads read the same block at once, as long as none of them alters the block (by resizing it, writing to it, etc.) However, if a thread needs to change a block, no other thread should have access at that time.
The routines
MemLockExcl()
,
MemLockShared()
,
MemUnlockShared()
, and
MemUnlockExcl()
take advantage of this situation. They maintain a queue of threads requesting access to a block. When the block is not being used, they awaken the highest priority thread on the queue. If that thread requested exclusive access, the other threads sleep until it relinquishes access (via
MemUnlockExcl()
). If it requested shared access, the routines awaken every other thread which requested shared access; the other threads on the queue will sleep until every active thread relinquishes access (via
MemUnlockShared()
).
MemLockExcl()
requests exclusive access to the block. If the block is not being accessed, the routine will grab exclusive access for the block, lock the block, and return the block's address. If the block is being accessed, the routine will sleep on the queue until it can get access; it will then awaken, lock the block, and return its address.
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all routines accessing the block get access with
MemLockExcl()
or
MemLockShared()
. The routines use the block's
HM_otherInfo
word; you must not alter it. When you are done accessing the block, make sure to relinquish access by calling
MemUnlockExcl()
.
Warnings: If a thread calls
MemLockExcl()
when it already has shared or exclusive access, it will deadlock; it will sleep until access is relinquished, but it cannot relinquish access while it is sleeping. If you try to grab a block which is owned by a different geode and is non-sharable, the routine will fatal-error.
Never Use Situations:
Never use
MemLockExcl()
or
MemLockShared()
on a fixed block. It will attempt to lock the block, and fixed blocks cannot be locked. Instead, use the
HandleP()
and
HandleV()
routines.
See Also: MemLockShared()
,
MemUnlockExcl()
,
MemUnlockShared()
.
void * MemLockFixedOrMovable( void * ptr); /* virtual segment */
Given a virtual segment, this routine locks it (if it was movable). A virtual segment is an opaque pointer to a block that an application views as locked or fixed--the memory manager can actually swap locked or fixed blocks and will designate them as virtual segments.
Include: heap.h
void * MemLockShared( MemHandle mh); /* Handle of block to grab */
MemLockShared()
requests shared access to the passed block. If the block is not being accessed, or if it is held for shared access and the queue is empty, the routine gets access, locks the block, and returns the block's address. Otherwise it sleeps on the queue until the shared requests are awakened; it then locks the block and returns the block's address.
Include: heap.h
Be Sure To: Make sure that all routines accessing the block get access with
MemLockExcl()
or
MemLockShared()
. The routines use the block's HM
_otherInfo
word; you must not alter it. When you are done accessing the block, make sure to relinquish access by calling
MemUnlockExcl()
.
Warnings: If a thread calls
MemLockShared()
when it already has exclusive access, it will deadlock; it will sleep until access is relinquished, but it cannot relinquish access while it is sleeping. The thread must be careful not to take actions which could change the block, such as resizing it or writing to it. The routine will not enforce this. If you try to grab a block which is owned by a different geode and is non-sharable, the routine will fatal-error.
Never Use Situations:
Never use
MemLockExcl()
or
MemLockShared()
on a fixed block. It will attempt to lock the block, and fixed blocks cannot be locked. Instead, use the
HandleP()
and
HandleV()
routines.
See Also: MemLockExcl()
,
MemUnlockExcl()
,
MemUnlockShared()
.
void MemModifyFlags( MemHandle mh, /* Handle of block to modify */ HeapFlags bitsToSet, /* HeapFlags to turn on */ HeapFlags bitsToClear); /* HeapFlags to turn off */
MemModifyFlags()
changes the
HeapFlags
record of the global memory
block specified. Not all flags can be changed after the block is created; only the flags
HF_SHARABLE, HF_DISCARDABLE, HF_SWAPABLE, and HF_LMEM can be changed.
The routine uses the handle table entry of the block specified; it does not need to look at the actual block. The routine performs normally whether or not the block is locked, fixed, or discarded.
Include: heap.h
Warnings: If the handle is not a global memory handle, results are unpredictable; the routine will change inappropriate bits of the handle table entry.
See Also: MemGetInfo()
,
HandleModifyOwner()
,
MemModifyOtherInfo()
.
void MemModifyOtherInfo( MemHandle mh, /* Handle of block to modify */ word otherInfo); /* New value of HM_otherInfo word */
Use this routine to change the value of the global memory block's HM
_otherInfo
word. Some blocks need this word left alone; for example, data-access synchronization routines use this word. Object blocks use this space to store the handle of the burden thread.
Include: heap.h
See Also: MemGetInfo()
,
MemModifyFlags()
,
HandleModifyOwner()
.
GeodeHandle MemOwner( MemHandle mh); /* handle of block queried */
This routine returns the owning geode of the passed block. If the block belongs to a VM file, the owner of the VM file will be returned (unlike
MemGetInfo()
, which returns the VM file handle).
Include: heap.h
void * MemPLock( MemHandle mh); /* Handle of block to lock */
If several different threads will be accessing the same global memory block, they need to make sure their activities will not conflict. The way they do that is to use synchronization routines to get control of a block.
MemPLock()
is part of one set of synchronization routines.
If the threads are using the
MemPLock()
family, then whenever a thread needs access to the block in question, it can call
MemPLock()
. This routine calls
HandleP()
to get control of the block; it then locks the block and returns its address. If the block has been discarded, it grabs the block and returns a null pointer; you can then reallocate the block. When the thread is done with the block, it should release it with
MemUnlockV()
.
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all threads accessing the block use
MemPLock()
and/or
HandleP()
to grab the block. These routines use the HM
_otherInfo
field of the block's handle table entry; do not alter this field. Release the block with
HandleV()
or
MemUnlockV()
when you are done with it.
Warnings: If a thread calls
MemPLock()
when it already has control of the block, it will deadlock.
MemThreadGrab()
avoids this conflict. If you try to grab a non-sharable block owned by another thread,
MemPLock()
will fatal-error.
Never Use Situations:
Never use
MemPLock()
with a fixed block. It will try to lock the block, and fixed blocks cannot be locked. Instead, use
HandleP()
.
See Also: HandleP()
,
MemUnlockV()
,
HandleV()
.
MemHandle MemPtrToHandle( void * ptr); /* pointer to locked block */
This routine returns the global handle of the locked block.
Include: heap.h
MemHandle MemReAlloc( MemHandle mh, /* Handle of block */ word byteSize, /* New size of the block */ HeapAllocFlags heapAllocFlags); /* How to reallocate block */
This routine reallocates a global memory block. It can be used to resize a block; it can also be used to reallocate memory for a discarded block. Locked and fixed blocks can be reallocated; however, they may move on the global heap, so all pointers within the block must be adjusted. Note, however, that if the new size is smaller than the old size, the block is guaranteed not to move. The reallocated block may be larger than the size requested, as the block size is rounded up to the next even paragraph (one paragraph equals sixteen bytes). If you request that the block be expanded, but this is impossible, then the routine will return NullHandle.
The routine is passed a record of
HeapAllocFlags
. Only the flags HAF_ZERO_INIT, HAF_LOCK, and HAF_NO_ERR may be passed.
If necessary, the routine will automatically compact the heap.
Include: heap.h
Warnings: If HAF_LOCK is passed, the lock count will be incremented even if the block is already locked by this thread. The routine does not care whether the block has been locked by another thread (possibly belonging to another geode); thus, if the block is being used by more than one thread, it is important to use the synchronization routines.
See Also: MemAlloc()
,
MemDeref()
.
void * MemThreadGrab( MemHandle mh); /* Handle of block to grab */
MemThreadGrab()
is used in conjunction with
MemThreadGrabNB()
and
MemThreadRelease()
to maintain data-access synchronization. If several threads will all have access to the same global memory block, they should use data-acess synchronization routines to make sure that their activities do not conflict. If a thread uses
MemThreadGrab()
and no other thread has grabbed the block in question, the routine will increment the "grab count," lock the block, and return its address. It can do this even if the calling thread has already grabbed the block. If another thread has grabbed the block,
MemThreadGrab()
will put the calling thread in a queue to get the block; the thread will sleep until it gets the block, then
MemThreadGrab()
will grab the block, lock it, and return its address.
If the block has been discarded,
MemThreadGrab()
grabs the block and returns a null pointer; you can then reallocate memory for the block.
Include: heap.h
Be Sure To: Make sure that all threads using the block use the
MemThread...()
routines to access it (not other data-acess synchronization routines). Do not change the HM
_otherInfo
word of the block's handle table entry (the routines use that word as a semaphore).
Warnings: If you try to grab a block which is owned by a different geode and is non-sharable, the routine will fatal-error.
Never Use Situations:
Never use
MemThreadGrab()
with a fixed block. It will try to lock the block, and fixed blocks cannot be locked. If you need data-access synchronization for a fixed block, use the
HandleP()
and
HandleV()
routines.
See Also: MemThreadGrabNB()
,
MemThreadRelease()
.
void * MemThreadGrabNB( MemHandle mh); /* handle of block to grab */
This is a data-synchronization routine to be used in conjunction with
MemThreadGrab()
and
MemThreadRelease()
. It is exactly the same as
MemThreadGrab()
, except that if it cannot grab the global memory block because another thread has it, the routine returns an error instead of blocking.
If successful,
MemThreadGrabNB()
returns a pointer to the block. If the block has been discarded, it grabs the block and returns a null pointer; you can then reallocate memory for the block. If the block has been grabbed by another thread,
MemThreadGrab()
returns the constant BLOCK_GRABBED.
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all threads using the block use the
MemThread...()
routines to access the block (not other data-access synchronization routines). Do not change the HM
_otherInfo
word of the block's handle table entry (the routines use that word as a semaphore).
Warnings: If you try to grab a block that is owned by a different geode and is non-sharable, the routine will fatal-error.
Never Use Situations:
Never use
MemThreadGrabNB()
with a fixed block. It will try to lock the block, and fixed blocks cannot be locked. If you need synchronization for a fixed block, use the
HandleP()
and
HandleV()
routines.
See Also: MemThreadGrab()
,
MemThreadRelease()
.
void MemThreadRelease( MemHandle mh); /* handle of locked block to release */
Use this routine to release a global memory block which you have grabbed with
MemThreadGrab()
or
MemThreadGrabNB()
. The routine decrements the grab count; if the grab count reaches zero, the routine unlocks the block.
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all threads using the block use the
MemThread...()
routines to access the block (not other data-access synchronization routines). Do not change the HM
_otherInfo
word of the block's handle table entry (the routines use that word as a semaphore). Make sure to release the block once for every time you grab it; the block is not unlocked until each of your grabs is released.
Warnings: If you try to release a block that you have not successfully grabbed, the routine will fatal-error.
See Also: MemThreadGrab()
,
MemThreadGrabNB()
.
void MemUnlock( MemHandle mh); /* Handle of block to unlock */
This routine decrements the lock count of the indicated block. If the lock count reaches zero, the block becomes unlocked (it can be moved, swapped, or discarded). Do not try to unlock a block that has not been locked.
Include: heap.h
void MemUnlockExcl( memHandle mh); /* Handle of block to release */
If a thread has gained access to a block with
MemLockExcl()
, it should release the block as soon as it can. Until it does, no other thread can access the block for either shared or exclusive access. It can release the block by calling
MemUnlockExcl()
. This routine unlocks the block and releases the thread's access to it. If there is a queue for this block, the highest-priority thread waiting will be awakened, as described in
MemLockExcl()
.
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all routines accessing the block get access with
MemLockExcl()
or
MemLockShared()
. The routines use the block's HM
_otherInfo
word; you must not alter it. Call this routine while the block is still locked; it will call
MemUnlock()
to unlock the block.
Warnings: If you call this routine on a block which you have not gained access to, it may fatal-error.
See Also: MemLockExcl()
,
MemLockShared()
,
MemUnlockShared()
.
void MemUnlockFixedOrMovable( void * ptr); /* virtual segment */
This routine unlocks a previously locked, movable virtual segment. Do not call this routine with normal locked or fixed blocks; only call it for those blocks locked with
MemLockFixedOrMovable()
.
Include: heap.h
void MemUnlockShared( MemHandle mh); /* Handle of block to release */
If a thread has gained access to a block with
MemLockShared()
, it should release the block as soon as it can. Until it does, no thread can be awakened from the queue. It can release the block by calling
MemUnlockShared()
. This routine calls
MemUnlock()
, decrementing the block's lock count; it then releases the thread's access to it. If no other thread is accessing the block and there is a queue for this block, the highest-priority thread waiting will be awakened, as described in
MemLockExcl()
.
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all routines accessing the block get access with
MemLockExcl()
or
MemLockShared()
. These routines use the block's HM
_otherInfo
word; you must not alter it. Call this routine while the block is still locked; it will call
MemUnlock()
to unlock the block.
Warnings: If you call this routine on a block which you have not gained access to, it may fatal-error.
See Also: MemLockExcl()
,
MemLockShared()
,
MemUnlockExcl()
.
void MemUnlockV( MemHandle mh); /* Handle of block to release */
This routine unlocks a block with
MemUnlock()
, then releases its semaphore with
HandleV()
. Do not use this routine unless the block's semaphore was grabbed and the block locked (typically with the
MemPLock()
routine).
Include: heap.h
Tips and Tricks: You can find out if the block is being accessed by looking at the HM
_otherInfo
word (with
MemGetInfo()
). If HM
_otherInfo
equals one, the block is not grabbed; if it equals zero, it is grabbed, but no threads are queued; otherwise, it equals the handle of the first thread queued.
Be Sure To: Make sure that all threads accessing the block use
HandleP()
or
MemPLock()
to access the thread. These routines use the
HM
_otherInfo
field of the handle table entry; do not alter this field.
Warnings: Do not use this on a block unless you have grabbed it. The routine does not check to see that you have grabbed the thread; it just clears the semaphore and returns.
Never Use Situations:
Never use this routine to release a fixed block. It will try to unlock the block; fixed blocks cannot be locked or unlocked. Instead, call
HandleV()
directly.
See Also: MemPLock()
,
HandleP()
,
HandleV()
.
void * MemUpgradeSharedLock( MemHandle mh); /* handle of locked block */
This routine upgrades a shared lock on the block to an exclusive lock, as if the caller had used MemLockExcl(). If other threads have access to the block, the caller will sleep in the access queue until it can gain exclusive access.
This routine returns the pointer of the locked block because, if the caller sleeps in the queue, the memory block could move between the call and the granting of access.
Include: heap.h
See Also: MemLockExcl()
,
MemLockShared()
,
MemDowngradeExclLock()
.
void MessageSetDestination( EventHandle event, /* handle of the event to be modified */ optr dest); /* new destination for the event */
This routine sets the destination of an event to the optr passed.
Include: object.h
Boolean ModemAnswerCall( SerialPortNum port, /* serial port number */ ModemResultCode *result);
Answers an incoming data call. Returns [???] if a connection has been established (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
See Also: ModemAutoAnswer()
.
Boolean ModemAutoAnswer( SerialPortNum port, /* serial port number */ word number_of_rings, ModemResultCode *result);
Sets modem to answer calls automatically. Does not wait for a call but returns [???] after successfully setting modem to auto-answer (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
Warnings: Modem must be in command mode when calling this routine.
See Also: ModemAnswerCall()
.
void ModemClose( SerialPortNum port, /* serial port number */ StreamLingerMode close_mode); /* manner in which to close stream */
Closes the serial port being used for a modem connection. Possible values for close_mode include STREAM_DISCARD or STREAM_LINGER.
Include: modemC.goh
Warnings: Use
ModemHangup()
to hang up an existing call.
See Also: ModemHangup()
.
Boolean ModemDial( SerialPortNum port, /* serial port number */ word dial_string_length, const char *dial_string, /* phone number to dial */ ModemResultCode *result);
Sends the modem's dial command to dial the specified number. Returns [???] if a connection has been established (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
See Also: ModemOpen()
.
Boolean ModemFactoryReset( SerialPortNum port, /* serial port number */ ModemResultCode *result);
Restores factory settings of modem. Returns [???] after successfully resetting (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
Warnings: Modem must be in command mode when calling this routine.
Boolean ModemHangup( SerialPortNum port, /* serial port number */ ModemResultCode *result);
Hangs up an existing data call. Returns [???] after successfully hanging up (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
See Also: ModemClose()
.
Boolean ModemInitModem( SerialPortNum port, /* serial port number */ word init_string_length, const char *init_string, /* initialization string */ ModemResultCode *result);
Initializes modem with modem command string. A lead "AT" need not be supplied. Returns [???] after successfully initializing (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
Warnings: Modem must be in command mode when calling this routine.
Boolean ModemOpen( GeodeHandle drHandle, /* handle of serial driver */ SerialPortNum port, /* serial port number */ StreamOpenFlags flags, /* manner in which to open stream */ word input_buffer_size, word output_buffer_size, word timeout); /* timeout if SOF_TIMEOUT */
Opens the serial port to be used for a modem connection and places modem in command mode. Possible values for flags are SOF_TIMEOUT and SOF_NOBLOCK.
Include: modemC.goh
See Also: ModemDial()
.
Boolean ModemReset( SerialPortNum port, /* serial port number */ ModemResultCode *result);
Switches to command mode and resets the modem. Returns [???] after successfully resetting (and writes MRC_OK to result) or non-zero if an error has occurred (and [???]).
Include: modemC.goh
See Also: ModemFactoryReset()
.
void ModemSetMessageDataNotify( SerialPortNum port, /* serial port number */ Message msg, /* msg to be sent upon notification */ optr destination); /* object to receive msg */
Registers a message to be sent when when data is received from the modem during an active call. As with the serial driver's data notification, further notification will not be sent until the serial port has been read. [MEANING UNTIL THE STREAM HAS BEEN READ???]
Be Sure To: Use the prototype for the message you are registering.
@prototype void MODEM_DATA_NOTIFICATION();
Include: modemC.goh
See Also: ModemSetRoutineDataNotify()
.
void ModemSetMessageEndCallNotify( SerialPortNum port, /* serial port number */ Message msg, /* msg to be sent upon notification */ optr destination); /* object to receive msg */
Registers a message to be sent when a call has ended for any reason. To "un-register," pass NullOptr in destination.
Be Sure To: Use the prototype for the message you are registering.
@prototype void MODEM_END_CALL_NOTIFICATION();
Warnings: All platforms may not support this feature.
Include: modemC.goh
void ModemSetMessageResponseNotify( SerialPortNum port, /* serial port number */ Message msg, /* msg to be sent upon notification */ optr destination); /* object to receive msg */
Registers a message to be sent when when a response is received from the modem (while the modem is in command mode). Response is passed in a memory block which the handler should free.
Be Sure To: Use the prototype for the message you are registering.
@prototype void MODEM_RESPONSE_NOTIFICATION();
Include: modemC.goh
See Also: ModemSetRoutineResponseNotify()
.
void ModemSetRoutineDataNotify( SerialPortNum port, /* serial port number */ word data, /* data passed to callback */ void _pascal (*NotifyRoutine) (word data));
Registers a routine to be called when data is received from the modem during an active call. As with the serial driver's data notification, further notification will not be sent until the serial port has been read. [MEANING UNTIL THE STREAM HAS BEEN READ???]
Include: modemC.goh
See Also: ModemSetMessageDataNotify()
.
void ModemSetRoutineResponseNotify( SerialPortNum port, /* serial port number */ word data, /* data passed to callback */ void _pascal (*NotifyRoutine) ( word data, word responseSize, char *response));
Registers a routine to be called when a response is received from the modem (while modem is in command mode).
Include: modemC.goh
See Also: ModemSetMessageResponseNotify()
.
word NameArrayAdd( optr arr, /* optr of name array */ const char * nameToAdd, /* Name of new element */ word nameLength, /* Length of name; pass zero if * name string is null-terminated */
NameArrayAddFlags flags, /* Described below */ const void * data); /* Copy this data to new element */
This routine creates a new element in a name array, copying the passed name and data into the new element. If no element with the passed name exists,
NameArrayAdd()
will create the element and return its token. If an element with the same name already exists, the existing element's reference count will be incremented and its token will be returned. The routine takes the following arguments:
array
nameToAdd
nameLength
NameArrayAdd()
will assume the string is null-terminated.
flags
NameArrayAddFlags
, described below.
data
Structures: The argument is passed a set of
NameArrayAddFlags
. Only one flag is currently defined:
Warnings: This routine may resize the name array; therefore, all pointers to the LMem heap are invalidated.
Include: chunkarr.h
dword NameArrayAddHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle arr, /* Chunk handle of name array */ const char * nameToAdd, /* Name of new element */ word nameLength, /* Length of name; pass zero if * name string is null-terminated */
NameArrayAddFlags flags, /* Described below */ const void * data); /* Copy this data to new element */
This routine is exactly like
NameArrayAdd()
above, except that the name array is specified by its global and chunk handles (instead of with an optr).
Warnings: This routine may resize the name array; therefore, all pointers to within the LMem heap are invalidated.
Include: chunkarr.h
void NameArrayChangeName( optr array, /* optr of name array */ word token, /* Token of element to be changed */ const char * newName, /* New name for element */ word nameLength); /* Length of name in bytes; pass * zero if name string is * null-terminated */
This routine changes the name of an element in a name array.
Warnings: If the new name is longer than the old, the chunk will be resized, invalidating all pointers to within the LMem heap.
Include: chunkarr.h
dword NameArrayChangeNameHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle array, /* Chunk handle of name array */ word token, /* Token of element to be changed */ const char * newName, /* New name for element */ word nameLength); /* Length of name in bytes; pass * zero if name string is * null-terminated */
This routine is exactly like
NameArrayChangeName()
above, except that the name array is specified by its global and chunk handles (instead of with an optr).
Warnings: If the new name is longer than the old, the chunk will be resized, invalidating all pointers to within the LMem heap.
Include: chunkarr.h
ChunkHandle NameArrayCreate( MemHandle mh, /* Global handle of LMem heap */ word dataSize, /* Size of data section for * each element */
word headerSize); /* Size of header; pass * zero for default header */
This routine creates a name array in the indicated LMem heap. It creates a
NameArrayHeader
structure at the head of a new chunk. If you want to leave extra space before the start of the array, you can pass a larger header size; if you want to use the standard header, pass a header size of zero.
You must specify the size of the data portion of each element when you create the array. The name portion will be variable sized.
Include: chunkarr.h
Tips and Tricks: If you want extra space after the
NameArrayHeader
, you may want to create your own header structure, the first element of which is a
NameArrayHeader
. You can pass the size of this header to
NameArrayCreate()
and access the data in your header via the structure fields.
Be Sure To: Lock the block on the global heap before calling this routine (unless it is fixed). If you pass a header size, make sure it is larger than
sizeof(NameArrayHeader)
.
Include: chunkarr.h
ChunkHandle NameArrayCreateAt( optr array, /* Turn this chunk into a name array */ word dataSize, /* Size of data section of each element */ word headerSize); /* Size of header; pass zero for default header */
This routine is just like
NameArrayCreate()
above, except that the element array is created in a pre-existing chunk. The contents of that chunk will be destroyed.
Include: chunkarr.h
Warnings: If the chunk isn't large enough, it will be resized. This will invalidate all pointers to chunks in that block.
Include: chunkarr.h
ChunkHandle NameArrayCreateAtHandles( MemHandle mh, /* Global handle of LMem heap */ ChunkHandle chunk, /* the chunk for the array */ word dataSize, /* Size of data for each element */ word headerSize); /* Size of header; pass * zero for default header */
This routine is exactly like
NameArrayCreateAt()
above, except that the name array is specified by its global and chunk handles (instead of with an optr).
Include: chunkarr.h
Warnings: If the chunk isn't large enough, it will be resized. This will invalidate all pointers to chunks in that block.
Include: chunkarr.h
word NameArrayFind( optr array, /* optr to name array */ const char * nameToFind, /* Find element with this name */ word nameLength, /* Pass zero if name string is * null-terminated */
void * returnData); /* Copy data section into this * buffer */
This routine locates the element with the specified name. It returns the token of the element and copies its data section into the passed buffer. If there is no element with the specified name, the routine will return CA_NULL_ELEMENT. The routine takes the following arguments:
array
nameToAdd
nameLength
NameArrayFind()
will assume the string is null-terminated.
returnData
Include: chunkarr.h
Warnings: You must make sure the
returnData
buffer is large enough to hold an element's data portion; otherwise, data after the buffer will be overwritten.
word NameArrayFindHandles( MemHandle mh, /* Handle of LMem heap */ ChunkHandle array, /* Handle of name array */ const char * nameToFind, /* Find element with this name */ word nameLength, /* Pass zero if name string is * null-terminated */
void * returnData); /* Copy data section into this * buffer */
This routine is exactly like
NameArrayFind()
above, except that the name array is specified by its global and chunk handles (instead of with an optr).
Include: chunkarr.h
NEC(line)
This macro defines a line of code that will only be compiled into the
non
-error-checking version of the geode. The
line
parameter of the macro is the actual line of code. When the non-EC version of the program is compiled, the line will be treated as a normal line of code; when the EC version is compiled, the line will be ignored.
See Also: EC()
.
Include: ec.h
optr ObjBlockGetOutput( MemHandle mh); /* handle of the subject object block */
This routine returns the optr of the output destination object set for the specified object block. The output object is stored in the object block's header in the
OLMBH_output
field. If the block has no output set, NullOptr will be returned.
Include: object.h
See Also: ObjLMemBlockHeader
.
void ObjBlockSetOutput( MemHandle mh, /* handle of the subject object block */ optr o); /* optr of the new output object */
This routine sets the
OLMBH_output
field in the specified object block's header. The optr passed in
o
will be set as the block's output.
Include: object.h
See Also: ObjLMemBlockHeader
.
void ObjCompAddChild( optr obj, /* optr of parent composite */ optr objToAdd, /* optr of new child */ word flags, /* CompChildFlags */ word masterOffset, /* offset to master part */ word compOffset, /* offset to comp field in master part */ word linkOffset); /* offset to link field in master part */
This routine adds the given object to an object tree as the child of another specified object. It returns nothing. You will not likely want to use this routine; instead, you will probably use the messages listed below under "See Also." The parameters of this routine are
obj
objToAdd
@link
).
flags
CompChildFlags
. These flags indicate whether the object should initially be marked dirty as well as where in the parent's child list the new child should be placed (first, second, last, etc.).
masterOffset
Class_masterOffset
field in its
ClassStruct
structure.)
compOffset
linkOffset
Warnings: This routine may resize and move LMem and Object blocks on the heap, thereby invalidating all segment addresses and pointers.
Include: metaC.goh
See Also: MSG_VIS_ADD_CHILD
,
MSG_GEN_ADD_CHILD
.
optr ObjCompFindChildByNumber( optr obj, /* parent's optr */ word childToFind, /* zero-based child number */ word masterOffset, /* offset to master part */ word compOffset, /* offset to comp field in master part */ word linkOffset); /* offset to link field in master part */
This routine returns the optr of the passed object's child; the child is specified based on its position in the object's child list. You will not often use this routine, but you will probably use the messages listed under "See Also" instead. The routine's parameters are listed below:
obj
childToFind
masterOffset
Class_masterOffset
field in its
ClassStruct
structure.)
compOffset
linkOffset
Include: metaC.goh
See Also: MSG_GEN_FIND_CHILD
,
MSG_VIS_FIND_CHILD
.
word ObjCompFindChildByOptr( optr obj, /* parent's optr */ optr childToFind, /* optr of child to find */ word masterOffset, /* offset to master part */ word compOffset, /* offset to comp field in master part */ word linkOffset); /* offset to link field in master part */
This routine returns the zero-based child number of an object given its optr and its parent's optr. The returned number represents the child's position in its parent's child list. For example, a return value of zero indicates the object is the parent's first child. You will not likely use this routine; instead, you will probably use the messages shown below under "See Also."
The parameters for this routine are listed below:
obj
childToFind
masterOffset
Class_masterOffset
field in its
ClassStruct
structure.)
compOffset
linkOffset
Include: metaC.goh
See Also: MSG_GEN_FIND_CHILD
,
MSG_VIS_FIND_CHILD
.
void ObjCompMoveChild( optr obj, /* parent's optr */ optr objToMove, /* optr of child to move */ word flags, /* CompChildFlags */ word masterOffset, /* offset to master part */ word compOffset, /* offset to comp field in master part */ word linkOffset); /* offset to link field in master part */
This routine moves the specified child within its parent's child list. This routine will not move a child from one parent to another, but it can reorganize a parent's children. You will not likely use this routine, but you may often use the messages listed under "See Also" below.
The parameters of this routine are shown below:
obj
objToMove
flags
CompChildFlags
indicating the new position of the child and whether the link should be marked dirty.
masterOffset
Class_masterOffset
field in its
ClassStruct
structure.)
compOffset
linkOffset
Warnings: This routine may cause LMem and/or Object Blocks to move or to shuffle their chunks, thereby invalidating any segment addresses or pointers.
Include: metaC.goh
See Also: MSG_GEN_MOVE_CHILD
,
MSG_VIS_MOVE_CHILD
.
Boolean ObjCompProcessChildren( optr obj, /* parent's optr */ optr firstChild, /* optr of first child to process */ ObjCompCallType stdCallback, /* standard callback type */ void * cbData, /* data passed to callback */ word masterOffset, /* offset to master part */ word compOffset, /* offset to comp field */ word linkOffset); /* offset to link field */ Boolean _pascal (*callback) (optr parent, optr child, void *cbData));
This routine performs a specific set of actions on all or some of an object's children. It is very rare that you will use this routine; typically, you should send a message to all of the parent's children. If, however, you use this routine, you must also write a callback routine that will be executed once for each affected child.
ObjCompProcessChildren()
returns
true
(nonzero) only if it was stopped before all children had been processed. The only two ways this could be returned is if an error occurs or if your callback returns
true
when called.
The parameters for this routine are
obj
firstChild
ObjCompFindChildByNumber()
--to process all children.
stdCallback
ObjCompCallType
indicating how the data in the buffer pointed to by
cbData
will be passed to your callback routine. These values are detailed below.
cbData
masterOffset
Class_masterOffset
field in its
ClassStruct
structure.)
compOffset
linkOffset
callback
The callback routine takes three parameters and returns a boolean value. It must be declared _pascal. The three parameters to the callback are listed below:
parent
child
cbData
ObjCompProcessChildren()
. What is actually in this buffer may depend on the value in the original
sdtCallback
parameter; if the buffer is not saved and restored by
ObjCompProcessChildren()
between children, each child may receive data altered by the previous child.
The callback routine can access and alter the buffer pointed to by
cbData
, or it can query the child or do anything else with the exception of destroying the child. It should return a Boolean value:
true
if
ObjCompProcessChildren()
should be aborted,
false
if it should not.
The values you can pass to
ObjCompProcessChildren()
in
stdCallback
are of type
ObjCompCallType
. You can use one of the following values to specify how the buffer in
cbData
will be passed on to the next child's callback routine:
cbData
before calling each child; abort the routine if the callback returns
true
.
cbData
before calling each child; do not check the return value of the callback before proceeding to the next child.
cbData
, and abort if the callback routine returns
true
.
cbData
, and do not check the callback routine's return value.Include: metaC.goh
See Also: @send
,
@call
,
MSG_META_SEND_CLASSED_EVENT
.
void ObjCompRemoveChild( optr obj, /* parent's optr */ optr objToRemove /* optr of child to be removed */ word flags, /* CompChildFlags */ word masterOffset, /* offset to master part */ word compOffset, /* offset to comp field in master part */ word linkOffset); /* offset to link field in master part */
This routine removes the given child from the specified parent composite. The child will be removed entirely from the object tree, but it will not be detached or freed. The parameters of this routine are listed below:
obj
objToRemove
flags
CompChildFlags
indicating whether the parent and child should be marked dirty after the operation.
masterOffset
Class_masterOffset
field in its
ClassStruct
structure.)
compOffset
linkOffset
Include: metaC.goh
void ObjDecInteractibleCount( MemHandle mh); /* subject object block */
This routine decrements the given object block's interactable count. Do not decrement the interactable count without first incrementing it with
ObjIncInteractibleCount()
. Visible objects automatically decrement the interactable count in their
MSG_VIS_CLOSE
handlers.
Include: object.h
See Also: ObjIncInteractibleCount()
,
MSG_VIS_CLOSE
,
ObjLMemBlockHeader
.
void ObjDecInUseCount( MemHandle mh); /* subject object block */
This routine decrements the given object block's in-use count. When the in-use count reaches zero, the block may safely be freed. You should not decrement the in-use count of a block without first incrementing it at some point with
ObjIncInUseCount()
.
Warnings: Do not decrement the in-use count without incrementing it first. An error will result.
Include: object.h
See Also: ObjIncInUseCount()
,
ObjDecInteractibleCount()
,
ObjLMemBlockHeader
.
void * ObjDeref( optr obj /* optr to dereference */ word masterLevel); /* specific master level to dereference */
This routine dereferences the given optr and master level to reset the message parameter
pself
. Because many routines and messages may cause the calling object's instance chunk to move, the
pself
parameter may become invalid. The two parameters to
ObjDeref()
are
obj
oself
.
masterLevel
pself
points to the first byte of a master part, you must specify which master part you are dereferencing.
For example, a visible object dereferencing its
VisClass
instance data would call this routine as follows:
pself = ObjDeref(oself, 4);
Note, however, the
ObjDeref1()
and
ObjDerefVis()
exist to dereference the Vis master part, and
ObjDeref2()
and
ObjDerefGen()
exist to dereference the Gen master part.
Include: object.h
See Also: ObjDeref1()
,
ObjDeref2()
.
void * ObjDerefHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ word masterLevel); /* master level to dereference */
This routine is exactly the same as
ObjDeref()
, above, except that the optr is specified as its separate handles.
Include: object.h
void * ObjDeref1( optr obj); /* optr of object to be dereferenced */
This routine is a special version of
ObjDeref()
which dereferences the first master part of an object. Visible objects should use this routine or
ObjDerefVis()
instead of
ObjDeref()
.
Include: object.h
See Also: ObjDeref()
,
ObjDeref2()
.
void *ObjDeref1Handles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch,); /* chunk handle portion of optr */
This routine is exactly like
ObjDeref1()
, above, except that the optr is specified as its separate handles.
Include: object.h
void * ObjDeref2( optr obj); /* optr of object to be dereferenced */
This routine is a specialized version of
ObjDeref()
which dereferences the second master part of an object. Generic objects should use this routine or
ObjDerefGen()
instead of
ObjDeref()
.
Include: object.h
See Also: ObjDeref()
,
ObjDeref1()
.
void * ObjDeref2Handles( MemHandle mh,/ /* handle portion of optr */ ChunkHandle ch); /* chunk portion of optr */
This routine is exactly like
ObjDeref2()
, above, except that the optr is specified as its separate handles.
Include: object.h
void * ObjDerefGen( optr obj); /* generic object to be dereferenced */
This routine is exactly the same as
ObjDeref2()
and dereferences the Gen master part of a generic object.
Include: object.h
See Also: ObjDeref()
,
ObjDeref2()
.
void * ObjDerefVis( optr obj); /* visible object to be dereferenced */
This routine is exactly the same as
ObjDeref1()
and dereferences the Vis master part of a visible object or a visibly-realized generic object.
Include: object.h
See Also: ObjDeref()
,
ObjDeref1()
.
Boolean ObjDoRelocation( /* returns true if error */ ObjRelocationType type, /* type of relocation */ MemHandle block, /* handle of info block */ void * sourceData, /* source of relocation */ void * destData); /* relocated value */
This routine relocates a given word or dword argument and is used for resolving handles and pointers to movable objects. Most often, relocation and unrelocation occur when resources are loaded, swapped, or saved, and this is in most cases taken care of by the kernel.
ObjDoRelocation()
takes four parameters:
type
RelocationType
). This can be one of the three values shown below.
block
sourceData
destData
sourceData
and
type
, above.
The type of relocation to be done affects the type of data passed in
sourceData
and
destData
. The relocation type is passed in the type parameter and must be one of the following enumerations of
RelocationType
:
sourceData
pointer should be cast to type word, and the
destData
pointer should be cast to type Handle.
sourceData
pointer should be cast to type word, and the
destData
pointer should be cast to type Segment.
sourceData
pointer and the
destData
pointer should be cast to type dword.
ObjDoRelocation()
returns an error flag that will be
true
if an error occurs,
false
otherwise.
The relocation done by this routine can be undone with
ObjDoUnRelocation()
.
Include: object.h
Boolean ObjDoUnRelocation( /* returns true if error */ ObjRelocationType type, /* type of relocation */ MemHandle block, /* handle of info block */ void * sourceData, /* source of relocation */ void * destData); /* relocated value */
This routine unrelocates a given word or dword. It translates a handle, a segment address, or an entry point back into a resource ID. The translation done is the exact reverse of that done by
ObjDoRelocation()
. See that routine (above) for more information.
ObjDoUnRelocation()
returns an error flag that will be
true
if an error occurs and
false
if the unrelocation is successful. The unrelocated resource ID will be returned pointed to by the
destData
pointer.
Include: object.h
See Also: ObjDoRelocation()
.
EventHandle ObjDuplicateMessage( EventHandle msg); /* event to duplicate */
This routine duplicates a prerecorded event, returning the event handle of the new event. Pass the handle of the event to be duplicated. You can then change information about the event with
MessageSetDestination()
.
Include: object.h
MemHandle ObjDuplicateResource( MemHandle blockToDup, /* handle of resource; must * not be loaded */
GeodeHandle owner, /* owner of duplicate */ ThreadHandle burdenThread); /* burden thread of duplicate */
This routine duplicates an entire object resource block. The new block will be put on the "saved blocks" list so it gets saved to the geode's state file. Usually this is used by the UI to make editable copies of an application's UI resources to ensure the proper state information gets saved. This routine takes three parameters:
blockToDup
ObjDuplicateResource()
is called. Also, it can only be a "template" resource--a resource that does not get used by the UI or the application directly, but only gets copied via this routine.
owner
owner
of -1, the new block will be owned by the same geode that owns the original.
burdenThread
burdenThread
of -1 makes the new resource have the same burden thread as the original.
ObjDuplicateResource()
returns the handle of the newly created block, which will be unlocked and may or may not be resident in memory.
Include: object.h
See Also: ObjFreeDuplicate()
,
MSG_META_BLOCK_FREE
,
ObjLockObjBlock()
.
void ObjEnableDetach( optr obj); /* object calling this routine */
This routine acts as an object's handler for
MSG_META_ACK
. This handler decrements the acknowledgment count (incremented with
ObjIncDetach()
) and, if the count is zero, enables the detach mechanism so the object can be fully detached. Because the detach mechanism is implemented in
MetaClass
, it is highly unlikely you will ever call this routine.
The lone parameter of this routine is the optr of the calling object (or, in the case of
MSG_META_ACK
, the object sending acknowledgment).
Warnings: This routine may resize and/or move chunks and object blocks, thereby invalidating all pointers and segment addresses.
Include: metaC.goh
See Also: MSG_META_DETACH
,
ObjInitDetach()
,
ObjIncDetach()
,
MSG_META_ACK
.
void ObjFreeChunk( optr o); /* optr of chunk to be freed */
This routine frees the passed object's instance chunk. If the object came from a loaded resource, however, the object is resized to zero and marked dirty rather than actually freed.
Warnings: The object must be fully detached, and its message queues must be empty before it can safely be freed. All this is handled by
MSG_META_DETACH
and
MSG_META_OBJ_FREE
.
Include: object.h
See Also: MSG_META_DETACH
,
MSG_META_OBJ_FREE
,
ObjInstantiate()
.
void ObjFreeChunkHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch); /* chunk portion of optr */
This routine is the same as ObjFreeChunk(); the chunk is specified by its handles rather than by an optr.
Include: object.h
void ObjFreeDuplicate( MemHandle mh); /* handle of duplicate block to be freed */
This routine frees a block that had been saved with
ObjSaveBlock()
or created with
ObjDuplicateResource()
. It must be passed the memory handle of the duplicated resource.
Warnings: All objects in the duplicated resource must be properly detached to ensure that nothing tries to send messages to the objects in the block. Additionally, the block's in-use count and interactable count should be zero.
Include: object.h
See Also: ObjDuplicateResource()
,
ObjSaveBlock()
,
ObjLMemBlockHeader
.
void ObjFreeMessage( EventHandle event); /* event to be freed */
This routine frees an event handle and its associated event. This is rarely, if ever, used by anything other than the kernel. The kernel uses this routine to free events after they have been handled.
Include: object.h
void ObjFreeObjBlock( MemHandle block); /* handle of the object block to be freed */
This routine frees the specified object block. It first checks the block's in-use count to see if any external references to the block are being kept. If the in-use count is nonzero,
ObjFreeObjBlock()
simply sets the block's auto-free bit and returns; the block will be freed the first time the in-use count reaches zero. If the in-use count is zero (no external references), the block will be freed immediately.
If the object block passed is not run by the calling thread, the operation will be handled by a remote call in the object block's thread.
Include: object.h
See Also: ObjFreeDuplicate()
,
MSG_META_BLOCK_FREE
.
ObjChunkFlags ObjGetFlags( optr o); /* optr of subject object */
This routine returns the object flags associated with a given object. The object is specified by the passed optr, and the flags are stored in the object's
ObjChunkFlags
record.
Include: object.h
See Also: ObjSetFlags()
,
ObjChunkFlags
.
ObjChunkFlags ObjGetFlagsHandles( Memhandle mh, /* handle portion of optr */ ChunkHandle ch); /* chunk portion of optr */
This routine is the same as
ObjGetFlags()
, but the object is specified with its handles rather than with its optr.
Include: object.h
Message ObjGetMessageInfo( EventHandle event, /* event to be queried */ optr * dest); /* buffer for destination optr */
This routine gets information about the specified
event
. The return value is the message number of the event. The
dest
parameter is a pointer to an optr. This routine will return with the optr represinting the event's destination object.
Include: object.h
void ObjIncDetach( optr obj); /* optr of calling object */
This routine increments the number of detach acknowledgments an object must receive before it can safely be detached. Each time the detaching object sends notification of its detachment, it must call
ObjIncDetach()
to indicate that it must receive a corresponding detach acknowledgment (
MSG_META_ACK
).
The calling object must have previously called
ObjInitDetach()
. Since the detach mechanism is implemented in
MetaClass
, it is highly unlikely you will ever need to call this routine.
ObjIncDetach()
takes a single parameter: the optr of the calling object.
Include: metaC.goh
See Also: MSG_META_DETACH
,
ObjInitDetach()
,
ObjEnableDetach()
,
MSG_META_ACK
.
void ObjIncInteractibleCount( MemHandle mh); /* handle of object block */
This routine increments the interactable count of the given object block. The interactable count maintains the number of objects currently visible to the user or about to be acted on by the user (e.g. via keyboard accelerator). The interactable count is maintained by the UI; only in extremely special cases may you need to increment or decrement the count. To decrement the count, use
ObjDecInteractibleCount()
.
Visible objects increment the interactable count in their
MSG_VIS_OPEN
handlers and decrement it in their
MSG_VIS_CLOSE
handlers. This is built into
VisClass
.
Include: object.h
See Also: ObjDecInteractibleCount()
,
MSG_VIS_OPEN
,
MSG_VIS_CLOSE
,
ObjLMemBlockHeader
.
void ObjIncInUseCount( MemHandle mh); /* handle of object block */
This routine increments the given object block's in-use count. The in-use count maintains the number of outside references to this object block which are stored elsewhere and which need to be removed before the block can safely be freed. If you store an optr to an object block, you should increment the in-use count of the block.
When the reference to the block is removed, the in-use count should be decremented with
ObjDecInUseCount()
.
Include: object.h
See Also: ObjDecInUseCount()
,
ObjIncInteractibleCount()
,
ObjLMemBlockHeader
.
void ObjInitDetach( MetaMessages msg, optr obj /* object being detached */ word callerID, /* an identifier token for the caller */ optr ackOD); /* object to which ack is sent */
Initialize the detach sequence for the specified object. The detach sequence severs all ties between the system and the object, allowing it to be destroyed without other objects or geodes trying to contact it. It is highly unlikely you will ever call this routine; typically, you will instead use
MSG_META_DETACH
or one of the generic or visible object messages, which will call this routine. The parameters for this routine are
obj
callerID
ackOD
Include: metaC.goh
See Also: MSG_META_DETACH
,
MSG_GEN_DESTROY
,
MSG_VIS_REMOVE
,
ObjIncDetach()
,
ObjEnableDetach()
,
MSG_META_ACK
.
void ObjInitializeMaster( optr obj, /* object to be initialized */ ClassStruct * class); /* class in master group */
This routine initializes the appropriate master part of the passed object, resizing the instance chunk if necessary. It takes two parameters:
obj
class
Warnings: This routine may resize and/or move chunks or object blocks, thereby invalidating pointers and segment addresses.
Include: object.h
See Also: ObjResizeMaster()
,
ObjInitializePart()
,
ClassStruct
.
void ObjInitializeMasterHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ ClassStruct * class); /* class in master group */
This routine is the same as
ObjInitializeMaster()
except it specifies the object via its handles rather than its optr.
Include: object.h
void ObjInitializePart( optr obj, /* object to have a part initialized */ word masterOffset); /* offset to master offset in chunk */
This routine initializes all master parts of the given object down to and including the master part specified in
masterOffset
. It will resize the chunk if necessary and even resolve variant classes above the master group specified, if necessary. This routine takes two parameters:
obj
masterOffset
Class_masterOffset
field in its
ClassStruct
structure).Warnings: This routine may move and/or resize chunks or object blocks, thereby invalidating pointers and segment addresses.
Include: object.h
See Also: ObjResizeMaster()
,
ObjInitializeMaster()
,
MSG_META_RESOLVE_VARIANT_SUPERCLASS
.
void ObjInitializePartHandles( Memhandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ word masterOffset); /* master group offset */
This routine is the same as
ObjInitializePart()
except that it specifies the object via its handles rather than an optr.
Include: object.h
optr ObjInstantiate( MemHandle block, /* block in which new object * will be instantiated */
ClassStruct * class); /* class of new object */
This routine instantiates a new object, allocating the proper size instance chunk. It returns the optr of the new object; this optr can then be used to send setup messages or other messages (such as adding the object to an object tree, setting it usable, etc.).
The new object's instance data will be initialized to all zeroes if it has no master parts (is a direct descendant of
MetaClass
). If it is a member of some master group, only enough space for the base structure (the master offsets and the class pointer) will be allocated. In either case, initialization of the instance data will occur at a later time.
ObjInstantiate()
takes two parameters:
block
class
ClassStruct
structure of the class of the new object. This pointer will be set in the object's class pointer (the first four bytes of the instance chunk).Warnings: This routine, because it allocates a new chunk, may cause LMem and Object blocks to move or resize, thereby invalidating any pointers and segment addresses. Be sure to dereference pointers after calls to this routine.
Include: object.h
See Also: ObjInstantiateForThread()
.
optr ObjInstantiateForThread( ThreadHandle thread, /* thread to run new object */ ClassStruct *class); /* class of new object */
This routine is similar to
ObjInstantiate()
except you pass the thread to run the new object rather than the memory handle to an object block (to store the new object). To specify the current thread, pass "0" in thread. This routine automatically allocates memory blocks as needed. It returns the optr to the new object.
Include: object.h
See Also: ObjInstantiate()
.
Boolean ObjIsClassADescendant( ClassStruct * class1, /* proposed ancestor */ ClassStruct * class2); /* proposed descendant */
This routine checks if
class2
is a descendand of
class1
and returns
true
if it is.
Include: object.h
Boolean ObjIsObjectInClass( optr obj, /* object to check */ ClassStruct * class); /* proposed class */
This routine checks to see if the passed object is a member of the specified class. It checks superclasses as well, but if an unresolved variant class is encountered, the variant will
not
be resolved. If you want to search past variant class links, you should sent
MSG_META_DUMMY
to the object first. The two parameters for this routine are
obj
class
ClassStruct
definition.
ObjIsObjectInClass()
returns
true
if the object is in the class,
false
(zero) if it is not.
Include: object.h
Boolean ObjIsObjectInClassHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ ClassStruct * class); /* proposed class */
This routine is just like
ObjIsObjectInClass()
except the object is specified via its handles rather than its optr.
Include: object.h
optr ObjLinkFindParent( optr obj, /* child's optr */ word masterOffset, /* offset to master part with link field */ word linkOffset); /* offset in master part to link field */
This routine returns the optr of the specified object's parent. It must be passed the following:
masterOffset
Class_masterOffset
field in its
ClassStruct
structure).
linkOffset
Include: metaC.goh
See Also: MSG_VIS_FIND_PARENT
,
MSG_GEN_FIND_PARENT
.
void * ObjLockObjBlock( MemHandle mh); /* handle of object block */
This routine locks an object block, loading in the block if necessary. It must be passed the handle of the block, and it returns the locked block's segment address. When the caller is done using the block, it should unlock it with
MemUnlock()
.
Be Sure To: Always unlock the block when you are done with it, with
MemUnlock()
.
Include: object.h
See Also: MemLock()
,
MemUnlock()
.
VMBlockHandle ObjMapSavedToState( MemHandle mh); /* handle of object block */
This routine returns the VM block handle of the state file block corresponding to the passed object block. If the specified object block has no state file equivalent, a null handle is returned.
Include: object.h
MemHandle ObjMapStateToSaved( VMBlockHandle vmbh, /* VM block handle of state block */ GeodeHandle gh); /* handle of geode owning block */
This routine takes a VM block handle and a geode handle and returns the memory block corresponding to the VM block, if any. The two parameters are
vmbh
gh
If the block is found,
ObjMapStateToSaved()
returns its handle. If the block is not found, it returns a null handle.
Include: object.h
void ObjMarkDirty( optr o); /* object to be marked dirty */
This routine marks an object dirty, indicating that changes to it should be saved when its object block is saved. If you want changes to objects saved, you should mark the object dirty.
Tips and Tricks: Often you do not need this routine because parameters or flags to other routines will set the object dirty automatically. If there is any doubt, however, you should use this routine.
Include: object.h
See Also: ObjChunkFlags
,
ObjSetFlags()
.
void ObjMarkDirtyHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch); /* chunk portion of optr */
This routine is the same as
ObjMarkDirty()
except that it specifies the object via handles rather than an optr.
void ObjProcBroadcastMessage( EventHandle event); /* the event to be broadcast */
This routine broadcasts the given event to all threads which have message queues. It must be passed an encapsulated event (usually recorded with
@record
) and returns nothing. This is typically used for notification purposes.
Include: metaC.goh
void ObjRelocOrUnRelocSuper( optr oself, ClassStruct *class, word frame);
Call this routine to relocate an object's superclass.
Include: object.h
void ObjResizeMaster( optr obj, /* object to have its master part resized */ word masterOffset, /* master offset of proper master part */ word newSize); /* new size for the master part */
This routine resizes a master part of an object's instance chunk. It is typically used to allocate space for a master part or to resize the master part to zero (as when the Vis part of a visible object is removed in
MSG_VIS_CLOSE
). This routine must be passed the following three parameters:
obj
masterOffset
Class_masterOffset
field).
newSize
Class_instanceSize
field.Warnings: This routine may resize and/or move chunks or object blocks, thereby invalidating stored segment addresses and pointers.
Include: object.h
See Also: ClassStruct
,
ObjInitializeMaster()
,
ObjInitializePart()
.
void ObjResizeMasterHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ word masterOffset, /* offset to master part */ word newSize); /* new size of master part */
This routine is the same as
ObjResizeMaster()
except that the object is specified with its handles rather than its optr.
Include: object.h
void ObjSaveBlock( MemHandle mh); /*handle of block to be marked for saving */
This routine sets up an object or LMem block to be saved to its owner's state file. The block's handle must be passed in
mh
. The block must be an object block.
Include: object.h
See Also: ObjMapSavedToState()
,
ObjMapStateToSaved()
.
void ObjSetFlags( optr o, /* object whose flags will be set */ ObjChunkFlags bitsToSet, /* flags to set */ ObjChunkFlags bitsToClear); /* flags to clear */
This routine sets the chunk flags for the specified object. Flags that should be set are passed in
bitsToSet
, and flags that should be cleared are passed in
bitsToClear
. Typically, applications will not use this routine but will rather let the kernel maintain the object's flags.
Include: object.h
See Also: ObjGetFlags()
,
ObjChunkFlags
.
void ObjSetFlagsHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ ObjChunkFlags bitsToSet, /* flags to set */ ObjChunkFlags bitsToClear); /* flags to clear */
This routine is the same as
ObjSetFlags()
except that the object is specified via its handles rather than its optr.
Include: object.h
Boolean ObjTestIfObjBlockRunByCurThread( MemHandle mh); /* handle of object block */
This routine checks if the calling thread is running the specified object block. This routine can be used to determine if calls to objects in the block are across threads or internal to the calling thread. Pass this routine the handle of the object block to be checked--if the object block is a VM block, the thread for the VM file is checked rather than that for the block.
If the block is run by the calling thread, the return value is
true
. If a different thread runs the block, the return is
false
(zero).
Include: object.h
void ObjUnrelocateEntryPoint( EntryPointRelocation * relocData, void * entryPoint);
void * ObjVarAddData( optr obj, /* object to add vardata to */ VardataKey dataType, /* vardata type */ word dataSize); /* vardata data size, if any */
This routine adds or alters a variable data entry for the specified object. If the data type does not currently exist in the instance chunk, it will be allocated and added to the chunk. If it does exist, the extra data of the entry will be re-initialized to all zeroes.
This routine returns a pointer to the extra data of the new or modified entry; if the entry has no extra data, an opaque pointer to the entry is passed, and you can use this pointer with
ObjVarDeleteDataAt()
. In either case, the object will be marked dirty.
If it is possible that you are adding the object's first/only field of
variable data, set the object's OCF_VARDATA_RELOC
flag by means
of the
ObjSetFlags()
routine or
MSG_META_SET_FLAGS.
The parameters of this routine are
obj
dataType
VardataKey
word declaring the data type and its flags. The VDF_SAVE_TO_STATE flag must be properly set; the VDF_EXTRA_DATA flag is ignored, however, as the routine will set it properly.
dataSize
Include: object.h
Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects' vardata remotely, use messages provided by
MetaClass
(see below under "See Also").
See Also: MSG_META_ADD_VAR_DATA
,
ObjVarDeleteDataAt()
.
void * ObjVarAddDataHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ VardataKey dataType, /* vardata type */ word dataSize); /* vardata data size, if any */
This routine is the same as
ObjVarAddData()
except that the object is specified via its handles rather than its optr.
Include: object.h
void ObjVarCopyDataRange( optr source, /* the optr of the source object */ optr dest, /* the optr of the destination (calling) object */ word rangeStart, /* the smallest data type value to be copied */ word rangeEnd); /* the largest data type value to be copied */
This routine copies all the vardata entries within the specified range from the
source
object to the
dest
object. The range to be copied is specified by data types and is between
rangeStart
and
rangeEnd
, inclusive. If any data entries are copied, the destination object will be marked dirty.
Warnings: This routine should be called only by the destination object; it is against OOP doctrine for one object to alter another's instance data.
Include: object.h
Boolean ObjVarDeleteData( optr obj, /* object to delete from */ VardataKey dataType); /* data type to delete */
This routine deletes a vardata entry from the specified object's instance chunk, if the entry exists. The entry is specified by its data type; to delete an entry specified by a pointer to it, use
ObjVarDeleteDataAt()
, below. It returns an error flag:
true
if the entry was not found,
false
if the entry was successfully deleted. The object will also be marked dirty by the routine.
The parameters for this routine are
obj
dataType
VardataKey
word declaring the data type and its flags. Both the VDF_SAVE_TO_STATE flag and the VDF_EXTRA_DATA flag are ignored.
Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects' vardata remotely, use messages provided by
MetaClass
(see below under "See Also").
Include: object.h
See Also: MSG_META_DELETE_VAR_DATA
,
ObjVarDeleteDataAt()
.
Boolean ObjVarDeleteDataHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ VardataKey dataType); /* data type to delete */
This routine is the same as
ObjVarDeleteData()
except that the object is specified via its handles rather than its optr.
Include: object.h
void ObjVarDeleteDataAt( optr obj, /* object to delete from */ word extraDataOffset); /* offset to extra data to delete */
This routine deletes the specified vardata entry from the given object's instance chunk. The vardata entry is specified by its pointer as returned by
ObjVarAddData()
,
ObjVarFindData()
, and
ObjVarDerefData()
. To delete an entry specified by its data type, use
ObjVarDeleteData()
, above.
Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects' vardata remotely, use messages provided by
MetaClass
(see below under "See Also").
Include: object.h
See Also: MSG_META_DELETE_VAR_DATA
,
ObjVarDeleteData()
.
void ObjVarDeleteDataAtHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ word extraDataOffset); /* offset to extra data to delete */
This routine is the same as
ObjVarDeleteDataAt()
except that the object is specified via its handles rather than its optr.
Include: object.h
void ObjVarDeleteDataRange( optr obj, /* object to delete from */ word rangeStart, /* start of range */ word rangeEnd, /* end of range */ Boolean useStateFlag); /* save to state flag */
This routine deletes all data entries within a given range for the passed object. The range is specified by beginning and ending data types and is inclusive. The four parameters to this routine are
obj
rangeStart
rangeEnd
useStateFlag
true
(nonzero) to take the state flag into account; pass
false
(zero) to delete all entries in the range.
Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects' vardata remotely, use messages provided by
MetaClass
(see below under "See Also").
Include: object.h
See Also: MSG_META_DELETE_VAR_DATA
.
void ObjVarDeleteDataRangeHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ word rangeStart, /* start of range */ word rangeEnd, /* end of range */ Boolean useStateFlag); /* save to state flag */
This routine is the same as
ObjVarDeleteDataRange()
except that the object is specified via its handles rather than its optr.
Include: object.h
void * ObjVarDerefData( optr obj, /* object having data type */ VardataKey dataType); /* data type to dereference */
This routine is exactly like
ObjVarFindData()
, below, except that it does not return a null pointer if the data type is not found. Do not use this routine unless you are absolutely sure the data type is in the object; otherwise, results are unpredictable.
Include: object.h
See Also: ObjVarFindData()
.
void * ObjVarDerefDataHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ VardataKey dataType); /* data type to dereference */
This routine is the same as
ObjVarDerefData()
except that the object is specified via its handles rather than its optr.
Include: object.h
void * ObjVarFindData( optr obj, /* object to be checked */ VardataKey dataType); /* data type to find */
This routine searches an object's variable data for a given data type. If the type is found,
ObjVarFindData()
returns a pointer to the entry's extra data; if the entry has no extra data, an opaque pointer is returned which may be used with
ObjVarDeleteDataAt()
. If the entry is not found, a null pointer is returned. The pointer returned by this routine must be used before any subsequent operations on the object's block; the pointer may be invalidated by other LMem or object operations.
The two parameters of this routine are
obj
dataType
VardataKey
word declaring the data type and its flags. Both the VDF_SAVE_TO_STATE flag and the VDF_EXTRA_DATA flag are ignored.
Warnings: This routine should be called only by the object whose vardata is affected. To operate on other objects' vardata remotely, use messages provided by
MetaClass
(see below under "See Also").
Include: object.h
See Also: MSG_META_FIND_VAR_DATA
.
void * ObjVarFindDataHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ VardataKey dataType); /* data type to find */
This routine is the same as
ObjVarFindData()
except that the object is specified via its handles rather than its optr.
Include: object.h
void ObjVarScanData( optr obj, /* object to be scanned */ word numHandlers, /* number of handlers in table */ VarDataCHandler * handlerTable, /* pointer to handler table */ void * handlerData); /* pointer to handler data */
This routine scans an object's vardata and calls all the vardata handlers specified in the passed handler table. Pass it the following parameters:
obj
numHandlers
handlerTable
VarDataCHandler
structures. Each of these structures contains a vardata data type and a pointer to the routine that is to handle it. All the handler routines must be in the same segment as the handler table.
handlerData
Vardata Handler Format:
A vardata handler routine must have the following format:
void _pascal (MemHandle mh, ChunkHandle chnk, VarDataEntry *extraData, word dataType, void *handlerData)
The handler should not free the object chunk or destroy the object; it can do anything else it pleases. The handler returns nothing and takes the following parameters:
mh:chnk
extraData
VarDataTypePtr()
,
VarDataFlagsPtr()
, and
VarDataSizePtr()
.
dataType
VardataKey
.
handlerData
ObjVarScanData()
. This buffer may be used for passing additional data to the handlers.
Structures: The
VarDataCHandler
structure contains two elements:
typedef struct { word VDCH_dataType; void _pascal (*VDCH_handler) ( MemHandle mh, ChunkHandle chnk, VarDataEntry * extraData, word dataType void * handlerData); } VarDataCHandler;
The first element is the data type, a record containing the data type and the vardata flags. The second element is a far pointer to the handler routine for the type.
Include: object.h
void ObjVarScanDataHandles( MemHandle mh, /* handle portion of optr */ ChunkHandle ch, /* chunk portion of optr */ word numHandlers, /* number of handlers in table */ VarDataCHandler * handlerTable, /* pointer to handler table */ void * handlerData); /* pointer to handler data */
This routine is the same as
ObjVarScanData()
except that the object is specified via its handles rather than its optr.
Include: object.h
word offsetof(struc, field);
This macro returns the offset of the specified field within the specified structure.
ChunkHandle OptrToChunk(op); optr op;
This macro extracts the chunk handle portion of the given optr.
See Also: ConstructOptr()
,
OptrToHandle()
.
MemHandle OptrToHandle(op); optr op;
This macro extracts the MemHandle portion of the given optr.
See Also: ConstructOptr()
,
OptrToChunk()
.
StreamError ParallelClose( GeodeHandle driver, ParallelUnit unit, Boolean linger);
Close the stream to a parallel port.
Include: streamC.h
StreamError ParallelGetError ( Handle driver, ParallelUnit unit, StreamRoles roles, ParallelError * errorCode);
This routine returns any parallel-driver-specific error codes set by the last call to the parallel-driver.
StreamError ParallelOpen( GeodeHandle driver, ParallelUnit unit, StreamOpenFlags flags, word outBuffSize, word timeout);
This routine opens a stream to the specified parallel port. It is passed the following arguments:
driver
GeodeToken
of the parallel driver.
unit
flags
outBuffSize
timeout
flags
is not STREAM_OPEN_TIMEOUT.)
If the routine is successful, it returns zero. If it is unsuccessful, it returns a member of the
StreamError
enumerated type.
Include: streamC.h
StreamError ParallelSetError( Handle driver, ParallelUnit unit, StreamRoles roles, ParallelError * errorCode);
This routine sets the device-specific error code for the specified parallel port.
StreamError ParallelWrite( GeodeHandle driver, ParallelUnit unit, StreamBlocker blocker, word buffSize, const byte * buffer, word * numBytesWritten);
Write data to a parallel port.
Include: streamC.h
StreamError ParallelWrite( GeodeHandle driver, ParallelUnit unit, StreamBlocker blocker, word buffSize, byte dataByte);
Write one byte of data to a parallel port.