#ifdef TCLCMD #include #else #include #endif #include static const char encoding_vector[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #ifdef TCLCMD static int atend; static int getidx(char *buffer, int len, int *posn) { char c; char *idx; if (atend) return -1; do { if ((*posn)>=len) { atend = 1; return -1; } c = buffer[*posn++]; if (c<0 || c=='=') { atend = 1; return -1; } idx = strchr(encoding_vector, c); } while (!idx); return idx - encoding_vector; } static int base64decode(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj **objv) { Tcl_Obj *result; char *inbuffer; int ilen, olen, pos; char outbuffer[3]; int c[4]; if (objc!=2) { Tcl_SetObjResult(interp, Tcl_NewStringObj("needs one argument " "(string to decode)", -1)); return TCL_ERROR; } inbuffer = Tcl_GetStringFromObj(interp, objv[1], &ilen); result = Tcl_NewStringObj("", 0); pos = 0; atend = 0; while (!atend) { c[0] = getidx(inbuffer, ilen, &pos); c[1] = getidx(inbuffer, ilen, &pos); c[2] = getidx(inbuffer, ilen, &pos); c[3] = getidx(inbuffer, ilen, &pos); olen = 0; if (c[0]>=0 && c[1]>=0) { outbuffer[0] = ((c[0]<<2)&0xfc)|((c[1]>>4)&0x03); olen++; if (c[2]>=0) { outbuffer[1] = ((c[1]<<4)&0xf0)|((c[2]>>2)&0x0f); olen++; if (c[3]>=0) { outbuffer[2] = ((c[2]<<6)&0xc0)|((c[3])&0x3f); olen++; } } } Tcl_StringObjAppend(interp, result, outbuffer, olen); } Tcl_SetObjResult(interp, result); return TCL_OK; } int Base64decode_Init(Tcl_Interp *interp) { if (TCL_VERSION<8) { Tcl_AppendResult(interp, "Need at least Tcl8 for binary string support", NULL); return TCL_ERROR; } Tcl_CreateObjCommand(interp, "base64decode", -1, base64decode, (ClientData)0, NULL); return TCL_OK; } #else static int atend; static int getidx(void) { char c; char *idx; if (atend) return -1; do { c = getchar(); if (c<0 || c=='=') { atend = 1; return -1; } idx = strchr(encoding_vector, c); } while (!idx); return idx - encoding_vector; } int main(int argc, char **argv) { int char1, char2, char3, char4; atend = 0; while (!atend) { char1 = getidx(); char2 = getidx(); char3 = getidx(); char4 = getidx(); if (char1>=0 && char2>=0) { putchar(((char1<<2)&0xfc)|((char2>>4)&0x03)); if (char3>=0) { putchar(((char2<<4)&0xf0)|((char3>>2)&0x0f)); if (char4>=0) { putchar(((char3<<6)&0xc0)|((char4)&0x3f)); } } } } return 0; } #endif