<commit_before>#include "libtrading/proto/fix_message.h"

#include "libtrading/proto/fix_session.h"
#include "libtrading/read-write.h"
#include "libtrading/buffer.h"
#include "libtrading/array.h"
#include "libtrading/trace.h"
#include "libtrading/itoa.h"

#include <sys/socket.h>
#include <inttypes.h>
#include <sys/uio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

static const char *fix_msg_types[FIX_MSG_TYPE_MAX] = {
	[FIX_MSG_TYPE_HEARTBEAT]		= "0",
	[FIX_MSG_TYPE_TEST_REQUEST]		= "1",
	[FIX_MSG_TYPE_RESEND_REQUEST]		= "2",
	[FIX_MSG_TYPE_REJECT]			= "3",
	[FIX_MSG_TYPE_SEQUENCE_RESET]		= "4",
	[FIX_MSG_TYPE_LOGOUT]			= "5",
	[FIX_MSG_TYPE_EXECUTION_REPORT]		= "8",
	[FIX_MSG_ORDER_CANCEL_REJECT]		= "9",
	[FIX_MSG_TYPE_LOGON]			= "A",
	[FIX_MSG_TYPE_NEW_ORDER_SINGLE]		= "D",
	[FIX_MSG_ORDER_CANCEL_REQUEST]		= "F",
	[FIX_MSG_ORDER_CANCEL_REPLACE]		= "G",
	[FIX_MSG_TYPE_SNAPSHOT_REFRESH]		= "W",
	[FIX_MSG_TYPE_INCREMENT_REFRESH]	= "X",
	[FIX_MSG_TYPE_SESSION_STATUS]		= "h",
	[FIX_MSG_TYPE_SECURITY_STATUS]		= "f",
};

enum fix_msg_type fix_msg_type_parse(const char *s, const char delim)
{
	if (s[1] != delim)
		return FIX_MSG_TYPE_UNKNOWN;

	/*
	 * Single-character message type:
	 */
	switch (s[0]) {
	case '0': return FIX_MSG_TYPE_HEARTBEAT;
	case '1': return FIX_MSG_TYPE_TEST_REQUEST;
	case '2': return FIX_MSG_TYPE_RESEND_REQUEST;
	case '3': return FIX_MSG_TYPE_REJECT;
	case '4': return FIX_MSG_TYPE_SEQUENCE_RESET;
	case '5': return FIX_MSG_TYPE_LOGOUT;
	case '8': return FIX_MSG_TYPE_EXECUTION_REPORT;
	case '9': return FIX_MSG_ORDER_CANCEL_REJECT;
	case 'A': return FIX_MSG_TYPE_LOGON;
	case 'D': return FIX_MSG_TYPE_NEW_ORDER_SINGLE;
	case 'F': return FIX_MSG_ORDER_CANCEL_REQUEST;
	case 'G': return FIX_MSG_ORDER_CANCEL_REPLACE;
	case 'W': return FIX_MSG_TYPE_SNAPSHOT_REFRESH;
	case 'X': return FIX_MSG_TYPE_INCREMENT_REFRESH;
	case 'h': return FIX_MSG_TYPE_SESSION_STATUS;
	case 'f': return FIX_MSG_TYPE_SECURITY_STATUS;
	default : return FIX_MSG_TYPE_UNKNOWN;
	}
}

static int parse_tag(struct buffer *self, int *tag)
{
	const char *delim;
	const char *start;
	char *end;
	int ret;

	start = buffer_start(self);
	delim = buffer_find(self, '=');

	if (!delim || *delim != '=')
		return FIX_MSG_STATE_PARTIAL;

	ret = strtol(start, &end, 10);
	if (end != delim)
		return FIX_MSG_STATE_GARBLED;

	buffer_advance(self, 1);

	*tag = ret;

	return 0;
}

