Skip to content

Commit

Permalink
Fixed bugs in conversion routines.
Browse files Browse the repository at this point in the history
  • Loading branch information
maxim2266 committed Sep 28, 2015
1 parent 30184f7 commit b6e6abb
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 14 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ _OS:_ Linux Mint 17.2 64bit
FIX message type | FIX specification | Validation | Average time to parse one message
----------------------------------|------------------------------------------|------------|----------------------------------
NewOrderSingle('D') | Hand-coded spec. for this message only | No | 0.317 µs/msg
NewOrderSingle('D') | Hand-coded spec. for this message only | Yes | 0.554 µs/msg
NewOrderSingle('D') | Compiled full spec. for FIX.4.4 | Yes | 0.757 µs/msg
MarketDataIncrementalRefresh('X') | Hand-coded spec. for this message only | Yes | 1.223 µs/msg
MarketDataIncrementalRefresh('X') | Compiled full spec. for FIX.4.4 | Yes | 1.386 µs/msg
NewOrderSingle('D') | Hand-coded spec. for this message only | Yes | 0.559 µs/msg
NewOrderSingle('D') | Compiled full spec. for FIX.4.4 | Yes | 0.756 µs/msg
MarketDataIncrementalRefresh('X') | Hand-coded spec. for this message only | Yes | 1.199 µs/msg
MarketDataIncrementalRefresh('X') | Compiled full spec. for FIX.4.4 | Yes | 1.398 µs/msg

For more details see `doc/` directory of the project.
26 changes: 16 additions & 10 deletions src/converters.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fix_error copy_fix_tag_as_string(const fix_group* const group, unsigned tag, cha
return FE_OK;
}

// ascii digits to long converters
// ascii digits to long integer converter
static
const char* convert_significant_digits(const char* s, long* const result)
{
Expand Down Expand Up @@ -125,14 +125,13 @@ fix_error get_fix_tag_as_long(const fix_group* const group, unsigned tag, long*

// conversion
long val;

value.begin = convert_digits(value.begin, &val);
const char* const s = convert_digits(value.begin, &val);

// validation
if(!value.begin || (neg && val == 0)) // overflow or '-0'
if(!s || s == value.begin || (neg && val == 0)) // overflow, no digits or '-0'
RETURN( FE_INVALID_VALUE );

if(value.begin < value.end) // unprocessed bytes
if(s < value.end) // unprocessed bytes
RETURN( FE_INCORRECT_VALUE_FORMAT );

// all clear
Expand Down Expand Up @@ -171,12 +170,19 @@ fix_error get_fix_tag_as_double(const fix_group* const group, unsigned tag, doub
}

// skip leading zeroes
while(*value.begin == '0')
++value.begin;
const char* s = value.begin;

while(*s == '0')
++s;

const unsigned nzero = s - value.begin;

value.begin = s;

// integer part
long int_part;
const char* s = convert_significant_digits(value.begin, &int_part);

s = convert_significant_digits(s, &int_part);

if(!s)
RETURN( FE_INVALID_VALUE );
Expand All @@ -189,7 +195,7 @@ fix_error get_fix_tag_as_double(const fix_group* const group, unsigned tag, doub
long frac_part = 0;
unsigned nfrac = 0;

if(*s == '.' && *++s != SOH)
if(*s == '.' && ++s < value.end)
{
// fractional part
value.begin = s;
Expand All @@ -205,7 +211,7 @@ fix_error get_fix_tag_as_double(const fix_group* const group, unsigned tag, doub
}

// final checks
if(s < value.end) // unprocessed bytes
if(s < value.end || (nzero + nsig + nfrac == 0)) // unprocessed bytes or no digits
RETURN( FE_INCORRECT_VALUE_FORMAT );

if(neg && int_part == 0 && frac_part == 0) // -0.0
Expand Down

0 comments on commit b6e6abb

Please sign in to comment.