The core problem with appendNumber is that it uses snprintf (a printf
variant) to format the number. The essential code is:
UtlString& UtlString::appendNumber(Int64 value, const char* format)
{
...
int formatResult = snprintf(conversionString, MAX_NUMBER_STRING_SIZE,
format, value);
...
}
As such, the conversion specification in the string 'format' must agree
with the type of 'value'. Currently, 'value' has type Int64, which is a
typedef for a 64-bit integer. Here is a list of the conversion
specifications that are now used (that is, are second arguments to
appendNumber), and the required argument types:
%d int the default 'format', used in many places
%0#16[FORMAT_INTLL]x long long int
%x int
%04o int
%[FORMAT_INTLL]d long long int
%03d int unit test
%08x int unit test
%lld long long int unit test
Here, I've used "[FORMAT_INTLL]" to represent the contents of the macro
FORMAT_INTLL (defined in UtlDefs.h), which is the length modifier for
long long int, which is not standardized, and is either "ll" or "I64".
Currently, the 'int' formats work on x86 platforms because the
conversion process reads the low-order 32 bits of the 64-bit 'value',
which happens to produce the correct results. On 64-bit platforms where
long long int is the same as int, all these cases should work correctly.
But on systems with 32-bit int and big-endian representation, we can
expect that numbers won't be converted correctly.
Note that unless int and long long int are the same type, there is no
type for 'value' that will work with all the formats we are now using.
There seem to be two ways out of this problem:
1 - Define more than one appendNumber, with different signatures. That
is, appendNumberInt would have an int 'value' and allow 'format' with
any conversion specification that is compatible with int, and
appendNumberLLInt would have a long long int 'value' and allow 'format'
with any conversion specification that is compatible with long long int.
2 - Pick some one type that has a standardized length modifier, and
convert appendNumber and all of its calls to use it -- that is, the
'value' argument has that type, and the 'format' always uses the
corresponding length modifier. In this regard, using type ssize_t and
length modifier "z" seems to be a good choice, as "z" was standardized
in ISO C99.
Dale
_______________________________________________
sipx-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipx-dev
Unsubscribe: http://list.sipfoundry.org/mailman/listinfo/sipx-dev