Пример #1
0
PHP_METHOD(MongoDB, setProfilingLevel) {
  long level;
  zval *data, *cmd_return;
  zval **ok;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &level) == FAILURE) {
    return;
  }

  MAKE_STD_ZVAL(data);
  array_init(data);
  add_assoc_long(data, "profile", level);

  MAKE_STD_ZVAL(cmd_return);
  MONGO_CMD(cmd_return, getThis());

  zval_ptr_dtor(&data);

  if (EG(exception)) {
    zval_ptr_dtor(&cmd_return);
    return;
  }

  if (zend_hash_find(HASH_P(cmd_return), "ok", 3, (void**)&ok) == SUCCESS &&
      ((Z_TYPE_PP(ok) == IS_BOOL && Z_BVAL_PP(ok)) || Z_DVAL_PP(ok) == 1)) {
    zend_hash_find(HASH_P(cmd_return), "was", 4, (void**)&ok);
    RETVAL_ZVAL(*ok, 1, 0);
  }
  else {
    RETVAL_NULL();
  }
  zval_ptr_dtor(&cmd_return);
}
Пример #2
0
U_CFUNC PHP_FUNCTION(intlcal_roll)
{
	long		field,
				value;
	zval		**args_a[3]		 = {0},
				***args			 = &args_a[0];
	zend_bool	bool_variant_val = (zend_bool)-1;
	CALENDAR_METHOD_INIT_VARS;

	if (ZEND_NUM_ARGS() > (getThis() ? 2 :3) ||
			zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"intlcal_set: too many arguments", 0 TSRMLS_CC);
		RETURN_FALSE;
	}
	if (!getThis()) {
		args++;
	}
	if (args[1] != NULL && Z_TYPE_PP(args[1]) == IS_BOOL) {
		if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
				"Olb", &object, Calendar_ce_ptr, &field, &bool_variant_val)
				== FAILURE) {
			intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
				"intlcal_roll: bad arguments", 0 TSRMLS_CC);
			RETURN_FALSE;
		}
		bool_variant_val = Z_BVAL_PP(args[1]);
	} else if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
			"Oll", &object, Calendar_ce_ptr, &field, &value) == FAILURE) {
		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"intlcal_roll: bad arguments", 0 TSRMLS_CC);
		RETURN_FALSE;
	}

	if (field < 0 || field >= UCAL_FIELD_COUNT) {
		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"intlcal_roll: invalid field", 0 TSRMLS_CC);
		RETURN_FALSE;
	}
	if (bool_variant_val == (zend_bool)-1 &&
			(value < INT32_MIN || value > INT32_MAX)) {
		intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"intlcal_roll: value out of bounds", 0 TSRMLS_CC);
		RETURN_FALSE;
	}

	CALENDAR_METHOD_FETCH_OBJECT;

	if (bool_variant_val != (zend_bool)-1) {
		co->ucal->roll((UCalendarDateFields)field, (UBool)bool_variant_val,
			CALENDAR_ERROR_CODE(co));
	} else {
		co->ucal->roll((UCalendarDateFields)field, (int32_t)value,
			CALENDAR_ERROR_CODE(co));
	}
	INTL_METHOD_CHECK_STATUS(co, "intlcal_roll: Error calling ICU Calendar::roll");

	RETURN_TRUE;
}
Пример #3
0
inline int validate_https(zval **z_route_options_pp, int https TSRMLS_DC) 
{
    zval **z_route_secure = NULL;
    if ( zend_hash_find( Z_ARRVAL_PP(z_route_options_pp) , "secure", sizeof("secure"), (void**) &z_route_secure ) == SUCCESS ) {
        // check HTTPS flag
        if ( https && ! Z_BVAL_PP(z_route_secure) ) {
            return 0;
        }
    }
    return 1;
}
Пример #4
0
static void php_mongo_db_profiling_level(INTERNAL_FUNCTION_PARAMETERS, int get)
{
	long level;
	zval *cmd, *cmd_return;
	zval **ok;
	mongo_db *db;

	if (get) {
		if (zend_parse_parameters_none() == FAILURE) {
			return;
		}
		level = -1;
	} else {
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &level) == FAILURE) {
			return;
		}
	}

	PHP_MONGO_GET_DB(getThis());

	MAKE_STD_ZVAL(cmd);
	array_init(cmd);
	add_assoc_long(cmd, "profile", level);

	cmd_return = php_mongo_runcommand(db->link, &db->read_pref, Z_STRVAL_P(db->name), Z_STRLEN_P(db->name), cmd, NULL, 0, NULL TSRMLS_CC);

	zval_ptr_dtor(&cmd);

	if (!cmd_return) {
		return;
	}

	if (
		zend_hash_find(HASH_P(cmd_return), "ok", 3, (void**)&ok) == SUCCESS &&
		((Z_TYPE_PP(ok) == IS_BOOL && Z_BVAL_PP(ok)) || Z_DVAL_PP(ok) == 1)
	) {
		zend_hash_find(HASH_P(cmd_return), "was", 4, (void**)&ok);
		RETVAL_ZVAL(*ok, 1, 0);
	} else {
		RETVAL_NULL();
	}
	zval_ptr_dtor(&cmd_return);
}
Пример #5
0
static SEXP php_zval_to_r(zval **value) /* {{{ */
{
	SEXP result = NULL_USER_OBJECT;

	switch (Z_TYPE_PP(value)) {
		case IS_LONG:
			PROTECT(result = NEW_INTEGER(1));
			INTEGER_DATA(result)[0] = Z_LVAL_PP(value);
			UNPROTECT(1);
			break;
		case IS_DOUBLE:
			PROTECT(result = NEW_NUMERIC(1));
			NUMERIC_DATA(result)[0] = Z_DVAL_PP(value);
			UNPROTECT(1);
			break;
		case IS_STRING:
			PROTECT(result = NEW_CHARACTER(1));
			SET_STRING_ELT(result, 0, COPY_TO_USER_STRING(Z_STRVAL_PP(value)));
			UNPROTECT(1);
			break;
		case IS_BOOL:
			PROTECT(result = NEW_LOGICAL(1));
			LOGICAL_DATA(result)[0] = Z_BVAL_PP(value);
			UNPROTECT(1);
			break;
		case IS_ARRAY:
			result = php_hash_to_r(Z_ARRVAL_PP(value));
			break;
		default:
			convert_to_string_ex(value);
			PROTECT(result = NEW_CHARACTER(1));
			SET_STRING_ELT(result, 0, COPY_TO_USER_STRING(Z_STRVAL_PP(value)));
			UNPROTECT(1);
			break;
	}
	return result;
}
Пример #6
0
/**
 *
 * @param chinese
 * @param flag
 * @return
 */
