7 int staticerr(Tcl_Interp *ip, const char *m) {
8 Tcl_SetResult(ip, (char*)m, TCL_STATIC);
12 static void hbytes_setintern(Tcl_Obj *o, const Byte *array, int l) {
15 HBYTES(o)->start= np= l ? TALLOC(l) : 0;
17 HBYTES(o)->end= np + l;
18 o->typePtr = &hbytes_type;
21 static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
22 hbytes_setintern(src, HBYTES(src)->start, HBYTES_LEN(src));
25 Tcl_Obj *hbytes_set(Tcl_Obj *overwrite, const Byte *array, int l) {
26 if (!overwrite) overwrite= Tcl_NewObj();
28 Tcl_InvalidateStringRep(overwrite);
29 hbytes_setintern(overwrite, array, l);
33 static void hbytes_t_free(Tcl_Obj *o) {
34 TFREE(HBYTES(o)->start);
37 static void hbytes_t_ustr(Tcl_Obj *o) {
43 byte= HBYTES(o)->start;
44 str= o->bytes= TALLOC(l*2+1);
47 sprintf(str,"%02x",*byte);
52 void objfreeir(Tcl_Obj *o) {
53 if (o->typePtr && o->typePtr->freeIntRepProc)
54 o->typePtr->freeIntRepProc(o);
57 static int hbytes_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) {
59 Byte *startbytes, *bytes;
63 os= str= Tcl_GetStringFromObj(o,&l); assert(str);
64 if (l & 1) return staticerr(ip, "hbytes: conversion from hex:"
65 " odd length in hex");
67 startbytes= bytes= l ? TALLOC(l*2) : 0;
72 *bytes++= strtoul(cbuf,&ep,16);
75 fprintf(stderr,">%d|%s|%s<\n",l,os,cbuf);
76 return staticerr(ip, "hbytes: conversion from hex:"
83 HBYTES(o)->start= startbytes;
84 HBYTES(o)->end= bytes;
85 o->typePtr = &hbytes_type;
89 Tcl_ObjType hbytes_type = {
91 hbytes_t_free, hbytes_t_dup, hbytes_t_ustr, hbytes_t_sfa
94 static Tcl_Obj *hb_getvar(Tcl_Interp *ip, Tcl_Obj *varname) {
98 value= Tcl_ObjGetVar2(ip,varname,0,TCL_LEAVE_ERR_MSG);
101 ec= Tcl_ConvertToType(ip,value,&hbytes_type);
109 Tcl_Obj *raw, *value;
115 str= Tcl_GetStringFromObj(raw,&l);
116 value= hbytes_set(0,str,l);
117 Tcl_SetObjResult(ip,value);
122 Tcl_Obj *value, *result;
126 result= Tcl_NewStringObj(HBYTES(value)->start, HBYTES_LEN(value));
127 Tcl_SetObjResult(ip,result);
136 static const PadKindInfo padkindinfos[0]= {
147 const PadKindInfo *pk;
148 const BlockCipherInfo *bc;
150 HC_ARG_ENUM(pk, padkindinfos);
152 if (!pk->algname) HC_ARG_INTRANGE(blocksize, 1,255);
153 else { HC_ARG_ENUM(bc, blockciphers); blocksize= bc->blocksize; }
161 static int hc_raw2h(ClientData cd, Tcl_Interp *ip, int objc,
162 Tcl_Obj *const *objv) {
164 Tcl_Obj *varname, *value, *result;
169 value= hb_getvar(ip,varname); if (!value) return TCL_ERROR;
171 Tcl_SetObjResult(ip,result);
177 value= Tcl_ObjSetVar2(ip,varname,0, value, TCL_LEAVE_ERR_MSG);
178 if (!value) return TCL_ERROR;
187 int minargs, maxargs;
188 Tcl_ObjCmdProc *func;
191 #define SUBCOMMANDS \
196 static const SubCommand subcommands[] = {
197 #define DO(c) { #c, hc_##c },
202 static int hb_proc(ClientData cd, Tcl_Interp *ip, int objc,
203 Tcl_Obj *const *objv) {
204 const SubCommand *sc;
206 if (objc<2) return staticerr(ip, "hbytes: need subcommand");
207 sc= enum_lookup_cached(ip,objv[1],subcommands,"hbytes subcommand");
208 if (!sc) return TCL_ERROR;
211 if (objc < sc->minargs)
212 return staticerr(ip, "too few args");
213 if (sc->maxargs >=0 && objc > sc->maxargs)
214 return staticerr(ip,"too many args");
215 return sc->func((void*)sc,ip,objc,objv);
218 int Hbytes_Init(Tcl_Interp *ip) {
219 Tcl_RegisterObjType(&hbytes_type);
220 Tcl_RegisterObjType(&enum_nearlytype);
221 Tcl_CreateObjCommand(ip,"hbytes", hb_proc,0,0);