xref: /freebsd/stand/ficl/softwords/string.fr (revision 26a58599a09a6181e0f5abe624021865a0c23186)
1*ca987d46SWarner Losh\ #if (FICL_WANT_OOP)
2*ca987d46SWarner Losh\ ** ficl/softwords/string.fr
3*ca987d46SWarner Losh\ A useful dynamic string class
4*ca987d46SWarner Losh\ John Sadler 14 Sep 1998
5*ca987d46SWarner Losh\
6*ca987d46SWarner Losh\ ** C - S T R I N G
7*ca987d46SWarner Losh\ counted string, buffer sized dynamically
8*ca987d46SWarner Losh\ Creation example:
9*ca987d46SWarner Losh\   c-string --> new str
10*ca987d46SWarner Losh\   s" arf arf!!" str --> set
11*ca987d46SWarner Losh\   s" woof woof woof " str --> cat
12*ca987d46SWarner Losh\   str --> type  cr
13*ca987d46SWarner Losh\
14*ca987d46SWarner Losh
15*ca987d46SWarner Loshalso oop definitions
16*ca987d46SWarner Losh
17*ca987d46SWarner Loshobject subclass c-string
18*ca987d46SWarner Losh    c-cell obj: .count
19*ca987d46SWarner Losh    c-cell obj: .buflen
20*ca987d46SWarner Losh    c-ptr  obj: .buf
21*ca987d46SWarner Losh    32 constant min-buf
22*ca987d46SWarner Losh
23*ca987d46SWarner Losh    : get-count   ( 2:this -- count )  my=[ .count  get ] ;
24*ca987d46SWarner Losh    : set-count   ( count 2:this -- )  my=[ .count  set ] ;
25*ca987d46SWarner Losh
26*ca987d46SWarner Losh    : ?empty   ( 2:this -- flag )  --> get-count 0= ;
27*ca987d46SWarner Losh
28*ca987d46SWarner Losh    : get-buflen   ( 2:this -- len )  my=[ .buflen  get ] ;
29*ca987d46SWarner Losh    : set-buflen   ( len 2:this -- )  my=[ .buflen  set ] ;
30*ca987d46SWarner Losh
31*ca987d46SWarner Losh    : get-buf   ( 2:this -- ptr )     my=[ .buf get-ptr ] ;
32*ca987d46SWarner Losh    : set-buf   { ptr len 2:this -- }
33*ca987d46SWarner Losh        ptr this my=[ .buf set-ptr ]
34*ca987d46SWarner Losh        len this my=> set-buflen
35*ca987d46SWarner Losh    ;
36*ca987d46SWarner Losh
37*ca987d46SWarner Losh    \ set buffer to null and buflen to zero
38*ca987d46SWarner Losh    : clr-buf   ( 2:this -- )
39*ca987d46SWarner Losh        0 0 2over  my=> set-buf
40*ca987d46SWarner Losh        0 -rot     my=> set-count
41*ca987d46SWarner Losh    ;
42*ca987d46SWarner Losh
43*ca987d46SWarner Losh    \ free the buffer if there is one, set buf pointer to null
44*ca987d46SWarner Losh    : free-buf   { 2:this -- }
45*ca987d46SWarner Losh        this my=> get-buf
46*ca987d46SWarner Losh        ?dup if
47*ca987d46SWarner Losh            free
48*ca987d46SWarner Losh			abort" c-string free failed"
49*ca987d46SWarner Losh			this  my=> clr-buf
50*ca987d46SWarner Losh        endif
51*ca987d46SWarner Losh    ;
52*ca987d46SWarner Losh
53*ca987d46SWarner Losh    \ guarantee buffer is large enough to hold size chars
54*ca987d46SWarner Losh    : size-buf  { size 2:this -- }
55*ca987d46SWarner Losh        size 0< abort" need positive size for size-buf"
56*ca987d46SWarner Losh        size 0= if
57*ca987d46SWarner Losh            this --> free-buf exit
58*ca987d46SWarner Losh        endif
59*ca987d46SWarner Losh
60*ca987d46SWarner Losh        \ force buflen to be a positive multiple of min-buf chars
61*ca987d46SWarner Losh        my=> min-buf size over / 1+ * chars to size
62*ca987d46SWarner Losh
63*ca987d46SWarner Losh        \ if buffer is null, allocate one, else resize it
64*ca987d46SWarner Losh        this --> get-buflen  0=
65*ca987d46SWarner Losh        if
66*ca987d46SWarner Losh            size allocate
67*ca987d46SWarner Losh            abort" out of memory"
68*ca987d46SWarner Losh            size this --> set-buf
69*ca987d46SWarner Losh            size this --> set-buflen
70*ca987d46SWarner Losh            exit
71*ca987d46SWarner Losh        endif
72*ca987d46SWarner Losh
73*ca987d46SWarner Losh        size this --> get-buflen > if
74*ca987d46SWarner Losh            this --> get-buf size resize
75*ca987d46SWarner Losh            abort" out of memory"
76*ca987d46SWarner Losh            size this --> set-buf
77*ca987d46SWarner Losh        endif
78*ca987d46SWarner Losh    ;
79*ca987d46SWarner Losh
80*ca987d46SWarner Losh    : set   { c-addr u 2:this -- }
81*ca987d46SWarner Losh        u this --> size-buf
82*ca987d46SWarner Losh        u this --> set-count
83*ca987d46SWarner Losh        c-addr this --> get-buf  u move
84*ca987d46SWarner Losh    ;
85*ca987d46SWarner Losh
86*ca987d46SWarner Losh    : get   { 2:this -- c-addr u }
87*ca987d46SWarner Losh        this --> get-buf
88*ca987d46SWarner Losh        this --> get-count
89*ca987d46SWarner Losh    ;
90*ca987d46SWarner Losh
91*ca987d46SWarner Losh    \ append string to existing one
92*ca987d46SWarner Losh    : cat   { c-addr u 2:this -- }
93*ca987d46SWarner Losh        this --> get-count u +  dup >r
94*ca987d46SWarner Losh        this --> size-buf
95*ca987d46SWarner Losh        c-addr  this --> get-buf this --> get-count +  u move
96*ca987d46SWarner Losh        r> this --> set-count
97*ca987d46SWarner Losh    ;
98*ca987d46SWarner Losh
99*ca987d46SWarner Losh    : type   { 2:this -- }
100*ca987d46SWarner Losh	    this --> ?empty if ." (empty) " exit endif
101*ca987d46SWarner Losh        this --> .buf --> get-ptr
102*ca987d46SWarner Losh        this --> .count --> get
103*ca987d46SWarner Losh        type
104*ca987d46SWarner Losh    ;
105*ca987d46SWarner Losh
106*ca987d46SWarner Losh    : compare   ( 2string 2:this -- n )
107*ca987d46SWarner Losh        --> get
108*ca987d46SWarner Losh        2swap
109*ca987d46SWarner Losh        --> get
110*ca987d46SWarner Losh        2swap compare
111*ca987d46SWarner Losh    ;
112*ca987d46SWarner Losh
113*ca987d46SWarner Losh    : hashcode   ( 2:this -- hashcode )
114*ca987d46SWarner Losh        --> get  hash
115*ca987d46SWarner Losh    ;
116*ca987d46SWarner Losh
117*ca987d46SWarner Losh    \ destructor method (overrides object --> free)
118*ca987d46SWarner Losh    : free   ( 2:this -- )  2dup --> free-buf  object => free ;
119*ca987d46SWarner Losh
120*ca987d46SWarner Loshend-class
121*ca987d46SWarner Losh
122*ca987d46SWarner Loshc-string subclass c-hashstring
123*ca987d46SWarner Losh    c-2byte obj: .hashcode
124*ca987d46SWarner Losh
125*ca987d46SWarner Losh    : set-hashcode   { 2:this -- }
126*ca987d46SWarner Losh        this  --> super --> hashcode
127*ca987d46SWarner Losh        this  --> .hashcode --> set
128*ca987d46SWarner Losh    ;
129*ca987d46SWarner Losh
130*ca987d46SWarner Losh    : get-hashcode   ( 2:this -- hashcode )
131*ca987d46SWarner Losh        --> .hashcode --> get
132*ca987d46SWarner Losh    ;
133*ca987d46SWarner Losh
134*ca987d46SWarner Losh    : set   ( c-addr u 2:this -- )
135*ca987d46SWarner Losh        2swap 2over --> super --> set
136*ca987d46SWarner Losh        --> set-hashcode
137*ca987d46SWarner Losh    ;
138*ca987d46SWarner Losh
139*ca987d46SWarner Losh    : cat   ( c-addr u 2:this -- )
140*ca987d46SWarner Losh        2swap 2over --> super --> cat
141*ca987d46SWarner Losh        --> set-hashcode
142*ca987d46SWarner Losh    ;
143*ca987d46SWarner Losh
144*ca987d46SWarner Loshend-class
145*ca987d46SWarner Losh
146*ca987d46SWarner Loshprevious definitions
147*ca987d46SWarner Losh\ #endif
148