Subversion Repositories HomeAutomation

Rev

Rev 1227 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1227 Rev 1380
1
 
1
 
2
#include <string>
2
#include <string>
3
 
3
 
4
/***************************************************************************
4
/***************************************************************************
5
 *   Copyright (C) 2004 by Mattias Runge                                   *
5
 *   Copyright (C) 2004 by Mattias Runge                                   *
6
 *   mattias@mrunge.se                                                     *
6
 *   mattias@mrunge.se                                                     *
7
 *                                                                         *
7
 *                                                                         *
8
 *   This program is free software; you can redistribute it and/or modify  *
8
 *   This program is free software; you can redistribute it and/or modify  *
9
 *   it under the terms of the GNU General Public License as published by  *
9
 *   it under the terms of the GNU General Public License as published by  *
10
 *   the Free Software Foundation; either version 2 of the License, or     *
10
 *   the Free Software Foundation; either version 2 of the License, or     *
11
 *   (at your option) any later version.                                   *
11
 *   (at your option) any later version.                                   *
12
 *                                                                         *
12
 *                                                                         *
13
 *   This program is distributed in the hope that it will be useful,       *
13
 *   This program is distributed in the hope that it will be useful,       *
14
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16
 *   GNU General Public License for more details.                          *
16
 *   GNU General Public License for more details.                          *
17
 *                                                                         *
17
 *                                                                         *
18
 *   You should have received a copy of the GNU General Public License     *
18
 *   You should have received a copy of the GNU General Public License     *
19
 *   along with this program; if not, write to the                         *
19
 *   along with this program; if not, write to the                         *
20
 *   Free Software Foundation, Inc.,                                       *
20
 *   Free Software Foundation, Inc.,                                       *
21
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
21
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
22
 ***************************************************************************/
22
 ***************************************************************************/
23
#include "tools.h"
23
#include "tools.h"
24
 
24
 
25
string niceTime()
25
string niceTime()
26
{
26
{
27
    string result;
27
    string result;
28
    struct tm tmStruct;
28
    struct tm tmStruct;
29
    time_t t = time(NULL);
29
    time_t t = time(NULL);
30
    localtime_r(&t, &tmStruct);
30
    localtime_r(&t, &tmStruct);
31
 
31
 
32
    result += lpad(itos(tmStruct.tm_hour), 2, '0');
32
    result += lpad(itos(tmStruct.tm_hour), 2, '0');
33
    result += ":";
33
    result += ":";
34
    result += lpad(itos(tmStruct.tm_min), 2, '0');
34
    result += lpad(itos(tmStruct.tm_min), 2, '0');
35
    result += ":";
35
    result += ":";
36
    result += lpad(itos(tmStruct.tm_sec), 2, '0');
36
    result += lpad(itos(tmStruct.tm_sec), 2, '0');
37
 
37
 
38
    return result;
38
    return result;
39
}
39
}
40
 
40
 
41
unsigned int hex2uint(string hex)
41
unsigned int hex2uint(string hex)
42
{
42
{
43
    return bin2uint(hex2bin(hex));
43
    return bin2uint(hex2bin(hex));
44
}
44
}
45
 
45
 
46
unsigned int bin2uint(string bin)
46
unsigned int bin2uint(string bin)
47
{
47
{
48
    unsigned int num = 0;
48
    unsigned int num = 0;
49
 
49
 
50
    for (int n = bin.length()-1; n >= 0; n--)
50
    for (int n = bin.length()-1; n >= 0; n--)
51
    {
51
    {
52
        if (bin[n] == '1')
52
        if (bin[n] == '1')
53
            num += (unsigned int)pow(2.0f, (int)(bin.length()-1-n));
53
            num += (unsigned int)pow(2.0f, (int)(bin.length()-1-n));
54
    }
54
    }
55
 
55
 
-
 
56
    return num;
-
 
57
}
-
 
58
 
-
 
59
int bin2int(string bin)
-
 
60
{
-
 
61
    int num = 0;
-
 
62
    if (bin[0] == '1') {
-
 
63
        for (int n = bin.length()-1; n >= 0; n--)
-
 
64
        {
-
 
65
            if (bin[n] == '0')
-
 
66
                num += (unsigned int)pow(2.0f, (int)(bin.length()-1-n));
-
 
67
        }
-
 
68
    num = (num*(-1)) -1;
-
 
69
    } else {
-
 
70
        for (int n = bin.length()-1; n >= 0; n--)
-
 
71
        {
-
 
72
            if (bin[n] == '1')
-
 
73
                num += (unsigned int)pow(2.0f, (int)(bin.length()-1-n));
-
 
74
        }
-
 
75
    }
56
    return num;
76
    return num;
57
}
77
}
58
 
