Posted to tcl by patthoyts at Tue Jun 10 22:48:33 GMT 2008view raw

  1. static int
  2. BinaryEncodeHex(ClientData clientData, Tcl_Interp *interp,
  3. int objc, Tcl_Obj *const objv[])
  4. {
  5. Tcl_Obj *resultObj = NULL;
  6. Tcl_Obj *stateObj = NULL;
  7. Tcl_Obj *statevarObj = NULL;
  8. unsigned char *data = NULL, *input = NULL, *state = NULL;
  9. unsigned char *cursor = NULL;
  10. const char *digits = clientData;
  11. int i, index, offset = 0, count = 0, state_count = 0;
  12. enum {OPT_STATE};
  13. static const char *optStrings[] = { "-state", NULL };
  14.  
  15. if (objc < 2 || objc%2 != 0) {
  16. Tcl_WrongNumArgs(interp, 1, objv, "?-state varname? data");
  17. return TCL_ERROR;
  18. }
  19. for (i = 1; i < objc-1; i += 2) {
  20. if (Tcl_GetIndexFromObj(interp, objv[i], optStrings,
  21. "option", TCL_EXACT, &index) != TCL_OK) {
  22. return TCL_ERROR;
  23. }
  24. switch (index) {
  25. case OPT_STATE: {
  26. statevarObj = objv[i+1];
  27. stateObj = Tcl_ObjGetVar2(interp, statevarObj,
  28. NULL, TCL_LEAVE_ERR_MSG);
  29. if (stateObj == NULL) {
  30. return TCL_ERROR;
  31. }
  32. break;
  33. }
  34. }
  35. }
  36.  
  37. TclNewObj(resultObj);
  38. data = input = Tcl_GetByteArrayFromObj(objv[objc-1], &count);
  39. if (stateObj) {
  40. data = state = Tcl_GetByteArrayFromObj(stateObj, &state_count);
  41. count += state_count;
  42. }
  43. cursor = Tcl_SetByteArrayLength(resultObj, count * 2);
  44. for (offset = 0; offset < count; ++offset) {
  45. if (state && offset >= state_count) {
  46. data = input;
  47. state = NULL;
  48. }
  49. *cursor++ = digits[((*data >> 4) & 0x0f)];
  50. *cursor++ = digits[( *data & 0x0f)];
  51. ++data;
  52. }
  53. if (statevarObj) {
  54. /*
  55. * the hex encoding never has any data left over so we always
  56. * set the state to an empty byte array.
  57. */
  58. Tcl_Obj *excessObj = Tcl_NewByteArrayObj(NULL, 0);
  59. Tcl_ObjSetVar2(interp, statevarObj, NULL, excessObj, 0);
  60. }
  61. Tcl_SetObjResult(interp, resultObj);
  62. return TCL_OK;
  63. }