py_row_data_list *py_split_sentence(const char *sentence, size_t flag)
{
    if(PY_GLOBAL(can_access) == false)
    {
        php_error(E_WARNING, "拼音转汉字初始化加载配置文件失败,转化失败!");
        return NULL;
    }
	
	char *chinese = estrdup(sentence);

    //正常的拼音化
    py_data_list *wordListPtr;
    char *wordPtr = NULL,
        *splitItem = NULL,
        *splitItemPtr = NULL,
        tmpStr[100] = {0};
    size_t splitLen = 0,
        isPinyin = 0,
        isChangeTone = 0,
        i = 0,
        j = 0,
        k = 0,
        m = 0;
    zend_ulong numKey;
#if PHP_MAJOR_VERSION < 7
    zval **entry,
        **splitIsPinyinEntry;
#else
    zval *entry,
        *splitIsPinyinEntry;
#endif
    zval *pinyinPieces = (zval *)py_malloc(sizeof(zval), 0),
        *splitIsPinyin = (zval *)py_malloc(sizeof(zval), 0);
    py_row_data_list *rowDataList = (py_row_data_list *)py_malloc(sizeof(py_row_data_list), 0),
        *rowDataListPtr = rowDataList,
        *rowDataListTmpPtr = NULL;

    array_init(pinyinPieces);
    array_init(splitIsPinyin);

    /* 替换姓名优先 */
    if (flag & PINYIN_ISNAME) {
        wordListPtr = PY_GLOBAL(surnameList)->next;
        while(wordListPtr != NULL)
        {
            while (NULL != (wordPtr = py_strstr(chinese, wordListPtr->key))) {
                py_add_index_stringl(pinyinPieces, wordPtr-chinese, wordListPtr->val, py_strlen(wordListPtr->val), 1);
                py_add_index_bool(splitIsPinyin, wordPtr-chinese, 1);
                memset(wordPtr, CHINESE_SUB_CHAR, py_strlen(wordListPtr->key));
            }
            wordListPtr = wordListPtr->next;
        }
    }
    
    wordListPtr = PY_GLOBAL(wordList)->next;
    while(wordListPtr != NULL)
    {
        while (NULL != (wordPtr = py_strstr(chinese, wordListPtr->key))) {
            py_add_index_stringl(pinyinPieces, wordPtr-chinese, wordListPtr->val, py_strlen(wordListPtr->val), 1);
            py_add_index_bool(splitIsPinyin, wordPtr-chinese, 1);
            memset(wordPtr, CHINESE_SUB_CHAR, py_strlen(wordListPtr->key));
        }
        wordListPtr = wordListPtr->next;
    }

    /* 切分标点符号 */
    wordPtr = chinese;
    for (; i<PY_CHAR_TRANS_MAP_NUM; i++) {
        while (NULL != (wordPtr = py_strstr(chinese, charTransMap[i][0]))) {
            py_add_index_stringl(pinyinPieces, wordPtr-chinese, charTransMap[i][0], py_strlen(charTransMap[i][0]), 1);
            py_add_index_bool(splitIsPinyin, wordPtr-chinese, 0);
            memset(wordPtr, CHINESE_SUB_CHAR, py_strlen(charTransMap[i][0]));
        }
        while (NULL != (wordPtr = py_strstr(chinese, charTransMap[i][1]))) {
            py_add_index_stringl(pinyinPieces, wordPtr-chinese, charTransMap[i][1], py_strlen(charTransMap[i][1]), 1);
            py_add_index_bool(splitIsPinyin, wordPtr-chinese, 0);
            memset(wordPtr, CHINESE_SUB_CHAR, py_strlen(charTransMap[i][1]));
        }
    }

    /* 切分非标点符号和汉字 */
    wordPtr = chinese;
    while (*wordPtr) {
        if (CHINESE_SUB_CHAR == *wordPtr) {
            if (splitLen > 0) {
                *wordPtr = 0;
                py_add_index_stringl(pinyinPieces, wordPtr-chinese-splitLen,wordPtr - splitLen, py_strlen(wordPtr - splitLen), 1);
                py_add_index_bool(splitIsPinyin, wordPtr-chinese-splitLen, 0);
            }
            splitLen = 0;
        } else {
            splitLen++;
        }
        ++wordPtr;
    }
	
	/* 特殊情况:最后一个为非汉字的时候 */
	if (splitLen > 0) {
		py_add_index_stringl(pinyinPieces, wordPtr-chinese-splitLen,wordPtr - splitLen, py_strlen(wordPtr - splitLen), 1);
        py_add_index_bool(splitIsPinyin, wordPtr-chinese-splitLen, 0);
	}

    /* 格式化数组,将汉字切分为单个的一个,去掉制表符 */
    for (i=0; i<=strlen(sentence); i++) {
        isPinyin = 0;
        #if PHP_MAJOR_VERSION < 7
            if (zend_hash_index_find(Z_ARRVAL_P(pinyinPieces), i, (void**)&entry) == FAILURE || py_strlen(Z_STRVAL_PP(entry)) <= 0)
                continue;
            splitItem = strtok(Z_STRVAL_PP(entry), "\t");
            if (zend_hash_index_find(Z_ARRVAL_P(splitIsPinyin), i, (void**)&splitIsPinyinEntry) == SUCCESS) {
                if (Z_BVAL_PP(splitIsPinyinEntry)) {
                    isPinyin = 1;
                }
            }
        #else
            entry = zend_hash_index_find(Z_ARRVAL_P(pinyinPieces), i);
            if (NULL == entry)
                continue;
            splitItem = strtok(Z_STRVAL_P(entry), "\t");
            splitIsPinyinEntry = zend_hash_index_find(Z_ARRVAL_P(splitIsPinyin), i);
            if (NULL != splitIsPinyinEntry) {
                if(Z_TYPE_INFO_P(splitIsPinyinEntry) == IS_TRUE) {
                    isPinyin = 1;
                }
            }
        #endif
        /* 不需要拼音声调 */
        CREATE_ROW_DATA_ITEM(rowDataListTmpPtr);
        rowDataListTmpPtr->ori = py_strdup(splitItem, 0);
        rowDataListPtr->next = rowDataListTmpPtr;
        rowDataListPtr = rowDataListTmpPtr;
        if (flag & (PINYIN_NONE|PINYIN_ASCII|PINYIN_LCFIRST|PINYIN_UCFIRST)) {
            isChangeTone = 0;
            for(m=0 ; m<PY_TONE_INFO_NUM; m++) {
                if (NULL != (wordPtr=py_strstr(splitItem, toneInfos[m].complete))){
                    CHANGE_STR(tmpStr, splitItem, wordPtr, toneInfos[m].complete, toneInfos[m].simple, j, k);
                    rowDataListTmpPtr->none = py_strdup(tmpStr, 0);
                    rowDataListTmpPtr->tone = toneInfos[m].tone;
                    isChangeTone = 1;
                    break;
                }
            }
            if (!isChangeTone && isPinyin) {
                rowDataListTmpPtr->none = py_strdup(rowDataListTmpPtr->ori, 0);
            }
        }
        if (flag & (PINYIN_LCFIRST|PINYIN_UCFIRST)){
            if (NULL != rowDataListTmpPtr->none) {
                rowDataListTmpPtr->lcfirst = *rowDataListTmpPtr->none;
                rowDataListTmpPtr->ucfirst = rowDataListTmpPtr->lcfirst - 32;
                if (!(rowDataListTmpPtr->lcfirst >= 65 && rowDataListTmpPtr->lcfirst <= 90)
                && !(rowDataListTmpPtr->lcfirst >= 97 && rowDataListTmpPtr->lcfirst <= 122)){
                    rowDataListTmpPtr->lcfirst = 0;
                    rowDataListTmpPtr->ucfirst = 0;
                }
            }
        }    

        while((splitItem = strtok(NULL, "\t")))
        {
            CREATE_ROW_DATA_ITEM(rowDataListTmpPtr);
            rowDataListTmpPtr->ori = py_strdup(splitItem, 0);
            rowDataListPtr->next = rowDataListTmpPtr;
            rowDataListPtr = rowDataListTmpPtr;      
            if (flag & (PINYIN_NONE|PINYIN_ASCII|PINYIN_LCFIRST|PINYIN_UCFIRST)) {
                isChangeTone = 0;
                for(m=0 ; m<PY_TONE_INFO_NUM; m++) {
                    if (NULL != (wordPtr=py_strstr(splitItem, toneInfos[m].complete))){
                        CHANGE_STR(tmpStr, splitItem, wordPtr, toneInfos[m].complete, toneInfos[m].simple, j, k);
                        rowDataListTmpPtr->none = py_strdup(tmpStr, 0);
                        rowDataListTmpPtr->tone = toneInfos[m].tone;
                        isChangeTone = 1;
                        break;
                    }
                }
                if (!isChangeTone && isPinyin) {
                    rowDataListTmpPtr->none = py_strdup(rowDataListTmpPtr->ori, 0);
                }
            }         
            if (flag & (PINYIN_LCFIRST|PINYIN_UCFIRST)){
                if (NULL != rowDataListTmpPtr->none) {
                    rowDataListTmpPtr->lcfirst = *rowDataListTmpPtr->none;
                    rowDataListTmpPtr->ucfirst = rowDataListTmpPtr->lcfirst - 32;
                    if (!(rowDataListTmpPtr->lcfirst >= 65 && rowDataListTmpPtr->lcfirst <= 90)
                    && !(rowDataListTmpPtr->lcfirst >= 97 && rowDataListTmpPtr->lcfirst <= 122)){
                        rowDataListTmpPtr->lcfirst = 0;
                        rowDataListTmpPtr->ucfirst = 0;
                    }
                }
            }   
        }
    }

	efree(chinese);
    zend_hash_destroy(Z_ARRVAL_P(pinyinPieces));
    efree(Z_ARRVAL_P(pinyinPieces));
    efree(pinyinPieces);
    zend_hash_destroy(Z_ARRVAL_P(splitIsPinyin));
    efree(Z_ARRVAL_P(splitIsPinyin));
    efree(splitIsPinyin);

    return rowDataList;
}
Пример #7
0
/** {{{ proto bool Win\Gdi\Window::endPaint( paint_data );
		Marks the end of painting in the specified window.
*/
PHP_METHOD( WinGdiWindow, endPaint )
{
	wingdi_devicecontext_object * dc_object;
	wingdi_window_object        * window_object = zend_object_store_get_object( getThis() TSRMLS_CC );
	HashTable                   * paint_data;
	PAINTSTRUCT                   paint_struct;

	WINGDI_ERROR_HANDLING();
	if ( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "h", &paint_data ) == FAILURE )
		return;
	WINGDI_RESTORE_ERRORS();

	// Error checking
	// Not sure about the error messages
	if ( ! zend_hash_exists( paint_data, "hdc", strlen( "hdc" ) + 1 ) )
	{
		php_error( E_ERROR, "no 'hdc' element found in array" );
		return;
	}
	else if ( ! zend_hash_exists( paint_data, "erase", strlen( "erase" ) + 1 ) )
	{
		php_error( E_ERROR, "no 'erase' element found in array" );
		return;
	}
	else if ( ! zend_hash_exists( paint_data, "paint", strlen( "paint" ) + 1 ) )
	{
		php_error( E_ERROR, "no 'paint' element found in array" );
		return;
	}
	else
	{
		zval ** hdc_element,
			 ** erase_element,
			 ** paint_element,
			 ** left = NULL, ** top = NULL, ** right = NULL, ** bottom = NULL;
		HashTable * paint_rect;

		zend_hash_find( paint_data, "hdc", strlen( "hdc" ) + 1, ( void ** ) &hdc_element );
		dc_object = ( wingdi_devicecontext_object * ) zend_objects_get_address( * hdc_element TSRMLS_CC );
		paint_struct.hdc = dc_object->hdc;

		zend_hash_find( paint_data, "erase", strlen( "erase" ) + 1, ( void ** ) &erase_element );
		paint_struct.fErase = Z_BVAL_PP( erase_element );

		zend_hash_find( paint_data, "paint", strlen( "paint" ) + 1, ( void ** ) &paint_element );
		if ( Z_TYPE_PP( paint_element ) != IS_ARRAY || zend_hash_num_elements( Z_ARRVAL_PP( paint_element ) ) < 4 )
		{
			php_error( E_ERROR, "expected an array of for elements for 'paint' element of array" );
			return;
		}
		paint_rect = Z_ARRVAL_PP( paint_element );
		// TODO: error checking
		zend_hash_index_find( paint_rect, 0, ( void ** ) &left );
		zend_hash_index_find( paint_rect, 1, ( void ** ) &top );
		zend_hash_index_find( paint_rect, 2, ( void ** ) &right );
		zend_hash_index_find( paint_rect, 3, ( void ** ) &bottom );
		paint_struct.rcPaint.left = Z_LVAL_PP( left );
		paint_struct.rcPaint.top = Z_LVAL_PP( top );
		paint_struct.rcPaint.right = Z_LVAL_PP( right );
		paint_struct.rcPaint.bottom = Z_LVAL_PP( bottom );

		RETURN_BOOL( EndPaint( window_object->window_handle, &paint_struct ) );
	}
}
Пример #8
0
/* Returns the bytes read on success
 * Returns -31 on unknown failure
 * Returns -80 on timeout
 * Returns -32 when remote server closes the connection
 */
