chiark / gitweb /
e649b5aa12a4dce45eb4ade79de62d2347d21c06
[chiark-tcl.git] / hbytes / chop.c
1 /*
2  * hbytes - hex-stringrep efficient byteblocks for Tcl
3  * Copyright 2006 Ian Jackson
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301, USA.
19  */
20
21
22 #include "chiark_tcl_hbytes.h"
23
24 static int strs1(Tcl_Interp *ip, int strc, Tcl_Obj *const *strv, int *l_r) {
25   int rc, l, i, pl;
26
27   l= 0;
28   for (i=1; i<strc; i++) {
29     rc= Tcl_ConvertToType(ip,strv[i],&cht_hbytes_type);
30     if (rc) return rc;
31     pl= cht_hb_len(OBJ_HBYTES(strv[i]));
32     assert(l < INT_MAX/2 && pl < INT_MAX/2);
33     l += pl;
34   }
35   *l_r= l;
36   return TCL_OK;
37 }
38
39 static void strs2(Byte *dest, int strc, Tcl_Obj *const *strv) {
40   int tl, i;
41   
42   for (i=1; i<strc; i++) {
43     tl= cht_hb_len(OBJ_HBYTES(strv[i]));
44     memcpy(dest, cht_hb_data(OBJ_HBYTES(strv[i])), tl);
45     dest += tl;
46   }
47 }
48
49 int cht_do_hbytes_prepend(ClientData cd, Tcl_Interp *ip,
50                       HBytes_Var v, int strc, Tcl_Obj *const *strv) {
51   int rc, el;
52   Byte *dest;
53   
54   rc= strs1(ip,strc,strv,&el);  if (rc) return rc;
55   dest= cht_hb_prepend(v.hb, el);
56   strs2(dest, strc,strv);
57   return TCL_OK;
58 }
59   
60 int cht_do_hbytes_append(ClientData cd, Tcl_Interp *ip,
61                      HBytes_Var v, int strc, Tcl_Obj *const *strv) {
62   int rc, el;
63   Byte *dest;
64
65   rc= strs1(ip,strc,strv,&el);  if (rc) return rc;
66   dest= cht_hb_append(v.hb, el);
67   strs2(dest,  strc,strv);
68   return TCL_OK;
69 }
70
71 int cht_do_hbytes_concat(ClientData cd, Tcl_Interp *ip,
72                      int strc, Tcl_Obj *const *strv, HBytes_Value *result) {
73   int rc, l;
74   Byte *dest;
75   
76   rc= strs1(ip,strc,strv,&l);  if (rc) return rc;
77   dest= cht_hb_arrayspace(result,l);
78   strs2(dest, strc,strv);
79   return TCL_OK;
80 }
81
82 static int underrun(Tcl_Interp *ip) {
83   return cht_staticerr(ip,"data underrun","HBYTES LENGTH UNDERRUN");
84 }
85
86 int cht_do_hbytes_unprepend(ClientData cd, Tcl_Interp *ip,
87                         HBytes_Var v, int preflength, HBytes_Value *result) {
88   const Byte *rdata= cht_hb_unprepend(v.hb, preflength);
89   if (!rdata) return underrun(ip);
90   cht_hb_array(result, rdata, preflength);
91   return TCL_OK;
92 }
93
94 int cht_do_hbytes_unappend(ClientData cd, Tcl_Interp *ip,
95                        HBytes_Var v, int suflength, HBytes_Value *result) {
96   const Byte *rdata= cht_hb_unappend(v.hb, suflength);
97   if (!rdata) return underrun(ip);
98   cht_hb_array(result, rdata, suflength);
99   return TCL_OK;
100 }
101
102 int cht_do_hbytes_chopto(ClientData cd, Tcl_Interp *ip,
103                      HBytes_Var v, int newlength, HBytes_Value *result) {
104   int suflength= cht_hb_len(v.hb) - newlength;
105   return cht_do_hbytes_unappend(0,ip,v, suflength, result);
106 }