7 #define COMPLEX(hb) ((HBytes_ComplexValue*)hb->begin_complex)
8 #define SIMPLE_LEN(hb) ((Byte*)(hb)->end_0 - (Byte*)(hb)->begin_complex)
12 int cht_hb_len(const HBytes_Value *hb) {
13 if (HBYTES_ISEMPTY(hb)) return 0;
14 else if (HBYTES_ISCOMPLEX(hb)) return COMPLEX(hb)->len;
15 else return SIMPLE_LEN(hb);
18 Byte *cht_hb_data(const HBytes_Value *hb) {
19 if (HBYTES_ISEMPTY(hb)) return 0;
20 else if (HBYTES_ISCOMPLEX(hb)) return COMPLEX(hb)->dstart;
21 else return hb->begin_complex;
24 int cht_hb_issentinel(const HBytes_Value *hb) {
25 return HBYTES_ISSENTINEL(hb);
30 void cht_hb_empty(HBytes_Value *returns) {
31 returns->begin_complex= returns->end_0= 0;
34 void cht_hb_sentinel(HBytes_Value *returns) {
35 returns->begin_complex= 0;
36 returns->end_0= (void*)&cht_hbytes_type;
39 Byte *cht_hb_arrayspace(HBytes_Value *returns, int l) {
40 if (!l) { cht_hb_empty(returns); return 0; }
41 returns->begin_complex= TALLOC(l);
42 returns->end_0= returns->begin_complex + l;
43 return returns->begin_complex;
46 void cht_hb_array(HBytes_Value *returns, const Byte *array, int l) {
47 memcpy(cht_hb_arrayspace(returns,l), array, l);
52 void cht_hb_free(const HBytes_Value *frees) {
53 if (HBYTES_ISCOMPLEX(frees)) {
54 HBytes_ComplexValue *cx= COMPLEX(frees);
55 TFREE(cx->dstart - cx->prespace);
57 TFREE(frees->begin_complex);
62 static HBytes_ComplexValue *complex(HBytes_Value *hb) {
63 HBytes_ComplexValue *cx;
65 if (HBYTES_ISCOMPLEX(hb)) return hb->begin_complex;
67 cx= TALLOC(sizeof(*cx));
68 cx->dstart= hb->begin_complex;
69 cx->len= cx->avail= SIMPLE_LEN(hb);
72 hb->begin_complex= cx;
78 Byte *cht_hb_prepend(HBytes_Value *hb, int el) {
79 HBytes_ComplexValue *cx;
81 Byte *old_block, *new_block, *new_dstart;
85 if (cx->prespace < el) {
86 new_prespace= el*2 + cx->len;
87 old_block= cx->dstart - cx->prespace;
88 new_block= Tcl_Realloc(old_block, new_prespace + cx->avail);
89 new_dstart= new_block + new_prespace;
90 memmove(new_dstart, new_block + cx->prespace, cx->len);
91 cx->prespace= new_prespace;
92 cx->dstart= new_dstart;
101 Byte *cht_hb_append(HBytes_Value *hb, int el) {
102 HBytes_ComplexValue *cx;
103 int new_len, new_avail;
104 Byte *newpart, *new_block, *old_block;
108 new_len= cx->len + el;
109 if (new_len > cx->avail) {
110 new_avail= new_len*2;
111 old_block= cx->dstart - cx->prespace;
112 new_block= Tcl_Realloc(old_block, cx->prespace + new_avail);
113 cx->dstart= new_block + cx->prespace;
114 cx->avail= new_avail;
116 newpart= cx->dstart + cx->len;
121 static HBytes_ComplexValue*
122 prechop(HBytes_Value *hb, int cl, const Byte **rv) {
123 HBytes_ComplexValue *cx;
125 if (cl<0) { *rv=0; return 0; }
126 if (cl==0) { *rv= (const void*)&cht_hbytes_type; return 0; }
129 if (cl > cx->len) { *rv=0; return 0; }
133 const Byte *cht_hb_unprepend(HBytes_Value *hb, int pl) {
135 HBytes_ComplexValue *cx= prechop(hb,pl,&chopped);
136 if (!cx) return chopped;
146 const Byte *cht_hb_unappend(HBytes_Value *hb, int sl) {
148 HBytes_ComplexValue *cx= prechop(hb,sl,&chopped);
149 if (!cx) return chopped;
152 return cx->dstart + cx->len;
155 void memxor(Byte *dest, const Byte *src, int l) {
156 while (l--) *dest++ ^= *src++;