vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[ |
2 | -- |
||
3 | -- Sea.string |
||
4 | -- |
||
5 | -- String manipulation functions |
||
6 | -- |
||
7 | -- $LastChangedBy: karlkfi $ |
||
8 | -- $Rev: 3520 $ |
||
9 | -- $Date: 2006-05-07 18:21:39 -0500 (Sun, 07 May 2006) $ |
||
10 | --]] |
||
11 | |||
12 | --Compatible with the following Mini-Libs |
||
13 | Sea.versions.SeaString = 0.11; -- SeaString |
||
14 | |||
15 | Sea.string = { |
||
16 | |||
17 | -- |
||
18 | -- byte(string) |
||
19 | -- |
||
20 | -- Converts a character to its bytecode |
||
21 | -- |
||
22 | -- Args: |
||
23 | -- string - the string |
||
24 | -- |
||
25 | -- Returns: |
||
26 | -- (string) |
||
27 | -- string - the string in byte code with format <##> |
||
28 | -- |
||
29 | byte = function(c) |
||
30 | return string.format("<%02X>",string.byte(c)); |
||
31 | end; |
||
32 | |||
33 | -- |
||
34 | -- byteSum (string s) |
||
35 | -- returns the bytecode sum for s |
||
36 | -- |
||
37 | -- Args: |
||
38 | -- s - the string |
||
39 | -- |
||
40 | -- Returns: |
||
41 | -- (number) |
||
42 | -- number - the value of the string with all of its |
||
43 | -- chars summed together. |
||
44 | -- |
||
45 | -- Recoded by Iriel (iriel@vigilance-committee.org) for performance |
||
46 | byteSum = function(s) |
||
47 | local sum = 0; |
||
48 | local len = string.len(s); |
||
49 | local sbyte = string.byte; |
||
50 | for i=1,len do |
||
51 | sum = sum + sbyte(s,i); |
||
52 | end |
||
53 | return sum; |
||
54 | end; |
||
55 | |||
56 | -- |
||
57 | -- toInt (string s) |
||
58 | -- |
||
59 | -- Converts the specified string to an int |
||
60 | -- |
||
61 | -- Returns: |
||
62 | -- (Number int) |
||
63 | -- int - the string S as a number |
||
64 | -- |
||
65 | toInt = tonumber; |
||
66 | |||
67 | -- |
||
68 | -- fromTime(Number time, Number decimalplaces) |
||
69 | -- |
||
70 | -- Creates a readable time from a number time in WoW |
||
71 | -- Decimal places gives the number of .### to display |
||
72 | -- |
||
73 | -- Returns: |
||
74 | -- (String timeString) |
||
75 | -- timeString - the time |
||
76 | -- |
||
77 | -- Recoded by Iriel (iriel@vigilance-committee.org) for performance |
||
78 | fromTime = function (time, decimalplaces) |
||
79 | if (time < 0) then |
||
80 | time = 0; |
||
81 | end |
||
82 | if ( not decimalplaces ) then |
||
83 | decimalplaces = 0; |
||
84 | end |
||
85 | |||
86 | local floor = math.floor; |
||
87 | local mod = math.mod; |
||
88 | |||
89 | local seconds = mod(time, 60); |
||
90 | local minutes = mod(floor(time/60), 60); |
||
91 | local hours = floor(time/(3600)); |
||
92 | local spfx = ''; |
||
93 | if (seconds < 10) then |
||
94 | spfx = '0'; |
||
95 | end |
||
96 | |||
97 | if (hours > 0) then |
||
98 | return string.format("%d:%.2d:%s%."..decimalplaces.."f", hours, minutes, spfx, seconds); |
||
99 | else |
||
100 | return string.format("%d:%s%."..decimalplaces.."f", minutes, spfx, seconds); |
||
101 | end |
||
102 | end; |
||
103 | |||
104 | --getglobal("ARCANEBAR_"..types[i].."COLOR_SET"); |
||
105 | -- capitalizeWords(String phrase) |
||
106 | -- |
||
107 | -- Takes a string like "hello world" and turns |
||
108 | -- it into "Hello World". |
||
109 | -- |
||
110 | -- Returns: |
||
111 | -- (String capitalizedPhrase) |
||
112 | -- |
||
113 | |||
114 | capitalizeWords = function ( text ) |
||
115 | if (not text) then |
||
116 | return text; |
||
117 | end |
||
118 | local capitalizedPhrase = ""; |
||
119 | local value, mend; |
||
120 | local mstart = 1; |
||
121 | local regexKey = "([^%s]+[%s]*)"; |
||
122 | local sfind = strfind; -- string.find if not in WoW (n calls) |
||
123 | local supper = strupper; |
||
124 | local slower = strlower; |
||
125 | local ssub = strsub; |
||
126 | |||
127 | -- Using string.find instead of string.gfind to avoid garbage generation |
||
128 | mstart, mend, value = sfind(text, regexKey, mstart); |
||
129 | while (value) do |
||
130 | if( sfind(text, "^[a-zA-Z].*") ) then |
||
131 | capitalizedPhrase = capitalizedPhrase..supper(ssub(value,1,1))..slower(ssub(value,2)); |
||
132 | else |
||
133 | capitalizedPhrase = capitalizedPhrase..supper(ssub(value,1,2))..slower(ssub(value,3)); |
||
134 | end |
||
135 | mstart = mend + 1; |
||
136 | mstart, mend, value = sfind(text, regexKey, mstart); |
||
137 | end |
||
138 | |||
139 | return capitalizedPhrase; |
||
140 | end; |
||
141 | |||
142 | |||
143 | -- |
||
144 | -- objectToString( value, [name] ) |
||
145 | -- |
||
146 | -- Converts a value to a serialized string. |
||
147 | -- Cannot serialize functions. |
||
148 | -- |
||
149 | -- returns: |
||
150 | -- A string which represents the object, |
||
151 | -- minus functions. |
||
152 | -- |
||
153 | -- |
||
154 | objectToString = function( value, name ) |
||
155 | local output = ""; |
||
156 | |||
157 | if ( name == nil ) then name = ""; |
||
158 | else |
||
159 | -- Serialize the name |
||
160 | name = Sea.string.objectToString(name); |
||
161 | -- Remove the <> |
||
162 | name = string.gsub(name, "<(.*)>", "%1"); |
||
163 | end |
||
164 | |||
165 | if (type(value) == "nil" ) then |
||
166 | output = name.."<".."nil:nil"..">"; |
||
167 | elseif ( type(value) == "string" ) then |
||
168 | value = string.gsub(value, "<", "<"); |
||
169 | value = string.gsub(value, ">", ">"); |
||
170 | output = name.."<".."s:"..value..">"; |
||
171 | elseif ( type(value) == "number" ) then |
||
172 | output = name.."<".."n:"..value..">"; |
||
173 | elseif ( type(value) == "boolean" ) then |
||
174 | if ( value ) then |
||
175 | output = name.."<".."b:".."true"..">"; |
||
176 | else |
||
177 | output = name.."<".."b:".."false"..">"; |
||
178 | end |
||
179 | elseif ( type(value) == "function" ) then |
||
180 | output = name.."<".."func:".."*invalid*"..">"; |
||
181 | elseif ( type(value) == "table" ) then |
||
182 | output = name.."<".."t:"; |
||
183 | for k,v in value do |
||
184 | output = output.." "..Sea.string.objectToString(v,k); |
||
185 | end |
||
186 | output = output .. ">"; |
||
187 | end |
||
188 | |||
189 | return output; |
||
190 | end; |
||
191 | |||
192 | -- |
||
193 | -- stringToObject(string) |
||
194 | -- |
||
195 | -- Turns a string serialized by objectToString into |
||
196 | -- and object. |
||
197 | -- |
||
198 | -- returns: |
||
199 | -- nil or number or string or boolean or table |
||
200 | -- |
||
201 | -- |
||
202 | stringToObject = function ( str ) |
||
203 | -- check for the format "keytype:keyvalue<valuetype:value>" |
||
204 | -- take the stuff in <> |
||
205 | typevalue = string.gsub(str, "%s*(%w*:?%w*)%s*(<.*>)","%2"); |
||
206 | |||
207 | local value = nil; |
||
208 | local typeString = string.gsub(typevalue, "<%s*(%w*):(.*)>","%1"); |
||
209 | local valueString = string.gsub(typevalue, "<%s*(%w*):(.*)>","%2"); |
||
210 | |||
211 | |||
212 | --print("str: ", str, " typevalue: ", typevalue); |
||
213 | --print("valueString: (", valueString, ") typeString: (", typeString,")"); |
||
214 | |||
215 | -- Error! |
||
216 | if ( typeString == typevalue ) then |
||
217 | Sea.io.error ( "Unparsable string passed to stringToObject: ", str ); |
||
218 | return nil; |
||
219 | end |
||
220 | |||
221 | -- Maybe no error! |
||
222 | if ( typeString == "nil" ) then |
||
223 | value = nil; |
||
224 | |||
225 | elseif ( typeString == "n" ) then |
||
226 | value = tonumber(valueString); |
||
227 | |||
228 | elseif ( typeString == "b" ) then |
||
229 | if ( valueString == "true" ) then |
||
230 | value = true; |
||
231 | else |
||
232 | value = false; |
||
233 | end |
||
234 | |||
235 | elseif ( typeString == "s" ) then |
||
236 | value = valueString; |
||
237 | -- Parse the <> back in |
||
238 | value = string.gsub(value, "<", "<"); |
||
239 | value = string.gsub(value, ">", ">"); |
||
240 | |||
241 | elseif ( typeString == "f" ) then |
||
242 | -- Functions are not supported, but if they were.. |
||
243 | |||
244 | -- ...this is how it should work |
||
245 | -- value = getglobal(typeString); |
||
246 | value = Sea.io.error; |
||
247 | |||
248 | elseif ( typeString == "t" ) then |
||
249 | -- Here's the hard part |
||
250 | -- I have to extract each set of <> |
||
251 | -- which might have nested tables! |
||
252 | -- |
||
253 | -- So I start off by tracking < until I get 0 |
||
254 | -- |
||
255 | value = {}; |
||
256 | |||
257 | local left = 1; |
||
258 | local right = 1; |
||
259 | |||
260 | local count = 0; |
||
261 | |||
262 | while ( valueString and valueString ~= "" ) do |
||
263 | local object = nil; |
||
264 | local key = nil; |
||
265 | |||
266 | -- Extract the key and convert it |
||
267 | key = string.gsub(valueString, "%s*(%w*:?.-)<.*>", "%1" ); |
||
268 | key = Sea.string.stringToObject("<"..key..">"); |
||
269 | |||
270 | |||
271 | left = string.find(valueString, "<", 1 ); |
||
272 | right = string.find(valueString, ">", 1 ); |
||
273 | |||
274 | if ( left < right ) then |
||
275 | nextleft = string.find(valueString, "<", left+1 ); |
||
276 | while ( nextleft and nextleft < right ) do |
||
277 | nextleft = string.find(valueString, "<", nextleft+1 ); |
||
278 | right = string.find(valueString, ">", right+1 ); |
||
279 | end |
||
280 | else |
||
281 | --error ( "we all die." ); |
||
282 | end |
||
283 | |||
284 | objectString = string.sub(valueString, left, right); |
||
285 | |||
286 | -- Create the object |
||
287 | object = Sea.string.stringToObject(objectString); |
||
288 | |||
289 | -- Add it to the table |
||
290 | value[key] = object; |
||
291 | |||
292 | -- See if there's another entry |
||
293 | valueString = string.sub(valueString, right+1); |
||
294 | end |
||
295 | end |
||
296 | |||
297 | return value; |
||
298 | end; |
||
299 | |||
300 | -- |
||
301 | -- startsWith(String s, String prefix) |
||
302 | -- |
||
303 | -- Looks for 'prefix' at the beginning of 's' |
||
304 | -- |
||
305 | -- Returns: |
||
306 | -- boolean |
||
307 | -- |
||
308 | |||
309 | startsWith = function ( text, prefix ) |
||
310 | if ( strfind(text, "^"..prefix, 1) ) then |
||
311 | return true; |
||
312 | else |
||
313 | return false; |
||
314 | end |
||
315 | end; |
||
316 | |||
317 | -- |
||
318 | -- endsWith(String s, String suffix) |
||
319 | -- |
||
320 | -- Looks for 'suffix' at the end of 's' |
||
321 | -- |
||
322 | -- Returns: |
||
323 | -- boolean |
||
324 | -- |
||
325 | |||
326 | endsWith = function ( text, suffix ) |
||
327 | if ( strfind(text, suffix.."$") ) then |
||
328 | return true; |
||
329 | else |
||
330 | return false; |
||
331 | end |
||
332 | end; |
||
333 | |||
334 | -- |
||
335 | -- colorToString(Table{r,g,b,a}) |
||
336 | -- |
||
337 | -- Converts a table to a Blizzard color code |
||
338 | -- |
||
339 | -- Returns: |
||
340 | -- string |
||
341 | -- The blizzard color code AARRGGBB |
||
342 | -- |
||
343 | -- Recoded by Iriel (iriel@vigilance-committee.org) for performance |
||
344 | colorToString = function ( color ) |
||
345 | if ( not color ) then |
||
346 | return "FFFFFFFF"; |
||
347 | end |
||
348 | return string.format("%.2X%.2X%.2X%.2X", |
||
349 | (color.a or color.opacity or 1) * 255, |
||
350 | (color.r or 0) * 255, |
||
351 | (color.g or 0) * 255, |
||
352 | (color.b or 0) * 255 |
||
353 | ); |
||
354 | end; |
||
355 | |||
356 | -- stringToColor(String colorCode) |
||
357 | -- |
||
358 | -- Converts a Blizzard color code to a table |
||
359 | -- |
||
360 | -- Returns: |
||
361 | -- table{r,g,b,a,opacity} |
||
362 | -- |
||
363 | -- a & opacity are the same thing here (this could change) |
||
364 | -- |
||
365 | stringToColor = function ( colorCode ) |
||
366 | local red, green, blue, alpha = Sea.math.rgbaFromHex( colorCode ); |
||
367 | return { r = red; g = green; b = blue; a = alpha; opacity = alpha }; |
||
368 | end; |
||
369 | }; |