chiark / gitweb /
provide errorCode for invalid reverse addrs
[chiark-tcl.git] / hbytes / hbytes.c
1 /*
2  *
3  */
4
5 #include "hbytes.h"
6
7 #define COMPLEX(hb) ((HBytes_ComplexValue*)hb->begin_complex)
8 #define SIMPLE_LEN(hb) ((Byte*)(hb)->end_0 - (Byte*)(hb)->begin_complex)
9
10 /* enquirers */
11
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);
16 }
17
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;
22 }
23
24 int cht_hb_issentinel(const HBytes_Value *hb) {
25   return HBYTES_ISSENTINEL(hb);
26 }
27
28 /* constructors */
29
30 void cht_hb_empty(HBytes_Value *returns) {
31   returns->begin_complex= returns->end_0= 0;
32 }
33
34 void cht_hb_sentinel(HBytes_Value *returns) {
35   returns->begin_complex= 0;
36   returns->end_0= (void*)&cht_hbytes_type;
37 }
38
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;
44 }
45   
46 void cht_hb_array(HBytes_Value *returns, const Byte *array, int l) {
47   memcpy(cht_hb_arrayspace(returns,l), array, l);
48 }
49
50 /* destructor */
51
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);
56   }
57   TFREE(frees->begin_complex);
58 }
59
60 /* mutators */
61
62 static HBytes_ComplexValue *complex(HBytes_Value *hb) {
63   HBytes_ComplexValue *cx;
64
65   if (HBYTES_ISCOMPLEX(hb)) return hb->begin_complex;
66
67   cx= TALLOC(sizeof(*cx));
68   cx->dstart= hb->begin_complex;
69   cx->len= cx->avail= SIMPLE_LEN(hb);
70   cx->prespace= 0;
71
72   hb->begin_complex= cx;
73   hb->end_0= 0;
74
75   return cx;
76 }
77
78 Byte *cht_hb_prepend(HBytes_Value *hb, int el) {
79   HBytes_ComplexValue *cx;
80   int new_prespace;
81   Byte *old_block, *new_block, *new_dstart;
82
83   cx= complex(hb);
84   
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;
93   }
94   cx->dstart -= el;
95   cx->prespace -= el;
96   cx->len += el;
97   cx->avail += el;
98   return cx->dstart;
99 }
100
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;
105
106   cx= complex(hb);
107
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;
115   }
116   newpart= cx->dstart + cx->len;
117   cx->len= new_len;
118   return newpart;
119 }
120
121 static HBytes_ComplexValue*
122 prechop(HBytes_Value *hb, int cl, const Byte **rv) {
123   HBytes_ComplexValue *cx;
124
125   if (cl<0) { *rv=0; return 0; }
126   if (cl==0) { *rv= (const void*)&cht_hbytes_type; return 0; }
127   
128   cx= complex(hb);
129   if (cl > cx->len) { *rv=0; return 0; }
130   return cx;
131 }
132
133 const Byte *cht_hb_unprepend(HBytes_Value *hb, int pl) {
134   const Byte *chopped;
135   HBytes_ComplexValue *cx= prechop(hb,pl,&chopped);
136   if (!cx) return chopped;
137
138   chopped= cx->dstart;
139   cx->dstart += pl;
140   cx->prespace += pl;
141   cx->len -= pl;
142   cx->avail -= pl;
143   return chopped;
144 }
145
146 const Byte *cht_hb_unappend(HBytes_Value *hb, int sl) {
147   const Byte *chopped;
148   HBytes_ComplexValue *cx= prechop(hb,sl,&chopped);
149   if (!cx) return chopped;
150
151   cx->len -= sl;
152   return cx->dstart + cx->len;
153 }
154
155 void memxor(Byte *dest, const Byte *src, int l) {
156   while (l--) *dest++ ^= *src++;
157 }