78
 
59
string invert(string bin)
79
string invert(string bin)
60
{
80
{
61
    string inverted;
81
    string inverted;
62
 
82
 
63
    for (int n = 0; n < bin.length(); n++)
83
    for (int n = 0; n < bin.length(); n++)
64
        inverted += (bin[n] == '1' ? '0' : '1');
84
        inverted += (bin[n] == '1' ? '0' : '1');
65
 
85
 
66
    return inverted;
86
    return inverted;
67
}
87
}
68
 
88
 
69
float bin2float(string bin)
89
float bin2float(string bin)
70
{
90
{
71
    float num = 0;
91
    float num = 0;
72
 
92
 
73
    if (bin.length() == 0)
93
    if (bin.length() == 0)
74
        return 0.0f;
94
        return 0.0f;
75
 
95
 
76
    bool isNegative = false;;
96
    bool isNegative = false;;
77
 
97
 
78
    if (bin[0] == '1')
98
    if (bin[0] == '1')
79
    {
99
    {
80
        bin = invert(bin);
100
        bin = invert(bin);
81
        isNegative = true;
101
        isNegative = true;
82
    }
102
    }
83
 
103
 
84
    for (int n = bin.length()-1; n > 0; n--)
104
    for (int n = bin.length()-1; n > 0; n--)
85
    {
105
    {
86
        if (bin[n] == '1')
106
        if (bin[n] == '1')
87
            num += pow(2.0f, (int)(bin.length()-1-n));
107
            num += pow(2.0f, (int)(bin.length()-1-n));
88
    }
108
    }
89
 
109
 
90
    num /= 64.0f;
110
    num /= 64.0f;
91
 
111
 
92
    if (isNegative)
112
    if (isNegative)
93
        num = -num;
113
        num = -num;
94
 
114
 
95
    return num;
115
    return num;
96
}
116
}
97
 
117
 
98
string bin2hex(string bin)
118
string bin2hex(string bin)
99
{
119
{
100
    string hex;
120
    string hex;
101
 
121
 
102
    while (bin.size() > 0)
122
    while (bin.size() > 0)
103
    {
123
    {
104
        string part;
124
        string part;
105
 
125
 
106
        try
126
        try
107
        {
127
        {
108
            part = bin.substr(0, 4);
128
            part = bin.substr(0, 4);
109
        }
129
        }
110
        catch (std::out_of_range& e)
130
        catch (std::out_of_range& e)
111
        {
131
        {
112
            cout << "DEBUG: bin2hex exception: " << e.what() << "\n";
132
            cout << "DEBUG: bin2hex exception: " << e.what() << "\n";
113
            cout << "DEBUG: A bin=" << bin << endl;
133
            cout << "DEBUG: A bin=" << bin << endl;
114
            continue;
134
            continue;
115
        }
135
        }
116
       
136
       
117
        bin.erase(0, part.size());
137
        bin.erase(0, part.size());
118
 
138
 
119
        while (part.size() < 4)
139
        while (part.size() < 4)
120
            part = "0" + part;
140
            part = "0" + part;
121
 
141
 
122
        if (part == "0000")
142
        if (part == "0000")
123
            hex += '0';
143
            hex += '0';
124
        else if (part == "0001")
144
        else if (part == "0001")
125
            hex += '1';
145
            hex += '1';
126
        else if (part == "0010")
146
        else if (part == "0010")
127
            hex += '2';
147
            hex += '2';
128
        else if (part == "0011")
148
        else if (part == "0011")
129
            hex += '3';
149
            hex += '3';
130
        else if (part == "0100")
150
        else if (part == "0100")
131
            hex += '4';
151
            hex += '4';
132
        else if (part == "0101")
152
        else if (part == "0101")
133
            hex += '5';
153
            hex += '5';
134
        else if (part == "0110")
154
        else if (part == "0110")
135
            hex += '6';
155
            hex += '6';
136
        else if (part == "0111")
156
        else if (part == "0111")
137
            hex += '7';
157
            hex += '7';
138
        else if (part == "1000")
158
        else if (part == "1000")
139
            hex += '8';
159
            hex += '8';
140
        else if (part == "1001")
160
        else if (part == "1001")
141
            hex += '9';
161
            hex += '9';
142
        else if (part == "1010")
162
        else if (part == "1010")
143
            hex += 'a';
163
            hex += 'a';
144
        else if (part == "1011")
164
        else if (part == "1011")
145
            hex += 'b';
165
            hex += 'b';
146
        else if (part == "1100")
166
        else if (part == "1100")
147
            hex += 'c';
167
            hex += 'c';
148
        else if (part == "1101")
168
        else if (part == "1101")
149
            hex += 'd';
169
            hex += 'd';
150
        else if (part == "1110")
170
        else if (part == "1110")
151
            hex += 'e';
171
            hex += 'e';
152
        else if (part == "1111")
172
        else if (part == "1111")
153
            hex += 'f';
173
            hex += 'f';
154
    }
174
    }
155
 
175
 
156
    return hex;
176
    return hex;
157
}
177
}
158
 
