matchrule.cs wasn't being used anymore; delete.
[versaplex.git] / wvdotnet / wvutils.cs
blobb8729f2077f8486b964857600833fd9e23e02cb7
1 #define DEBUG
2 #define TRACE
4 using System;
5 using System.Collections;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.IO;
9 using System.Security.Cryptography;
10 using System.Text;
11 using System.Threading;
12 using System.Web;
14 namespace Wv
16 public partial class wv
18 public static void sleep(int msec_delay)
20 if (msec_delay < 0)
21 Thread.Sleep(Int32.MaxValue);
22 else
23 Thread.Sleep(msec_delay);
26 public static string shift(ref string[] array, int index)
28 string s = array[index];
29 string[] outa = new string[array.Length-1];
30 Array.Copy(array, 0, outa, 0, index);
31 Array.Copy(array, index+1, outa, index, array.Length-index-1);
32 array = outa;
33 return s;
36 public static string shift(ref string[] array)
38 return shift(ref array, 0);
41 public static void assert(bool b, string msg)
43 if (!b)
44 throw new System.ArgumentException(msg);
47 public static void assert(bool b)
49 assert(b, "Assertion Failure");
52 public static void assert()
54 assert(false);
57 public static DateTime date(object s)
59 try
61 return DateTime.Parse(s.ToString());
63 catch (FormatException)
65 return DateTime.MinValue;
69 public static string httpdate(DateTime d)
71 return d.ToUniversalTime()
72 .ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
75 static string intclean(object o, bool allow_dot)
77 if (o == null) return "0";
79 // All this nonsense is to make it so that we can parse
80 // strings a little more liberally. Double.Parse() would
81 // give up in case of invalid characters; we just ignore
82 // anything after that point instead, like C would do.
83 string s = o.ToString();
85 char[] ca = s.ToCharArray();
86 int i = 0;
87 if (ca.Length > 0 && ca[0] == '-')
88 i++;
89 bool saw_dot = false;
90 for (; i < ca.Length; i++)
92 if (ca[i] == '.')
94 if (saw_dot || !allow_dot)
95 break;
96 saw_dot = true;
98 if ("0123456789.".IndexOf(ca[i]) < 0)
99 break;
102 return s.Substring(0, i);
105 public static double atod(object o)
107 try {
108 return Double.Parse(intclean(o, true));
109 } catch (FormatException) {
110 return 0.0;
114 public static int atoi(object o)
116 try {
117 return Int32.Parse(intclean(o, false));
118 } catch (FormatException) {
119 return 0;
123 public static long atol(object o)
125 try {
126 return Int64.Parse(intclean(o, false));
127 } catch (FormatException) {
128 return 0;
132 public static bool isempty(string s)
134 return s == null || s == "";
137 public static bool isempty(DateTime d)
139 return d == DateTime.MinValue;
142 public static bool isempty(TimeSpan t)
144 return t == TimeSpan.Zero;
147 public static string fmt(string format, params object[] args)
149 return String.Format(format, args);
152 public static void print(string format, params object[] args)
154 Console.Write(format, args);
157 public static void printerr(string format, params object[] args)
159 Console.Error.Write(format, args);
162 public static Array sort(ICollection keys, IComparer comparer)
164 object[] sorted = new object[keys.Count];
165 keys.CopyTo(sorted, 0);
166 Array.Sort(sorted, comparer);
167 return sorted;
170 public static Array sort(ICollection keys)
172 return sort(keys, Comparer.Default);
175 public static string[] stringify(ICollection keys)
177 string[] a = new string[keys.Count];
178 int i = 0;
179 foreach (object o in keys)
180 a[i++] = o.ToString();
181 return a;
184 public static string getenv(string key)
186 string o = Environment.GetEnvironmentVariable(key);
187 if (o != null)
188 return o;
189 else
190 return "";
193 public static string urldecode(string s)
195 return HttpUtility.UrlDecode(s);
198 public static string urlencode(string s)
200 return HttpUtility.UrlEncode(s);
203 public static void urlsplit(Dictionary<string,string> d, string query)
205 // Multiple values separated by & signs, as in URLs
206 foreach (string ent in query.Split('&'))
208 string[] kv = ent.Split("=".ToCharArray(), 2);
209 string k = HttpUtility.UrlDecode(kv[0]);
210 string v =
211 kv.Length>1 ? HttpUtility.UrlDecode(kv[1]) : "1";
212 d.Remove(k);
213 d.Add(k, v);
217 public static void cookiesplit(Dictionary<string,string> d,
218 string query)
220 // Multiple values separated by & signs, as in URLs
221 foreach (string ent in query.Split(';'))
223 string[] kv = ent.Split("=".ToCharArray(), 2);
224 string k = wv.urldecode(kv[0].Trim());
225 string v = kv.Length>1 ? wv.urldecode(kv[1]) : "1";
226 d.Remove(k);
227 d.Add(k, v);
231 static RandomNumberGenerator randserv = null;
232 public static byte[] randombytes(int num)
234 // lazy initialization, since it might be expensive. But we'll
235 // keep it around to ensure "maximum randomness"
236 if (randserv == null)
237 randserv = new RNGCryptoServiceProvider();
239 byte[] b = new byte[num];
240 randserv.GetBytes(b);
241 return b;
245 * A handy tool for making timeout loops. Use it like this:
247 * foreach (int remain in wv.until(t)) {
248 * do_stuff();
249 * if (exit_condition) break;
252 * New iterations of the loop will continue until DateTime.Now==t,
253 * or you exit the loop by hand.
255 * If t==DateTime.MinValue, loop will continue forever.
257 * 'remain' at each iteration will be the number of milliseconds
258 * remaining, or -1 if t==DateTime.MinValue.
260 * Even if the timeout is in the past, this is guaranteed to return
261 * at least once.
263 public static IEnumerable<int> until(DateTime t)
265 bool forever = (t == DateTime.MinValue);
266 DateTime n = DateTime.Now;
267 bool once = false;
269 while (!once || t==DateTime.MinValue || n < t)
271 once = true;
272 if (forever)
273 yield return -1;
274 else
276 int s = (int)((n-t).TotalMilliseconds);
277 if (s < 0)
278 s = 0;
279 yield return s;
281 n = DateTime.Now;
286 * Like until(DateTime t), but works with a timeout in msec instead
287 * of an exact time.
289 * A negative timeout means "forever".
291 public static IEnumerable<int> until(int msec_timeout)
293 DateTime t;
294 if (msec_timeout < 0)
295 t = DateTime.MinValue;
296 else
297 t = DateTime.Now + TimeSpan.FromMilliseconds(msec_timeout);
298 foreach (var i in until(t))
299 yield return i;
302 public static string add_breaks_to_newlines(string orig)
304 StringBuilder retval = new StringBuilder();
305 // Add a bit of space, since we expect to get a few newlines.
306 retval.EnsureCapacity(orig.Length + 32);
307 string[] split = orig.Split('\n');
308 for (int i = 0; i < split.Length; i++)
310 string s = split[i];
311 retval.Append(s);
312 // Don't do anything to the very end of the string
313 if (i != split.Length - 1)
315 string trimmed = s.Trim();
316 if (!trimmed.EndsWith("<br>") && !trimmed.EndsWith("<br/>")
317 && !trimmed.EndsWith("<br />"))
319 retval.Append("<br/>\n");
321 else
322 retval.Append("\n");
325 return retval.ToString();
328 // Extend Path.Combine to work on more than two path elements.
329 public static string PathCombine(string first, params string[] rest)
331 string combined = first;
332 foreach (string elem in rest)
333 combined = Path.Combine(combined, elem);
334 return combined;
337 public static bool IsMono()
339 return Type.GetType("Mono.Runtime") != null;
344 namespace Wv.Obsolete
346 public class Log
348 protected string logname;
350 static int refs = 0;
351 static TraceListener mytrace = null;
352 static bool disable_mytrace = false;
354 public Log(string logname)
356 refs++;
357 if (mytrace == null && !disable_mytrace
358 && Trace.Listeners.Count < 2)
360 mytrace = new TextWriterTraceListener(Console.Error);
361 Trace.Listeners.Add(mytrace);
364 //Trace.WriteLine(String.Format("Log constructor for '{0}'.",
365 // logname));
366 Trace.Flush();
367 this.logname = logname;
370 ~Log()
372 refs--;
373 if (refs == 0)
375 if (mytrace != null)
376 Trace.Listeners.Remove(mytrace);
377 mytrace = null;
381 public static void no_default_listener()
383 disable_mytrace = true;
384 if (mytrace != null)
386 Trace.Listeners.Remove(mytrace);
387 mytrace = null;
391 public virtual void log(string format, params object [] arg)
393 // Console.Error.WriteLine("<" + logname + "> " + format, arg);
394 Trace.WriteLine(String.Format
395 ("[" + logname + "] " + format, arg));
396 Trace.Flush();
399 public void log(string s)
401 log("{0}", s);
405 public class SilentLog : Log
407 public SilentLog(string logname) : base(logname)
411 public override void log(string format, params object [] arg)
416 // This is intended to work sort of like PHP arrays, which are a mix of
417 // hash tables and lists. Looking up an entry in the hash is O(1), but
418 // when you iterate through all the entries, the ordering is well-defined.
420 // So far, this implementation is pretty limited and lacks a bunch of the
421 // things PHP can do, such as assigning to a particular array index.
422 public class SortedHash : IEnumerable
424 ArrayList array = new ArrayList();
425 Hashtable hash = new Hashtable();
427 public IEnumerator GetEnumerator()
429 return array.GetEnumerator();
432 public void Add(string key, object value)
434 array.Add(value);
435 if (!hash.Contains(key))
436 hash.Add(key, value);
439 public int Count
441 get { return hash.Count; }
444 public bool Contains(object key)
446 return hash.Contains(key);
449 public object Find(string key)
451 return hash[key];
454 public virtual object this[int index]
456 get { return array[index]; }
459 public virtual void Sort()
461 array.Sort();
464 public virtual void Sort(IComparer comparer)
466 array.Sort(comparer);
469 public void Clear()
471 array.Clear();
472 hash.Clear();
475 public static explicit operator ArrayList(SortedHash x)
477 return ArrayList.ReadOnly(x.array);
481 public class ObjectCounter : Hashtable
483 public new virtual int this [object key]
487 if (!Contains(key))
488 Add(key, 0);
489 return (int)base[key];
494 if (Contains(key))
495 Remove(key);
496 Add(key, (int)value);