My hobbyist coding updates and releases as the mysterious "Mr. Tines"

Monday, 27 April 2009

ZLIB and .Net

A recurring problem in several of the projects I have in the pipeline is the matter of handling ZLIB. Java, through java.util.zip offers ZLIB compression with a 32k byte window (but no means of tuning the window) with the DeflaterOutputStream. The .Net framework doesn't offer direct ZLIB at all, but provides naked Deflate via System.IO.Compression.DeflateStream.

That gives us enough to be able to reflate the output of a ZLIB deflation, since a ZLIB is a 2 byte header, a deflate section and finally a 4 byte checksum:

import clr    
clr.AddReference( 'vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' )
from java.io import *
from java.util.zip import *
from System.IO import *
from System.IO.Compression import *
from System import Array, Byte, SByte, Int64
from System.Text import Encoding

def readFileToSByteArray(name):
  # open a file via Java I/O
  raw = RandomAccessFile(name, 'r')
  # print "File size in bytes = %d "  % (raw.length())

  # read into signed byte array
  dim = Array[Int64]([raw.length()])
  helper = Array[SByte]([0])
  buffer = Array.CreateInstance(helper[0].GetType(), dim)
  raw.readFully(buffer)
  raw.close()
  return buffer
  
def sbyteArrayToUbyteArray(buffer, offset=0, length=-1):
  if length < 0:
    length = buffer.Length
 
  dim = Array[Int64]([length])
  helper = Array[Byte]([0])
  ubuffer = Array.CreateInstance(helper[0].GetType(), dim)
  
  # copy into unsigned byte array
  for i in range(0,length):
    ubuffer[i] = buffer[i+offset] & 0xff
  return ubuffer
  
def jdeflate(buffer):
  sink0 = ByteArrayOutputStream()
  sink = DeflaterOutputStream(sink0)
  sink.write(buffer, 0, buffer.Length)
  sink.close()
  sink0.close()
  return sink0.toByteArray()
  
def update_adler(adler, buffer):
  s1 = adler & 0xffff
  s2 = (adler >> 16) & 0xffff
  BASE = 65521
  for n in range(0,buffer.Length):
          s1 = (s1 + buffer[n]) % BASE
          s2 = (s2 + s1)     % BASE
  return (s2 << 16) + s1
  
def ninflate(buffer):
  mem = MemoryStream(buffer)
  inflate = DeflateStream(mem, CompressionMode.Decompress)

  mem = MemoryStream()
  while True:
    x = inflate.ReadByte()
    if x < 0:
      break
    mem.WriteByte(x)
 
  inflate.Close()
  mem.Close()
  return mem.ToArray()
  
 
##==========================================

# select a file
name = ...

# make signed, unsigned buffers and string
buffer = readFileToSByteArray(name)
print "Constructed buffer size %d" % (buffer.Length)
ubuffer = sbyteArrayToUbyteArray(buffer)
instring = Encoding.Default.GetString(ubuffer)

# compute the Adler32 checksum
adler = update_adler(1, ubuffer)
print "Adler32 = %d" % (adler)
 
# deflate in Java
deflated = jdeflate(buffer)

# check the ZLIB header -- expect 120, 156 actually (120,-100)
first = (deflated[0] & 0xff)
second = (deflated[1] & 0xff)
print "header value EXPECTED 120:156 ACTUAL %d:%d" % (first, second)

i = deflated.Length-4
x = ((deflated[i]&0xff) << 24) | ((deflated[i+1]&0xff) << 16) | ((deflated[i+2]&0xff) << 8) | (deflated[i+3]&0xff)
print "Java Adler32 = %d" % (x)

# discard header and Adler32 tail
newbuffer = sbyteArrayToUbyteArray(deflated, 2, deflated.Length-6)
print "ZLIB length %d" % (deflated.Length)
print "deflate section length %d" % (newbuffer.Length)

# reflate
out = ninflate(newbuffer)

# compare with input
print "reflated buffer length : %d" % (out.Length)
outstring = Encoding.Default.GetString(out)
same = outstring.Equals(instring)
print "Output == Input ?? %s" %(str(same))

That works fine; but the converse, taking a .Net deflate and adding the appropriate top and tail took a bit of getting to work.

First pitfall -- the InflaterInputStream has to be read in chunks as large as feasible, rather than byte at a time, so as not to throw a premature EOFException. That overcome, I got a result of the right length, but differing in the final few characters for the file under test, which I resolved by doing a belt-and-braces closing of the deflate operation. The un-refactored code I currently have continues from the above as:

# now the other way around
sink0 = MemoryStream()
sink = DeflateStream(sink0, CompressionMode.Compress)
sink.Write(ubuffer, 0, ubuffer.Length)
## overkill the flush and close here
sink.Flush()
sink.Close()
sink0.Flush()
sink0.Close()

deflated = sink0.ToArray()
print "deflate section length %d" % (deflated.Length)

#now inflate
dim = Array[Int64]([deflated.Length+6])
jbuffer = Array.CreateInstance(buffer[0].GetType(), dim)

jbuffer[0] = 120 # 0111 0100 = 120 : 32 kbit window, Deflate
jbuffer[1] = -100 # 10 0 ????? = 128 + x : default compress, no dict, checksum

def sbyte(x):
  y = x & 0xff
  if y > 127:
    return y - 256
  return y
 
for i  in range(0,deflated.Length):
    jbuffer[i+2] = sbyte(deflated[i])
 
i = deflated.Length+2
jbuffer[i] = sbyte(adler>>24) 
jbuffer[i+1] = sbyte(adler>>16) 
jbuffer[i+2] = sbyte(adler>>8)
jbuffer[i+3] = sbyte( adler )
 
 
source0 = ByteArrayInputStream(jbuffer)
source = InflaterInputStream(source0)

dim = Array[Int64]([ubuffer.Length])
helper = Array[SByte]([0])
xbuffer = Array.CreateInstance(helper[0].GetType(), dim)

## take big bites
offset = 0
try:
 while True:
  x = source.read(xbuffer, offset, xbuffer.Length-offset)
  if x < 0:
    break
  offset += x
except EOFException:
  pass

reflated = sbyteArrayToUbyteArray(xbuffer)

print "reflated length is %d" % (reflated.Length)
outstring = Encoding.Default.GetString(reflated)

same = outstring.Equals(instring)
print same

This should allow me to simplify the baggage accumulated for the C#/Erlang bridge, which currently uses a second-generation port of the original 'C' ZLIB for this sort of interoperation.

Much Later — I have ported this to F# on .net 4.5.



There's a lot of buffer to stream to buffer conversion involved -- the {n,j}{in,de}flate functions are just that. It's ndeflateZLIB, ninflateZLIBFull that do the complete transformation from a byte array to a compressed byte array and back again. The sbyte bit is purely a J# compatibility thing. Full solution here.

Sunday, 22 March 2009

Belatedly, more IronPython + Silverlight

Domestic happenings and the demands of the day-job have kept me away from the codeface for playtime for a while; but at last, following up from last year, a SilverLight2/IronPython2 orrery-clock. Back-ported from F#, I confess, hence the possibly less than Pythonic idioms at times.

Sunday, 11 January 2009

Python swinging both ways

Following up to the last post I made in my quest for a cross-VM (JVM and CLR), single code-base, polyglot language stack, which doesn't involve any more Java than can be helped. Especially when there is Scala to play with, a language which a reading of the stairway book shows is very nifty indeed.

To summarise where we are, and what we have discovered to date --

  • Python can call Scala and Java happily
  • Java calling into Python is funky and platform dependent; doubly so for Scala
  • Scala cannot both call into java.* classes and compile on .net
  • Low-level Scala pre-defs differ in the Byte type (signed in Java/J#/Scala-JVM, unsigned in Scala-msil)
  • Ruby's predilection for Pascal-case namespaces (fudged in JRuby to match Java's lower-case convention) would require a lot of plumbing around in C# to mate IronRuby to J# or Scala-msil (as the rest of .net uses Pascal-casing).

And then there is this weekend's discovery.

As J# is a barely JDK1.2 implementation at best, I can't use the latest Java splash-screen feature, and have to fall back on older implementations. I have one to hand, back from c. JDK 1.4 days. It uses synchronized(), Object.wait() and Object.notifyAll().

The first is easy enough to deal with when wanting to put as much as possible of this GUI-driving code into Python -- define an interface to hold a code block

public interface ISynchronizedAction
{
  void performAction();
}

and then have a class which knows about the object to synchronize on, and can execute the block in a synchronized scope

public class Synchronized {
  private Object lock;

  public Synchronized(Object lock) {this.lock = lock;}

  public void Lock(ISynchronizedAction action)
  {
    synchronized(lock) {action.performAction();}
  }
}

Except in IronPython, I also discover by dumping the dir() of an object sub-classing java.awt.Window -- inheritance being needed for the splash-screen window class rather than composition, in order to hook the update/repaint APIs -- that neither Object.wait() nor Object.notifyAll() are present to be called. Fortunately the object I want these methods on is the same one I want to synchronize on, the splash-screen window itself, so I was able to just extend Synchronized with

  public void delegateWait() throws InterruptedException
  {
    lock.wait();
  }

  public void delegateNotifyAll()
  {
    lock.notifyAll();
  }

and make the there-and-back-again calls as required.

Then I just had to work around the older dialect's lack of support for .png (by using a .gif) by using the handy Java-1.1 compatible javapng-1.3.0 library to actually paint the image into the splash screen.

As usual, Jython needs the helper .jar file in the CLASSPATH, while IronPython can reference the equivalent .dll from code by assembly file name.

Saturday, 10 January 2009

Towards Scala/.net 2.0

A propos of my last bit of banging head against a wall... Oh, and these snippets are definitely offered under the WTFPL.

The main things that the scala-msil compilation balks at when looking at .Net assemblies post framework 1.x are generics; and things marked as var. Looking at the source in http://lampsvn.epfl.ch/svn-repos/scala/msil/trunk/src/, the first changes to make are, first in msil/util/Signature.java, add the extra byte code values

    public static final int ELEMENT_TYPE_VAR = 0x13;     // a class type variable VAR
    /***/
    public static final int  ELEMENT_TYPE_GENERICINST    = 0x15;     // GENERICINST    ...

and then start to do something about parsing them in msil/PEFile.java, in method PEFile.Sig.decodeType0()

        case ELEMENT_TYPE_GENERICINST:
        // Followed by <type> token
        //ELEMENT_TYPE_GENERICINST <an mdTypeDef metadata token> <argument Count> <arg1> ... <argN>
        {
            // base type
            int tmp = readByte();
            if((tmp != ELEMENT_TYPE_VALUETYPE) && (tmp != ELEMENT_TYPE_CLASS))
                throw new RuntimeException("*1*>> "+ byte2hex(tmp) +
        "@" + pos() + " in " + this);   
            int id = decodeInt();
            type = pemodule.getTypeDefOrRef(id);
            if (type == null)   throw new RuntimeException("**>> "+ byte2hex(desc) +
        "@" + pos() + " in " + this);
            // number of type arguments
            int num = decodeInt();
            System.out.println("num = "+num);
            for(int i=0;i<num;++i)
            {
                Type t = decodeType0();
                //TODO: use this information
            }
        }
        break;

        case ELEMENT_TYPE_VAR:
        {
            int index = decodeInt();
            System.out.println("var of type "+index);
            // TODO: actually look up what the index means 
            return Type.GetType("System.Object");
        }

This is necessary but not sufficient -- this still leaves problems with types involving templated subtypes or interfaces, for which the first TODO is probably meaningful. As a consequence we're still a long way from a "hello .net 2.0 world!" example yet; let alone a rebuilt scala-compiler.jar, alas.

Tuesday, 16 December 2008

More Silverlight Clock

I could, I suppose, have implemented this project in JavaScript -- that language has all the tools to get the current URL query string and set a permalink to a custom URL, one that wouldn't need clicking, but could be right-clicked; and save the self-inflicted DLR download hit.

If I wanted to, I could put the permalink URL out to an element in the DOM with Silverlight, too, which negates one perceived advantage. And using Silverlight gives me something extra -- multithreading.

Yes, there are JavaScript clocks, like this annoying mouse-following one, but they have to fake such things because they are running full-time in the UI thread. By using a BackgroundWorker to prompt a redraw at intervals (and, later, perform updates on the positions of celestial bodies), with Silverlight, I can offload everything but the painting from the UI thread.

Sunday, 14 December 2008

Persisting user settings in Silverlight

Many years ago, the first GUI application I wrote (in X with Motif) was a little orrery-cum-clock thing, with the clock face doubling as a view of the sky, showing the classical planets. Some time in the intermediate past, I thought about doing this as a Java applet, but it never got anywhere, because out on the web, it would have to be settable to the user's geographic location, and I never figured a good way to persist that data between page visits.

Having done the basic tinkering with IronPython and Silverlight to get the two working together, I thought about resurrecting the project. And the first thing to solve is the settings persistence.