int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
	int num = 1, received = 0;
	TSRMLS_FETCH();

	int socketTimeoutMS = options->socketTimeoutMS ? options->socketTimeoutMS : FG(default_socket_timeout) * 1000;

	/* Convert negative values to -1 second, which implies no timeout */
	socketTimeoutMS = socketTimeoutMS < 0 ? -1000 : socketTimeoutMS;
	timeout = timeout < 0 ? -1000 : timeout;

	/* Socket timeout behavior varies based on the following:
	 * - Negative => no timeout (i.e. block indefinitely)
	 * - Zero => not specified (no changes to existing configuration)
	 * - Positive => used specified timeout (revert to previous value later) */
	if (timeout && timeout != socketTimeoutMS) {
		struct timeval rtimeout = {0, 0};

		rtimeout.tv_sec = timeout / 1000;
		rtimeout.tv_usec = (timeout % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
		mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Setting the stream timeout to %d.%06d", rtimeout.tv_sec, rtimeout.tv_usec);
	} else {
		mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "No timeout changes for %s", con->hash);
	}

	php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_READ, 0, size TSRMLS_CC);

	/* this can return FAILED if there is just no more data from db */
	while (received < size && num > 0) {
		int len = 4096 < (size - received) ? 4096 : size - received;
		ERROR_HANDLER_DECLARATION(error_handler)

		ERROR_HANDLER_REPLACE(error_handler, mongo_ce_ConnectionException);
		num = php_stream_read(con->socket, (char *) data, len);
		ERROR_HANDLER_RESTORE(error_handler);

		if (num < 0) {
			/* Doesn't look like this can happen, php_sockop_read overwrites
			 * the failure from recv() to return 0 */
			*error_message = strdup("Read from socket failed");
			return -31;
		}

		/* It *may* have failed. It also may simply have no data */
		if (num == 0) {
			zval *metadata;

			MAKE_STD_ZVAL(metadata);
			array_init(metadata);
			if (php_stream_populate_meta_data(con->socket, metadata)) {
				zval **tmp;

				if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						struct timeval rtimeout = {0, 0};

						if (timeout > 0 && options->socketTimeoutMS != timeout) {
							rtimeout.tv_sec = timeout / 1000;
							rtimeout.tv_usec = (timeout % 1000) * 1000;
						} else {
							/* Convert timeout=-1 to -1second, which PHP interprets as no timeout */
							int socketTimeoutMS = options->socketTimeoutMS == -1 ? -1000 : options->socketTimeoutMS;
							rtimeout.tv_sec = socketTimeoutMS / 1000;
							rtimeout.tv_usec = (socketTimeoutMS % 1000) * 1000;
						}
						*error_message = malloc(256);
						snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec);
						zval_ptr_dtor(&metadata);
						return -80;
					}
				}
				if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						*error_message = strdup("Remote server has closed the connection");
						zval_ptr_dtor(&metadata);
						return -32;
					}
				}
			}
			zval_ptr_dtor(&metadata);
		}

		data = (char*)data + num;
		received += num;
	}
	/* PHP may have sent notify-progress of *more then* 'received' in some
	 * cases.
	 * PHP will read 8192 byte chunks at a time, but if we request less data
	 * then that PHP will just buffer the rest, which is fine.  It could
	 * confuse users a little, why their progress update was higher then the
	 * max-bytes-expected though... */
	php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_COMPLETED, received, size TSRMLS_CC);

	/* If the timeout was changed, revert to the previous value now */
	if (timeout && timeout != socketTimeoutMS) {
		struct timeval rtimeout = {0, 0};

		/* If socketTimeoutMS was never specified, revert to default_socket_timeout */
		if (options->socketTimeoutMS == 0) {
			mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Stream timeout will be reverted to default_socket_timeout (%d)", FG(default_socket_timeout));
		}

		rtimeout.tv_sec = socketTimeoutMS / 1000;
		rtimeout.tv_usec = (socketTimeoutMS % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
		mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Now setting stream timeout back to %d.%06d", rtimeout.tv_sec, rtimeout.tv_usec);
	}

	return received;
}
Пример #9
0
void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval** value, HashTable* fieldspec) {
    // At this point the typeID (and field num, if applicable) should've already been written to the output so all we need to do is write the payload.
    switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
        return;
    case T_STRUCT: {
        TSRMLS_FETCH();
        if (Z_TYPE_PP(value) != IS_OBJECT) {
            throw_tprotocolexception("Attempt to send non-object type as a T_STRUCT", INVALID_DATA);
        }
        zval* spec = zend_read_static_property(zend_get_class_entry(*value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
        binary_serialize_spec(*value, transport, Z_ARRVAL_P(spec));
    }
    return;
    case T_BOOL:
        if (Z_TYPE_PP(value) != IS_BOOL) convert_to_boolean(*value);
        transport.writeI8(Z_BVAL_PP(value) ? 1 : 0);
        return;
    case T_BYTE:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI8(Z_LVAL_PP(value));
        return;
    case T_I16:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI16(Z_LVAL_PP(value));
        return;
    case T_I32:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI32(Z_LVAL_PP(value));
        return;
    case T_I64:
    case T_U64:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI64(Z_LVAL_PP(value));
        return;
    case T_DOUBLE: {
        union {
            int64_t c;
            double d;
        } a;
        if (Z_TYPE_PP(value) != IS_DOUBLE) convert_to_double(*value);
        a.d = Z_DVAL_PP(value);
        transport.writeI64(a.c);
    }
    return;
    //case T_UTF7:
    case T_UTF8:
    case T_UTF16:
    case T_STRING:
        if (Z_TYPE_PP(value) != IS_STRING) convert_to_string(*value);
        transport.writeString(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
        return;
    case T_MAP: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_MAP)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "ktype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t keytype = Z_LVAL_PP(val_ptr);
        transport.writeI8(keytype);
        zend_hash_find(fieldspec, "vtype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t valtype = Z_LVAL_PP(val_ptr);
        transport.writeI8(valtype);

        zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
            binary_serialize(valtype, transport, val_ptr, valspec);
        }
    }
    return;
    case T_LIST: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_LIST)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t valtype = Z_LVAL_PP(val_ptr);
        transport.writeI8(valtype);

        zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize(valtype, transport, val_ptr, valspec);
        }
    }
    return;
    case T_SET: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_SET)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t keytype = Z_LVAL_PP(val_ptr);
        transport.writeI8(keytype);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
        }
    }
    return;
    };
    char errbuf[128];
    sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
    throw_tprotocolexception(errbuf, INVALID_DATA);
}
Пример #10
0
/* Returns the bytes read on success
 * Returns -31 on unknown failure
 * Returns -80 on timeout
 * Returns -32 when remote server closes the connection
 */
