11 #define COMPLEX(hb) ((HBytes_ComplexValue*)hb->begin_complex)
12 #define SIMPLE_LEN(hb) ((Byte*)(hb)->end_0 - (Byte*)(hb)->begin_complex)
16 int hbytes_len(const HBytes_Value *hb) {
17 if (HBYTES_ISEMPTY(hb)) return 0;
18 else if (HBYTES_ISCOMPLEX(hb)) return COMPLEX(hb)->len;
19 else return SIMPLE_LEN(hb);
22 Byte *hbytes_data(const HBytes_Value *hb) {
23 if (HBYTES_ISEMPTY(hb)) return 0;
24 else if (HBYTES_ISCOMPLEX(hb)) return COMPLEX(hb)->dstart;
25 else return hb->begin_complex;
28 int hbytes_issentinel(const HBytes_Value *hb) {
29 return HBYTES_ISCOMPLEX(hb);
34 void hbytes_empty(HBytes_Value *returns) {
35 returns->begin_complex= returns->end_0= 0;
38 void hbytes_sentinel(HBytes_Value *returns) {
39 returns->begin_complex= 0;
40 returns->end_0= (void*)&hbytes_type;
43 Byte *hbytes_arrayspace(HBytes_Value *returns, int l) {
44 if (!l) { hbytes_empty(returns); return 0; }
45 returns->begin_complex= TALLOC(l);
46 returns->end_0= returns->begin_complex + l;
47 return returns->begin_complex;
50 void hbytes_array(HBytes_Value *returns, const Byte *array, int l) {
51 memcpy(hbytes_arrayspace(returns,l), array, l);
56 void hbytes_free(HBytes_Value *frees) {
57 if (HBYTES_ISCOMPLEX(frees)) {
58 HBytes_ComplexValue *cx= COMPLEX(frees);
59 TFREE(cx->dstart - cx->prespace);
61 TFREE(frees->begin_complex);
66 static HBytes_ComplexValue *complex(HBytes_Value *hb) {
67 HBytes_ComplexValue *cx;
69 if (HBYTES_ISCOMPLEX(hb)) return hb->begin_complex;
71 cx= TALLOC(sizeof(*cx));
72 cx->dstart= hb->begin_complex;
73 cx->len= cx->avail= SIMPLE_LEN(hb);
76 hb->begin_complex= cx;
82 Byte *hbytes_prepend(HBytes_Value *hb, int el) {
83 HBytes_ComplexValue *cx;
85 Byte *old_block, *new_block, *new_dstart;
89 if (cx->prespace < el) {
90 new_prespace= el*2 + cx->len;
91 old_block= cx->dstart - cx->prespace;
92 new_block= Tcl_Realloc(old_block, new_prespace + cx->avail);
93 new_dstart= new_block + new_prespace;
94 memmove(new_dstart, new_block + cx->prespace, cx->len);
95 cx->prespace= new_prespace;
96 cx->dstart= new_dstart;
105 Byte *hbytes_append(HBytes_Value *hb, int el) {
106 HBytes_ComplexValue *cx;
107 int new_len, new_avail;
108 Byte *newpart, *new_block, *old_block;
112 new_len= cx->len + el;
113 if (new_len > cx->avail) {
114 new_avail= new_len*2;
115 old_block= cx->dstart - cx->prespace;
116 new_block= Tcl_Realloc(old_block, cx->prespace + new_avail);
117 cx->dstart= new_block + cx->prespace;
118 cx->avail= new_avail;
120 newpart= cx->dstart + cx->len;
125 HBytes_ComplexValue *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;