Saturday, April 27, 2013

js-deflate in Dart

‹prev | My Chain | next›

I love me a good mystery.

Last night, I figured out how to gzip and base64 encode data in Dart. That was not the mystery. It worked so well, that I could even pass the result to the linux base64 and gzip utilities. The mystery is why the JavaScript equivalents, js-deflate and btoa, do not produce the same result.

Since Dart seems compatible with the linux utilities, it would seem that it is "right". So my first inclination is to see if I can get the JavaScript version right. I start with the same code string as yesterday:
> str
"<body></body>
<script src="http://gamingJS.com/Three.js"></script>
<script src="http://gamingJS.com/ChromeFixes.js"></script>
<script>
  // Your code goes here...
</script>"
Instead of deflating / zipping that string immediately, I try base64 encoding, then deflating it, and then base64 encoding it again:
> btoa(RawDeflate.deflate(btoa(str)))
"Rc9Bb4MgGIDhH9QLQU3k0MO0mcAoYzrb+t0UFyvD4RLF4a9fdmh2e05v8qqCe6CfB5WTscNlogaXaixDe8sQozI0OxpbWiJ9cl7g/t5d7QpofheT9F1F6pZyC1XyrQP7a+xNxGdN3w65+Xl40BE3quKup+X2OqYe8PPSXpOvyp7XBpNFIOn0RBaoYf4oLruY5p2ZOBWRNHqyW3+KXxT9N8ufvAgZdNElsEJ6KOoBMLE6ZA5u3IoxXnOz+ceHGo7HXw=="
I then take the result, pass it to the linux base64 and gzip utilities to find:
➜  ice-code-editor git:(master) ✗ echo -n "Rc9Bb4MgGIDhH9QLQU3k0MO0mcAoYzrb+t0UFyvD4RLF4a9fdmh2e05v8qqCe6CfB5WTscNlogaXaixDe8sQozI0OxpbWiJ9cl7g/t5d7QpofheT9F1F6pZyC1XyrQP7a+xNxGdN3w65+Xl40BE3quKup+X2OqYe8PPSXpOvyp7XBpNFIOn0RBaoYf4oLruY5p2ZOBWRNHqyW3+KXxT9N8ufvAgZdNElsEJ6KOoBMLE6ZA5u3IoxXnOz+ceHGo7HXw==" | base64 -d | gunzip -dc

gzip: stdin: not in gzip format
Blah.

So it really seems like the js-deflate is not producing gzip compatible data.

So let's see what Dart can do with the JavaScript deflate implementation:
<head>
  <script src="scripts/rawdeflate.js" type="text/javascript" charset="utf-8"></script>
  <script src="scripts/ace/ace.js" type="text/javascript" charset="utf-8"></script>
  <script type="application/dart" src="scripts/ice.dart"></script>
  <script src="scripts/packages/browser/dart.js"></script>
</head>
<h1>Hello</h1>
<div style="width:600px; height: 400px" id="ace"></div>
Next, I modify my ice.dart script to deflate the same code, this time using the JavaScipt js-deflate implementation, and then base64 encode it:
import 'dart:html';
import 'dart:async';
import 'dart:crypto';
import 'package:js/js.dart' as js;

main() {
  var context = js.context;
  // ...
  var code = '''<body></body>
<script src="http://gamingJS.com/Three.js"></script>
<script src="http://gamingJS.com/ChromeFixes.js"></script>
<script>
  // Your code goes here...
</script>''';

  var str_d = context.RawDeflate.deflate(code);
  print(str_d);
  print(CryptoUtils.bytesToBase64(str_d.codeUnits));
}
The result in the Dartium console:
s0nKT6m0s9EHU1w2xclFmQUlCsVFybZKGSUlBVb6+umJuZl56V7Besn5ufohGUWpqXpZxUpALRC1RGhyzijKz011y6xILcau1Y5LQUFfXyEyv7RIITk/JVUhPT+1WCEjtShVT0+PC64cAA==
By way of comparison, the pure JavaScript result is:
s0nKT6m0s9EHU1w2xclFmQUlCsVFybZKGSUlBVb6+umJuZl56V7Besn5ufohGUWpqXpZxUpALRC1RGhyzijKz011y6xILcau1Y5LQUFfXyEyv7RIITk/JVUhPT+1WCEjtShVT0+PC64cAA==
So in then end, I have no idea what the JavaScript function is doing. What I do know is that the JavaScript btoa() and Dart bytesToBase64() produce identical results. I also know that I can deflate identically in both Dart and JavaScript thanks to Dart's js-interop.

Sadly, the mystery remains. But happily for my efforts to convert the ICE Code Editor to Dart, I can still invoke the screwy JavaScript implementation and continue merrily on my way. It comes at the expense of being required to load in yet another JavaScript library, but only until I come up with a migration scheme.


Day #734

No comments:

Post a Comment