]> git.donarmstrong.com Git - lilypond.git/blob - flower/string-convert.cc
release: 0.0.65
[lilypond.git] / flower / string-convert.cc
1 /*
2   PROJECT: FlowerSoft C++ library
3   FILE   : string-convert.cc
4
5 --*/
6
7
8 #include <assert.h>
9 #include <limits.h>
10 #include "libc-extension.hh"
11 #include "string.hh"
12 #include "string-convert.hh"
13
14 /**
15    a safe length for stringconversion buffers
16
17    worst case would be %f printing HUGE (or 1/HUGE), which is approx
18    2e318, this number would have approx 318 zero's in its string.
19
20    Should enlarge buff dynamically.
21    
22    @see
23    man 3 snprintf
24    */
25 static const int STRING_BUFFER_LEN=1024;
26
27 String
28 String_convert::bin2hex_str( String bin_str )
29 {
30     String str;
31     Byte const* byte_C = bin_str.byte_C();
32     for ( int i = 0; i < bin_str.length_i(); i++ ) {
33         str += (char)nibble2hex_byte( *byte_C >> 4 );
34         str += (char)nibble2hex_byte( *byte_C++ );
35     }
36     return str;
37 }
38
39 int
40 String_convert::bin2_i( String bin_str )
41 {
42     assert( bin_str.length_i() <= 4 );
43
44     int result_i = 0;
45     for ( int i = 0; i < bin_str.length_i(); i++ ) {
46         result_i <<= 8;
47         result_i += (Byte)bin_str[ i ];
48     }
49     return result_i;
50 }
51
52 // breendet imp from String
53 int
54 String_convert::dec2_i( String dec_str )
55 {
56     if ( !dec_str.length_i() )
57         return 0;
58
59     long l = 0;
60     int conv = sscanf( dec_str.ch_C(), "%ld", &l );
61     assert( conv );
62
63     return (int)l;
64 }
65
66 String
67 String_convert::i64_str( I64 i64, char const* fmt)
68 {
69     char buffer[STRING_BUFFER_LEN];
70     snprintf(buffer, STRING_BUFFER_LEN,
71              (fmt ? fmt : "%Ld"), i64 );     // assume radix 10
72     return String(buffer);
73
74 }
75 // breendet imp from String
76 double
77 String_convert::dec2_f( String dec_str )
78 {
79     if ( !dec_str.length_i() )
80         return 0;
81     double d = 0;
82     int conv = sscanf( dec_str.ch_C(), "%lf", &d );
83     assert( conv );
84     return d;
85 }
86
87 int
88 String_convert::hex2bin_i( String hex_str, String& bin_str_r )
89 {
90     if ( hex_str.length_i() % 2 )
91         hex_str = "0" + hex_str;
92
93     bin_str_r = "";
94     Byte const* byte_C= hex_str.byte_C();
95     int i = 0;
96     while ( i < hex_str.length_i() ) {   
97         int high_i = hex2nibble_i( *byte_C++ );
98         int low_i = hex2nibble_i( *byte_C++ );
99         if ( high_i < 0 || low_i < 0 )
100             return 1; // illegal char
101         bin_str_r += String( (char)( high_i << 4 | low_i ), 1 );
102         i += 2;
103     }
104     return 0;
105 }
106
107 String 
108 String_convert::hex2bin_str( String hex_str )
109 {
110     String str;
111 //  silly, asserts should alway be "on"!
112 //    assert( !hex2bin_i( hex_str, str ) );
113     int error_i = hex2bin_i( hex_str, str );
114     assert( !error_i );
115     return str;
116 }
117
118 int 
119 String_convert::hex2nibble_i( Byte byte )
120 {
121     if ( byte >= '0' && byte <= '9' )
122         return byte - '0';
123     if ( byte >= 'A' && byte <= 'F' )
124         return byte - 'A' + 10;
125     if ( byte >= 'a' && byte <= 'f')
126         return byte - 'a' + 10;
127     return -1;
128 }
129
130 // stupido.  Should use int_str()
131 String 
132 String_convert::i2dec_str( int i, int length_i, char ch )
133 {
134     char fill_ch = ch;
135     if ( fill_ch)
136         fill_ch = '0';
137
138     // ugh
139     String dec_str( i );
140     
141     // ugh
142     return String( fill_ch, length_i - dec_str.length_i() ) + dec_str;
143 }
144
145
146 // stupido.  Should use int_str()
147 String 
148 String_convert::u2hex_str( unsigned u, int length_i, char fill_ch )
149 {
150     String str;
151     if ( !u )
152         str = "0";
153
154 #if 1 // both go...
155     while ( u ) {
156         str = String( (char)( ( u % 16 )["0123456789abcdef"] ) ) + str;
157         u /= 16;
158     }
159 #else
160     str += int_str( u, "%x" );  // hmm. %lx vs. %x -> portability?
161 #endif
162
163     str = String( fill_ch, length_i - str.length_i() ) + str;
164     while ( ( str.length_i() > length_i ) &&  ( str[ 0 ] == 'f' ) )
165         str = str.mid_str( 2, INT_MAX );
166
167     return str;
168 }
169
170 String 
171 String_convert::i2hex_str( int i, int length_i, char fill_ch )
172 {
173     return u2hex_str( (unsigned)i, length_i, fill_ch );
174 }
175
176 Byte
177 String_convert::nibble2hex_byte( Byte byte )
178 {
179     if ( ( byte & 0x0f ) <= 9 )
180         return ( byte & 0x0f ) + '0';
181     else
182         return ( byte & 0x0f ) - 10 + 'a';
183 }
184 /**
185   Convert an integer to a string
186
187   @param
188   #fmt# is a printf style format, default assumes "%d" as format. 
189   */
190 String
191 String_convert::int_str(int i, char const* fmt)
192 {
193     char buffer[STRING_BUFFER_LEN];
194     snprintf(buffer, STRING_BUFFER_LEN,
195              (fmt ? fmt : "%d"), i );     // assume radix 10
196     return String(buffer);
197 }
198
199 /**
200   Convert a double to a string.
201
202   @param #fmt# is a printf style format, default assumes "%lf" as format
203  */
204 String
205 String_convert::double_str(double f, char const* fmt)
206 {
207     char buf[STRING_BUFFER_LEN]; 
208
209     snprintf(buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f);
210     return buf;
211 }
212
213 /**
214   Make a string from a single character.
215
216   @param
217     #n# is a repetition count, default value is 1
218  */
219 String
220 String_convert::char_str(char c, int n)
221 {
222     n = n >= 0 ? n : 0;
223     char* ch_p = new char[ n ];
224     memset( ch_p, c, n );
225     String s((Byte*)ch_p, n);
226     delete ch_p;
227     return s;
228 }
229
230 String
231 String_convert::rational_str(Rational r)
232 {
233     char * n = Itoa(r.numerator()); // LEAK????
234     
235     String s = n;
236     if (r.denominator() != 1) {
237         char * d = Itoa(r.denominator());
238         s +=  String( '/' ) + String(d);
239         //delete d;
240     }
241 /*    delete n;
242     */
243     return s;
244 }
245
246 String
247 String_convert::pointer_str(void const *l)
248 {
249     char buffer[STRING_BUFFER_LEN];
250     snprintf(buffer, STRING_BUFFER_LEN, "%p", l );     // assume radix 10
251     return String(buffer);
252 }