C# で InputBox

負けた気分になりながら Microsoft.VisualBasic.Interaction.InputBox を使ってみたら、キャンセルボタンを押した場合と空文字列を入力した場合の区別がつかなくて絶望した!
しかし、こういうコードを書くと with が欲しくなるね.

public static string InputBox(string Prompt, string Title, string DefaultResponse) {
    var textBox = new TextBox();
    textBox.Location = new Point(12, 84);
    textBox.Size = new Size(329, 19);
    textBox.Text = DefaultResponse;

    var okButton = new Button();
    okButton.DialogResult = DialogResult.OK;
    okButton.Location = new Point(266, 9);
    okButton.Size = new Size(75, 23);
    okButton.Text = "OK";
    okButton.UseVisualStyleBackColor = true;

    var cancelButton = new Button();
    cancelButton.DialogResult = DialogResult.Cancel;
    cancelButton.Location = new Point(266, 38);
    cancelButton.Size = new Size(75, 23);
    cancelButton.Text = "キャンセル";
    cancelButton.UseVisualStyleBackColor = true;

    var label = new Label();
    label.AutoSize = true;
    label.Location = new Point(12, 9);
    label.Size = new Size(0, 12);
    label.Text = Prompt;

    var form = new Form();
    form.SuspendLayout();
    form.AcceptButton = okButton;
    form.CancelButton = cancelButton;
    form.AutoScaleDimensions = new SizeF(6F, 12F);
    form.AutoScaleMode = AutoScaleMode.Font;
    form.ClientSize = new Size(353, 120);
    form.ControlBox = false;
    form.Controls.Add(textBox);
    form.Controls.Add(okButton);
    form.Controls.Add(cancelButton);
    form.Controls.Add(label);
    form.FormBorderStyle = FormBorderStyle.FixedDialog;
    form.ShowInTaskbar = false;
    form.StartPosition = FormStartPosition.CenterParent;
    form.ResumeLayout(false);
    form.PerformLayout();
    form.Text = Title;

    if (form.ShowDialog() == DialogResult.OK) return textBox.Text;
    else return null;
}

.NET 2.0 で Parallel.For

.NET 4.0 に Parallel.For が入るのはいいけど、普及するのにどんだけかかるんだよと思ったら手が動いていた(ぉ)

using System;
using System.Threading;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            Parallel.For(0, 10, x => {
                Console.Write("{0} ", x);
                Thread.Sleep(1000);
            });
        }
    }
}

namespace System.Threading {
    class Parallel {
        public static void For(int fromInclusive, int toExclusive, Action<int> body) {
            var threadCount = Environment.ProcessorCount;
            Func<int, int[]> Range = i => {
                Func<int, int> DividingPoint = j => {
                    return fromInclusive + (toExclusive - fromInclusive) * j / threadCount;
                };
                return new int[] { DividingPoint(i), DividingPoint(i + 1) };
            };
            var threads = new Thread[threadCount];
            for (var i = 0; i < threadCount; i++) {
                threads[i] = new Thread(new ParameterizedThreadStart(obj => {
                    for (int j = ((int[])obj)[0]; j < ((int[])obj)[1]; j++) {
                        body(j);
                    }
                }));
            }
            for (var i = 0; i < threadCount; i++) threads[i].Start(Range(i));
            for (var i = 0; i < threadCount; i++) threads[i].Join();
        }
    }
}

// For .NET Framework 2.0 Only
namespace System {
    public delegate TResult Func<T, TResult>(T arg);
}

C# で MD5 string

byte 配列止まりで、文字列に落とすところまでやってくれないのってなんでなんだろうね? そっちの利用の方が多いとおもうのに. Java もそうなんだけど.

public static string MD5HexString(string s) {
	return BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(Encoding.ASCII.GetBytes(s))).Replace("-", "").ToLower();
}

C# でスライス

C# で配列のスライスがあまりにも苦痛だったので作った. string も気がついたら作っていた. skip はめったに使わないので放置.

namespace MyExtensions {
    public static class Extension {
        public static T[] Slice<T>(this T[] source, int start, int end) {
            if (start < 0) start = source.Length + start;
            if (end < 0) end = source.Length + end;
            T[] result = new T[end - start];
            Array.Copy(source, start, result, 0, end - start);
            return result;
        }
        public static T[] Slice<T>(this T[] source, int start) {
            return Slice(source, start, source.Length);
        }
        // XXX: サロゲートペアが正しく処理されない
        public static string Slice(this string source, int start, int end) {
            if (start < 0) start = source.Length + start;
            if (end < 0) end = source.Length + end;
            return source.Substring(start, end - start);
        }
        public static string Slice(this string source, int start) {
            return Slice(source, start, source.Length);
        }
    }
}

// For .NET Framework 2.0 Only
namespace System.Runtime.CompilerServices {
    public class ExtensionAttribute : Attribute { }
}

名前が引けないと mod_proxy_connect で DNS エラーになる障害の対策パッチ

インターネットの名前が引けない中間フォーワードプロキシーで mod_proxy_connect を動作させるパッチ. 2.2.4 から 2.2.6 の間のリグレッションが原因で動作しないのだが、報告から22ヶ月経った現在も直す気配は無し.

--- mod_proxy_connect.c.bak	Mon Sep  3 02:42:59 2007
+++ mod_proxy_connect.c	Mon Aug 10 10:56:35 2009
@@ -124,10 +124,12 @@
     /* do a DNS lookup for the destination host */
     err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port,
                                 0, p);
-    if (APR_SUCCESS != err) {
-        return ap_proxyerror(r, HTTP_BAD_GATEWAY,
-                             apr_pstrcat(p, "DNS lookup failure for: ",
-                                         uri.hostname, NULL));
+    if (!proxyname || (conf->noproxies->nelts != 0)) {
+        if (APR_SUCCESS != err) {
+            return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+                                 apr_pstrcat(p, "DNS lookup failure for: ",
+                                             uri.hostname, NULL));
+        }
     }
 
     /* are we connecting directly, or via a proxy? */

アッカーマン関数

一応残しておく.

$ python
Python 2.6.2 (r262:71600, Jun  5 2009, 23:21:35)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> cache = {}
>>>
>>> def memoize(f):
...     global cache
...     def _(*args):
...         if not args in cache:
...             cache[args] = f(*args)
...         return cache[args]
...     return _
...
>>> @memoize
... def ack(m, n):
...     if m == 0:
...         return n + 1
...     elif m == 1:
...         return n + 2
...     elif m == 2:
...         return n * 2 + 3
...     elif m == 3:
...         return 2 ** (n + 3) - 3
...     elif n == 0:
...         return ack(m - 1, 1)
...     else:
...         if not (m, n - 1) in cache:
...             for i in range(n):
...                 ack(m, i)
...         return ack(m - 1, ack(m, n - 1))
...
>>> ack(4, 1)
65533
>>> len(str(ack(4, 2)))
19729

Poderosa の自動操作マクロ

Poderosa は更新が無くなってしまったので使わないと思うけど、発掘したので.

import Poderosa;
import Poderosa.ConnectionParam;
import Poderosa.Terminal;
import Poderosa.Macro;
import Poderosa.View;
import System.Drawing;
import System.Threading;

var vars = new Object();

connect("telnet-host", ConnectionMethod.Telnet, 23, EncodingType.EUC_JP, "id", "pw");
//connect("ssh-host", ConnectionMethod.SSH2, 22, EncodingType.UTF8, "id", "pw");

wait("$");
sendln("hostname");
wait("$");
sendln("date");

function connect(host, method, port, encoding, id, password) {
    vars.env = new Environment();
    if (method == ConnectionMethod.Telnet) {
        vars.param = new TelnetTerminalParam(host);
    } else {
        vars.param = new SSHTerminalParam(method, host, id, password);
    }
    vars.param.Port = port;
    vars.param.Encoding = encoding;
    vars.connection = vars.env.Connections.Open(vars.param);
    if (method == ConnectionMethod.Telnet) {
        wait("login: ");
        sendln(id);
        wait("Password: ");
        sendln(password);
    }
}

function sendln(s) {
    vars.connection.TransmitLn(s);
}

function wait(s) {
    Thread.Sleep(10);
    var r = vars.connection.ReceiveData();
    while(r.indexOf(s) == -1) {
        Thread.Sleep(10);
        r += vars.connection.ReceiveData();
    }
}