⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pack.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.txt                                  |   | If you did not receive a copy of the PHP license and are unable to   |   | obtain it through the world-wide-web, please send a note to          |   | license@php.net so we can mail you a copy immediately.               |   +----------------------------------------------------------------------+   | Author: Chris Schneider <cschneid@relog.ch>                          |   +----------------------------------------------------------------------+ *//* $Id: pack.c,v 1.40.2.7.2.6 2007/01/01 09:46:48 sebastian Exp $ */#include "php.h"#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#ifdef PHP_WIN32#include <windows.h>#include <winsock.h>#define O_RDONLY _O_RDONLY#include "win32/param.h"#elif defined(NETWARE)#ifdef USE_WINSOCK#include <novsock2.h>#else#include <sys/socket.h>#endif#include <sys/param.h>#else#include <sys/param.h>#endif#include "ext/standard/head.h"#include "safe_mode.h"#include "php_string.h"#include "pack.h"#if HAVE_PWD_H#ifdef PHP_WIN32#include "win32/pwd.h"#else#include <pwd.h>#endif#endif#include "fsock.h"#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#define INC_OUTPUTPOS(a,b) \	if ((a) < 0 || ((INT_MAX - outputpos)/(b)) < (a)) { \		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: integer overflow in format string", code); \		RETURN_FALSE; \	} \	outputpos += (a)*(b);/* Whether machine is little endian */char machine_little_endian;/* Mapping of byte from char (8bit) to long for machine endian */static int byte_map[1];/* Mappings of bytes from int (machine dependant) to int for machine endian */static int int_map[sizeof(int)];/* Mappings of bytes from shorts (16bit) for all endian environments */static int machine_endian_short_map[2];static int big_endian_short_map[2];static int little_endian_short_map[2];/* Mappings of bytes from longs (32bit) for all endian environments */static int machine_endian_long_map[4];static int big_endian_long_map[4];static int little_endian_long_map[4];/* {{{ php_pack */static void php_pack(zval **val, int size, int *map, char *output){	int i;	char *v;	convert_to_long_ex(val);	v = (char *) &Z_LVAL_PP(val);	for (i = 0; i < size; i++) {		*output++ = v[map[i]];	}}/* }}} *//* pack() idea stolen from Perl (implemented formats behave the same as there) * Implemented formats are A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @. *//* {{{ proto string pack(string format, mixed arg1 [, mixed arg2 [, mixed ...]])   Takes one or more arguments and packs them into a binary string according to the format argument */PHP_FUNCTION(pack){	zval ***argv;	int argc, i;	int currentarg;	char *format;	int formatlen;	char *formatcodes;	int *formatargs;	int formatcount = 0;	int outputpos = 0, outputsize = 0;	char *output;	argc = ZEND_NUM_ARGS();	if (argc < 1) {		WRONG_PARAM_COUNT;	}	argv = safe_emalloc(sizeof(zval **), argc, 0);	if (zend_get_parameters_array_ex(argc, argv) == FAILURE) {		efree(argv);		WRONG_PARAM_COUNT;	}	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) {			/* Never uses any args */			case 'x': 			case 'X':				case '@':				if (arg < 0) {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: '*' ignored", code);					arg = 1;				}				break;			/* Always uses one arg */			case 'a': 			case 'A': 			case 'h': 			case 'H':				if (currentarg >= argc) {					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) {					arg = Z_STRLEN_PP(argv[currentarg]);				}				currentarg++;				break;			/* Use as many args as specified */			case 'c': 			case 'C': 			case 's': 			case 'S': 			case 'i': 			case 'I':			case 'l': 			case 'L': 			case 'n': 			case 'N': 			case 'v': 			case 'V':			case 'f': 			case 'd': 				if (arg < 0) {					arg = argc - currentarg;				}				currentarg += arg;				if (currentarg > argc) {					efree(argv);					efree(formatcodes);					efree(formatargs);					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: too few arguments", code);					RETURN_FALSE;				}				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 < argc) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d arguments unused", (argc - 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;			case 'a': 			case 'A':			case 'c': 			case 'C':			case 'x':				INC_OUTPUTPOS(arg,1)		/* 8 bit per arg */				break;			case 's': 			case 'S': 			case 'n': 			case 'v':				INC_OUTPUTPOS(arg,2)		/* 16 bit per arg */				break;			case 'i': 			case 'I':				INC_OUTPUTPOS(arg,sizeof(int))				break;			case 'l': 			case 'L': 			case 'N': 			case 'V':				INC_OUTPUTPOS(arg,4)		/* 32 bit per arg */				break;			case 'f':				INC_OUTPUTPOS(arg,sizeof(float))				break;			case 'd':				INC_OUTPUTPOS(arg,sizeof(double))				break;			case 'X':				outputpos -= arg;				if (outputpos < 0) {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: outside of string", code);					outputpos = 0;				}				break;			case '@':				outputpos = 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 'a': 			case 'A': 				memset(&output[outputpos], (code == 'a') ? '\0' : ' ', arg);				val = argv[currentarg++];				convert_to_string_ex(val);				memcpy(&output[outputpos], Z_STRVAL_PP(val),					   (Z_STRLEN_PP(val) < arg) ? Z_STRLEN_PP(val) : arg);				outputpos += arg;				break;			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;			}			case 'c': 			case 'C':				while (arg-- > 0) {					php_pack(argv[currentarg++], 1, byte_map, &output[outputpos]);					outputpos++;				}				break;			case 's': 			case 'S': 			case 'n': 			case 'v': {				int *map = machine_endian_short_map;				if (code == 'n') {					map = big_endian_short_map;				} else if (code == 'v') {					map = little_endian_short_map;				}				while (arg-- > 0) {					php_pack(argv[currentarg++], 2, map, &output[outputpos]);					outputpos += 2;				}				break;			}			case 'i': 			case 'I': 				while (arg-- > 0) {					php_pack(argv[currentarg++], sizeof(int), int_map, &output[outputpos]);					outputpos += sizeof(int);				}				break;			case 'l': 			case 'L': 			case 'N': 			case 'V': {				int *map = machine_endian_long_map;				if (code == 'N') {					map = big_endian_long_map;				} else if (code == 'V') {					map = little_endian_long_map;				}				while (arg-- > 0) {					php_pack(argv[currentarg++], 4, map, &output[outputpos]);					outputpos += 4;				}				break;			}			case 'f': {				float v;				while (arg-- > 0) {					val = argv[currentarg++];					convert_to_double_ex(val);					v = (float) Z_DVAL_PP(val);					memcpy(&output[outputpos], &v, sizeof(v));					outputpos += sizeof(v);				}				break;			}			case 'd': {				double v;				while (arg-- > 0) {					val = argv[currentarg++];					convert_to_double_ex(val);					v = (double) Z_DVAL_PP(val);					memcpy(&output[outputpos], &v, sizeof(v));					outputpos += sizeof(v);				}				break;			}			case 'x':				memset(&output[outputpos], '\0', arg);				outputpos += arg;				break;			case 'X':				outputpos -= arg;				if (outputpos < 0) {					outputpos = 0;				}				break;			case '@':				if (arg > outputpos) {					memset(&output[outputpos], '\0', arg - outputpos);				}				outputpos = arg;				break;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -