batman-rails-flo 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +29 -0
  3. data/Rakefile +2 -0
  4. data/lib/batman-rails-flo.rb +5 -0
  5. data/lib/batman_rails_flo/railtie.rb +9 -0
  6. data/lib/batman_rails_flo/tasks.rake +14 -0
  7. data/lib/batman_rails_flo/version.rb +3 -0
  8. data/vendor/assets/javascripts/batman_rails_flo/flo_server.js +67 -0
  9. data/vendor/assets/javascripts/batman_rails_flo/live_reload.js.coffee +129 -0
  10. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/CNAME +1 -0
  11. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/CONTRIBUTING.md +9 -0
  12. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/LICENSE +22 -0
  13. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/README +50 -0
  14. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/bin/cake +7 -0
  15. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/bin/coffee +7 -0
  16. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/browser.js +134 -0
  17. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/cake.js +112 -0
  18. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/coffee-script.js +335 -0
  19. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/command.js +569 -0
  20. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/grammar.js +631 -0
  21. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/helpers.js +252 -0
  22. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/index.js +11 -0
  23. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/lexer.js +926 -0
  24. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/nodes.js +3158 -0
  25. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/optparse.js +139 -0
  26. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/parser.js +724 -0
  27. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/register.js +66 -0
  28. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/repl.js +163 -0
  29. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/rewriter.js +475 -0
  30. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/scope.js +146 -0
  31. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/sourcemap.js +161 -0
  32. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/LICENSE +21 -0
  33. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/examples/pow.js +6 -0
  34. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/index.js +82 -0
  35. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/package.json +34 -0
  36. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/readme.markdown +63 -0
  37. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/chmod.js +38 -0
  38. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/clobber.js +37 -0
  39. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/mkdirp.js +28 -0
  40. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/perm.js +32 -0
  41. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/perm_sync.js +39 -0
  42. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/race.js +41 -0
  43. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/rel.js +32 -0
  44. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/return.js +25 -0
  45. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/return_sync.js +24 -0
  46. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/root.js +18 -0
  47. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/sync.js +32 -0
  48. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/umask.js +28 -0
  49. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/umask_sync.js +32 -0
  50. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/package.json +50 -0
  51. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/register.js +1 -0
  52. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/LICENSE +30 -0
  53. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/PATENTS +23 -0
  54. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/README.md +124 -0
  55. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/bin/flo +26 -0
  56. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/configure/configure.html +57 -0
  57. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/configure/configure.js +205 -0
  58. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/configure/style.css +334 -0
  59. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/connection.js +235 -0
  60. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/devtools.html +12 -0
  61. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/index.js +323 -0
  62. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/logger.js +42 -0
  63. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/logo.png +0 -0
  64. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/manifest.json +13 -0
  65. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/session.js +305 -0
  66. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/index.js +10 -0
  67. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/lib/flo.js +226 -0
  68. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/lib/server.js +94 -0
  69. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/README.md +66 -0
  70. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/index.js +437 -0
  71. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/LICENSE +23 -0
  72. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/README.md +218 -0
  73. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/minimatch.js +1055 -0
  74. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +14 -0
  75. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/LICENSE +23 -0
  76. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/README.md +97 -0
  77. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +252 -0
  78. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/package.json +33 -0
  79. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/test/basic.js +369 -0
  80. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +52 -0
  81. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +50 -0
  82. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/LICENSE +27 -0
  83. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/README.md +53 -0
  84. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/bench.js +283 -0
  85. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/package.json +42 -0
  86. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/sigmund.js +39 -0
  87. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/test/basic.js +24 -0
  88. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/package.json +40 -0
  89. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/basic.js +399 -0
  90. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/brace-expand.js +33 -0
  91. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/caching.js +14 -0
  92. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/defaults.js +274 -0
  93. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/extglob-ending-with-state-char.js +8 -0
  94. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/lib/walker.js +111 -0
  95. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/license +13 -0
  96. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/lib/makeerror.js +87 -0
  97. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/node_modules/tmpl/lib/tmpl.js +17 -0
  98. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/node_modules/tmpl/package.json +31 -0
  99. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/node_modules/tmpl/readme.md +10 -0
  100. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/package.json +34 -0
  101. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/readme.md +77 -0
  102. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/package.json +36 -0
  103. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/readme.md +52 -0
  104. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/LICENSE +55 -0
  105. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/main.js +128 -0
  106. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/package.json +34 -0
  107. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/readme.mkd +72 -0
  108. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/d/d/t +0 -0
  109. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/d/t +0 -0
  110. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/test_monitor.js +31 -0
  111. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/test_monitorRootDirectory.js +28 -0
  112. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/test_watchTree.js +20 -0
  113. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/package.json +45 -0
  114. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/test/test.js +243 -0
  115. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/CHANGELOG.md +81 -0
  116. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/LICENSE +177 -0
  117. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/Makefile +11 -0
  118. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/README.md +245 -0
  119. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/binding.gyp +14 -0
  120. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Makefile +355 -0
  121. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/linker.lock +0 -0
  122. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/obj.target/validation/src/validation.o +0 -0
  123. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/obj.target/xor/src/xor.o +0 -0
  124. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/validation.node +0 -0
  125. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/xor.node +0 -0
  126. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/binding.Makefile +6 -0
  127. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/config.gypi +115 -0
  128. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/gyp-mac-tool +512 -0
  129. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/validation.target.mk +154 -0
  130. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/xor.target.mk +154 -0
  131. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/index.js +1 -0
  132. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/install.js +31 -0
  133. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Constants.js +23 -0
  134. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Deprecation.js +38 -0
  135. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Validation.fallback.js +12 -0
  136. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Validation.js +18 -0
  137. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketClient.js +359 -0
  138. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketConnection.js +717 -0
  139. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketFrame.js +282 -0
  140. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketRequest.js +478 -0
  141. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketRouter.js +154 -0
  142. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketRouterRequest.js +59 -0
  143. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketServer.js +216 -0
  144. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/utils.js +7 -0
  145. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/websocket.js +11 -0
  146. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/xor.fallback.js +13 -0
  147. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/xor.js +18 -0
  148. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/package.json +43 -0
  149. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/src/validation.cc +144 -0
  150. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/src/xor.cpp +86 -0
  151. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/vendor/FastBufferList.js +192 -0
  152. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/vendor/node-ctype/LICENSE +18 -0
  153. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/vendor/node-ctype/ctio-faster.js +1126 -0
  154. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/package.json +25 -0
  155. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/browser_websocket.js +63 -0
  156. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/connection_test.js +57 -0
  157. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/logger_mock.js +15 -0
  158. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/session_test.js +194 -0
  159. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/server/flo_test.js +211 -0
  160. data/vendor/assets/javascripts/batman_rails_flo/package.json +15 -0
  161. data/vendor/assets/javascripts/batman_rails_flo/reload_event_handler.js.coffee +56 -0
  162. metadata +232 -0