178
 
159
string float2bin(float num, int length)
179
string float2bin(float num, int length)
160
{
180
{
-
 
181
    // This is 16 bits, 6 bits is the decimal
161
    string bin;
182
    string bin;
162
 
-
 
163
    ///FIXME
183
    num = num*64;
164
 
-
 
165
    while (bin.size() < length)
-
 
166
        bin = "0" + bin;
184
    int16_t temp = (int16_t)num;
167
 
-
 
168
    return bin;
185
    return int2bin(temp, length);
169
}
186
}
170
 
187
 
171
string hex2bin(string hex)
188
string hex2bin(string hex)
172
{
189
{
173
    hex = strtolower(hex);
190
    hex = strtolower(hex);
174
 
191
 
175
    string bin;
192
    string bin;
176
 
193
 
177
    for (int n = 0; n < hex.length(); n++)
194
    for (int n = 0; n < hex.length(); n++)
178
    {
195
    {
179
        switch (hex[n])
196
        switch (hex[n])
180
        {
197
        {
181
            case '0': bin += "0000"; break;
198
            case '0': bin += "0000"; break;
182
            case '1': bin += "0001"; break;
199
            case '1': bin += "0001"; break;
183
            case '2': bin += "0010"; break;
200
            case '2': bin += "0010"; break;
184
            case '3': bin += "0011"; break;
201
            case '3': bin += "0011"; break;
185
            case '4': bin += "0100"; break;
202
            case '4': bin += "0100"; break;
186
            case '5': bin += "0101"; break;
203
            case '5': bin += "0101"; break;
187
            case '6': bin += "0110"; break;
204
            case '6': bin += "0110"; break;
188
            case '7': bin += "0111"; break;
205
            case '7': bin += "0111"; break;
189
            case '8': bin += "1000"; break;
206
            case '8': bin += "1000"; break;
190
            case '9': bin += "1001"; break;
207
            case '9': bin += "1001"; break;
191
            case 'a': bin += "1010"; break;
208
            case 'a': bin += "1010"; break;
192
            case 'b': bin += "1011"; break;
209
            case 'b': bin += "1011"; break;
193
            case 'c': bin += "1100"; break;
210
            case 'c': bin += "1100"; break;
194
            case 'd': bin += "1101"; break;
211
            case 'd': bin += "1101"; break;
195
            case 'e': bin += "1110"; break;
212
            case 'e': bin += "1110"; break;
196
            case 'f': bin += "1111"; break;
213
            case 'f': bin += "1111"; break;
197
        }
214
        }
198
    }
215
    }
199
 
216
 
200
    return bin;
217
    return bin;
201
}
218
}
202
 
219
 
