1 /*
2  *  ppui/Tools.cpp
3  *
4  *  Copyright 2009 Peter Barth
5  *
6  *  This file is part of Milkytracker.
7  *
8  *  Milkytracker is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  Milkytracker is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with Milkytracker.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include "Tools.h"
24 
25 const char PPTools::hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
26 
getHexNumDigits(pp_uint32 value)27 pp_uint32 PPTools::getHexNumDigits(pp_uint32 value)
28 {
29 	if (value == 0 || (signed)value < 0)
30 		return 1;
31 
32 	pp_uint32 i = 0;
33 	while (value >> i*4)
34 		i++;
35 
36 	return i;
37 }
38 
convertToHex(char * name,pp_uint32 value,pp_uint32 numDigits)39 void PPTools::convertToHex(char* name, pp_uint32 value, pp_uint32 numDigits)
40 {
41 	pp_uint32 i;
42 	for (i = 0; i < numDigits; i++)
43 		name[i] = hex[((value>>(numDigits-1-i)*4)&0xF)];
44 
45 	name[i] = 0;
46 }
47 
getDecNumDigits(pp_uint32 value)48 pp_uint32 PPTools::getDecNumDigits(pp_uint32 value)
49 {
50 	if (value == 0)
51 		return 1;
52 
53 	pp_uint32 i = 0;
54 	pp_uint32 start = 1;
55 	while (value / start)
56 	{
57 		i++;
58 		start*=10;
59 	}
60 
61 	return i;
62 }
63 
convertToDec(char * name,pp_uint32 value,pp_uint32 numDigits)64 void PPTools::convertToDec(char* name, pp_uint32 value, pp_uint32 numDigits)
65 {
66 	pp_uint32 i;
67 	pp_uint32 start = 1;
68 	for (i = 0; i < numDigits-1; i++)
69 		start*=10;
70 
71 	for (i = 0; i < numDigits; i++)
72 	{
73 		name[i] = hex[(value / start)%10];
74 		start/=10;
75 	}
76 
77 	name[i] = 0;
78 }
79 
80 // you're responsible for deleting this vector
extractStringList(const PPString & str)81 PPSimpleVector<PPString>* PPTools::extractStringList(const PPString& str)
82 {
83 	PPSimpleVector<PPString>* stringList = new PPSimpleVector<PPString>();
84 
85 	const char* sz = str;
86 
87 	PPString* line = new PPString();
88 
89 	while (*sz)
90 	{
91 		if (*sz == '\n')
92 		{
93 			stringList->add(line);
94 			line = new PPString();
95 		}
96 		else
97 		{
98 			line->append(*sz);
99 		}
100 		sz++;
101 	}
102 
103 	if (!line->length())
104 		delete line;
105 	else
106 		stringList->add(line);
107 
108 	return stringList;
109 }
110 
encodeByteArray(const pp_uint8 * array,pp_uint32 size)111 PPString PPTools::encodeByteArray(const pp_uint8* array, pp_uint32 size)
112 {
113 	char buffer[10];
114 
115 	// Convert number of bytes
116 	convertToHex(buffer, size, 8);
117 
118 	PPString str = buffer;
119 
120 	for (pp_uint32 i = 0; i < size; i++)
121 	{
122 		convertToHex(buffer, array[i], 2);
123 		str.append(buffer);
124 	}
125 
126 	return str;
127 }
128 
getNibble(const char * str)129 pp_uint8 PPTools::getNibble(const char* str)
130 {
131 	if (*str >= '0' && *str <= '9')
132 		return (*str - '0');
133 	if (*str >= 'A' && *str <= 'F')
134 		return (*str - 'A' + 10);
135 	if (*str >= 'a' && *str <= 'f')
136 		return (*str - 'a' + 10);
137 
138 	return 0;
139 }
140 
getByte(const char * str)141 pp_uint8 PPTools::getByte(const char* str)
142 {
143 	return (getNibble(str)<<4) + getNibble(str+1);
144 }
145 
getWord(const char * str)146 pp_uint16 PPTools::getWord(const char* str)
147 {
148 	return (getByte(str)<<8) + getByte(str+2);
149 }
150 
getDWord(const char * str)151 pp_uint32 PPTools::getDWord(const char* str)
152 {
153 	return (getWord(str)<<16) + getWord(str+4);
154 }
155 
decodeByteArray(pp_uint8 * array,pp_uint32 size,const PPString & str)156 bool PPTools::decodeByteArray(pp_uint8* array, pp_uint32 size, const PPString& str)
157 {
158 	const char* ptr = str;
159 
160 	pp_uint32 length = getDWord(ptr);
161 
162 	if (length != size)
163 		return false;
164 
165 	ptr+=8;
166 
167 	for (pp_uint32 i = 0; i < length; i++)
168 	{
169 		*array++ = getByte(ptr);
170 		ptr+=2;
171 	}
172 
173 	return true;
174 }
175 
clamp(pp_int32 a,pp_int32 min,pp_int32 max)176 pp_int32 PPTools::clamp(pp_int32 a, pp_int32 min, pp_int32 max)
177 {
178 	return (a < min ? min : (a >= max ? max-1 : a));
179 }
180 
181