10 #define COMPLEX(hb) ((HBytes_ComplexValue*)hb->begin_complex)
11 #define SIMPLE_LEN(hb) ((Byte*)(hb)->end_0 - (Byte*)(hb)->begin_complex)
15 int hbytes_len(const HBytes_Value *hb) {
16 if (HBYTES_ISEMPTY(hb)) return 0;
17 else if (HBYTES_ISCOMPLEX(hb)) return COMPLEX(hb)->len;
18 else return SIMPLE_LEN(hb);
21 Byte *hbytes_data(const HBytes_Value *hb) {
22 if (HBYTES_ISEMPTY(hb)) return 0;
23 else if (HBYTES_ISCOMPLEX(hb)) return COMPLEX(hb)->dstart;
24 else return hb->begin_complex;
27 int hbytes_issentinel(const HBytes_Value *hb) {
28 return HBYTES_ISSENTINEL(hb);
33 void hbytes_empty(HBytes_Value *returns) {
34 returns->begin_complex= returns->end_0= 0;
37 void hbytes_sentinel(HBytes_Value *returns) {
38 returns->begin_complex= 0;
39 returns->end_0= (void*)&hbytes_type;
42 Byte *hbytes_arrayspace(HBytes_Value *returns, int l) {
43 if (!l) { hbytes_empty(returns); return 0; }
44 returns->begin_complex= TALLOC(l);
45 returns->end_0= returns->begin_complex + l;
46 return returns->begin_complex;
49 void hbytes_array(HBytes_Value *returns, const Byte *array, int l) {
50 memcpy(hbytes_arrayspace(returns,l), array, l);
55 void hbytes_free(const HBytes_Value *frees) {
56 if (HBYTES_ISCOMPLEX(frees)) {
57 HBytes_ComplexValue *cx= COMPLEX(frees);
58 TFREE(cx->dstart - cx->prespace);
60 TFREE(frees->begin_complex);
65 static HBytes_ComplexValue *complex(HBytes_Value *hb) {
66 HBytes_ComplexValue *cx;
68 if (HBYTES_ISCOMPLEX(hb)) return hb->begin_complex;
70 cx= TALLOC(sizeof(*cx));
71 cx->dstart= hb->begin_complex;
72 cx->len= cx->avail= SIMPLE_LEN(hb);
75 hb->begin_complex= cx;
81 Byte *hbytes_prepend(HBytes_Value *hb, int el) {
82 HBytes_ComplexValue *cx;
84 Byte *old_block, *new_block, *new_dstart;
88 if (cx->prespace < el) {
89 new_prespace= el*2 + cx->len;
90 old_block= cx->dstart - cx->prespace;
91 new_block= Tcl_Realloc(old_block, new_prespace + cx->avail);
92 new_dstart= new_block + new_prespace;
93 memmove(new_dstart, new_block + cx->prespace, cx->len);
94 cx->prespace= new_prespace;
95 cx->dstart= new_dstart;
104 Byte *hbytes_append(HBytes_Value *hb, int el) {
105 HBytes_ComplexValue *cx;
106 int new_len, new_avail;
107 Byte *newpart, *new_block, *old_block;
111 new_len= cx->len + el;
112 if (new_len > cx->avail) {
113 new_avail= new_len*2;
114 old_block= cx->dstart - cx->prespace;
115 new_block= Tcl_Realloc(old_block, cx->prespace + new_avail);
116 cx->dstart= new_block + cx->prespace;
117 cx->avail= new_avail;
119 newpart= cx->dstart + cx->len;
124 static HBytes_ComplexValue*
125 prechop(HBytes_Value *hb, int cl, const Byte **rv) {
126 HBytes_ComplexValue *cx;
128 if (cl<0) { *rv=0; return 0; }
129 if (cl==0) { *rv= (const void*)&hbytes_type; return 0; }
132 if (cl > cx->len) { *rv=0; return 0; }
136 const Byte *hbytes_unprepend(HBytes_Value *hb, int pl) {
138 HBytes_ComplexValue *cx= prechop(hb,pl,&chopped);
139 if (!cx) return chopped;
149 const Byte *hbytes_unappend(HBytes_Value *hb, int sl) {
151 HBytes_ComplexValue *cx= prechop(hb,sl,&chopped);
152 if (!cx) return chopped;
155 return cx->dstart + cx->len;