Иногда надо хранить данные (часто строки) в буфере, таким образом, чтобы этими данными можно было в любой момент воспользоваться, и при этом, во-первых, не хочется (или нельзя) выделять фиксированное место фиксированного размера, во-вторых, не хочется помнить о том, что выделенную память надо освобождать, и в-третьих, вообще хочется забыть о том, как хранятся данные и конечно же обойтись без "сборки мусора".
В случае со словом POCKET создается именованный карман, которым можно пользоваться при работе с массивами байт, точнее со строками. Если на входе у полученного слова будет 0, то слово вернет адрес и длину хранимой в хипе строки (если она там есть, иначе просто FALSE) Если на входе у полученного слова будет адрес и длина (ненулевая) , то строка сохранится в карман, и сразу будут получены адрес и длина полученной строки.
Слово BOCKET в отличие от POCKET не копирует исходные данные, а просто выделяет в ХИПе место, под массив указанного размера. В остальном поведение слов совпадает. Память выделяется в локальном ХИПе потока, поэтому эти слова нельзя использовать для обмена данными между потоками а так же между потоком и системой, для этого см. gocket.fts
<pre>
\ 06.11.2009 ~mOleg
\ Сopyright [C] 2009 mOleg
mininoleg@yahoo.com
\ карман для строк и массивов
\ создать строковую пользовательскую переменную со следующим поведением
\ если на входе 0 - вернуть хранимую строку
\ если на входе число отличное от нуля, считать его счетчиком строки
\ коприровать строку в хип, вернуть адрес и длину строки в хипе
\ в случае, если ранее в кармане была строка, удалить ее
: POCKET ( / name --> )
CREATE CELL USER-PLACE ,
DOES> ( asc # addr | 0 addr --> asc # | 0 )
@ TlsIndex@ + A>L
*IF S>HEAP DUP AL> ACHANGE
*IF FREE THEN DROP COUNT
;THEN DROP
AL> A@ *IF COUNT THEN ;
\ создать именованный буфер\карман
\ если на входе 0 - вернуть адрес и длину ранее выделенного буфера
\ если на входе число, отличное от нуля, старый буфер освободить
\ выделить место под новый буфер, вернуть адрес начала и длину буфера
\ в случае неуспеха вернуть 0 ,
\ ошибка выделения пространства под буфер: THROW
: BOCKET ( / name --> )
CREATE ADDR CELL + USER-PLACE ,
DOES> ( # | 0 --> addr # | 0 )
@ TlsIndex@ +
OVER *IF ALLOCATE THROW
OVER ACHANGE *IF FREE THEN DROP
TUCK ADDR + !
ELSE DROP NIP
THEN
DUP A@ *IF SWAP ADDR + @ ;THEN
NIP ;
</pre>
Иногда надо хранить данные (часто строки) в буфере, таким образом, чтобы этими данными можно было в любой момент воспользоваться, и при этом, во-первых, не хочется (или нельзя) выделять фиксированное место фиксированного размера, во-вторых, не хочется помнить о том, что выделенную память надо освобождать, и в-третьих, вообще хочется забыть о том, как хранятся данные и конечно же обойтись без "сборки мусора".
В случае со словом POCKET создается именованный карман, которым можно пользоваться при работе с массивами байт, точнее со строками. Если на входе у полученного слова будет 0, то слово вернет адрес и длину хранимой в хипе строки (если она там есть, иначе просто FALSE) Если на входе у полученного слова будет адрес и длина (ненулевая) , то строка сохранится в карман, и сразу будут получены адрес и длина полученной строки.
Слово BOCKET в отличие от POCKET не копирует исходные данные, а просто выделяет в ХИПе место, под массив указанного размера. В остальном поведение слов совпадает. Память выделяется в локальном ХИПе потока, поэтому эти слова нельзя использовать для обмена данными между потоками а так же между потоком и системой, для этого см. gocket.fts
<pre>
\ 06.11.2009 ~mOleg
\ Сopyright [C] 2009 mOleg mininoleg@yahoo.com
\ карман для строк и массивов
\ создать строковую пользовательскую переменную со следующим поведением
\ если на входе 0 - вернуть хранимую строку
\ если на входе число отличное от нуля, считать его счетчиком строки
\ коприровать строку в хип, вернуть адрес и длину строки в хипе
\ в случае, если ранее в кармане была строка, удалить ее
: POCKET ( / name --> )
CREATE CELL USER-PLACE ,
DOES> ( asc # addr | 0 addr --> asc # | 0 )
@ TlsIndex@ + A>L
*IF S>HEAP DUP AL> ACHANGE
*IF FREE THEN DROP COUNT
;THEN DROP
AL> A@ *IF COUNT THEN ;
\ создать именованный буфер\карман
\ если на входе 0 - вернуть адрес и длину ранее выделенного буфера
\ если на входе число, отличное от нуля, старый буфер освободить
\ выделить место под новый буфер, вернуть адрес начала и длину буфера
\ в случае неуспеха вернуть 0 ,
\ ошибка выделения пространства под буфер: THROW
: BOCKET ( / name --> )
CREATE ADDR CELL + USER-PLACE ,
DOES> ( # | 0 --> addr # | 0 )
@ TlsIndex@ +
OVER *IF ALLOCATE THROW
OVER ACHANGE *IF FREE THEN DROP
TUCK ADDR + !
ELSE DROP NIP
THEN
DUP A@ *IF SWAP ADDR + @ ;THEN
NIP ;
</pre>