203
string uint2bin(unsigned int num, int length)
220
string uint2bin(unsigned int num, int length)
204
{
221
{
-
 
222
    string bin;
-
 
223
    while (num)
-
 
224
    {
-
 
225
        bin = char((num&1)+'0') + bin;
-
 
226
        num >>= 1;
-
 
227
    }
-
 
228
 
-
 
229
    while (bin.size() < length)
-
 
230
        bin = "0" + bin;
-
 
231
   
-
 
232
    string bin2;
-
 
233
    for (int i = 0; i < length; i++)
-
 
234
    {
-
 
235
        bin2 = bin2 + bin[i];
-
 
236
    }
-
 
237
   
-
 
238
    return bin2;
-
 
239
}
-
 
240
 
-
 
241
string int2bin(int num, int length)
-
 
242
{
205
    string bin;
243
    string bin;
-
 
244
    if (num < 0) {
-
 
245
    num *= -1;
-
 
246
    num -= 1;
-
 
247
    while (num)
-
 
248
    {
-
 
249
        bin = char((num&1)+'0') + bin;
-
 
250
        num >>= 1;
-
 
251
    }
-
 
252
 
-
 
253
    while (bin.size() < length)
-
 
254
        bin = "0" + bin;
-
 
255
    for (int i = 0; i < length; i++)
-
 
256
    {
-
 
257
        if (bin[i] == '0')
-
 
258
            bin[i] = '1';
-
 
259
        else
-
 
260
            bin[i] = '0';
-
 
261
    }
-
 
262
} else {
206
    while (num)
263
    while (num)
207
    {
264
    {
208
        bin = char((num&1)+'0') + bin;
265
        bin = char((num&1)+'0') + bin;
209
        num >>= 1;
266
        num >>= 1;
210
    }
267
    }
211
 
268
 
212
    while (bin.size() < length)
269
    while (bin.size() < length)
213
        bin = "0" + bin;
270
        bin = "0" + bin;
-
 
271
 
214
   
272
}
215
    string bin2;
273
    string bin2;
216
    for (int i = 0; i < length; i++)
274
    for (int i = 0; i < length; i++)
217
    {
275
    {
218
        bin2 = bin2 + bin[i];
276
        bin2 = bin2 + bin[i];
219
    }
277
    }
220
   
278
   
221
    return bin2;
279
    return bin2;
-
 
280
}
-
 
281
 
-
 
282
string int2hex(int num, int length)
-
 
283
{
-
 
284
    return bin2hex(int2bin(num, length));
222
}
285
}
223
 
286
 
224
string uint2hex(unsigned int num, int length)
287
string uint2hex(unsigned int num, int length)
225
{
288
{
226
    return bin2hex(uint2bin(num, length));
289
    return bin2hex(uint2bin(num, length));
227
}
290
}
228
 
291
 
229
vector<string> explode(string delimiter, string str)
292
vector<string> explode(string delimiter, string str)
230
{
293
{
231
    vector<string> parts;
294
    vector<string> parts;
232
    string::size_type startPos = 0;
295
    string::size_type startPos = 0;
233
    string::size_type endPos = 0;
296
    string::size_type endPos = 0;
234
 
297
 
235
    while ((endPos = str.find(delimiter, startPos)) != string::npos)
298
    while ((endPos = str.find(delimiter, startPos)) != string::npos)
236
    {
299
    {
237
        try
300
        try
238
        {
301
        {
239
            parts.push_back(str.substr(startPos, endPos-startPos));
302
            parts.push_back(str.substr(startPos, endPos-startPos));
240
        }
303
        }
241
        catch (std::out_of_range& e)
304
        catch (std::out_of_range& e)
242
        {
305
        {
243
            cout << "DEBUG: explode exception: " << e.what() << "\n";
306
            cout << "DEBUG: explode exception: " << e.what() << "\n";
244
            cout << "DEBUG: A str=" << str << " :: startPos=" << startPos << " :: endPos=" << endPos << endl;
307
            cout << "DEBUG: A str=" << str << " :: startPos=" << startPos << " :: endPos=" << endPos << endl;
245
            continue;
308
            continue;
246
        }
309
        }
247
       
310
       
248
        startPos = endPos+delimiter.length();
311
        startPos = endPos+delimiter.length();
249
    }
312
    }
250
 
313
 
251
    if (startPos < str.length())
314
    if (startPos < str.length())
252
    {
315
    {
253
        try
316
        try
254
        {
317
        {
255
            parts.push_back(str.substr(startPos, str.length()-startPos));
318
            parts.push_back(str.substr(startPos, str.length()-startPos));
256
        }
319
        }
257
        catch (std::out_of_range& e)
320
        catch (std::out_of_range& e)
258
        {
321
        {
259
            cout << "DEBUG: explode exception: " << e.what() << "\n";
322
            cout << "DEBUG: explode exception: " << e.what() << "\n";
260
            cout << "DEBUG: B str=" << str << " :: startPos=" << startPos << " :: endPos=" << endPos << endl;
323
            cout << "DEBUG: B str=" << str << " :: startPos=" << startPos << " :: endPos=" << endPos << endl;
261
        }
324
        }
262
    }
325
    }
263
 
326
 
264
    return parts;
327
    return parts;
265
}
328
}
266
 
