static void* construct_create_message(OUTPROCESS_HANDLE_DATA* handleData, int32_t * creationMessageSize) { void * result; uint32_t uri_length = STRING_length(handleData->message_uri); char * uri_string = (char*)STRING_c_str(handleData->message_uri); uint32_t args_length = STRING_length(handleData->module_args); char * args_string = (char*)STRING_c_str(handleData->module_args); if (uri_length == 0 || uri_string == NULL || args_length == 0 || args_string == NULL) { result = NULL; } else { /*Codes_SRS_OUTPROCESS_MODULE_17_012: [ This function shall construct a Create Message from configuration. ]*/ CONTROL_MESSAGE_MODULE_CREATE create_msg = { { CONTROL_MESSAGE_VERSION_CURRENT, /*version*/ CONTROL_MESSAGE_TYPE_MODULE_CREATE /*type*/ }, GATEWAY_MESSAGE_VERSION_CURRENT, /*gateway_message_version*/ { uri_length + 1, /*uri_size (+1 for null)*/ (uint8_t)NN_PAIR, /*uri_type*/ uri_string /*uri*/ }, args_length + 1, /*args_size;(+1 for null)*/ args_string /*args;*/ }; result = serialize_control_message((CONTROL_MESSAGE *)&create_msg, creationMessageSize); } return result; }
PARROT_WARN_UNUSED_RESULT INTVAL encoding_equal(PARROT_INTERP, ARGIN(const STRING *lhs), ARGIN(const STRING *rhs)) { ASSERT_ARGS(encoding_equal) String_iter l_iter, r_iter; const UINTVAL len = STRING_length(lhs); if (len != STRING_length(rhs)) return 0; if (len == 0) return 1; if (lhs == rhs) return 1; if (lhs->hashval && rhs->hashval && lhs->hashval != rhs->hashval) return 0; if (lhs->encoding == rhs->encoding) return memcmp(lhs->strstart, rhs->strstart, STRING_byte_length(lhs)) == 0; STRING_ITER_INIT(interp, &l_iter); STRING_ITER_INIT(interp, &r_iter); while (l_iter.charpos < len) { const UINTVAL cl = STRING_iter_get_and_advance(interp, lhs, &l_iter); const UINTVAL cr = STRING_iter_get_and_advance(interp, rhs, &r_iter); if (cl != cr) return 0; } return 1; }
PARROT_WARN_UNUSED_RESULT INTVAL encoding_index(PARROT_INTERP, ARGIN(const STRING *src), ARGIN(const STRING *search), INTVAL offset) { ASSERT_ARGS(encoding_index) String_iter start, end; if ((UINTVAL)offset >= STRING_length(src) || !STRING_length(search)) return -1; STRING_ITER_INIT(interp, &start); STRING_iter_skip(interp, src, &start, offset); return Parrot_str_iter_index(interp, src, &start, &end, search); }
PARROT_CANNOT_RETURN_NULL STRING * encoding_substr(PARROT_INTERP, ARGIN(const STRING *src), INTVAL offset, INTVAL length) { ASSERT_ARGS(encoding_substr) const UINTVAL strlen = STRING_length(src); STRING *return_string; String_iter iter; UINTVAL start; if (offset < 0) offset += strlen; if ((UINTVAL)offset >= strlen || length <= 0) { /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */ if ((UINTVAL)offset == strlen || length <= 0) return Parrot_str_new_constant(interp, ""); Parrot_ex_throw_from_c_noargs(interp, EXCEPTION_SUBSTR_OUT_OF_STRING, "Cannot take substr outside string"); } return_string = Parrot_str_copy(interp, src); if (offset == 0 && (UINTVAL)length >= strlen) return return_string; STRING_ITER_INIT(interp, &iter); if (offset) STRING_iter_skip(interp, src, &iter, offset); start = iter.bytepos; return_string->strstart += start; if ((UINTVAL)length >= strlen - (UINTVAL)offset) { return_string->bufused -= start; return_string->strlen -= offset; } else { STRING_iter_skip(interp, src, &iter, length); return_string->bufused = iter.bytepos - start; return_string->strlen = length; } return_string->hashval = 0; return return_string; }
PARROT_WARN_UNUSED_RESULT INTVAL encoding_compare(PARROT_INTERP, ARGIN(const STRING *lhs), ARGIN(const STRING *rhs)) { ASSERT_ARGS(encoding_compare) String_iter l_iter, r_iter; const UINTVAL l_len = STRING_length(lhs); const UINTVAL r_len = STRING_length(rhs); UINTVAL min_len; if (r_len == 0) return l_len != 0; if (l_len == 0) return -1; STRING_ITER_INIT(interp, &l_iter); STRING_ITER_INIT(interp, &r_iter); min_len = l_len > r_len ? r_len : l_len; while (l_iter.charpos < min_len) { const UINTVAL cl = STRING_iter_get_and_advance(interp, lhs, &l_iter); const UINTVAL cr = STRING_iter_get_and_advance(interp, rhs, &r_iter); if (cl != cr) return cl < cr ? -1 : 1; } if (l_len < r_len) return -1; if (l_len > r_len) return 1; return 0; }
static UINTVAL utf8_ord(PARROT_INTERP, ARGIN(const STRING *src), INTVAL idx) { ASSERT_ARGS(utf8_ord) const UINTVAL len = STRING_length(src); const utf8_t *start; if (idx < 0) idx += len; if ((UINTVAL)idx >= len) encoding_ord_error(interp, src, idx); start = utf8_skip_forward((utf8_t *)src->strstart, idx); return utf8_decode(interp, start); }
PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL static STRING * utf16_to_encoding(PARROT_INTERP, ARGIN(const STRING *src)) { ASSERT_ARGS(utf16_to_encoding) STRING *result; UINTVAL src_len; src_len = STRING_length(src); if (STRING_max_bytes_per_codepoint(src) == 1) { result = Parrot_gc_new_string_header(interp, 0); result->encoding = Parrot_ucs2_encoding_ptr; result->bufused = 2 * src_len; result->strlen = src_len; if (src_len) { UINTVAL i; Parrot_UInt2 *p; Parrot_gc_allocate_string_storage(interp, result, 2 * src_len); p = (Parrot_UInt2 *)result->strstart; for (i = 0; i < src_len; ++i) { p[i] = (unsigned char)src->strstart[i]; } } } else if (src->encoding == Parrot_utf16_encoding_ptr || src->encoding == Parrot_ucs2_encoding_ptr) { /* we have to use clone instead of copy because the Unicode upcase * and downcase functions assume to get an unshared buffer */ result = Parrot_str_clone(interp, src); } else { result = encoding_to_encoding(interp, src, Parrot_utf16_encoding_ptr, 2.2); /* downgrade if possible */ if (result->bufused == result->strlen << 1) result->encoding = Parrot_ucs2_encoding_ptr; } return result; }
PARROT_DOES_NOT_RETURN void encoding_ord_error(PARROT_INTERP, ARGIN(const STRING *s), INTVAL offset) { ASSERT_ARGS(encoding_ord_error) const UINTVAL len = STRING_length(s); const char *err_msg; if (!len) err_msg = "Cannot get character of empty string"; else if (offset >= 0) err_msg = "Cannot get character past end of string"; else if (offset < 0) err_msg = "Cannot get character before beginning of string"; else err_msg = "Unknown encoding_ord_error"; Parrot_ex_throw_from_c_noargs(interp, EXCEPTION_ORD_OUT_OF_STRING, err_msg); }
static BROKER_RESULT start_module(BROKER_MODULEINFO* module_info, STRING_HANDLE url) { BROKER_RESULT result; /* Connect to pub/sub */ /*Codes_SRS_BROKER_17_013: [ The function shall create a nanomsg socket for reception. ]*/ module_info->receive_socket = nn_socket(AF_SP, NN_SUB); if (module_info->receive_socket < 0) { /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/ LogError("module receive socket create failed"); result = BROKER_ERROR; } else { /*Codes_SRS_BROKER_17_014: [ The function shall bind the socket to the the BROKER_HANDLE_DATA::url. ]*/ int connect_result = nn_connect(module_info->receive_socket, STRING_c_str(url)); if (connect_result < 0) { /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/ LogError("nn_connect failed"); nn_close(module_info->receive_socket); module_info->receive_socket = -1; result = BROKER_ERROR; } else { /* Codes_SRS_BROKER_17_028: [ The function shall subscribe BROKER_MODULEINFO::receive_socket to the quit signal GUID. ]*/ if (nn_setsockopt( module_info->receive_socket, NN_SUB, NN_SUB_SUBSCRIBE, STRING_c_str(module_info->quit_message_guid), STRING_length(module_info->quit_message_guid)) < 0) { /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/ LogError("nn_setsockopt failed"); nn_close(module_info->receive_socket); module_info->receive_socket = -1; result = BROKER_ERROR; } else { /*Codes_SRS_BROKER_13_102: [The function shall create a new thread for the module by calling ThreadAPI_Create using module_worker as the thread callback and using the newly allocated BROKER_MODULEINFO object as the thread context.*/ if (ThreadAPI_Create( &(module_info->thread), module_worker, (void*)module_info ) != THREADAPI_OK) { /*Codes_SRS_BROKER_13_047: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/ LogError("ThreadAPI_Create failed"); nn_close(module_info->receive_socket); result = BROKER_ERROR; } else { result = BROKER_OK; } } } } return result; }
PARROT_EXPORT PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC* Parrot_make_cb(PARROT_INTERP, ARGMOD(PMC* sub), ARGIN(PMC* user_data), ARGIN(STRING *cb_signature)) { ASSERT_ARGS(Parrot_make_cb) PMC *cb, *cb_sig; int type = 0; STRING *sc; /* * we stuff all the information into the user_data PMC and pass that * on to the external sub */ PMC * const interp_pmc = VTABLE_get_pmc_keyed_int(interp, interp->iglobals, (INTVAL) IGLOBALS_INTERPRETER); if (default_interp == NULL) default_interp = interp; /* be sure __LINE__ is consistent */ sc = CONST_STRING(interp, "_interpreter"); Parrot_pmc_setprop(interp, user_data, sc, interp_pmc); sc = CONST_STRING(interp, "_sub"); Parrot_pmc_setprop(interp, user_data, sc, sub); /* only ASCII signatures are supported */ if (STRING_length(cb_signature) == 3) { /* Callback return type ignored */ if (STRING_ord(interp, cb_signature, 1) == 'U') { type = 'D'; } else { if (STRING_ord(interp, cb_signature, 2) == 'U') { type = 'C'; } } } if (type != 'C' && type != 'D') Parrot_ex_throw_from_c_args(interp, NULL, 1, "unhandled signature '%Ss' in make_cb", cb_signature); cb_sig = Parrot_pmc_new(interp, enum_class_String); VTABLE_set_string_native(interp, cb_sig, cb_signature); sc = CONST_STRING(interp, "_signature"); Parrot_pmc_setprop(interp, user_data, sc, cb_sig); /* * We are going to be passing the user_data PMC to external code, but * it may go out of scope until the callback is called -- we don't know * for certain as we don't know when the callback will be called. * Therefore, to prevent the PMC from being destroyed by a GC sweep, * we need to anchor it. * */ Parrot_pmc_gc_register(interp, user_data); /* * Finally, the external lib awaits a function pointer. * Create a PMC that points to Parrot_callback_C (or _D); * it can be passed on with signature 'p'. */ cb = Parrot_pmc_new(interp, enum_class_UnManagedStruct); /* * Currently, we handle only 2 types: * _C ... user_data is 2nd parameter * _D ... user_data is 1st parameter */ if (type == 'C') VTABLE_set_pointer(interp, cb, F2DPTR(Parrot_callback_C)); else VTABLE_set_pointer(interp, cb, F2DPTR(Parrot_callback_D)); Parrot_pmc_gc_register(interp, cb); return cb; }
static int stream_lof(STREAM *stream, int64_t *len) { *len = STRING_length(stream->string.buffer); return FALSE; }
STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, size_t expiry) { STRING_HANDLE result = NULL; char tokenExpirationTime[32] = { 0 }; /*Codes_SRS_SASTOKEN_06_001: [If key is NULL then SASToken_Create shall return NULL.]*/ /*Codes_SRS_SASTOKEN_06_003: [If scope is NULL then SASToken_Create shall return NULL.]*/ /*Codes_SRS_SASTOKEN_06_007: [If keyName is NULL then SASToken_Create shall return NULL.]*/ if ((key == NULL) || (scope == NULL) || (keyName == NULL)) { LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p\r\n", key, scope, keyName); } else { BUFFER_HANDLE decodedKey; /*Codes_SRS_SASTOKEN_06_029: [The key parameter is decoded from base64.]*/ if ((decodedKey = Base64_Decoder(STRING_c_str(key))) == NULL) { /*Codes_SRS_SASTOKEN_06_030: [If there is an error in the decoding then SASToken_Create shall return NULL.]*/ LogError("Unable to decode the key for generating the SAS.\r\n"); } else { /*Codes_SRS_SASTOKEN_06_026: [If the conversion to string form fails for any reason then SASToken_Create shall return NULL.]*/ if (size_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0) { LogError("For some reason converting seconds to a string failed. No SAS can be generated.\r\n"); } else { STRING_HANDLE toBeHashed = NULL; BUFFER_HANDLE hash = NULL; if (((hash = BUFFER_new()) == NULL) || ((toBeHashed = STRING_new()) == NULL) || ((result = STRING_new()) == NULL)) { LogError("Unable to allocate memory to prepare SAS token.\r\n") } else { /*Codes_SRS_SASTOKEN_06_009: [The scope is the basis for creating a STRING_HANDLE.]*/ /*Codes_SRS_SASTOKEN_06_010: [A "\n" is appended to that string.]*/ /*Codes_SRS_SASTOKEN_06_011: [tokenExpirationTime is appended to that string.]*/ if ((STRING_concat_with_STRING(toBeHashed, scope) != 0) || (STRING_concat(toBeHashed, "\n") != 0) || (STRING_concat(toBeHashed, tokenExpirationTime) != 0)) { LogError("Unable to build the input to the HMAC to prepare SAS token.\r\n"); STRING_delete(result); result = NULL; } else { STRING_HANDLE base64Signature = NULL; STRING_HANDLE urlEncodedSignature = NULL; /*Codes_SRS_SASTOKEN_06_013: [If an error is returned from the HMAC256 function then NULL is returned from SASToken_Create.]*/ /*Codes_SRS_SASTOKEN_06_012: [An HMAC256 hash is calculated using the decodedKey, over toBeHashed.]*/ /*Codes_SRS_SASTOKEN_06_014: [If there are any errors from the following operations then NULL shall be returned.]*/ /*Codes_SRS_SASTOKEN_06_015: [The hash is base 64 encoded.]*/ /*Codes_SRS_SASTOKEN_06_028: [base64Signature shall be url encoded.]*/ /*Codes_SRS_SASTOKEN_06_016: [The string "SharedAccessSignature sr=" is the first part of the result of SASToken_Create.]*/ /*Codes_SRS_SASTOKEN_06_017: [The scope parameter is appended to result.]*/ /*Codes_SRS_SASTOKEN_06_018: [The string "&sig=" is appended to result.]*/ /*Codes_SRS_SASTOKEN_06_019: [The string urlEncodedSignature shall be appended to result.]*/ /*Codes_SRS_SASTOKEN_06_020: [The string "&se=" shall be appended to result.]*/ /*Codes_SRS_SASTOKEN_06_021: [tokenExpirationTime is appended to result.]*/ /*Codes_SRS_SASTOKEN_06_022: [The string "&skn=" is appended to result.]*/ /*Codes_SRS_SASTOKEN_06_023: [The argument keyName is appended to result.]*/ if ((HMACSHA256_ComputeHash(BUFFER_u_char(decodedKey), BUFFER_length(decodedKey), (const unsigned char*)STRING_c_str(toBeHashed), STRING_length(toBeHashed), hash) != HMACSHA256_OK) || ((base64Signature = Base64_Encode(hash)) == NULL) || ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL) || (STRING_copy(result, "SharedAccessSignature sr=") != 0) || (STRING_concat_with_STRING(result, scope) != 0) || (STRING_concat(result, "&sig=") != 0) || (STRING_concat_with_STRING(result, urlEncodedSignature) != 0) || (STRING_concat(result, "&se=") != 0) || (STRING_concat(result, tokenExpirationTime) != 0) || (STRING_concat(result, "&skn=") != 0) || (STRING_concat_with_STRING(result, keyName) != 0)) { LogError("Unable to build the SAS token.\r\n"); STRING_delete(result); result = NULL; } else { /* everything OK */ } STRING_delete(base64Signature); STRING_delete(urlEncodedSignature); } } STRING_delete(toBeHashed); BUFFER_delete(hash); } BUFFER_delete(decodedKey); } } return result; }