1 #ifndef __cxxtest__ValueTraits_cpp__
2 #define __cxxtest__ValueTraits_cpp__
3 
4 #include <cxxtest/ValueTraits.h>
5 
6 namespace CxxTest
7 {
8     //
9     // Non-inline functions from ValueTraits.h
10     //
11 
digitToChar(unsigned digit)12     char digitToChar( unsigned digit )
13     {
14         if ( digit < 10 )
15             return (char)('0' + digit);
16         if ( digit <= 10 + 'Z' - 'A' )
17             return (char)('A' + digit - 10);
18         return '?';
19     }
20 
byteToHex(unsigned char byte)21     const char *byteToHex( unsigned char byte )
22     {
23         static char asHex[3];
24         asHex[0] = digitToChar( byte >> 4 );
25         asHex[1] = digitToChar( byte & 0x0F );
26         asHex[2] = '\0';
27         return asHex;
28     }
29 
copyString(char * dst,const char * src)30     char *copyString( char *dst, const char *src )
31     {
32         while ( (*dst = *src) != '\0' ) {
33             ++ dst;
34             ++ src;
35         }
36         return dst;
37     }
38 
stringsEqual(const char * s1,const char * s2)39     bool stringsEqual( const char *s1, const char *s2 )
40     {
41         char c;
42         while ( (c = *s1++) == *s2++ )
43             if ( c == '\0' )
44                 return true;
45         return false;
46     }
47 
charToString(unsigned long c,char * s)48     char *charToString( unsigned long c, char *s )
49     {
50         switch( c ) {
51         case '\\': return copyString( s, "\\\\" );
52         case '\"': return copyString( s, "\\\"" );
53         case '\'': return copyString( s, "\\\'" );
54         case '\0': return copyString( s, "\\0" );
55         case '\a': return copyString( s, "\\a" );
56         case '\b': return copyString( s, "\\b" );
57         case '\n': return copyString( s, "\\n" );
58         case '\r': return copyString( s, "\\r" );
59         case '\t': return copyString( s, "\\t" );
60         }
61         if ( c >= 32 && c <= 127 ) {
62             s[0] = (char)c;
63             s[1] = '\0';
64             return s + 1;
65         }
66         else {
67             s[0] = '\\';
68             s[1] = 'x';
69             if ( c < 0x10 ) {
70                 s[2] = '0';
71                 ++ s;
72             }
73             return numberToString( c, s + 2 );
74         }
75     }
76 
charToString(char c,char * s)77     char *charToString( char c, char *s )
78     {
79         return charToString( (unsigned long)(unsigned char)c, s );
80     }
81 
bytesToString(const unsigned char * bytes,unsigned numBytes,unsigned maxBytes,char * s)82     char *bytesToString( const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s )
83     {
84         bool truncate = (numBytes > maxBytes);
85         if ( truncate )
86             numBytes = maxBytes;
87 
88         s = copyString( s, "{ " );
89         for ( unsigned i = 0; i < numBytes; ++ i, ++ bytes )
90             s = copyString( copyString( s, byteToHex( *bytes ) ), " " );
91         if ( truncate )
92             s = copyString( s, "..." );
93         return copyString( s, " }" );
94     }
95 
96 #ifndef CXXTEST_USER_VALUE_TRAITS
requiredDigitsOnLeft(double t)97     unsigned ValueTraits<const double>::requiredDigitsOnLeft( double t )
98     {
99         unsigned digits = 1;
100         for ( t = (t < 0.0) ? -t : t; t > 1.0; t /= BASE )
101             ++ digits;
102         return digits;
103     }
104 
doNegative(double & t)105     char *ValueTraits<const double>::doNegative( double &t )
106     {
107         if ( t >= 0 )
108             return _asString;
109         _asString[0] = '-';
110         t = -t;
111         return _asString + 1;
112     }
113 
hugeNumber(double t)114     void ValueTraits<const double>::hugeNumber( double t )
115     {
116         char *s = doNegative( t );
117         s = doubleToString( t, s );
118         s = copyString( s, "." );
119         s = doubleToString( t, s );
120         s = copyString( s, "E" );
121         s = numberToString( requiredDigitsOnLeft( t ) - 1, s );
122     }
123 
normalNumber(double t)124     void ValueTraits<const double>::normalNumber( double t )
125     {
126         char *s = doNegative( t );
127         s = doubleToString( t, s );
128         s = copyString( s, "." );
129         for ( unsigned i = 0; i < DIGITS_ON_RIGHT; ++ i )
130             s = numberToString( (unsigned)(t *= BASE) % BASE, s );
131     }
132 
doubleToString(double t,char * s)133     char *ValueTraits<const double>::doubleToString( double t, char *s )
134     {
135         return numberToString<double>( t, s );
136     }
137 #endif // !CXXTEST_USER_VALUE_TRAITS
138 };
139 
140 #endif // __cxxtest__ValueTraits_cpp__
141