int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
	int num = 1, received = 0;
	TSRMLS_FETCH();

	if (timeout > 0 && options->socketTimeoutMS != timeout) {
		struct timeval rtimeout = {0, 0};
		rtimeout.tv_sec = timeout / 1000;
		rtimeout.tv_usec = (timeout % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
	}

	php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_READ, 0, size TSRMLS_CC);

	/* this can return FAILED if there is just no more data from db */
	while (received < size && num > 0) {
		int len = 4096 < (size - received) ? 4096 : size - received;
		ERROR_HANDLER_DECLARATION(error_handler)

		ERROR_HANDLER_REPLACE(error_handler, mongo_ce_ConnectionException);
		num = php_stream_read(con->socket, (char *) data, len);
		ERROR_HANDLER_RESTORE(error_handler);

		if (num < 0) {
			/* Doesn't look like this can happen, php_sockop_read overwrites
			 * the failure from recv() to return 0 */
			*error_message = strdup("Read from socket failed");
			return -31;
		}

		/* It *may* have failed. It also may simply have no data */
		if (num == 0) {
			zval *metadata;

			MAKE_STD_ZVAL(metadata);
			array_init(metadata);
			if (php_stream_populate_meta_data(con->socket, metadata)) {
				zval **tmp;

				if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						struct timeval rtimeout = {0, 0};

						if (timeout > 0 && options->socketTimeoutMS != timeout) {
							rtimeout.tv_sec = timeout / 1000;
							rtimeout.tv_usec = (timeout % 1000) * 1000;
						} else {
							rtimeout.tv_sec = options->socketTimeoutMS / 1000;
							rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000;
						}
						*error_message = malloc(256);
						snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec);
						zval_ptr_dtor(&metadata);
						return -80;
					}
				}
				if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						*error_message = strdup("Remote server has closed the connection");
						zval_ptr_dtor(&metadata);
						return -32;
					}
				}
			}
			zval_ptr_dtor(&metadata);
		}

		data = (char*)data + num;
		received += num;
	}
	/* PHP may have sent notify-progress of *more then* 'received' in some
	 * cases.
	 * PHP will read 8192 byte chunks at a time, but if we request less data
	 * then that PHP will just buffer the rest, which is fine.  It could
	 * confuse users a little, why their progress update was higher then the
	 * max-bytes-expected though... */
	php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_COMPLETED, received, size TSRMLS_CC);

	if (timeout > 0 && options->socketTimeoutMS != timeout) {
		struct timeval rtimeout = {0, 0};
		rtimeout.tv_sec = options->socketTimeoutMS / 1000;
		rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
	}

	return received;
}
Пример #11
0
/* Returns the bytes read on success
 * Returns -31 on unknown failure
 * Returns -80 on timeout
 * Returns -32 when remote server closes the connection
 */
