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