static int parse_value(struct buffer *self, const char **value)
{
	char *start, *end;<commit_msg>FIX: Micro-optimize parse_tag()<commit_after>#include "libtrading/proto/fix_message.h"

#include "libtrading/proto/fix_session.h"
#include "libtrading/read-write.h"
#include "libtrading/buffer.h"
#include "libtrading/array.h"
#include "libtrading/trace.h"
#include "libtrading/itoa.h"

#include <sys/socket.h>
#include <inttypes.h>
#include <sys/uio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

static const char *fix_msg_types[FIX_MSG_TYPE_MAX] = {
	[FIX_MSG_TYPE_HEARTBEAT]		= "0",
	[FIX_MSG_TYPE_TEST_REQUEST]		= "1",
	[FIX_MSG_TYPE_RESEND_REQUEST]		= "2",
	[FIX_MSG_TYPE_REJECT]			= "3",
	[FIX_MSG_TYPE_SEQUENCE_RESET]		= "4",
	[FIX_MSG_TYPE_LOGOUT]			= "5",
	[FIX_MSG_TYPE_EXECUTION_REPORT]		= "8",
	[FIX_MSG_ORDER_CANCEL_REJECT]		= "9",
	[FIX_MSG_TYPE_LOGON]			= "A",
	[FIX_MSG_TYPE_NEW_ORDER_SINGLE]		= "D",
	[FIX_MSG_ORDER_CANCEL_REQUEST]		= "F",
	[FIX_MSG_ORDER_CANCEL_REPLACE]		= "G",
	[FIX_MSG_TYPE_SNAPSHOT_REFRESH]		= "W",
	[FIX_MSG_TYPE_INCREMENT_REFRESH]	= "X",
	[FIX_MSG_TYPE_SESSION_STATUS]		= "h",
	[FIX_MSG_TYPE_SECURITY_STATUS]		= "f",
};

enum fix_msg_type fix_msg_type_parse(const char *s, const char delim)
{
	if (s[1] != delim)
		return FIX_MSG_TYPE_UNKNOWN;

	/*
	 * Single-character message type:
	 */
	switch (s[0]) {
	case '0': return FIX_MSG_TYPE_HEARTBEAT;
	case '1': return FIX_MSG_TYPE_TEST_REQUEST;
	case '2': return FIX_MSG_TYPE_RESEND_REQUEST;
	case '3': return FIX_MSG_TYPE_REJECT;
	case '4': return FIX_MSG_TYPE_SEQUENCE_RESET;
	case '5': return FIX_MSG_TYPE_LOGOUT;
	case '8': return FIX_MSG_TYPE_EXECUTION_REPORT;
	case '9': return FIX_MSG_ORDER_CANCEL_REJECT;
	case 'A': return FIX_MSG_TYPE_LOGON;
	case 'D': return FIX_MSG_TYPE_NEW_ORDER_SINGLE;
	case 'F': return FIX_MSG_ORDER_CANCEL_REQUEST;
	case 'G': return FIX_MSG_ORDER_CANCEL_REPLACE;
	case 'W': return FIX_MSG_TYPE_SNAPSHOT_REFRESH;
	case 'X': return FIX_MSG_TYPE_INCREMENT_REFRESH;
	case 'h': return FIX_MSG_TYPE_SESSION_STATUS;
	case 'f': return FIX_MSG_TYPE_SECURITY_STATUS;
	default : return FIX_MSG_TYPE_UNKNOWN;
	}
}

static int fix_uatoi(const char *p, const char **end)
{
	int ret = 0;
	while (*p >= '0' && *p <= '9') {
		ret = (ret*10) + (*p - '0');
		p++;
	}
	*end = p;
	return ret;
}

static int parse_tag(struct buffer *self, int *tag)
{
	const char *delim;
	const char *start;
	const char *end;
	int ret;

	start = buffer_start(self);
	delim = buffer_find(self, '=');

	if (!delim || *delim != '=')
		return FIX_MSG_STATE_PARTIAL;
	ret = fix_uatoi(start, &end);
	if (end != delim)
		return FIX_MSG_STATE_GARBLED;

	buffer_advance(self, 1);

	*tag = ret;

	return 0;
}

static int parse_value(struct buffer *self, const char **value)
{
	char *start, *end;
{'fraction_non_alphanumeric': 0.13869992441421014, 'fraction_numerical': 0.009070294784580499, 'mean_word_length': 5.7598978288633464, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3590113', 'n_tokens_mistral': 2358, 'n_tokens_neox': 2307, 'n_words': 436}