int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message)
{
	int num = 1, received = 0;
	TSRMLS_FETCH();

	if (timeout > 0 && options->socketTimeoutMS != timeout) {
		struct timeval rtimeout = {0};
		rtimeout.tv_sec = timeout / 1000;
		rtimeout.tv_usec = (timeout % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
	}

	/* this can return FAILED if there is just no more data from db */
	while (received < size && num > 0) {
		int len = 4096 < (size - received) ? 4096 : size - received;

		num = php_stream_read(con->socket, (char *) data, len);

		if (num < 0) {
			/* Doesn't look like this can happen, php_sockop_read overwrites
			 * the failure from recv() to return 0 */
			*error_message = strdup("Read from socket failed");
			return -31;
		}

		/* It *may* have failed. It also may simply have no data */
		if (num == 0) {
			zval *metadata;

			MAKE_STD_ZVAL(metadata);
			array_init(metadata);
			if (php_stream_populate_meta_data(con->socket, metadata)) {
				zval **tmp;

				if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						struct timeval rtimeout = {0};

						if (timeout > 0 && options->socketTimeoutMS != timeout) {
							rtimeout.tv_sec = timeout / 1000;
							rtimeout.tv_usec = (timeout % 1000) * 1000;
						} else {
							rtimeout.tv_sec = options->socketTimeoutMS / 1000;
							rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000;
						}
						*error_message = malloc(256);
						snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec);
						zval_ptr_dtor(&metadata);
						return -80;
					}
				}
				if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) {
					convert_to_boolean_ex(tmp);
					if (Z_BVAL_PP(tmp)) {
						*error_message = strdup("Remote server has closed the connection");
						zval_ptr_dtor(&metadata);
						return -32;
					}
				}
			}
			zval_ptr_dtor(&metadata);
		}

		data = (char*)data + num;
		received += num;
	}

	if (options && options->ctx) {
		php_stream_notify_progress_increment((php_stream_context *)options->ctx, received, size);
	}
	if (timeout > 0 && options->socketTimeoutMS != timeout) {
		struct timeval rtimeout = {0};
		rtimeout.tv_sec = options->socketTimeoutMS / 1000;
		rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000;

		php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout);
	}

	return received;
}
Пример #12
0
// PHP函数参数转换为go类型的参数
static void* phpgo_function_conv_arg(int cbid, int idx, char ch, int zty, zval **zarg)
{
    int prmty = zty;
    void *rv = NULL;

    if (ch == 's') {
        if (prmty != IS_STRING) {
            zend_error(E_WARNING, "Parameters type not match, need (%c), given: %s",
                       ch, type2name(prmty));
        }

        convert_to_string_ex(zarg);
        char *arg = Z_STRVAL_PP(zarg);
        printf("arg%d(%c), %s(%d)\n", idx, ch, arg, Z_STRLEN_PP(zarg));
        goapi_new_value(GT_String, (uint64_t)arg, &rv);
    } else if (ch == 'l') {
        if (prmty != IS_LONG) {
            zend_error(E_WARNING, "Parameters type not match, need (%c), given: %s",
                       ch, type2name(prmty));
        }

        convert_to_long_ex(zarg);
        long arg = (long)Z_LVAL_PP(zarg);
        printf("arg%d(%c), %d\n", idx, ch, arg);
        goapi_new_value(GT_Int64, (uint64_t)arg, &rv);
    } else if (ch == 'b') {
        convert_to_boolean_ex(zarg);
        zend_bool arg = (zend_bool)Z_BVAL_PP(zarg);
        goapi_new_value(GT_Bool, (uint64_t)arg, &rv);
    } else if (ch == 'd') {
        convert_to_double_ex(zarg);
        double arg = (double)Z_DVAL_PP(zarg);
        double* parg = calloc(1, sizeof(double));
        *parg = (double)Z_DVAL_PP(zarg);
        // argv[idx] = (void*)(ulong)arg;  // error
        // memcpy(&argv[idx], &arg, sizeof(argv[idx])); // ok
        // float32(uintptr(ax))
        goapi_new_value(GT_Float64, (uint64_t)parg, &rv);
    } else if (ch == 'a') {
        if (Z_TYPE_PP(zarg) == IS_STRING) {
            char *arg = Z_STRVAL_PP(zarg);
            goapi_new_value(GT_String, (uint64_t)arg, &rv);
#ifdef ZEND_ENGINE_3
        } else if (Z_TYPE_PP(zarg) == _IS_BOOL) {
#else
        } else if (Z_TYPE_PP(zarg) == IS_BOOL) {
#endif
            zend_bool arg = (zend_bool)Z_BVAL_PP(zarg);
            goapi_new_value(GT_Bool, (uint64_t)arg, &rv);
        } else if (Z_TYPE_PP(zarg) == IS_DOUBLE) {
            double* parg = calloc(1, sizeof(double));
            *parg = (double)Z_DVAL_PP(zarg);
            goapi_new_value(GT_Float64, (uint64_t)parg, &rv);
        } else if (Z_TYPE_PP(zarg) == IS_LONG) {
            long arg = (long)Z_LVAL_PP(zarg);
            goapi_new_value(GT_Int64, (uint64_t)arg, &rv);
        } else if (Z_TYPE_PP(zarg) == IS_OBJECT) {
            void *parg = (void*)zarg;
            goapi_new_value(GT_UnsafePointer, (uint64_t)parg, &rv);
        } else if (Z_TYPE_PP(zarg) == IS_RESOURCE) {
            void *parg = (void*)zarg;
            goapi_new_value(GT_UnsafePointer, (uint64_t)parg, &rv);
        } else {
            printf("arg%d(%c), %s(%d) unsported to Any\n", idx, ch,
                   type2name(Z_TYPE_PP(zarg)), Z_TYPE_PP(zarg));
        }

        // TODO array/vector convert
    } else if (ch == 'v') {
        HashTable *arr_hash = Z_ARRVAL_PP(zarg);
        HashPosition pos;
        zval **edata;

        for (zend_hash_internal_pointer_reset_ex(arr_hash, &pos);
#ifdef ZEND_ENGINE_3
             (edata = zend_hash_get_current_data_ex(arr_hash, &pos)) != NULL;
#else
             zend_hash_get_current_data_ex(arr_hash, (void**)&edata, &pos) == SUCCESS;
#endif
             zend_hash_move_forward_ex(arr_hash, &pos)) {

            if (rv == NULL) {
                switch (Z_TYPE_PP(edata)) {
                case IS_LONG:
                    goapi_array_new(GT_Int64, &rv);
                    break;
                default:
                    goapi_array_new(GT_String, &rv);
                    break;
                }
            }

            switch (Z_TYPE_PP(edata)) {
            case IS_LONG:
                goapi_array_push(rv, (void*)Z_LVAL_PP(edata), &rv);
                break;
            default:
                convert_to_string_ex(edata);
                printf("array idx(%d)=T(%d=%s, val=%s)\n", pos,
                       Z_TYPE_PP(edata), type2name(Z_TYPE_PP(edata)), Z_STRVAL_PP(edata));
                goapi_array_push(rv, Z_STRVAL_PP(edata), &rv);
                break;
            }
        }

        // TODO array/map convert
    } else if (ch == 'm') {
Пример #13
0
int mongo_util_server_ping(mongo_server *server, time_t now TSRMLS_DC) {
  server_info* info;
  zval *response = 0, **secondary = 0, **bson = 0, **self = 0;
  struct timeval start, end;

  if ((info = mongo_util_server__get_info(server TSRMLS_CC)) == 0) {
    return FAILURE;
  }

  if (info->guts->last_ping + MONGO_PING_INTERVAL > now) {
    return info->guts->master ? SUCCESS : FAILURE;
  }

  gettimeofday(&start, 0);
  response = mongo_util_rs__ismaster(server TSRMLS_CC);
  gettimeofday(&end, 0);

  mongo_util_server__set_ping(info, start, end);

  if (!response) {
    return FAILURE;
  }

  zend_hash_find(HASH_P(response), "me", strlen("me")+1, (void**)&self);
  if (!info->guts->pinged && self &&
      strncmp(Z_STRVAL_PP(self), server->label, Z_STRLEN_PP(self)) != 0) {

    // this server thinks its name is different than what we have recorded
    mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: found another name for %s: %s",
              server->label, Z_STRVAL_PP(self));

    // make a new info entry for this name, pointing to our info
    make_other_le(Z_STRVAL_PP(self), info TSRMLS_CC);
  }

  // now we have pinged it at least once
  info->guts->pinged = 1;

  zend_hash_find(HASH_P(response), "secondary", strlen("secondary")+1, (void**)&secondary);
  if (secondary && Z_BVAL_PP(secondary)) {
    if (!info->guts->readable) {
      mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: %s is now a secondary", server->label);
    }

    info->guts->readable = 1;
    info->guts->master = 0;
  }
  else {
    if (info->guts->readable) {
      mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: %s is now not readable", server->label);
    }

    info->guts->readable = 0;
    info->guts->master = 0;
  }

  zend_hash_find(HASH_P(response), "maxBsonObjectSize", strlen("maxBsonObjectSize")+1, (void**)&bson);
  if (bson) {
    if (Z_TYPE_PP(bson) == IS_LONG) {
      info->guts->max_bson_size = Z_LVAL_PP(bson);
    }
    else if (Z_TYPE_PP(bson) == IS_DOUBLE) {
      info->guts->max_bson_size = (int)Z_DVAL_PP(bson);
    }
    // otherwise, leave as the default
    else {
      mongo_log(MONGO_LOG_SERVER, MONGO_LOG_WARNING TSRMLS_CC,
                "server: could not find max bson size on %s, consider upgrading your server", server->label);
    }
  }

  if (mongo_util_rs__get_ismaster(response TSRMLS_CC)) {
    if (!info->guts->master) {
      mongo_log(MONGO_LOG_SERVER, MONGO_LOG_INFO TSRMLS_CC, "server: %s is now primary", server->label);
    }

    info->guts->master = 1;
    info->guts->readable = 1;
    zval_ptr_dtor(&response);
    return SUCCESS;
  }

  zval_ptr_dtor(&response);
  return FAILURE;
}