static ERL_NIF_TERM make_strings(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char a0string[8] = {'a','0','s','t','r','i','n','g'}; const char a0string0[9] = {'a','\0','s','t','r','i','n','g',0}; const char astringwith8bits[37] = {'E','r','l','a','n','g',' ',0xE4 /* 'ä' */,'r',' ','e','t','t',' ','g','e','n','e','r','e','l','l','t',' ','p','r','o','g','r','a','m','s','p','r', 0xE5 /* 'å' */,'k',0}; return enif_make_tuple5(env, enif_make_string(env, "a0string", ERL_NIF_LATIN1), enif_make_string_len(env, "a0string", 8, ERL_NIF_LATIN1), enif_make_string_len(env, a0string, 8, ERL_NIF_LATIN1), enif_make_string_len(env, a0string0, 9, ERL_NIF_LATIN1), enif_make_string(env, astringwith8bits, ERL_NIF_LATIN1)); }
static ERL_NIF_TERM hexlify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin, ret; unsigned int flags = 0; unsigned i, j; const char* digits; if (argc != 2 || !enif_inspect_binary(env, argv[0], &bin) || !enif_get_uint(env, argv[1], &flags)) { return enif_make_badarg(env); } digits = (flags & HMAC_UPPER) ? UPPER : LOWER; enif_alloc_binary(bin.size*2, &ret); for (i = 0, j = 0; i < bin.size; ++i) { unsigned char c = bin.data[i]; ret.data[j++] = digits[(c & 0xF0) >> 4]; ret.data[j++] = digits[(c & 0x0F)]; } if (flags & HMAC_STRING) { const char* data = (char*)ret.data; ERL_NIF_TERM s = enif_make_string_len(env, data, ret.size, ERL_NIF_LATIN1); enif_release_binary(&ret); return s; } else { return enif_make_binary(env, &ret); } }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM get_string_field(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[]) { ERL_NIF_TERM parser_res; ERL_NIF_TERM msg_res; ERL_NIF_TERM group_res; ParserRes* parser = NULL; FIXMsg* msg = NULL; FIXGroup* group = NULL; ERL_NIF_TERM res = get_parser_msg_group(env, argv[0], &parser_res, &msg_res, &group_res, &parser, &msg, &group); if (res != ok_atom) { return res; } int32_t tagNum = 0; if (!enif_get_int(env, argv[1], &tagNum)) { return make_error(env, FIX_FAILED, "Wrong tag num."); } char const* data = NULL; uint32_t len = 0; FIXError* error = NULL; pthread_rwlock_rdlock(&parser->lock); FIXErrCode err = fix_msg_get_string(msg, group, tagNum, &data, &len, &error); pthread_rwlock_unlock(&parser->lock); if (err == FIX_FAILED) { ERL_NIF_TERM ret = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); return ret; } return enif_make_tuple2(env, ok_atom, enif_make_string_len(env, data, len, ERL_NIF_LATIN1)); }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM get_header(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[]) { int32_t delimiter = 0; ErlNifBinary bin; if (!enif_inspect_binary(env, argv[0], &bin)) { return make_error(env, FIX_FAILED, "Wrong delimiter."); } if (!enif_get_int(env, argv[1], &delimiter) || delimiter <= 0 || delimiter >= 255) { return make_error(env, FIX_FAILED, "Wrong binary."); } char const* beginString = NULL; uint32_t beginStringLen = 0; char const* msgType = NULL; uint32_t msgTypeLen = 0; char const* senderCompID = NULL; uint32_t senderCompIDLen = 0; char const* targetCompID = NULL; uint32_t targetCompIDLen = 0; int64_t msgSeqNum = 0; FIXError* error = NULL; if (FIX_FAILED == fix_parser_get_header((char const*)bin.data, bin.size, delimiter, &beginString, &beginStringLen, &msgType, &msgTypeLen, &senderCompID, &senderCompIDLen, &targetCompID, &targetCompIDLen, &msgSeqNum, &error)) { ERL_NIF_TERM err = make_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); return err; } return enif_make_tuple2(env, ok_atom, enif_make_tuple6(env, msg_header, enif_make_string_len(env, beginString, beginStringLen, ERL_NIF_LATIN1), enif_make_string_len(env, msgType, msgTypeLen, ERL_NIF_LATIN1), enif_make_string_len(env, senderCompID, senderCompIDLen, ERL_NIF_LATIN1), enif_make_string_len(env, targetCompID, targetCompIDLen, ERL_NIF_LATIN1), enif_make_int64(env, msgSeqNum))); }
ERL_NIF_TERM enif_make_string(ErlNifEnv* env, const char* string, ErlNifCharEncoding encoding) { return enif_make_string_len(env, string, sys_strlen(string), encoding); }