The xsuex user exit obtains and manipulates external strings, allowing the caller (likely non-FlashBASIC) to store data without writing to a file or storing it in BASIC string space.
External strings exist outside of FlashBASIC or BASIC and are called with the create command. This prompts the system to return a handle, which is then used for append, clear, delete, and get operations.
External strings can be shared and are persistent (even after rebooting).
The general syntax for this user exit is:
<result> = oconv(<xscmdcommand>: @am : <parameters>, xsuex)
where xscmdcommand is the specified command (either append, clear, create, delete, or get) prefixed by the literal xscmd.
u005b
There are five command-specific forms for this user exit, each performing a specific task. They are:
append, clear, create, delete and getappend
The append form attaches a specified string to the specified external string.
lresult = oconv(xscmdappend: @am : hxstring: @am : sstring, xsuex)
lresult | Return code. |
hxstring | Handle of the external string to be appended (obtained from a create command). |
sstring | Specifies the string to attach to the external string. |
clear
The clear form clears an external string.
lresult = oconv(xscmdclear: @am : hxstring, xsuex)
lresult | Return code. |
hxstring | Handle of the external string to be appended (obtained from a create command). |
create
The create form creates an external string.
lresult = oconv(xscmdcreate, xsuex)
lresult | Return code. If the call succeeds, this is the handle (for example, hxstring) to be used in subsequent calls. |
delete
The delete form deletes an external string.
lresult = oconv(xscmddelete: @am : hxstring, xsuex)
lresult | Return code. |
hxstring | Handle of the external string to delete (obtained from a create command.) |
get
The get form gets an external string and copies it into a BASIC variable.
sresult = oconv(xscmdget: @am : hxstring, xsuex)
sresult | External string or failure code. |
hxstring | Handle of the external string to get (obtained from a create command). |
External strings improve performance by maintaining a pointer at the end of the string. This facilitates rapid appends since they can quickly jump to the end of the string. Furthermore, when extra space is required, it can be quickly linked to the end of the string.
External strings are most effectively used to build large strings by repeatedly appending smaller strings, especially when the resulting string is to be used only after being completely built (for example, in operations using multiple append calls and few get calls).
External strings exist outside of BASIC string space and thus are not subject to the time consuming process of garbage collection (compaction of BASIC string space).
As BASIC strings expand they can quickly overflow their existing buffer. When this occurs, the existing buffer must be abandoned and a new buffer allocated. If the strings are exceptionally large, this can cause significant performance degradation. External strings add on additional space as needed. They do not need to abandon and reallocate space.
BASIC strings are relatively short lived. For example, they exist only for the duration of a called subroutine, or in the case of a named common, as long as the line is logged on. External strings are persistent. They remain intact after rebooting (however, not after a full system restore).
BASIC strings can only be used in specific scopes, such as within a called routine or a named common. External strings can be shared across multiple lines as long as the proper precautions are taken, such as accessing the string only while it is under some instance of an exclusive use lock.
External strings are not saved during a file-save.
There is currently no locking scheme available. Disaster prevention is therefore the responsibility of the programmer. However, a minimal safeguard does exist: The external string is signed. Before access is granted, the signature is checked to confirm that the handle references an external string. This prevents errors such as appending a string to space that has been released.
When appending very large strings or getting very large external strings, an overflow runaway condition can result. See the TCL set-runaway-limit command to configure the system as needed.
The return code returned is dependent upon the statement executed. Not all return codes apply to every statement.
xssuccess = 0 xserrbadcommand = -2147483648 = 0xffff80000000 xserrbadhandle = -2147483647 = 0xffff80000001 xserrbadsign = -2147483646 = 0xffff80000002 <external string> (Returned by a successful get statement.)
This program pauses at each step. Press any key to move to the next step.
include dm,bp,includes xs.inc print print "allocating an external string." in k hxstring = oconv(xscmdcreate, xsuex) print "handle = '" : hxstring : "'" gosub showit print print "appending 500 bytes." in k lresult = oconv(xscmdappend : @am : hxstring : @am : str("!", 500), xsuex) print "lresult = '" : lresult : "'" gosub showit gosub clearit gosub showit print print "appending 250 bytes." in k lresult = oconv(xscmdappend : @am : hxstring : @am : str("@", 250), xsuex) print "lresult = '" : lresult : "'" gosub showit print print "appending 10000 bytes." in k lresult = oconv(xscmdappend : @am : hxstring : @am : str("#", 10000), xsuex) print "lresult = '" : lresult : "'" gosub showit gosub clearit gosub showit print print "appending 3000 bytes." in k lresult = oconv(xscmdappend : @am : hxstring : @am : str("$", 3000), xsuex) print "lresult = '" : lresult : "'" gosub showit print print "appending 6000 bytes." in k lresult = oconv(xscmdappend : @am : hxstring : @am : str("%", 6000), xsuex) print "lresult = '" : lresult : "'" gosub showit print print "deleting." in k lresult = oconv(xscmddelete : @am : hxstring, xsuex) print "lresult = '" : lresult : "'" gosub showit print print "deleting again." in k lresult = oconv(xscmddelete : @am : hxstring, xsuex) print "lresult = '" : lresult : "'"
gosub showit print print "issuing bad command." in k lresult = oconv("999", xsuex) print "lresult = '" : lresult : "'" print print "issuing get with bad handle." in k lresult = oconv(xscmdget : @am : "0", xsuex) print "lresult = '" : lresult : "'" stop clearit: print print "clearing." in k lresult = oconv(xscmdclear : @am : hxstring, xsuex) print "lresult = '" : lresult : "'" return showit: print print "getting string." in k sresult = oconv(xscmdget : @am : hxstring, xsuex) print "sresult = '" : sresult : "', len(sresult) = '" : len(sresult) : "'" return end