chiark / gitweb /
Table-generated stuff. Now need parsing funcs.
[chiark-tcl.git] / hbytes / hbytes.c
1 /*
2  *
3  */
4
5 #include "hbytes.h"
6 #include "tables.h"
7
8 int staticerr(Tcl_Interp *ip, const char *m) {
9   Tcl_SetResult(ip, (char*)m, TCL_STATIC);
10   return TCL_ERROR;
11 }
12
13 void hbytes_set(HBytes_Value *upd, const Byte *array, int l) {
14   Byte *np;
15
16   upd->start= np= l ? TALLOC(l) : 0;
17   memcpy(np, array, l);
18   upd->end= np + l;
19 }
20
21 static void hbytes_setintern(Tcl_Obj *o, const Byte *array, int l) {
22   hbytes_set(&HBYTES(o), array, l);
23   o->typePtr = &hbytes_type;
24 }
25
26 static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) {
27   hbytes_setintern(src, HBYTES(src).start, HBYTES_LEN(HBYTES(src)));
28 }
29
30 Tcl_Obj *hbytes_set_obj(Tcl_Obj *overwrite, const Byte *array, int l) {
31   if (!overwrite) overwrite= Tcl_NewObj();
32   objfreeir(overwrite);
33   Tcl_InvalidateStringRep(overwrite);
34   hbytes_setintern(overwrite, array, l);
35   return overwrite;
36 }
37
38 static void hbytes_t_free(Tcl_Obj *o) {
39   TFREE(HBYTES(o).start);
40 }
41
42 static void hbytes_t_ustr(Tcl_Obj *o) {
43   int l;
44   char *str;
45   const Byte *byte;
46
47   l= HBYTES_LEN(HBYTES(o));
48   byte= HBYTES(o).start;
49   str= o->bytes= TALLOC(l*2+1);
50   o->length= l*2;
51   while (l>0) {
52     sprintf(str,"%02x",*byte);
53     str+=2; byte++; l--;
54   }
55 }
56
57 void objfreeir(Tcl_Obj *o) {
58   if (o->typePtr && o->typePtr->freeIntRepProc)
59     o->typePtr->freeIntRepProc(o);
60 }  
61
62 static int hbytes_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) {
63   char *str, *ep, *os;
64   Byte *startbytes, *bytes;
65   int l;
66   char cbuf[3];
67
68   os= str= Tcl_GetStringFromObj(o,&l);  assert(str);
69   if (l & 1) return staticerr(ip, "hbytes: conversion from hex:"
70                               " odd length in hex");
71
72   startbytes= bytes= l ? TALLOC(l*2) : 0;
73   cbuf[2]= 0;
74   while (l>0) {
75     cbuf[0]= *str++;
76     cbuf[1]= *str++;
77     *bytes++= strtoul(cbuf,&ep,16);
78     if (ep != cbuf+2) {
79       TFREE(startbytes);
80 fprintf(stderr,">%d|%s|%s<\n",l,os,cbuf);
81       return staticerr(ip, "hbytes: conversion from hex:"
82                        " bad hex digit");
83     }
84     l -= 2;
85   }
86   objfreeir(o);
87
88   HBYTES(o).start= startbytes;
89   HBYTES(o).end= bytes;
90   o->typePtr = &hbytes_type;
91   return TCL_OK;
92 }
93
94 Tcl_ObjType hbytes_type = {
95   "hbytes",
96   hbytes_t_free, hbytes_t_dup, hbytes_t_ustr, hbytes_t_sfa
97 };
98
99 int do_hbytes_raw2h(ClientData cd, Tcl_Interp *ip,
100                     Tcl_Obj *binary, HBytes_Value *result) {
101   const char *str;
102   int l;
103
104   str= Tcl_GetStringFromObj(binary,&l);
105   hbytes_set(result, str, l);
106   return TCL_OK;
107 }
108
109 int do_hbytes_h2raw(ClientData cd, Tcl_Interp *ip,
110                     HBytes_Value hex, Tcl_Obj **result) {
111   *result= Tcl_NewStringObj(hex.start, HBYTES_LEN(hex));
112   return TCL_OK;
113 }
114
115 #if 0
116 HC_DEFINE(pkcs5) {
117   static const PadKindInfo padkindinfos[0]= {
118     { "pa", 1, 1 },
119     { "pn", 1, 0 },
120     { "ua", 0, 1 },
121     { "un", 0, 0 },
122     { 0 }
123   };
124
125   HC_DECLS_HBV;
126   Tcl_Obj *v;
127   int blocksize;
128   const PadKindInfo *pk;
129   const BlockCipherInfo *bc;
130
131   HC_ARG_ENUM(pk, padkindinfos);
132   HC_ARG_HBV;
133   if (!pk->algname) HC_ARG_INTRANGE(blocksize, 1,255);
134   else { HC_ARG_ENUM(bc, blockciphers); blocksize= bc->blocksize; }
135   HC_ARGS_E;
136
137   /* do nothing :-) */
138
139   HC_FINI_HBV;
140 }
141 #endif
142
143 int do__hbytes(ClientData cd, Tcl_Interp *ip,
144                const ParserCommandTableEntry *subcmd,
145                int objc, Tcl_Obj *const *objv) {
146   return subcmd->func(0,ip,objc,objv);
147 }
148
149 int Hbytes_Init(Tcl_Interp *ip) {
150   Tcl_RegisterObjType(&hbytes_type);
151   Tcl_RegisterObjType(&enum_nearlytype);
152   Tcl_CreateObjCommand(ip,"hbytes", pa__hbytes,0,0);
153   return TCL_OK;
154 }