But now, I have an easy API to get at the current URL and such via System.Windows.Browser.HtmlPage.Document -- so I can read the values from its query string; and set the values in a hyperlink for bookmarking purposes, thus (app.py):

from System.Windows import Application
from System.Windows.Controls import Canvas
import System
import System.Windows.Browser

xaml = Application.Current.LoadRootVisual(Canvas(), "astroclock.xaml")
xaml.hyperlink.NavigateUri = System.Windows.Browser.HtmlPage.Document.DocumentUri
thisPage = System.Windows.Browser.HtmlPage.Document.DocumentUri.GetComponents(
  System.UriComponents.SchemeAndServer | System.UriComponents.Path,
  System.UriFormat.SafeUnescaped)
query = System.Windows.Browser.HtmlPage.Document.QueryString
  
try:
  xaml.slider1.Value = float(query['lat'])
except:
  pass
try:
  xaml.slider2.Value = float(query['long'])
except:
  pass
 
def latValueChanged(s, e):
  v = xaml.slider1.Value
  if v > 0:
 xaml.label1.Text = "Latitude %.2fN" % (v)
  elif v < 0:
 xaml.label1.Text = "Latitude %.2fS" % (-v)
  else: 
 xaml.label1.Text = "Latitude 0"
 xaml.hyperlink.NavigateUri = System.Uri("%s?lat=%f&long=%f" % (thisPage, v, xaml.slider2.Value))

xaml.slider1.ValueChanged += latValueChanged
latValueChanged(None, None)

def longValueChanged(s, e):
  v = xaml.slider2.Value
  if v > 0:
 xaml.label2.Text = "Longitude %.2fE" % (v)
  elif v < 0:
 xaml.label2.Text = "Longitude %.2fW" % (-v)
  else:
 xaml.label2.Text = "Longitude 0"
 xaml.hyperlink.NavigateUri = System.Uri("%s?lat=%f&long=%f" % (thisPage, xaml.slider1.Value, v))
 
xaml.slider2.ValueChanged += longValueChanged
longValueChanged(None, None)

driving some UI described by (astroclock.xaml)

<Canvas 
  x:Class="System.Windows.Controls.Canvas"
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Name="parentCanvas">
    <Grid>
        <Canvas Name="canvas1" Margin="0,0,0,129" Background="Black" Width="480" Height="240"/>
        <Slider Height="22" Margin="128,0,0,93" Name="slider1" VerticalAlignment="Bottom" Maximum="90" Minimum="-90" Value="52" LargeChange="10" SmallChange="1" Width="360"/>
        <TextBlock Height="28" Margin="0,0,0,87" Name="label1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="120">Latitude</TextBlock>
        <TextBlock Height="28" HorizontalAlignment="Left" Margin="0,0,0,62" Name="label2" VerticalAlignment="Bottom" Width="120">Longitude</TextBlock>
        <Slider Height="22" Margin="128,0,0,65" Name="slider2" VerticalAlignment="Bottom" Maximum="180" Minimum="-180" LargeChange="10" SmallChange="1" Width="360"/>
        <HyperlinkButton Height="28" HorizontalAlignment="Left" Margin="0,0,0,17" Name="hyperlink" VerticalAlignment="Bottom" Width="87" NavigateUri="astroclock.html" Content="Permalink" />
    </Grid>
</Canvas>

Evolving implementation here.

Tuesday, 2 December 2008

Syntax highlighting

Following on from Scott Hanselman's post about the SyntaxHighlighter script, here's the secret sauce I needed to get it to work.

The separate hosting is the easy bit -- the trick was getting the code I needed to run the repainting into a window.onload, and to keep Blogger from mutilating the code by use of a CDATA section.

Et voilà!

<link href='.../SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script src='.../shCore.js' type='text/javascript'/>
<script src='.../shBrushPython.js' type='text/javascript'/>
<script src='.../shBrushRuby.js' type='text/javascript'/>
...
<script type='text/javascript'>//<![CDATA[
window.onload = function () {
    dp.SyntaxHighlighter.ClipboardSwf = ".../clipboard.swf";
    dp.SyntaxHighlighter.BloggerMode();
    dp.SyntaxHighlighter.HighlightAll("code",true,false,false,1,false);
}
//]]></script>

There is also a Scala brush for this -- but F# or Erlang will need to be hand-cranked first.

Later: hand cranking done & linked.