下面是php中pack函数关于H*部分的代码:PHP_FUNCTION(pack)
{
zval ***argv = NULL;
int num_args, i;
int currentarg;
char *format;
int formatlen;
char *formatcodes;
int *formatargs;
int formatcount = 0;
int outputpos = 0, outputsize = 0;
char *output; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &argv, &num_args) == FAILURE) {
return;
} convert_to_string_ex(argv[0]); format = Z_STRVAL_PP(argv[0]);
formatlen = Z_STRLEN_PP(argv[0]); /* We have a maximum of <formatlen> format codes to deal with */
formatcodes = safe_emalloc(formatlen, sizeof(*formatcodes), 0);
formatargs = safe_emalloc(formatlen, sizeof(*formatargs), 0);
currentarg = 1; /* Preprocess format into formatcodes and formatargs */
for (i = 0; i < formatlen; formatcount++) {
char code = format[i++];
int arg = 1; /* Handle format arguments if any */
if (i < formatlen) {
char c = format[i]; if (c == '*') {
arg = -1;
i++;
}
else if (c >= '0' && c <= '9') {
arg = atoi(&format[i]);
  
while (format[i] >= '0' && format[i] <= '9' && i < formatlen) {
i++;
}
}
} /* Handle special arg '*' for all codes and check argv overflows */
switch ((int) code) {
/* Always uses one arg */
case 'h': 
case 'H':
if (currentarg >= num_args) {
efree(argv);
efree(formatcodes);
efree(formatargs);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: not enough arguments", code);
RETURN_FALSE;
} if (arg < 0) {
convert_to_string_ex(argv[currentarg]);
arg = Z_STRLEN_PP(argv[currentarg]);
} currentarg++;
break; default:
efree(argv);
efree(formatcodes);
efree(formatargs);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: unknown format code", code);
RETURN_FALSE;
} formatcodes[formatcount] = code;
formatargs[formatcount] = arg;
} if (currentarg < num_args) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d arguments unused", (num_args - currentarg));
} /* Calculate output length and upper bound while processing*/
for (i = 0; i < formatcount; i++) {
    int code = (int) formatcodes[i];
int arg = formatargs[i]; switch ((int) code) {
case 'h': 
case 'H': 
INC_OUTPUTPOS((arg + (arg % 2)) / 2,1) /* 4 bit per arg */
break;
} if (outputsize < outputpos) {
outputsize = outputpos;
}
} output = emalloc(outputsize + 1);
outputpos = 0;
currentarg = 1; /* Do actual packing */
for (i = 0; i < formatcount; i++) {
    int code = (int) formatcodes[i];
int arg = formatargs[i];
zval **val; switch ((int) code) {
case 'h': 
case 'H': {
int nibbleshift = (code == 'h') ? 0 : 4;
int first = 1;
char *v; val = argv[currentarg++];
convert_to_string_ex(val);
v = Z_STRVAL_PP(val);
outputpos--;
if(arg > Z_STRLEN_PP(val)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: not enough characters in string", code);
arg = Z_STRLEN_PP(val);
} while (arg-- > 0) {
char n = *v++; if (n >= '0' && n <= '9') {
n -= '0';
} else if (n >= 'A' && n <= 'F') {
n -= ('A' - 10);
} else if (n >= 'a' && n <= 'f') {
n -= ('a' - 10);
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: illegal hex digit %c", code, n);
n = 0;
} if (first--) {
output[++outputpos] = 0;
} else {
  first = 1;
} output[outputpos] |= (n << nibbleshift);
nibbleshift = (nibbleshift + 4) & 7;
} outputpos++;
break;
}
}
} efree(argv);
efree(formatcodes);
efree(formatargs);
output[outputpos] = '\0';
RETVAL_STRINGL(output, outputpos, 1);
efree(output);
}