329
 
267
string strtoupper(string s)
330
string strtoupper(string s)
268
{
331
{
269
    for (unsigned int n = 0; n < s.size(); n++)
332
    for (unsigned int n = 0; n < s.size(); n++)
270
        s[n] = (char)toupper(s[n]);
333
        s[n] = (char)toupper(s[n]);
271
 
334
 
272
    return s;
335
    return s;
273
}
336
}
274
 
337
 
275
string strtolower(string s)
338
string strtolower(string s)
276
{
339
{
277
    for (unsigned int n = 0; n < s.size(); n++)
340
    for (unsigned int n = 0; n < s.size(); n++)
278
        s[n] = (char)tolower(s[n]);
341
        s[n] = (char)tolower(s[n]);
279
 
342
 
280
    return s;
343
    return s;
281
}
344
}
282
 
345
 
283
string trim(string s)
346
string trim(string s)
284
{
347
{
285
    return trim(s, ' ');
348
    return trim(s, ' ');
286
}
349
}
287
 
350
 
288
string trim(const string s, char c)
351
string trim(const string s, char c)
289
{
352
{
290
    string result = s;
353
    string result = s;
291
    while (result[0] == c)
354
    while (result[0] == c)
292
        result.erase(0, 1);
355
        result.erase(0, 1);
293
 
356
 
294
    while (result[result.length()-1] == c)
357
    while (result[result.length()-1] == c)
295
        result.erase(result.length()-1, 1);
358
        result.erase(result.length()-1, 1);
296
 
359
 
297
    return result;
360
    return result;
298
}
361
}
299
 
362
 
300
int stoi(const string s)
363
int stoi(const string s)
301
{
364
{
302
    istringstream in(s);
365
    istringstream in(s);
303
    int i;
366
    int i;
304
    in >> i;
367
    in >> i;
305
    return i;
368
    return i;
306
}
369
}
307
 
370
 
308
string itos(int i)
371
string itos(int i)
309
{
372
{
310
    ostringstream out;
373
    ostringstream out;
311
    out << i;
374
    out << i;
312
    return out.str();
375
    return out.str();
313
}
376
}
314
 
377
 
315
unsigned int stou(const string s)
378
unsigned int stou(const string s)
316
{
379
{
317
    istringstream in(s);
380
    istringstream in(s);
318
    unsigned int i;
381
    unsigned int i;
319
    in >> i;
382
    in >> i;
320
    return i;
383
    return i;
321
}
384
}
322
 
385
 
323
string utos(unsigned int i)
386
string utos(unsigned int i)
324
{
387
{
325
    ostringstream out;
388
    ostringstream out;
326
    out << i;
389
    out << i;
327
    return out.str();
390
    return out.str();
328
}
391
}
329
 
392
 
330
float stof(const string s)
393
float stof(const string s)
331
{
394
{
332
    istringstream in(s);
395
    istringstream in(s);
333
    float f;
396
    float f;
334
    in >> f;
397
    in >> f;
335
    return f;
398
    return f;
336
}
399
}
337
 
400
 
338
string ftos(float f)
401
string ftos(float f)
339
{
402
{
340
    ostringstream out;
403
    ostringstream out;
341
    out << f;
404
    out << f;
342
    return out.str();
405
    return out.str();
343
}
406
}
344
 
407
 
