Skip to content
This repository has been archived by the owner on May 29, 2020. It is now read-only.

Commit

Permalink
FIX: access to raw message representation introduced
Browse files Browse the repository at this point in the history
This patch adds a simple but quite useful feature.
Once a FIX message is sent or received a user is
allowed to inspect its raw representation i.e. a
user is allowed to inspect a message in a form it
is transfered through the wire (pure FIX payload).

This feature can be applied in various cases but
the main one is logging. If one's goal is to log
FIX session, this feature allows to do that in a
very efficient way. No need to process a message
in any way, no need to format a message. Once
fix_session_send or fix_session_recv returns a
user can access msg->iov and log the data which
were sent or received - no preprocessing is needed.

As an illustration, this patch implements fprintmsg_iov
using a new feature. fprintmsg_iov looks more elegant
in comparison to fprintmsg. Moreover, it outputs every
single field while fprintmsg has its own limitation.
Furthermore, fprintmsg_iov tells us how floats were
formatted in a real stream which fprintmsg has no
chances to know.

Important notes:

* msg->iov is *only* valid after fix_session_recv or
fix_session_send returns. Subsequent calls invalidate
the pointer.

* msg->iov[i].iov_len might be zero (i = 0, 1)

Signed-off-by: Marat Stanichenko <mstanichenko@gmail.com>
  • Loading branch information
mstanichenko committed Jul 29, 2015
1 parent 701dd1e commit 1254d4e
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 6 deletions.
3 changes: 3 additions & 0 deletions include/libtrading/proto/fix_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
extern "C" {
#endif

#include <sys/uio.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Expand Down Expand Up @@ -209,6 +210,8 @@ struct fix_message {

unsigned long nr_fields;
struct fix_field *fields;

struct iovec iov[2];
};

enum fix_parse_flag {
Expand Down
10 changes: 6 additions & 4 deletions lib/proto/fix_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ int fix_message_parse(struct fix_message *self, struct fix_dialect *dialect, str

rest_of_message(self, dialect, buffer);

self->iov[0].iov_base = (void *)start;
self->iov[0].iov_len = buffer_start(buffer) - start;

TRACE(LIBTRADING_FIX_MESSAGE_PARSE_RET());

return 0;
Expand Down Expand Up @@ -684,18 +687,17 @@ void fix_message_unparse(struct fix_message *self)

int fix_message_send(struct fix_message *self, int sockfd, int flags)
{
struct iovec iov[2];
int ret = 0;

TRACE(LIBTRADING_FIX_MESSAGE_SEND(self, sockfd, flags));

if (!(flags & FIX_SEND_FLAG_PRESERVE_BUFFER))
fix_message_unparse(self);

buffer_to_iovec(self->head_buf, &iov[0]);
buffer_to_iovec(self->body_buf, &iov[1]);
buffer_to_iovec(self->head_buf, &self->iov[0]);
buffer_to_iovec(self->body_buf, &self->iov[1]);

if (io_sendmsg(sockfd, iov, 2, 0) < 0) {
if (io_sendmsg(sockfd, self->iov, 2, 0) < 0) {
ret = -1;
goto error_out;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/fix/fix_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ static int fix_client_script(struct fix_session_cfg *cfg, struct fix_client_arg
goto retry;

fprintf(stdout, "< ");
fprintmsg(stdout, msg);
fprintmsg_iov(stdout, msg);

if (fmsgcmp(&expected_elem->msg, msg)) {
fprintf(stderr, "Client: messages differ\n");
Expand Down
2 changes: 1 addition & 1 deletion tools/fix/fix_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static int fix_server_script(struct fix_session_cfg *cfg, struct fix_server_arg
continue;

fprintf(stdout, "> ");
fprintmsg(stdout, msg);
fprintmsg_iov(stdout, msg);

if (fmsgcmp(&expected_elem->msg, msg)) {
fprintf(stderr, "Server: messages differ\n");
Expand Down
25 changes: 25 additions & 0 deletions tools/fix/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,28 @@ void fprintmsg(FILE *stream, struct fix_message *msg)

fprintf(stream, "%s%c\n", buf, delim);
}

void fprintmsg_iov(FILE *stream, struct fix_message *msg)
{
char delim = '|';
int i;

if (!msg)
return;

for (i = 0; i < 2; ++i) {
const char *start = msg->iov[i].iov_base;
unsigned int len = msg->iov[i].iov_len;
const char *end = start;

while ((end = memchr(start, 0x01, len))) {
fprintf(stdout, "%c%.*s", delim, (int)(end - start), start);
len -= (end - start + 1);
start = end + 1;
}
}

fprintf(stdout, "%c\n", delim);

return;
}
1 change: 1 addition & 0 deletions tools/fix/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ struct fcontainer *fcontainer_new(void);

int script_read(FILE *stream, struct fcontainer *server, struct fcontainer *client);
int fmsgcmp(struct fix_message *expected, struct fix_message *actual);
void fprintmsg_iov(FILE *stream, struct fix_message *msg);
void fprintmsg(FILE *stream, struct fix_message *msg);

0 comments on commit 1254d4e

Please sign in to comment.