.\" -------------------- sec5.3.t -------------------- .sh 2 "Buffers" .pp SB-Prolog supports the concept of buffers. A buffer is actually a constant and the characters that make up the buffer is the name of the constant. However, the symbol table entry for a buffer is not hashed and thus is not added to the obj-list, so two different buffers will never unify. Buffers can be allocated either in permanent space or on the heap. Buffers in permanent space stay there forever; buffers on the heap are deallocated when the ``allocate buffer'' goal is backtracked over. .pp A buffer allocated on the heap can either be a simple buffer, or it can be allocated as a subbuffer of another buffer already on the heap. A subbuffer will be deallocated when its superbuffer is deallocated. .pp There are occasions when it is not known, in advance, exactly how much space will be required and so how big a buffer should be allocated. Sometimes this problem can be overcome by allocating a large buffer and then, after using as much as is needed, returning the rest of the buffer to the system. This can be done, but only under \fIvery\fR limited circumstances: a buffer is allocated from the end of the permanent space, the top of the heap, or from the next available space in the superbuffer; if no more space has been used beyond the end of the buffer, a tail portion of the buffer can be returned to the system. This operation is called ``trimming'' the buffer. .pp The following is a list of library predicates for buffer management (predicates whose names begin with `$' are low-level routines intended only for serious hackers willing to put up with little or no protection): .sp .ip \fBalloc_\|perm\fR(\fISize\fR,\ \fIBuff\fR) Allocates a buffer with a length \fISize\fR in the permanent (i.e. program) area. \fISize\fR must be bound to a number. On successful return, \fIBuff\fR will be bound to the allocated buffer. .(x b (L) alloc_\|perm/2 .)x The buffer, being in the permanent area, is never de-allocated. .ip \fBalloc_\|heap\fR(\fISize\fR,\ \fIBuff\fR) Allocates a buffer of size \fISize\fR on the heap and binds \fIBuff\fR to it. Since it is on the heap, it will be deallocated on backtracking. .(x b (L) alloc_\|heap/2 .)x .lp \fB$alloc_\|buff\fR(\fISize\fR,\fIBuff\fR,\fIType\fR,\fISupbuff\fR,\fIRetcode\fR) .ip Allocates a buffer. \fISize\fR is the length (in bytes) of the buffer to allocate; .(x b (L) $alloc_\|heap/5 .)x \fIBuff\fR is the buffer allocated, and should be unbound at the time of the call; \fIType\fR indicates where to allocate the buffer: a value of 0 indicates that the buffer is to be allocated in permanent space, 1 that it should be on the heap, and 2 indicates that it should be allocated from a larger heap buffer; \fISupbuff\fR is the larger buffer to allocate a subbuffer out of, and is only looked at if the value of \fIType\fR is 2; \fIRetcode\fR is the return code: a value of 0 indicates that the buffer has been allocated, while a value of 1 indicates that the buffer could not be allocated due to lack of space. The arguments \fISize\fR, \fIType\fR, and \fISupbuff\fR (if \fIType\fR = 2) are input arguments, and should be bound at the time of the call; \fIBuff\fR and \fIRetcode\fR are output arguments, and should be unbound at the time of the call. .ip \fBtrimbuff\fR(\fIType\fR,\ \fIBuff\fR,\ \fINewlen\fR) This allows (in some very restricted circumstances) the changing of the size of a buffer. \fIType\fR is 0 if the buffer is permanent, 1 if the buffer is on the heap. \fIBuff\fR is the buffer. .(x b (L) trimbuff/3 .)x \fINewlen\fR is an integer: the size (which should be smaller than the original length of the buffer) to make the buffer. If the buffer is at the top of the heap (if heap buffer) or the end of the program area (if permanent) then the heap-top (or program area top) will be readjusted down. The length of the buffer will be modified to \fINewlen\fR. This is (obviously) a very low-level primitive and is for hackers only to implement grungy stuff. .lp \fB$trim_\|buff\fR(\fISize\fR,\fIBuff\fR,\fIType\fR,\fISupbuff\fR\^) .ip Trims the buffer \fIBuff\fR (possibly contained in superbuffer \fISupbuff\fR) of type \fIType\fR to \fISize\fR bytes. .(x b (L) $trim_\|buff/4 .)x The value of \fIType\fR indicates where the buffer is located: a value of 0 denotes a buffer in permanent space, a value of 1 a buffer on the heap, and a value of 2 a buffer within another buffer (the superbuffer). All the arguments are input arguments, and should be instantiated at the time of call (with the possible exception of \fISupbuff\fR, which is looked at only if \fIType\fR is 2). The internal length of the buffer \fIBuff\fR is changed to \fISize\fR. .lp \fBconlength\fR(\fIConstant\fR,\fILength\fR\^) .ip Succeeds if the length of the print name of the constant \fIConstant\fR (which can be an atom, buffer or integer), in bytes, is \fILength\fR. If \fIConstant\fR is a buffer, it is the length of the buffer; if \fIConstant\fR is an integer, it is the length of the decimal representation of that integer, i.e., the number of bytes that a $\fIwritename\fR will use. .\" -------------------- end of section sec5.3.t -------------------- .