345
string str_replace(string search, string replace, string str)
408
string str_replace(string search, string replace, string str)
346
{
409
{
347
    vector<string> parts = explode(search, str);
410
    vector<string> parts = explode(search, str);
348
 
411
 
349
    string result;
412
    string result;
350
    for (int n = 0; n < parts.size(); n++)
413
    for (int n = 0; n < parts.size(); n++)
351
    {
414
    {
352
        result += parts[n];
415
        result += parts[n];
353
 
416
 
354
        if (n < parts.size()-1)
417
        if (n < parts.size()-1)
355
            result += replace;
418
            result += replace;
356
    }
419
    }
357
 
420
 
358
    return result;
421
    return result;
359
}
422
}
360
 
423
 
361
string file_get_contents(string filename)
424
string file_get_contents(string filename)
362
{
425
{
363
    ifstream srcfile(filename.c_str());
426
    ifstream srcfile(filename.c_str());
364
 
427
 
365
    if (!srcfile.is_open())
428
    if (!srcfile.is_open())
366
    {
429
    {
367
        srcfile.close();
430
        srcfile.close();
368
        return "";
431
        return "";
369
    }
432
    }
370
 
433
 
371
    string buffer = "";
434
    string buffer = "";
372
    string line;
435
    string line;
373
 
436
 
374
    while (!srcfile.eof())
437
    while (!srcfile.eof())
375
    {
438
    {
376
        getline(srcfile, line);
439
        getline(srcfile, line);
377
 
440
 
378
        if (srcfile.eof())
441
        if (srcfile.eof())
379
            break;
442
            break;
380
       
443
       
381
        buffer += line + "\n";
444
        buffer += line + "\n";
382
    };
445
    };
383
 
446
 
384
    srcfile.close();
447
    srcfile.close();
385
 
448
 
386
    return buffer;
449
    return buffer;
387
}
450
}
388
 
451
 
389
bool file_exists(string filename)
452
bool file_exists(string filename)
390
{
453
{
391
    ifstream file(filename.c_str());
454
    ifstream file(filename.c_str());
392
    if (file.is_open())
455
    if (file.is_open())
393
    {
456
    {
394
        file.close();
457
        file.close();
395
        return true;
458
        return true;
396
    }
459
    }
397
 
460
 
398
    return false;
461
    return false;
399
}
462
}
400
 
463
 
401
string escape(string in)
464
string escape(string in)
402
{
465
{
403
    string out;
466
    string out;
404
 
467
 
405
    for (int n = 0; n < in.length(); n++)
468
    for (int n = 0; n < in.length(); n++)
406
    {
469
    {
407
        switch (in[n])
470
        switch (in[n])
408
        {
471
        {
409
            case '\r':
472
            case '\r':
410
                break;
473
                break;
411
 
474
 
412
            case '\n':
475
            case '\n':
413
                out += "\\n";
476
                out += "\\n";
414
                break;
477
                break;
415
 
478
 
416
            case '\'':
479
            case '\'':
417
                out += "\\'";
480
                out += "\\'";
418
                break;
481
                break;
419
 
482
 
420
            case '"':
483
            case '"':
421
                out += "\\\"";
484
                out += "\\\"";
422
                break;
485
                break;
423
 
486
 
424
            default:
487
            default:
425
                out += in[n];
488
                out += in[n];
426
                break;
489
                break;
427
        }
490
        }
428
    }
491
    }
429
 
492
 
430
    return out;
493
    return out;
431
}
494
}
432
 
495
 
433
string rpad(string in, int length, char c)
496
string rpad(string in, int length, char c)
434
{
497
{
435
    while (in.length() < length)
498
    while (in.length() < length)
436
    {
499
    {
437
        in += c;
500
        in += c;
438
    }
501
    }
439
 
502
 
440
    return in;
503
    return in;
441
}
504
}
442
 
505
 
443
string lpad(string in, int length, char c)
506
string lpad(string in, int length, char c)
444
{
507
{
445
    while (in.length() < length)
508
    while (in.length() < length)
446
    {
509
    {
447
        in = c + in;
510
        in = c + in;
448
    }
511
    }
449
 
512
 
450
    return in;
513
    return in;
451
}
514
}
452
 
515