# xsuex user exit

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.

**Synonyms:** u005b

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.

## Command-Specific Forms

There are five command-specific
forms for this user exit, each performing a specific task. They are:

append, clear, create, delete and get**append**

The append form attaches a specified string to the specified external string.

## Syntax

```
lresult = oconv(xscmdappend: @am : hxstring: @am : sstring, xsuex)
```

## Parameter(s)

| 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.

## Syntax

```
lresult = oconv(xscmdclear: @am : hxstring, xsuex)
```

## Parameter(s)

| 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.

## Syntax

```
lresult = oconv(xscmdcreate, xsuex)
```

## Parameter(s)

| 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.

## Syntax

```
lresult = oconv(xscmddelete: @am : hxstring, xsuex)
```

## Parameter(s)

| 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.

## Syntax

```
sresult = oconv(xscmdget: @am : hxstring, xsuex)
```

## Parameter(s)

| sresult | External string or failure code. |
| --- | --- |
| hxstring | Handle of the external string to get (obtained from a create command). |

## Description

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).

## Differences Between BASIC and External Strings

- 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.

Warning:

- 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.

Tip: Use the dm,bp,includes xs.inc for programmer
readable code.

## Return Codes

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.)
```

## Example(s)

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 = &#39;" : hxstring : "&#39;"

gosub showit

print
print "appending 500 bytes."
in k
lresult = oconv(xscmdappend : @am : hxstring : @am : str("!", 500), xsuex)
print "lresult = &#39;" : lresult : "&#39;"

gosub showit

gosub clearit

gosub showit

print
print "appending 250 bytes."
in k
lresult = oconv(xscmdappend : @am : hxstring : @am : str("@", 250), xsuex)
print "lresult = &#39;" : lresult : "&#39;"

gosub showit

print
print "appending 10000 bytes."
in k
lresult = oconv(xscmdappend : @am : hxstring : @am : str("#", 10000), xsuex)
print "lresult = &#39;" : lresult : "&#39;"

gosub showit

gosub clearit

gosub showit

print
print "appending 3000 bytes."
in k
lresult = oconv(xscmdappend : @am : hxstring : @am : str("$", 3000), xsuex)
print "lresult = &#39;" : lresult : "&#39;"

gosub showit

print
print "appending 6000 bytes."
in k
lresult = oconv(xscmdappend : @am : hxstring : @am : str("%", 6000), xsuex)
print "lresult = &#39;" : lresult : "&#39;"

gosub showit

print
print "deleting."
in k
lresult = oconv(xscmddelete : @am : hxstring, xsuex)
print "lresult = &#39;" : lresult : "&#39;"

gosub showit

print
print "deleting again."
in k
lresult = oconv(xscmddelete : @am : hxstring, xsuex)
print "lresult = &#39;" : lresult : "&#39;"
```

```
gosub showit

print
print "issuing bad command."
in k
lresult = oconv("999", xsuex)
print "lresult = &#39;" : lresult : "&#39;"
print
print "issuing get with bad handle."
in k
lresult = oconv(xscmdget : @am : "0", xsuex)
print "lresult = &#39;" : lresult : "&#39;"
stop

clearit:

print
print "clearing."
in k
lresult = oconv(xscmdclear : @am : hxstring, xsuex)
print "lresult = &#39;" : lresult : "&#39;"

return

showit:
print
print "getting string."
in k
sresult = oconv(xscmdget : @am : hxstring, xsuex)
print "sresult = &#39;" : sresult : "&#39;, len(sresult) = &#39;" : len(sresult) : "&#39;"

return

end
```

---
Source: https://d3codex.com/pickbasic-flashbasic/xsuex-user-exit/ - part of the D3Codex reference.