@@ -0,0 +1,18 @@
1
+ Copyright 2011, Robert Mustacchi. All rights reserved.
2
+ Permission is hereby granted, free of charge, to any person obtaining a copy
3
+ of this software and associated documentation files (the "Software"), to
4
+ deal in the Software without restriction, including without limitation the
5
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6
+ sell copies of the Software, and to permit persons to whom the Software is
7
+ furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in
10
+ all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18
+ IN THE SOFTWARE.
@@ -0,0 +1,1126 @@
1
+ /*
2
+ * rm - Feb 2011
3
+ * ctio-faster.js:
4
+ * This file is a modification of ctio.js that removes all the runtime sanity
5
+ * checking for efficiency.
6
+ *
7
+ * A simple way to read and write simple ctypes. Of course, as you'll find the
8
+ * code isn't as simple as it might appear. The following types are currently
9
+ * supported in big and little endian formats:
10
+ *
11
+ * uint8_t int8_t
12
+ * uint16_t int16_t
13
+ * uint32_t int32_t
14
+ * float (single precision IEEE 754)
15
+ * double (double precision IEEE 754)
16
+ *
17
+ * This is designed to work in Node and v8. It may in fact work in other
18
+ * Javascript interpreters (that'd be pretty neat), but it hasn't been tested.
19
+ * If you find that it does in fact work, that's pretty cool. Try and pass word
20
+ * back to the original author.
21
+ *
22
+ * Note to the reader: If you're tabstop isn't set to 8, parts of this may look
23
+ * weird.
24
+ */
25
+
26
+ /*
27
+ * Numbers in Javascript have a secret: all numbers must be represented with an
28
+ * IEEE-754 double. The double has a mantissa with a length of 52 bits with an
29
+ * implicit one. Thus the range of integers that can be represented is limited
30
+ * to the size of the mantissa, this makes reading and writing 64-bit integers
31
+ * difficult, but far from impossible.
32
+ *
33
+ * Another side effect of this representation is what happens when you use the
34
+ * bitwise operators, i.e. shift left, shift right, and, or, etc. In Javascript,
35
+ * each operand and the result is cast to a signed 32-bit number. However, in
36
+ * the case of >>> the values are cast to an unsigned number.
37
+ */
38
+
39
+ /*
40
+ * A reminder on endian related issues:
41
+ *
42
+ * Big Endian: MSB -> First byte
43
+ * Little Endian: MSB->Last byte
44
+ */
45
+
46
+ /*
47
+ * An 8 bit unsigned integer involves doing no significant work.
48
+ */
49
+ function ruint8(buffer, endian, offset)
50
+ {
51
+ return (buffer[offset]);
52
+ }
53
+
54
+ /*
55
+ * For 16 bit unsigned numbers we can do all the casting that we want to do.
56
+ */
57
+ function ruint16(buffer, endian, offset)
58
+ {
59
+ var val = 0;
60
+ if (endian == 'big') {
61
+ val = buffer[offset] << 8;
62
+ val |= buffer[offset+1];
63
+ } else {
64
+ val = buffer[offset];
65
+ val |= buffer[offset+1] << 8;
66
+ }
67
+
68
+ return (val);
69
+ }
70
+
71
+ /*
72
+ * Because most bitshifting is done using signed numbers, if we would go into
73
+ * the realm where we use that 32nd bit, we'll end up going into the negative
74
+ * range. i.e.:
75
+ * > 200 << 24
76
+ * -939524096
77
+ *
78
+ * Not the value you'd expect. To work around this, we instead do a
79
+ * multiplication by (1 << 24) which does the same thing, but in a way that
80
+ * ensures we don't lose that bit.
81
+ */
82
+
83
+ /*
84
+ * Handle the case of losing our MSBit
85
+ */
86
+ function fixu32(upper, lower)
87
+ {
88
+ return ((upper * (1 << 24)) + lower);
89
+ }
90
+
91
+ function ruint32(buffer, endian, offset)
92
+ {
93
+ var val = 0;
94
+
95
+ if (endian == 'big') {
96
+ val = buffer[offset+1] << 16;
97
+ val |= buffer[offset+2] << 8;
98
+ val |= buffer[offset+3];
99
+ val = fixu32(buffer[offset], val);
100
+ } else {
101
+ val = buffer[offset+2] << 16;
102
+ val |= buffer[offset+1] << 8;
103
+ val |= buffer[offset];
104
+ val = fixu32(buffer[offset+3], val);
105
+ }
106
+
107
+ return (val);
108
+ }
109
+
110
+ /*
111
+ * Reads a 64-bit unsigned number. The astue observer will note that this
112
+ * doesn't quite work. Javascript has chosen to only have numbers that can be
113
+ * represented by a double. A double only has 52 bits of mantissa with an
114
+ * implicit 1, thus we have up to 53 bits to represent an integer. However, 2^53
115
+ * doesn't quite give us what we want. Isn't 53 bits enough for anyone? What
116
+ * could you have possibly wanted to represent that was larger than that? Oh,
117
+ * maybe a size? You mean we bypassed the 4 GB limit on file sizes, when did
118
+ * that happen?
119
+ *
120
+ * To get around this egregious language issue, we're going to instead construct
121
+ * an array of two 32 bit unsigned integers. Where arr[0] << 32 + arr[1] would
122
+ * give the actual number. However, note that the above code probably won't
123
+ * produce the desired results because of the way Javascript numbers are
124
+ * doubles.
125
+ */
126
+ function ruint64(buffer, endian, offset)
127
+ {
128
+ var val = new Array(2);
129
+
130
+ if (endian == 'big') {
131
+ val[0] = ruint32(buffer, endian, offset);
132
+ val[1] = ruint32(buffer, endian, offset+4);
133
+ } else {
134
+ val[0] = ruint32(buffer, endian, offset+4);
135
+ val[1] = ruint32(buffer, endian, offset);
136
+ }
137
+
138
+ return (val);
139
+ }
140
+
141
+
142
+ /*
143
+ * Signed integer types, yay team! A reminder on how two's complement actually
144
+ * works. The first bit is the signed bit, i.e. tells us whether or not the
145
+ * number should be positive or negative. If the two's complement value is
146
+ * positive, then we're done, as it's equivalent to the unsigned representation.
147
+ *
148
+ * Now if the number is positive, you're pretty much done, you can just leverage
149
+ * the unsigned translations and return those. Unfortunately, negative numbers
150
+ * aren't quite that straightforward.
151
+ *
152
+ * At first glance, one might be inclined to use the traditional formula to
153
+ * translate binary numbers between the positive and negative values in two's
154
+ * complement. (Though it doesn't quite work for the most negative value)
155
+ * Mainly:
156
+ * - invert all the bits
157
+ * - add one to the result
158
+ *
159
+ * Of course, this doesn't quite work in Javascript. Take for example the value
160
+ * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
161
+ * course, Javascript will do the following:
162
+ *
163
+ * > ~0xff80
164
+ * -65409
165
+ *
166
+ * Whoh there, Javascript, that's not quite right. But wait, according to
167
+ * Javascript that's perfectly correct. When Javascript ends up seeing the
168
+ * constant 0xff80, it has no notion that it is actually a signed number. It
169
+ * assumes that we've input the unsigned value 0xff80. Thus, when it does the
170
+ * binary negation, it casts it into a signed value, (positive 0xff80). Then
171
+ * when you perform binary negation on that, it turns it into a negative number.
172
+ *
173
+ * Instead, we're going to have to use the following general formula, that works
174
+ * in a rather Javascript friendly way. I'm glad we don't support this kind of
175
+ * weird numbering scheme in the kernel.
176
+ *
177
+ * (BIT-MAX - (unsigned)val + 1) * -1
178
+ *
179
+ * The astute observer, may think that this doesn't make sense for 8-bit numbers
180
+ * (really it isn't necessary for them). However, when you get 16-bit numbers,
181
+ * you do. Let's go back to our prior example and see how this will look:
182
+ *
183
+ * (0xffff - 0xff80 + 1) * -1
184
+ * (0x007f + 1) * -1
185
+ * (0x0080) * -1
186
+ *
187
+ * Doing it this way ends up allowing us to treat it appropriately in
188
+ * Javascript. Sigh, that's really quite ugly for what should just be a few bit
189
+ * shifts, ~ and &.
190
+ */
191
+
192
+ /*
193
+ * Endianness doesn't matter for 8-bit signed values. We could in fact optimize
194
+ * this case because the more traditional methods work, but for consistency,
195
+ * we'll keep doing this the same way.
196
+ */
197
+ function rsint8(buffer, endian, offset)
198
+ {
199
+ var neg;
200
+
201
+ neg = buffer[offset] & 0x80;
202
+ if (!neg)
203
+ return (buffer[offset]);
204
+
205
+ return ((0xff - buffer[offset] + 1) * -1);
206
+ }
207
+
208
+ /*
209
+ * The 16-bit version requires a bit more effort. In this case, we can leverage
210
+ * our unsigned code to generate the value we want to return.
211
+ */
212
+ function rsint16(buffer, endian, offset)
213
+ {
214
+ var neg, val;
215
+
216
+ val = ruint16(buffer, endian, offset);
217
+ neg = val & 0x8000;
218
+ if (!neg)
219
+ return (val);
220
+
221
+ return ((0xffff - val + 1) * -1);
222
+ }
223
+
224
+ /*
225
+ * We really shouldn't leverage our 32-bit code here and instead utilize the
226
+ * fact that we know that since these are signed numbers, we can do all the
227
+ * shifting and binary anding to generate the 32-bit number. But, for
228
+ * consistency we'll do the same. If we want to do otherwise, we should instead
229
+ * make the 32 bit unsigned code do the optimization. But as long as there
230
+ * aren't floats secretly under the hood for that, we /should/ be okay.
231
+ */
232
+ function rsint32(buffer, endian, offset)
233
+ {
234
+ var neg, val;
235
+
236
+ val = ruint32(buffer, endian, offset);
237
+ neg = val & 0x80000000;
238
+ if (!neg)
239
+ return (val);
240
+
241
+ return ((0xffffffff - val + 1) * -1);
242
+ }
243
+
244
+ /*
245
+ * The signed version of this code suffers from all of the same problems of the
246
+ * other 64 bit version.
247
+ */
248
+ function rsint64(buffer, endian, offset)
249
+ {
250
+ var neg, val;
251
+
252
+ val = ruint64(buffer, endian, offset);
253
+ neg = val[0] & 0x80000000;
254
+
255
+ if (!neg)
256
+ return (val);
257
+
258
+ val[0] = (0xffffffff - val[0]) * -1;
259
+ val[1] = (0xffffffff - val[1] + 1) * -1;
260
+
261
+ return (val);
262
+ }
263
+
264
+ /*
265
+ * We now move onto IEEE 754: The traditional form for floating point numbers
266
+ * and what is secretly hiding at the heart of everything in this. I really hope
267
+ * that someone is actually using this, as otherwise, this effort is probably
268
+ * going to be more wasted.
269
+ *
270
+ * One might be tempted to use parseFloat here, but that wouldn't work at all
271
+ * for several reasons. Mostly due to the way floats actually work, and
272
+ * parseFloat only actually works in base 10. I don't see base 10 anywhere near
273
+ * this file.
274
+ *
275
+ * In this case we'll implement the single and double precision versions. The
276
+ * quadruple precision, while probably useful, wouldn't really be accepted by
277
+ * Javascript, so let's not even waste our time.
278
+ *
279
+ * So let's review how this format looks like. A single precision value is 32
280
+ * bits and has three parts:
281
+ * - Sign bit
282
+ * - Exponent (Using bias notation)
283
+ * - Mantissa
284
+ *
285
+ * |s|eeeeeeee|mmmmmmmmmmmmmmmmmmmmmmmmm|
286
+ * 31| 30-23 | 22 - 0 |
287
+ *
288
+ * The exponent is stored in a biased input. The bias in this case 127.
289
+ * Therefore, our exponent is equal to the 8-bit value - 127.
290
+ *
291
+ * By default, a number is normalized in IEEE, that means that the mantissa has
292
+ * an implicit one that we don't see. So really the value stored is 1.m.
293
+ * However, if the exponent is all zeros, then instead we have to shift
294
+ * everything to the right one and there is no more implicit one.
295
+ *
296
+ * Special values:
297
+ * - Positive Infinity:
298
+ * Sign: 0
299
+ * Exponent: All 1s
300
+ * Mantissa: 0
301
+ * - Negative Infinity:
302
+ * Sign: 1
303
+ * Exponent: All 1s
304
+ * Mantissa: 0
305
+ * - NaN:
306
+ * Sign: *
307
+ * Exponent: All 1s
308
+ * Mantissa: non-zero
309
+ * - Zero:
310
+ * Sign: *
311
+ * Exponent: All 0s
312
+ * Mantissa: 0
313
+ *
314
+ * In the case of zero, the sign bit determines whether we get a positive or
315
+ * negative zero. However, since Javascript cannot determine the difference
316
+ * between the two: i.e. -0 == 0, we just always return 0.
317
+ *
318
+ */
319
+ function rfloat(buffer, endian, offset)
320
+ {
321
+ var bytes = [];
322
+ var sign, exponent, mantissa, val;
323
+ var bias = 127;
324
+ var maxexp = 0xff;
325
+
326
+ /* Normalize the bytes to be in endian order */
327
+ if (endian == 'big') {
328
+ bytes[0] = buffer[offset];
329
+ bytes[1] = buffer[offset+1];
330
+ bytes[2] = buffer[offset+2];
331
+ bytes[3] = buffer[offset+3];
332
+ } else {
333
+ bytes[3] = buffer[offset];
334
+ bytes[2] = buffer[offset+1];
335
+ bytes[1] = buffer[offset+2];
336
+ bytes[0] = buffer[offset+3];
337
+ }
338
+
339
+ sign = bytes[0] & 0x80;
340
+ exponent = (bytes[0] & 0x7f) << 1;
341
+ exponent |= (bytes[1] & 0x80) >>> 7;
342
+ mantissa = (bytes[1] & 0x7f) << 16;
343
+ mantissa |= bytes[2] << 8;
344
+ mantissa |= bytes[3];
345
+
346
+ /* Check for special cases before we do general parsing */
347
+ if (!sign && exponent == maxexp && mantissa === 0)
348
+ return (Number.POSITIVE_INFINITY);
349
+
350
+ if (sign && exponent == maxexp && mantissa === 0)
351
+ return (Number.NEGATIVE_INFINITY);
352
+
353
+ if (exponent == maxexp && mantissa !== 0)
354
+ return (Number.NaN);
355
+
356
+ /*
357
+ * Javascript really doesn't have support for positive or negative zero.
358
+ * So we're not going to try and give it to you. That would be just
359
+ * plain weird. Besides -0 == 0.
360
+ */
361
+ if (exponent === 0 && mantissa === 0)
362
+ return (0);
363
+
364
+ /*
365
+ * Now we can deal with the bias and the determine whether the mantissa
366
+ * has the implicit one or not.
367
+ */
368
+ exponent -= bias;
369
+ if (exponent == -bias) {
370
+ exponent++;
371
+ val = 0;
372
+ } else {
373
+ val = 1;
374
+ }
375
+
376
+ val = (val + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
377
+
378
+ if (sign)
379
+ val *= -1;
380
+
381
+ return (val);
382
+ }
383
+
384
+ /*
385
+ * Doubles in IEEE 754 are like their brothers except for a few changes and
386
+ * increases in size:
387
+ * - The exponent is now 11 bits
388
+ * - The mantissa is now 52 bits
389
+ * - The bias is now 1023
390
+ *
391
+ * |s|eeeeeeeeeee|mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm|
392
+ * 63| 62 - 52 | 51 - 0 |
393
+ * 63| 62 - 52 | 51 - 0 |
394
+ *
395
+ * While the size has increased a fair amount, we're going to end up keeping the
396
+ * same general formula for calculating the final value. As a reminder, this
397
+ * formula is:
398
+ *
399
+ * (-1)^s * (n + m) * 2^(e-b)
400
+ *
401
+ * Where:
402
+ * s is the sign bit
403
+ * n is (exponent > 0) ? 1 : 0 -- Determines whether we're normalized
404
+ * or not
405
+ * m is the mantissa
406
+ * e is the exponent specified
407
+ * b is the bias for the exponent
408
+ *
409
+ */
410
+ function rdouble(buffer, endian, offset)
411
+ {
412
+ var bytes = [];
413
+ var sign, exponent, mantissa, val, lowmant;
414
+ var bias = 1023;
415
+ var maxexp = 0x7ff;
416
+
417
+ /* Normalize the bytes to be in endian order */
418
+ if (endian == 'big') {
419
+ bytes[0] = buffer[offset];
420
+ bytes[1] = buffer[offset+1];
421
+ bytes[2] = buffer[offset+2];
422
+ bytes[3] = buffer[offset+3];
423
+ bytes[4] = buffer[offset+4];
424
+ bytes[5] = buffer[offset+5];
425
+ bytes[6] = buffer[offset+6];
426
+ bytes[7] = buffer[offset+7];
427
+ } else {
428
+ bytes[7] = buffer[offset];
429
+ bytes[6] = buffer[offset+1];
430
+ bytes[5] = buffer[offset+2];
431
+ bytes[4] = buffer[offset+3];
432
+ bytes[3] = buffer[offset+4];
433
+ bytes[2] = buffer[offset+5];
434
+ bytes[1] = buffer[offset+6];
435
+ bytes[0] = buffer[offset+7];
436
+ }
437
+
438
+ /*
439
+ * We can construct the exponent and mantissa the same way as we did in
440
+ * the case of a float, just increase the range of the exponent.
441
+ */
442
+ sign = bytes[0] & 0x80;
443
+ exponent = (bytes[0] & 0x7f) << 4;
444
+ exponent |= (bytes[1] & 0xf0) >>> 4;
445
+
446
+ /*
447
+ * This is going to be ugly but then again, we're dealing with IEEE 754.
448
+ * This could probably be done as a node add on in a few lines of C++,
449
+ * but oh we'll, we've made it this far so let's be native the rest of
450
+ * the way...
451
+ *
452
+ * What we're going to do is break the mantissa into two parts, the
453
+ * lower 24 bits and the upper 28 bits. We'll multiply the upper 28 bits
454
+ * by the appropriate power and then add in the lower 24-bits. Not
455
+ * really that great. It's pretty much a giant kludge to deal with
456
+ * Javascript eccentricities around numbers.
457
+ */
458
+ lowmant = bytes[7];
459
+ lowmant |= bytes[6] << 8;
460
+ lowmant |= bytes[5] << 16;
461
+ mantissa = bytes[4];
462
+ mantissa |= bytes[3] << 8;
463
+ mantissa |= bytes[2] << 16;
464
+ mantissa |= (bytes[1] & 0x0f) << 24;
465
+ mantissa *= Math.pow(2, 24); /* Equivalent to << 24, but JS compat */
466
+ mantissa += lowmant;
467
+
468
+ /* Check for special cases before we do general parsing */
469
+ if (!sign && exponent == maxexp && mantissa === 0)
470
+ return (Number.POSITIVE_INFINITY);
471
+
472
+ if (sign && exponent == maxexp && mantissa === 0)
473
+ return (Number.NEGATIVE_INFINITY);
474
+
475
+ if (exponent == maxexp && mantissa !== 0)
476
+ return (Number.NaN);
477
+
478
+ /*
479
+ * Javascript really doesn't have support for positive or negative zero.
480
+ * So we're not going to try and give it to you. That would be just
481
+ * plain weird. Besides -0 == 0.
482
+ */
483
+ if (exponent === 0 && mantissa === 0)
484
+ return (0);
485
+
486
+ /*
487
+ * Now we can deal with the bias and the determine whether the mantissa
488
+ * has the implicit one or not.
489
+ */
490
+ exponent -= bias;
491
+ if (exponent == -bias) {
492
+ exponent++;
493
+ val = 0;
494
+ } else {
495
+ val = 1;
496
+ }
497
+
498
+ val = (val + mantissa * Math.pow(2, -52)) * Math.pow(2, exponent);
499
+
500
+ if (sign)
501
+ val *= -1;
502
+
503
+ return (val);
504
+ }
505
+
506
+ /*
507
+ * Now that we have gone through the pain of reading the individual types, we're
508
+ * probably going to want some way to write these back. None of this is going to
509
+ * be good. But since we have Javascript numbers this should certainly be more
510
+ * interesting. Though we can constrain this end a little bit more in what is
511
+ * valid. For now, let's go back to our friends the unsigned value.
512
+ */
513
+
514
+ /*
515
+ * Unsigned numbers seem deceptively easy. Here are the general steps and rules
516
+ * that we are going to take:
517
+ * - If the number is negative, throw an Error
518
+ * - Truncate any floating point portion
519
+ * - Take the modulus of the number in our base
520
+ * - Write it out to the buffer in the endian format requested at the offset
521
+ */
522
+
523
+ /*
524
+ * We have to make sure that the value is a valid integer. This means that it is
525
+ * non-negative. It has no fractional component and that it does not exceed the
526
+ * maximum allowed value.
527
+ *
528
+ * value The number to check for validity
529
+ *
530
+ * max The maximum value
531
+ */
532
+ function prepuint(value, max)
533
+ {
534
+ if (typeof (value) != 'number')
535
+ throw (new (Error('cannot write a non-number as a number')));
536
+
537
+ if (value < 0)
538
+ throw (new Error('specified a negative value for writing an ' +
539
+ 'unsigned value'));
540
+
541
+ if (value > max)
542
+ throw (new Error('value is larger than maximum value for ' +
543
+ 'type'));
544
+
545
+ if (Math.floor(value) !== value)
546
+ throw (new Error('value has a fractional component'));
547
+
548
+ return (value);
549
+ }
550
+
551
+ /*
552
+ * 8-bit version, classy. We can ignore endianness which is good.
553
+ */
554
+ function wuint8(value, endian, buffer, offset)
555
+ {
556
+ var val;
557
+
558
+ val = prepuint(value, 0xff);
559
+ buffer[offset] = val;
560
+ }
561
+
562
+ /*
563
+ * Pretty much the same as the 8-bit version, just this time we need to worry
564
+ * about endian related issues.
565
+ */
566
+ function wuint16(value, endian, buffer, offset)
567
+ {
568
+ var val;
569
+
570
+ val = prepuint(value, 0xffff);
571
+ if (endian == 'big') {
572
+ buffer[offset] = (val & 0xff00) >>> 8;
573
+ buffer[offset+1] = val & 0x00ff;
574
+ } else {
575
+ buffer[offset+1] = (val & 0xff00) >>> 8;
576
+ buffer[offset] = val & 0x00ff;
577
+ }
578
+ }
579
+
580
+ /*
581
+ * The 32-bit version is going to have to be a little different unfortunately.
582
+ * We can't quite bitshift to get the largest byte, because that would end up
583
+ * getting us caught by the signed values.
584
+ *
585
+ * And yes, we do want to subtract out the lower part by default. This means
586
+ * that when we do the division, it will be treated as a bit shift and we won't
587
+ * end up generating a floating point value. If we did generate a floating point
588
+ * value we'd have to truncate it intelligently, this saves us that problem and
589
+ * may even be somewhat faster under the hood.
590
+ */
591
+ function wuint32(value, endian, buffer, offset)
592
+ {
593
+ var val;
594
+
595
+ val = prepuint(value, 0xffffffff);
596
+ if (endian == 'big') {
597
+ buffer[offset] = (val - (val & 0x00ffffff)) / Math.pow(2, 24);
598
+ buffer[offset+1] = (val >>> 16) & 0xff;
599
+ buffer[offset+2] = (val >>> 8) & 0xff;
600
+ buffer[offset+3] = val & 0xff;
601
+ } else {
602
+ buffer[offset+3] = (val - (val & 0x00ffffff)) /
603
+ Math.pow(2, 24);
604
+ buffer[offset+2] = (val >>> 16) & 0xff;
605
+ buffer[offset+1] = (val >>> 8) & 0xff;
606
+ buffer[offset] = val & 0xff;
607
+ }
608
+ }
609
+
610
+ /*
611
+ * Unlike the other versions, we expect the value to be in the form of two
612
+ * arrays where value[0] << 32 + value[1] would result in the value that we
613
+ * want.
614
+ */
615
+ function wuint64(value, endian, buffer, offset)
616
+ {
617
+ prepuint(value[0], 0xffffffff);
618
+ prepuint(value[1], 0xffffffff);
619
+
620
+ if (endian == 'big') {
621
+ wuint32(value[0], endian, buffer, offset);
622
+ wuint32(value[1], endian, buffer, offset+4);
623
+ } else {
624
+ wuint32(value[0], endian, buffer, offset+4);
625
+ wuint32(value[1], endian, buffer, offset);
626
+ }
627
+ }
628
+
629
+ /*
630
+ * We now move onto our friends in the signed number category. Unlike unsigned
631
+ * numbers, we're going to have to worry a bit more about how we put values into
632
+ * arrays. Since we are only worrying about signed 32-bit values, we're in
633
+ * slightly better shape. Unfortunately, we really can't do our favorite binary
634
+ * & in this system. It really seems to do the wrong thing. For example:
635
+ *
636
+ * > -32 & 0xff
637
+ * 224
638
+ *
639
+ * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
640
+ * this aren't treated as a signed number. Ultimately a bad thing.
641
+ *
642
+ * What we're going to want to do is basically create the unsigned equivalent of
643
+ * our representation and pass that off to the wuint* functions. To do that
644
+ * we're going to do the following:
645
+ *
646
+ * - if the value is positive
647
+ * we can pass it directly off to the equivalent wuint
648
+ * - if the value is negative
649
+ * we do the following computation:
650
+ * mb + val + 1, where
651
+ * mb is the maximum unsigned value in that byte size
652
+ * val is the Javascript negative integer
653
+ *
654
+ *
655
+ * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
656
+ * you do out the computations:
657
+ *
658
+ * 0xffff - 128 + 1
659
+ * 0xffff - 127
660
+ * 0xff80
661
+ *
662
+ * You can then encode this value as the signed version. This is really rather
663
+ * hacky, but it should work and get the job done which is our goal here.
664
+ *
665
+ * Thus the overall flow is:
666
+ * - Truncate the floating point part of the number
667
+ * - We don't have to take the modulus, because the unsigned versions will
668
+ * take care of that for us. And we don't have to worry about that
669
+ * potentially causing bad things to happen because of sign extension
670
+ * - Pass it off to the appropriate unsigned version, potentially modifying
671
+ * the negative portions as necessary.
672
+ */
673
+
674
+ /*
675
+ * A series of checks to make sure we actually have a signed 32-bit number
676
+ */
677
+ function prepsint(value, max, min)
678
+ {
679
+ if (typeof (value) != 'number')
680
+ throw (new (Error('cannot write a non-number as a number')));
681
+
682
+ if (value > max)
683
+ throw (new Error('value larger than maximum allowed value'));
684
+
685
+ if (value < min)
686
+ throw (new Error('value smaller than minimum allowed value'));
687
+
688
+ if (Math.floor(value) !== value)
689
+ throw (new Error('value has a fractional component'));
690
+
691
+ return (value);
692
+ }
693
+
694
+ /*
695
+ * The 8-bit version of the signed value. Overall, fairly straightforward.
696
+ */
697
+ function wsint8(value, endian, buffer, offset)
698
+ {
699
+ var val;
700
+
701
+ val = prepsint(value, 0x7f, -0xf0);
702
+ if (val >= 0)
703
+ wuint8(val, endian, buffer, offset);
704
+ else
705
+ wuint8(0xff + val + 1, endian, buffer, offset);
706
+ }
707
+
708
+ /*
709
+ * The 16-bit version of the signed value. Also, fairly straightforward.
710
+ */
711
+ function wsint16(value, endian, buffer, offset)
712
+ {
713
+ var val;
714
+
715
+ val = prepsint(value, 0x7fff, -0xf000);
716
+ if (val >= 0)
717
+ wuint16(val, endian, buffer, offset);
718
+ else
719
+ wuint16(0xffff + val + 1, endian, buffer, offset);
720
+
721
+ }
722
+
723
+ /*
724
+ * We can do this relatively easily by leveraging the code used for 32-bit
725
+ * unsigned code.
726
+ */
727
+ function wsint32(value, endian, buffer, offset)
728
+ {
729
+ var val;
730
+
731
+ val = prepsint(value, 0x7fffffff, -0xf0000000);
732
+ if (val >= 0)
733
+ wuint32(val, endian, buffer, offset);
734
+ else
735
+ wuint32(0xffffffff + val + 1, endian, buffer, offset);
736
+ }
737
+
738
+ /*
739
+ * The signed 64 bit integer should by in the same format as when received.
740
+ * Mainly it should ensure that the value is an array of two integers where
741
+ * value[0] << 32 + value[1] is the desired number.
742
+ */
743
+ function wsint64(value, endian, buffer, offset)
744
+ {
745
+ var vals = new Array(2);
746
+
747
+ prepsint(value[0], 0x7fffffff, -0xf0000000);
748
+ prepsint(value[1], 0xffffffff, -0xffffffff);
749
+
750
+ /* Fix negative numbers */
751
+ if (value[0] < 0 || value[1] < 0) {
752
+ vals[0] = 0xffffffff - Math.abs(value[0]);
753
+ vals[1] = 0x100000000 - Math.abs(value[1]);
754
+ if (vals[1] == 0x100000000) {
755
+ vals[1] = 0;
756
+ vals[0]++;
757
+ }
758
+ } else {
759
+ vals[0] = value[0];
760
+ vals[1] = value[1];
761
+ }
762
+
763
+ if (endian == 'big') {
764
+ wuint32(vals[0], endian, buffer, offset);
765
+ wuint32(vals[1], endian, buffer, offset+4);
766
+ } else {
767
+ wuint32(vals[0], endian, buffer, offset+4);
768
+ wuint32(vals[1], endian, buffer, offset);
769
+ }
770
+ }
771
+
772
+ /*
773
+ * Now we are moving onto the weirder of these, the float and double. For this
774
+ * we're going to just have to do something that's pretty weird. First off, we
775
+ * have no way to get at the underlying float representation, at least not
776
+ * easily. But that doesn't mean we can't figure it out, we just have to use our
777
+ * heads.
778
+ *
779
+ * One might propose to use Number.toString(2). Of course, this is not really
780
+ * that good, because the ECMAScript 262 v3 Standard says the following Section
781
+ * 15.7.4.2-Number.prototype.toString (radix):
782
+ *
783
+ * If radix is an integer from 2 to 36, but not 10, the result is a string, the
784
+ * choice of which is implementation-dependent.
785
+ *
786
+ * Well that doesn't really help us one bit now does it? We could use the
787
+ * standard base 10 version of the string, but that's just going to create more
788
+ * errors as we end up trying to convert it back to a binary value. So, really
789
+ * this just means we have to be non-lazy and parse the structure intelligently.
790
+ *
791
+ * First off, we can do the basic checks: NaN, positive and negative infinity.
792
+ *
793
+ * Now that those are done we can work backwards to generate the mantissa and
794
+ * exponent.
795
+ *
796
+ * The first thing we need to do is determine the sign bit, easy to do, check
797
+ * whether the value is less than 0. And convert the number to its absolute
798
+ * value representation. Next, we need to determine if the value is less than
799
+ * one or greater than or equal to one and from there determine what power was
800
+ * used to get there. What follows is now specific to floats, though the general
801
+ * ideas behind this will hold for doubles as well, but the exact numbers
802
+ * involved will change.
803
+ *
804
+ * Once we have that power we can determine the exponent and the mantissa. Call
805
+ * the value that has the number of bits to reach the power ebits. In the
806
+ * general case they have the following values:
807
+ *
808
+ * exponent 127 + ebits
809
+ * mantissa value * 2^(23 - ebits) & 0x7fffff
810
+ *
811
+ * In the case where the value of ebits is <= -127 we are now in the case where
812
+ * we no longer have normalized numbers. In this case the values take on the
813
+ * following values:
814
+ *
815
+ * exponent 0
816
+ * mantissa value * 2^149 & 0x7fffff
817
+ *
818
+ * Once we have the values for the sign, mantissa, and exponent. We reconstruct
819
+ * the four bytes as follows:
820
+ *
821
+ * byte0 sign bit and seven most significant bits from the exp
822
+ * sign << 7 | (exponent & 0xfe) >>> 1
823
+ *
824
+ * byte1 lsb from the exponent and 7 top bits from the mantissa
825
+ * (exponent & 0x01) << 7 | (mantissa & 0x7f0000) >>> 16
826
+ *
827
+ * byte2 bits 8-15 (zero indexing) from mantissa
828
+ * mantissa & 0xff00 >> 8
829
+ *
830
+ * byte3 bits 0-7 from mantissa
831
+ * mantissa & 0xff
832
+ *
833
+ * Once we have this we have to assign them into the buffer in proper endian
834
+ * order.
835
+ */
836
+
837
+ /*
838
+ * Compute the log base 2 of the value. Now, someone who remembers basic
839
+ * properties of logarithms will point out that we could use the change of base
840
+ * formula for logs, and in fact that would be astute, because that's what we'll
841
+ * do for now. It feels cleaner, albeit it may be less efficient than just
842
+ * iterating and dividing by 2. We may want to come back and revisit that some
843
+ * day.
844
+ */
845
+ function log2(value)
846
+ {
847
+ return (Math.log(value) / Math.log(2));
848
+ }
849
+
850
+ /*
851
+ * Helper to determine the exponent of the number we're looking at.
852
+ */
853
+ function intexp(value)
854
+ {
855
+ return (Math.floor(log2(value)));
856
+ }
857
+
858
+ /*
859
+ * Helper to determine the exponent of the fractional part of the value.
860
+ */
861
+ function fracexp(value)
862
+ {
863
+ return (Math.floor(log2(value)));
864
+ }
865
+
866
+ function wfloat(value, endian, buffer, offset)
867
+ {
868
+ var sign, exponent, mantissa, ebits;
869
+ var bytes = [];
870
+
871
+ if (isNaN(value)) {
872
+ sign = 0;
873
+ exponent = 0xff;
874
+ mantissa = 23;
875
+ } else if (value == Number.POSITIVE_INFINITY) {
876
+ sign = 0;
877
+ exponent = 0xff;
878
+ mantissa = 0;
879
+ } else if (value == Number.NEGATIVE_INFINITY) {
880
+ sign = 1;
881
+ exponent = 0xff;
882
+ mantissa = 0;
883
+ } else {
884
+ /* Well we have some work to do */
885
+
886
+ /* Thankfully the sign bit is trivial */
887
+ if (value < 0) {
888
+ sign = 1;
889
+ value = Math.abs(value);
890
+ } else {
891
+ sign = 0;
892
+ }
893
+
894
+ /* Use the correct function to determine number of bits */
895
+ if (value < 1)
896
+ ebits = fracexp(value);
897
+ else
898
+ ebits = intexp(value);
899
+
900
+ /* Time to deal with the issues surrounding normalization */
901
+ if (ebits <= -127) {
902
+ exponent = 0;
903
+ mantissa = (value * Math.pow(2, 149)) & 0x7fffff;
904
+ } else {
905
+ exponent = 127 + ebits;
906
+ mantissa = value * Math.pow(2, 23 - ebits);
907
+ mantissa &= 0x7fffff;
908
+ }
909
+ }
910
+
911
+ bytes[0] = sign << 7 | (exponent & 0xfe) >>> 1;
912
+ bytes[1] = (exponent & 0x01) << 7 | (mantissa & 0x7f0000) >>> 16;
913
+ bytes[2] = (mantissa & 0x00ff00) >>> 8;
914
+ bytes[3] = mantissa & 0x0000ff;
915
+
916
+ if (endian == 'big') {
917
+ buffer[offset] = bytes[0];
918
+ buffer[offset+1] = bytes[1];
919
+ buffer[offset+2] = bytes[2];
920
+ buffer[offset+3] = bytes[3];
921
+ } else {
922
+ buffer[offset] = bytes[3];
923
+ buffer[offset+1] = bytes[2];
924
+ buffer[offset+2] = bytes[1];
925
+ buffer[offset+3] = bytes[0];
926
+ }
927
+ }
928
+
929
+ /*
930
+ * Now we move onto doubles. Doubles are similar to floats in pretty much all
931
+ * ways except that the processing isn't quite as straightforward because we
932
+ * can't always use shifting, i.e. we have > 32 bit values.
933
+ *
934
+ * We're going to proceed in an identical fashion to floats and utilize the same
935
+ * helper functions. All that really is changing are the specific values that we
936
+ * use to do the calculations. Thus, to review we have to do the following.
937
+ *
938
+ * First get the sign bit and convert the value to its absolute value
939
+ * representation. Next, we determine the number of bits that we used to get to
940
+ * the value, branching whether the value is greater than or less than 1. Once
941
+ * we have that value which we will again call ebits, we have to do the
942
+ * following in the general case:
943
+ *
944
+ * exponent 1023 + ebits
945
+ * mantissa [value * 2^(52 - ebits)] % 2^52
946
+ *
947
+ * In the case where the value of ebits <= -1023 we no longer use normalized
948
+ * numbers, thus like with floats we have to do slightly different processing:
949
+ *
950
+ * exponent 0
951
+ * mantissa [value * 2^1074] % 2^52
952
+ *
953
+ * Once we have determined the sign, exponent and mantissa we can construct the
954
+ * bytes as follows:
955
+ *
956
+ * byte0 sign bit and seven most significant bits form the exp
957
+ * sign << 7 | (exponent & 0x7f0) >>> 4
958
+ *
959
+ * byte1 Remaining 4 bits from the exponent and the four most
960
+ * significant bits from the mantissa 48-51
961
+ * (exponent & 0x00f) << 4 | mantissa >>> 48
962
+ *
963
+ * byte2 Bits 40-47 from the mantissa
964
+ * (mantissa >>> 40) & 0xff
965
+ *
966
+ * byte3 Bits 32-39 from the mantissa
967
+ * (mantissa >>> 32) & 0xff
968
+ *
969
+ * byte4 Bits 24-31 from the mantissa
970
+ * (mantissa >>> 24) & 0xff
971
+ *
972
+ * byte5 Bits 16-23 from the Mantissa
973
+ * (mantissa >>> 16) & 0xff
974
+ *
975
+ * byte6 Bits 8-15 from the mantissa
976
+ * (mantissa >>> 8) & 0xff
977
+ *
978
+ * byte7 Bits 0-7 from the mantissa
979
+ * mantissa & 0xff
980
+ *
981
+ * Now we can't quite do the right shifting that we want in bytes 1 - 3, because
982
+ * we'll have extended too far and we'll lose those values when we try and do
983
+ * the shift. Instead we have to use an alternate approach. To try and stay out
984
+ * of floating point, what we'll do is say that mantissa -= bytes[4-7] and then
985
+ * divide by 2^32. Once we've done that we can use binary arithmetic. Oof,
986
+ * that's ugly, but it seems to avoid using floating point (just based on how v8
987
+ * seems to be optimizing for base 2 arithmetic).
988
+ */
989
+ function wdouble(value, endian, buffer, offset)
990
+ {
991
+ var sign, exponent, mantissa, ebits;
992
+ var bytes = [];
993
+
994
+ if (isNaN(value)) {
995
+ sign = 0;
996
+ exponent = 0x7ff;
997
+ mantissa = 23;
998
+ } else if (value == Number.POSITIVE_INFINITY) {
999
+ sign = 0;
1000
+ exponent = 0x7ff;
1001
+ mantissa = 0;
1002
+ } else if (value == Number.NEGATIVE_INFINITY) {
1003
+ sign = 1;
1004
+ exponent = 0x7ff;
1005
+ mantissa = 0;
1006
+ } else {
1007
+ /* Well we have some work to do */
1008
+
1009
+ /* Thankfully the sign bit is trivial */
1010
+ if (value < 0) {
1011
+ sign = 1;
1012
+ value = Math.abs(value);
1013
+ } else {
1014
+ sign = 0;
1015
+ }
1016
+
1017
+ /* Use the correct function to determine number of bits */
1018
+ if (value < 1)
1019
+ ebits = fracexp(value);
1020
+ else
1021
+ ebits = intexp(value);
1022
+
1023
+ /*
1024
+ * This is a total hack to determine a denormalized value.
1025
+ * Unfortunately, we sometimes do not get a proper value for
1026
+ * ebits, i.e. we lose the values that would get rounded off.
1027
+ *
1028
+ *
1029
+ * The astute observer may wonder why we would be
1030
+ * multiplying by two Math.pows rather than just summing
1031
+ * them. Well, that's to get around a small bug in the
1032
+ * way v8 seems to implement the function. On occasion
1033
+ * doing:
1034
+ *
1035
+ * foo * Math.pow(2, 1023 + 51)
1036
+ *
1037
+ * Causes us to overflow to infinity, where as doing:
1038
+ *
1039
+ * foo * Math.pow(2, 1023) * Math.pow(2, 51)
1040
+ *
1041
+ * Does not cause us to overflow. Go figure.
1042
+ *
1043
+ */
1044
+ if (value <= 2.225073858507201e-308 || ebits <= -1023) {
1045
+ exponent = 0;
1046
+ mantissa = value * Math.pow(2, 1023) * Math.pow(2, 51);
1047
+ mantissa %= Math.pow(2, 52);
1048
+ } else {
1049
+ /*
1050
+ * We might have gotten fucked by our floating point
1051
+ * logarithm magic. This is rather crappy, but that's
1052
+ * our luck. If we just had a log base 2 or access to
1053
+ * the stupid underlying representation this would have
1054
+ * been much easier and we wouldn't have such stupid
1055
+ * kludges or hacks.
1056
+ */
1057
+ if (ebits > 1023)
1058
+ ebits = 1023;
1059
+ exponent = 1023 + ebits;
1060
+ mantissa = value * Math.pow(2, -ebits);
1061
+ mantissa *= Math.pow(2, 52);
1062
+ mantissa %= Math.pow(2, 52);
1063
+ }
1064
+ }
1065
+
1066
+ /* Fill the bytes in backwards to deal with the size issues */
1067
+ bytes[7] = mantissa & 0xff;
1068
+ bytes[6] = (mantissa >>> 8) & 0xff;
1069
+ bytes[5] = (mantissa >>> 16) & 0xff;
1070
+ mantissa = (mantissa - (mantissa & 0xffffff)) / Math.pow(2, 24);
1071
+ bytes[4] = mantissa & 0xff;
1072
+ bytes[3] = (mantissa >>> 8) & 0xff;
1073
+ bytes[2] = (mantissa >>> 16) & 0xff;
1074
+ bytes[1] = (exponent & 0x00f) << 4 | mantissa >>> 24;
1075
+ bytes[0] = (sign << 7) | (exponent & 0x7f0) >>> 4;
1076
+
1077
+ if (endian == 'big') {
1078
+ buffer[offset] = bytes[0];
1079
+ buffer[offset+1] = bytes[1];
1080
+ buffer[offset+2] = bytes[2];
1081
+ buffer[offset+3] = bytes[3];
1082
+ buffer[offset+4] = bytes[4];
1083
+ buffer[offset+5] = bytes[5];
1084
+ buffer[offset+6] = bytes[6];
1085
+ buffer[offset+7] = bytes[7];
1086
+ } else {
1087
+ buffer[offset+7] = bytes[0];
1088
+ buffer[offset+6] = bytes[1];
1089
+ buffer[offset+5] = bytes[2];
1090
+ buffer[offset+4] = bytes[3];
1091
+ buffer[offset+3] = bytes[4];
1092
+ buffer[offset+2] = bytes[5];
1093
+ buffer[offset+1] = bytes[6];
1094
+ buffer[offset] = bytes[7];
1095
+ }
1096
+ }
1097
+
1098
+ /*
1099
+ * Actually export our work above. One might argue that we shouldn't expose
1100
+ * these interfaces and just force people to use the higher level abstractions
1101
+ * around this work. However, unlike say other libraries we've come across, this
1102
+ * interface has several properties: it makes sense, it's simple, and it's
1103
+ * useful.
1104
+ */
1105
+ exports.ruint8 = ruint8;
1106
+ exports.ruint16 = ruint16;
1107
+ exports.ruint32 = ruint32;
1108
+ exports.ruint64 = ruint64;
1109
+ exports.wuint8 = wuint8;
1110
+ exports.wuint16 = wuint16;
1111
+ exports.wuint32 = wuint32;
1112
+ exports.wuint64 = wuint64;
1113
+
1114
+ exports.rsint8 = rsint8;
1115
+ exports.rsint16 = rsint16;
1116
+ exports.rsint32 = rsint32;
1117
+ exports.rsint64 = rsint64;
1118
+ exports.wsint8 = wsint8;
1119
+ exports.wsint16 = wsint16;
1120
+ exports.wsint32 = wsint32;
1121
+ exports.wsint64 = wsint64;
1122
+
1123
+ exports.rfloat = rfloat;
1124
+ exports.rdouble = rdouble;
1125
+ exports.wfloat = wfloat;
1126
+ exports.wdouble = wdouble;