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); }
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; }
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; }
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); }
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; }
/** * * @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; }
/** {{{ 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 ) ); } }
/* 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; }
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); }
/* 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; }
/* 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; }
// 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') {
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; }