surpass 0.0.4 → 0.0.6

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 (259) hide show
  1. data/History.txt +4 -0
  2. data/README.txt +3 -20
  3. data/Rakefile +2 -13
  4. data/bin/surpass +8 -0
  5. data/examples/big-16mb.rb +25 -0
  6. data/examples/big-random-strings.rb +28 -0
  7. data/examples/blanks.rb +34 -0
  8. data/examples/blanks.xls +0 -0
  9. data/examples/col_width.rb +16 -0
  10. data/examples/col_width.xls +0 -0
  11. data/examples/dates.rb +31 -0
  12. data/examples/dates.xls +0 -0
  13. data/examples/format.rb +23 -0
  14. data/examples/format.xls +0 -0
  15. data/examples/hello-world.rb +9 -0
  16. data/examples/hello-world.xls +0 -0
  17. data/examples/image.rb +10 -0
  18. data/examples/image.xls +0 -0
  19. data/examples/merged.rb +36 -0
  20. data/examples/merged.xls +0 -0
  21. data/examples/merged0.rb +27 -0
  22. data/examples/merged0.xls +0 -0
  23. data/examples/merged1.rb +99 -0
  24. data/examples/merged1.xls +0 -0
  25. data/examples/num_formats.rb +55 -0
  26. data/examples/num_formats.xls +0 -0
  27. data/examples/numbers.rb +24 -0
  28. data/examples/numbers.xls +0 -0
  29. data/examples/outline.rb +110 -0
  30. data/examples/outline.xls +0 -0
  31. data/examples/panes.rb +48 -0
  32. data/examples/panes.xls +0 -0
  33. data/examples/protection.rb +132 -0
  34. data/examples/protection.xls +0 -0
  35. data/examples/python.bmp +0 -0
  36. data/examples/row_styles.rb +16 -0
  37. data/examples/row_styles.xls +0 -0
  38. data/examples/row_styles_empty.rb +15 -0
  39. data/examples/row_styles_empty.xls +0 -0
  40. data/examples/set_cell_and_range_style.rb +12 -0
  41. data/examples/set_cell_and_range_style.xls +0 -0
  42. data/examples/wrapped-text.rb +13 -0
  43. data/examples/wrapped-text.xls +0 -0
  44. data/examples/write_arrays.rb +22 -0
  45. data/examples/write_arrays.xls +0 -0
  46. data/examples/ws_props.rb +80 -0
  47. data/lib/surpass/ExcelFormula.g +366 -0
  48. data/lib/surpass/ExcelFormula.tokens +30 -0
  49. data/lib/surpass/ExcelFormulaLexer.rb +922 -0
  50. data/lib/surpass/ExcelFormulaParser.rb +602 -0
  51. data/lib/{biff_record.rb → surpass/biff_record.rb} +0 -0
  52. data/lib/{bitmap.rb → surpass/bitmap.rb} +0 -0
  53. data/lib/{cell.rb → surpass/cell.rb} +2 -34
  54. data/lib/{chart.rb → surpass/chart.rb} +0 -0
  55. data/lib/{column.rb → surpass/column.rb} +0 -0
  56. data/lib/{document.rb → surpass/document.rb} +0 -0
  57. data/lib/surpass/excel_formula.rb +23 -0
  58. data/lib/{excel_magic.rb → surpass/excel_magic.rb} +0 -0
  59. data/lib/{formatting.rb → surpass/formatting.rb} +93 -53
  60. data/lib/{row.rb → surpass/row.rb} +0 -0
  61. data/lib/{style.rb → surpass/style.rb} +2 -1
  62. data/lib/surpass/tokens.txt +2 -0
  63. data/lib/{utilities.rb → surpass/utilities.rb} +0 -0
  64. data/lib/{workbook.rb → surpass/workbook.rb} +0 -0
  65. data/lib/{worksheet.rb → surpass/worksheet.rb} +15 -6
  66. data/lib/surpass.rb +1 -1
  67. data/spec/biff_record_spec.rb +268 -0
  68. data/spec/cell_spec.rb +56 -0
  69. data/spec/data/random-strings.txt +10000 -0
  70. data/spec/document_spec.rb +168 -0
  71. data/spec/excel_formula_spec.rb +27 -0
  72. data/spec/formatting_spec.rb +53 -0
  73. data/spec/output/cells-rk.xls +0 -0
  74. data/spec/output/cells.xls +0 -0
  75. data/spec/output/mini.xls +0 -0
  76. data/spec/reference/P-0508-0000507647-3280-5298.xls +0 -0
  77. data/spec/reference/all-cell-styles.bin +0 -0
  78. data/spec/reference/all-number-formats.bin +0 -0
  79. data/spec/reference/all-styles.bin +0 -0
  80. data/spec/reference/mini.xls +0 -0
  81. data/spec/row_spec.rb +19 -0
  82. data/spec/spec_helper.rb +10 -0
  83. data/spec/style_spec.rb +89 -0
  84. data/spec/surpass_spec.rb +7 -0
  85. data/spec/utilities_spec.rb +57 -0
  86. data/spec/workbook_spec.rb +48 -0
  87. data/spec/worksheet_spec.rb +0 -0
  88. data/stats/cloc.txt +8 -0
  89. data/stats/rcov.txt +0 -0
  90. data/stats/specdoc.txt +158 -0
  91. data/surpass.gemspec +40 -0
  92. data/tasks/setup.rb +1 -1
  93. data/tasks/zentest.rake +36 -0
  94. data/webby/README.txt +6 -0
  95. data/webby/Sitefile +43 -0
  96. data/webby/content/css/pygments.txt +6 -0
  97. data/webby/content/css/style.css +279 -0
  98. data/webby/content/examples/autoformat.png +0 -0
  99. data/webby/content/examples/autoformat.rb +32 -0
  100. data/webby/content/examples/autoformat.xls +0 -0
  101. data/webby/content/examples/borders.png +0 -0
  102. data/webby/content/examples/borders.rb +15 -0
  103. data/webby/content/examples/borders.xls +0 -0
  104. data/webby/content/examples/colours.png +0 -0
  105. data/webby/content/examples/colours.rb +23 -0
  106. data/webby/content/examples/colours.xls +0 -0
  107. data/webby/content/examples/data.png +0 -0
  108. data/webby/content/examples/data.rb +11 -0
  109. data/webby/content/examples/data.xls +0 -0
  110. data/webby/content/examples/formatting.png +0 -0
  111. data/webby/content/examples/formatting.rb +78 -0
  112. data/webby/content/examples/formatting.xls +0 -0
  113. data/webby/content/examples/hello-world.png +0 -0
  114. data/webby/content/examples/hello-world.py +8 -0
  115. data/webby/content/examples/hello-world.rb +9 -0
  116. data/webby/content/examples/hello-world.xls +0 -0
  117. data/webby/content/examples/number-format-string.png +0 -0
  118. data/webby/content/examples/number-format-string.rb +14 -0
  119. data/webby/content/examples/number-format-string.xls +0 -0
  120. data/webby/content/examples/patterns.png +0 -0
  121. data/webby/content/examples/patterns.rb +26 -0
  122. data/webby/content/examples/patterns.xls +0 -0
  123. data/webby/content/examples/show-greens.sh +1 -0
  124. data/webby/content/examples/surpass-info.sh +1 -0
  125. data/webby/content/img/Thumbs.db +0 -0
  126. data/webby/content/img/bg_menu.gif +0 -0
  127. data/webby/content/img/bg_t.gif +0 -0
  128. data/webby/content/img/bullet.gif +0 -0
  129. data/webby/content/img/logo.png +0 -0
  130. data/webby/content/img/logo_.jpg +0 -0
  131. data/webby/content/img/top_bg.gif +0 -0
  132. data/webby/content/img/top_bg_.gif +0 -0
  133. data/webby/content/index.txt +16 -0
  134. data/webby/content/installation/index.txt +24 -0
  135. data/webby/content/source/ExcelFormulaLexer.txt +7 -0
  136. data/webby/content/source/ExcelFormulaParser.txt +7 -0
  137. data/webby/content/source/biff_record.txt +7 -0
  138. data/webby/content/source/bitmap.txt +7 -0
  139. data/webby/content/source/cell.txt +7 -0
  140. data/webby/content/source/chart.txt +7 -0
  141. data/webby/content/source/column.txt +7 -0
  142. data/webby/content/source/document.txt +7 -0
  143. data/webby/content/source/excel_formula.txt +7 -0
  144. data/webby/content/source/excel_magic.txt +7 -0
  145. data/webby/content/source/formatting.txt +7 -0
  146. data/webby/content/source/row.txt +7 -0
  147. data/webby/content/source/style.txt +7 -0
  148. data/webby/content/source/utilities.txt +7 -0
  149. data/webby/content/source/workbook.txt +7 -0
  150. data/webby/content/source/worksheet.txt +7 -0
  151. data/webby/content/surpass-manual.erb +198 -0
  152. data/webby/layouts/book.txt +29 -0
  153. data/webby/layouts/default.txt +27 -0
  154. data/webby/layouts/two_column.txt +25 -0
  155. data/webby/layouts/web.txt +66 -0
  156. data/webby/output/.cairn +0 -0
  157. data/webby/output/css/blueprint/ie.css +26 -0
  158. data/webby/output/css/blueprint/plugins/buttons/icons/cross.png +0 -0
  159. data/webby/output/css/blueprint/plugins/buttons/icons/key.png +0 -0
  160. data/webby/output/css/blueprint/plugins/buttons/icons/tick.png +0 -0
  161. data/webby/output/css/blueprint/plugins/buttons/readme.txt +32 -0
  162. data/webby/output/css/blueprint/plugins/buttons/screen.css +97 -0
  163. data/webby/output/css/blueprint/plugins/fancy-type/readme.txt +14 -0
  164. data/webby/output/css/blueprint/plugins/fancy-type/screen.css +71 -0
  165. data/webby/output/css/blueprint/plugins/link-icons/icons/doc.png +0 -0
  166. data/webby/output/css/blueprint/plugins/link-icons/icons/email.png +0 -0
  167. data/webby/output/css/blueprint/plugins/link-icons/icons/external.png +0 -0
  168. data/webby/output/css/blueprint/plugins/link-icons/icons/feed.png +0 -0
  169. data/webby/output/css/blueprint/plugins/link-icons/icons/im.png +0 -0
  170. data/webby/output/css/blueprint/plugins/link-icons/icons/pdf.png +0 -0
  171. data/webby/output/css/blueprint/plugins/link-icons/icons/visited.png +0 -0
  172. data/webby/output/css/blueprint/plugins/link-icons/icons/xls.png +0 -0
  173. data/webby/output/css/blueprint/plugins/link-icons/readme.txt +18 -0
  174. data/webby/output/css/blueprint/plugins/link-icons/screen.css +40 -0
  175. data/webby/output/css/blueprint/plugins/rtl/readme.txt +10 -0
  176. data/webby/output/css/blueprint/plugins/rtl/screen.css +109 -0
  177. data/webby/output/css/blueprint/print.css +30 -0
  178. data/webby/output/css/blueprint/screen.css +251 -0
  179. data/webby/output/css/blueprint/src/forms.css +49 -0
  180. data/webby/output/css/blueprint/src/grid.css +212 -0
  181. data/webby/output/css/blueprint/src/grid.png +0 -0
  182. data/webby/output/css/blueprint/src/ie.css +59 -0
  183. data/webby/output/css/blueprint/src/print.css +85 -0
  184. data/webby/output/css/blueprint/src/reset.css +38 -0
  185. data/webby/output/css/blueprint/src/typography.css +105 -0
  186. data/webby/output/css/pygments.css +59 -0
  187. data/webby/output/css/site.css +62 -0
  188. data/webby/output/css/style.css +279 -0
  189. data/webby/output/examples/autoformat.png +0 -0
  190. data/webby/output/examples/autoformat.rb +32 -0
  191. data/webby/output/examples/autoformat.xls +0 -0
  192. data/webby/output/examples/borders.png +0 -0
  193. data/webby/output/examples/borders.rb +15 -0
  194. data/webby/output/examples/borders.xls +0 -0
  195. data/webby/output/examples/colours.png +0 -0
  196. data/webby/output/examples/colours.rb +23 -0
  197. data/webby/output/examples/colours.xls +0 -0
  198. data/webby/output/examples/data.png +0 -0
  199. data/webby/output/examples/data.rb +11 -0
  200. data/webby/output/examples/data.xls +0 -0
  201. data/webby/output/examples/formatting.png +0 -0
  202. data/webby/output/examples/formatting.rb +78 -0
  203. data/webby/output/examples/formatting.xls +0 -0
  204. data/webby/output/examples/hello-world.png +0 -0
  205. data/webby/output/examples/hello-world.py +8 -0
  206. data/webby/output/examples/hello-world.rb +9 -0
  207. data/webby/output/examples/hello-world.xls +0 -0
  208. data/webby/output/examples/number-format-string.png +0 -0
  209. data/webby/output/examples/number-format-string.rb +14 -0
  210. data/webby/output/examples/number-format-string.xls +0 -0
  211. data/webby/output/examples/patterns.png +0 -0
  212. data/webby/output/examples/patterns.rb +26 -0
  213. data/webby/output/examples/patterns.xls +0 -0
  214. data/webby/output/examples/show-greens.sh +1 -0
  215. data/webby/output/examples/surpass-info.sh +1 -0
  216. data/webby/output/img/Thumbs.db +0 -0
  217. data/webby/output/img/bg_menu.gif +0 -0
  218. data/webby/output/img/bg_t.gif +0 -0
  219. data/webby/output/img/bullet.gif +0 -0
  220. data/webby/output/img/logo.png +0 -0
  221. data/webby/output/img/logo_.jpg +0 -0
  222. data/webby/output/img/top_bg.gif +0 -0
  223. data/webby/output/img/top_bg_.gif +0 -0
  224. data/webby/output/index.html +138 -0
  225. data/webby/output/installation/index.html +64 -0
  226. data/webby/output/installation/installation.html +1 -0
  227. data/webby/output/installation.html +1 -0
  228. data/webby/output/source/ExcelFormulaLexer.html +981 -0
  229. data/webby/output/source/ExcelFormulaParser.html +661 -0
  230. data/webby/output/source/biff_record.html +462 -0
  231. data/webby/output/source/bitmap.html +277 -0
  232. data/webby/output/source/cell.html +241 -0
  233. data/webby/output/source/chart.html +64 -0
  234. data/webby/output/source/column.html +99 -0
  235. data/webby/output/source/document.html +465 -0
  236. data/webby/output/source/excel_formula.html +82 -0
  237. data/webby/output/source/excel_magic.html +1072 -0
  238. data/webby/output/source/formatting.html +664 -0
  239. data/webby/output/source/row.html +169 -0
  240. data/webby/output/source/style.html +158 -0
  241. data/webby/output/source/surpass.html +110 -0
  242. data/webby/output/source/utilities.html +145 -0
  243. data/webby/output/source/workbook.html +265 -0
  244. data/webby/output/source/worksheet.html +331 -0
  245. data/webby/output/surpass-manual-0-0-5.pdf +0 -0
  246. data/webby/output/surpass-manual.aux +50 -0
  247. data/webby/output/surpass-manual.log +366 -0
  248. data/webby/output/surpass-manual.out +20 -0
  249. data/webby/output/surpass-manual.tex +582 -0
  250. data/webby/output/surpass-manual.toc +20 -0
  251. data/webby/rsync-exclude +7 -0
  252. data/webby/tasks/latex.rake +14 -0
  253. data/webby/tasks/screenshots.rb +58 -0
  254. data/webby/templates/article.erb +15 -0
  255. data/webby/templates/book.erb +16 -0
  256. data/webby/templates/page.erb +9 -0
  257. metadata +302 -24
  258. data/bin/surpass-info +0 -20
  259. data/lib/excel_formula.rb +0 -6
@@ -0,0 +1,465 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+
3
+ <!-- ========================================================== -->
4
+ <!-- Created by Devit Schizoper -->
5
+ <!-- Created HomePages http://LoadFoo.starzonewebhost.com -->
6
+ <!-- Created Day 01.12.2006 -->
7
+ <!-- ========================================================== -->
8
+
9
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
10
+ <head>
11
+ <meta http-equiv="content-type" content="text/html;charset=utf-8" />
12
+ <meta name="author" content="LoadFoO" />
13
+ <meta name="description" content="Site description" />
14
+ <meta name="keywords" content="key, words" />
15
+ <title>Surpass :: document.rb</title>
16
+ <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
17
+ <link rel="stylesheet" href="/css/pygments.css" type="text/css" />
18
+ <link rel="shortcut icon" href="favicon.ico" />
19
+ </head>
20
+
21
+ <body>
22
+ <div id="wrap">
23
+ <div id="top">
24
+ <h2><a href="/" title="Back to main page">Surpass</a></h2>
25
+ <div id="menu">
26
+ <ul>
27
+ <li><a href="/installation">Installation</a></li>
28
+ <li><a href="/examples">Examples</a></li>
29
+ <li><a href="/source">Source</a></li>
30
+ </ul>
31
+ </div>
32
+ </div>
33
+ <div id="content">
34
+ <div id="left">
35
+ <h2>document.rb</h2>
36
+ <div class="highlight"><pre><span class="k">class</span> <span class="nc">Reader</span>
37
+ <span class="no">DIR_ENTRY_SIZE</span> <span class="o">=</span> <span class="mi">128</span>
38
+
39
+ <span class="kp">attr_accessor</span> <span class="ss">:header</span>
40
+ <span class="kp">attr_accessor</span> <span class="ss">:data</span>
41
+
42
+ <span class="kp">attr_accessor</span> <span class="ss">:doc_magic</span>
43
+ <span class="kp">attr_accessor</span> <span class="ss">:file_uid</span>
44
+ <span class="kp">attr_accessor</span> <span class="ss">:rev_num</span>
45
+ <span class="kp">attr_accessor</span> <span class="ss">:ver_num</span>
46
+ <span class="kp">attr_accessor</span> <span class="ss">:byte_order</span>
47
+ <span class="kp">attr_accessor</span> <span class="ss">:sect_size</span>
48
+ <span class="kp">attr_accessor</span> <span class="ss">:short_sect_size</span>
49
+
50
+ <span class="kp">attr_accessor</span> <span class="ss">:total_sat_sectors</span>
51
+ <span class="kp">attr_accessor</span> <span class="ss">:dir_start_sid</span>
52
+ <span class="kp">attr_accessor</span> <span class="ss">:min_stream_size</span>
53
+ <span class="kp">attr_accessor</span> <span class="ss">:ssat_start_sid</span>
54
+ <span class="kp">attr_accessor</span> <span class="ss">:total_ssat_sectors</span>
55
+ <span class="kp">attr_accessor</span> <span class="ss">:msat_start_sid</span>
56
+ <span class="kp">attr_accessor</span> <span class="ss">:total_msat_sectors</span>
57
+
58
+ <span class="kp">attr_accessor</span> <span class="ss">:msat</span>
59
+ <span class="kp">attr_accessor</span> <span class="ss">:sat</span>
60
+ <span class="kp">attr_accessor</span> <span class="ss">:ssat</span>
61
+ <span class="kp">attr_accessor</span> <span class="ss">:dir_entry_list</span>
62
+
63
+ <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
64
+ <span class="vi">@streams</span> <span class="o">=</span> <span class="p">{}</span>
65
+
66
+ <span class="n">file</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">unless</span> <span class="n">file</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="ss">:read</span><span class="p">)</span>
67
+ <span class="n">doc</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span>
68
+ <span class="vi">@header</span><span class="p">,</span> <span class="vi">@data</span> <span class="o">=</span> <span class="n">doc</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">512</span><span class="o">]</span><span class="p">,</span> <span class="n">doc</span><span class="o">[</span><span class="mi">512</span><span class="o">.</span><span class="n">.</span><span class="o">-</span><span class="mi">1</span><span class="o">]</span>
69
+
70
+ <span class="n">build_header</span>
71
+ <span class="n">build_msat</span>
72
+ <span class="n">build_sat</span>
73
+ <span class="n">build_directory</span>
74
+ <span class="n">build_short_sectors_data</span>
75
+
76
+ <span class="k">if</span> <span class="vi">@short_sectors_data</span><span class="o">.</span><span class="n">length</span> <span class="o">&gt;</span> <span class="mi">0</span>
77
+ <span class="n">build_ssat</span>
78
+ <span class="k">else</span>
79
+ <span class="vi">@ssat_start_sid</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span>
80
+ <span class="vi">@total_ssat_sectors</span> <span class="o">=</span> <span class="mi">0</span>
81
+ <span class="vi">@ssat</span> <span class="o">=</span> <span class="o">[-</span><span class="mi">2</span><span class="o">]</span>
82
+ <span class="k">end</span>
83
+
84
+ <span class="vi">@dir_entry_list</span><span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="o">-</span><span class="mi">1</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">d</span><span class="o">|</span>
85
+ <span class="n">did</span><span class="p">,</span> <span class="n">sz</span><span class="p">,</span> <span class="nb">name</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">dentry_start_sid</span><span class="p">,</span> <span class="n">stream_size</span> <span class="o">=</span> <span class="n">d</span>
86
+ <span class="n">stream_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
87
+ <span class="k">if</span> <span class="n">stream_size</span> <span class="o">&gt;</span> <span class="mi">0</span>
88
+ <span class="k">if</span> <span class="n">stream_size</span> <span class="o">&gt;</span> <span class="vi">@min_stream_size</span>
89
+ <span class="n">args</span> <span class="o">=</span> <span class="o">[</span><span class="vi">@data</span><span class="p">,</span> <span class="vi">@sat</span><span class="p">,</span> <span class="n">dentry_start_sid</span><span class="p">,</span> <span class="vi">@sect_size</span><span class="o">]</span>
90
+ <span class="k">else</span>
91
+ <span class="n">args</span> <span class="o">=</span> <span class="o">[</span><span class="vi">@short_sectors_data</span><span class="p">,</span> <span class="vi">@ssat</span><span class="p">,</span> <span class="n">dentry_start_sid</span><span class="p">,</span> <span class="vi">@short_sect_size</span><span class="o">]</span>
92
+ <span class="k">end</span>
93
+ <span class="n">stream_data</span> <span class="o">=</span> <span class="n">stream_data</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
94
+ <span class="k">end</span>
95
+ <span class="c1"># BAD IDEA: names may be equal. NEED use full paths...</span>
96
+ <span class="vi">@streams</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="o">=</span> <span class="n">stream_data</span> <span class="k">if</span> <span class="o">!</span><span class="nb">name</span><span class="o">.</span><span class="n">length</span> <span class="o">==</span> <span class="mi">0</span>
97
+ <span class="k">end</span>
98
+ <span class="k">end</span>
99
+
100
+ <span class="k">def</span> <span class="nf">build_header</span>
101
+ <span class="vi">@doc_magic</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">8</span><span class="o">]</span>
102
+ <span class="k">raise</span> <span class="s1">&#39;Not an OLE file.&#39;</span> <span class="k">unless</span> <span class="vi">@doc_magic</span> <span class="o">===</span> <span class="s2">&quot;</span><span class="se">\320\317\021\340\241\261\032\341</span><span class="s2">&quot;</span>
103
+
104
+ <span class="vi">@file_uid</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">8</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">24</span><span class="o">]</span>
105
+ <span class="vi">@rev_num</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">24</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">26</span><span class="o">]</span>
106
+ <span class="vi">@ver_num</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">26</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">28</span><span class="o">]</span>
107
+ <span class="vi">@byte_order</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">28</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">30</span><span class="o">]</span>
108
+ <span class="vi">@log2_sect_size</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">30</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">32</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;v&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
109
+ <span class="vi">@log2_short_sect_size</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">32</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">34</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;v&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
110
+ <span class="vi">@total_sat_sectors</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">44</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">48</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
111
+ <span class="vi">@dir_start_sid</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">48</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">52</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
112
+ <span class="vi">@min_stream_size</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">56</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">60</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
113
+ <span class="vi">@ssat_start_sid</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">60</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">64</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
114
+ <span class="vi">@total_ssat_sectors</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">64</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">68</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
115
+ <span class="vi">@msat_start_sid</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">68</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">72</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
116
+ <span class="vi">@total_msat_sectors</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">72</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">76</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
117
+
118
+ <span class="vi">@sect_size</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="vi">@log2_sect_size</span>
119
+ <span class="vi">@short_sect_size</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="vi">@log2_short_sect_size</span>
120
+ <span class="k">end</span>
121
+
122
+ <span class="k">def</span> <span class="nf">build_msat</span>
123
+ <span class="vi">@msat</span> <span class="o">=</span> <span class="vi">@header</span><span class="o">[</span><span class="mi">76</span><span class="o">.</span><span class="n">.</span><span class="o">-</span><span class="mi">1</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V109&#39;</span><span class="p">)</span>
124
+ <span class="n">next_sector</span> <span class="o">=</span> <span class="vi">@msat_start_sid</span>
125
+ <span class="k">while</span> <span class="n">next_sector</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">do</span>
126
+ <span class="k">raise</span> <span class="s2">&quot;not implemented&quot;</span>
127
+ <span class="n">start</span> <span class="o">=</span> <span class="n">next_sector</span> <span class="o">*</span> <span class="vi">@sect_size</span>
128
+ <span class="n">finish</span> <span class="o">=</span> <span class="p">(</span><span class="n">next_sector</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="vi">@sect_size</span>
129
+ <span class="n">msat_sector</span> <span class="o">=</span> <span class="vi">@data</span><span class="o">[</span><span class="n">start</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">finish</span><span class="o">]</span>
130
+ <span class="vi">@msat</span> <span class="o">&lt;&lt;</span> <span class="n">msat_sector</span>
131
+ <span class="n">next_sector</span> <span class="o">=</span> <span class="n">msat_sector</span><span class="o">[-</span><span class="mi">1</span><span class="o">]</span>
132
+ <span class="k">end</span>
133
+ <span class="k">end</span>
134
+
135
+ <span class="k">def</span> <span class="nf">build_sat</span>
136
+ <span class="n">sat_stream</span> <span class="o">=</span> <span class="vi">@msat</span><span class="o">.</span><span class="n">collect</span> <span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">?</span> <span class="vi">@data</span><span class="o">[</span><span class="p">(</span><span class="n">i</span><span class="o">*</span><span class="vi">@sect_size</span><span class="p">)</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="p">((</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="vi">@sect_size</span><span class="p">)</span><span class="o">]</span> <span class="p">:</span> <span class="s1">&#39;&#39;</span> <span class="p">}</span><span class="o">.</span><span class="n">join</span>
137
+ <span class="vi">@sat</span> <span class="o">=</span> <span class="n">sat_stream</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V*&#39;</span><span class="p">)</span>
138
+ <span class="k">end</span>
139
+
140
+ <span class="k">def</span> <span class="nf">build_ssat</span>
141
+ <span class="n">ssat_stream</span> <span class="o">=</span> <span class="n">stream_data</span><span class="p">(</span><span class="vi">@data</span><span class="p">,</span> <span class="vi">@sat</span><span class="p">,</span> <span class="vi">@ssat_start_sid</span><span class="p">,</span> <span class="vi">@sect_size</span><span class="p">)</span>
142
+ <span class="vi">@ssat</span> <span class="o">=</span> <span class="n">ssat_stream</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V*&#39;</span><span class="p">)</span>
143
+ <span class="k">end</span>
144
+
145
+ <span class="k">def</span> <span class="nf">build_directory</span>
146
+ <span class="n">dir_stream</span> <span class="o">=</span> <span class="n">stream_data</span><span class="p">(</span><span class="vi">@data</span><span class="p">,</span> <span class="vi">@sat</span><span class="p">,</span> <span class="vi">@dir_start_sid</span><span class="p">,</span> <span class="vi">@sect_size</span><span class="p">)</span>
147
+ <span class="vi">@dir_entry_list</span> <span class="o">=</span> <span class="o">[]</span>
148
+ <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
149
+ <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">dir_stream</span><span class="o">.</span><span class="n">length</span> <span class="k">do</span>
150
+ <span class="n">dentry</span> <span class="o">=</span> <span class="n">dir_stream</span><span class="o">[</span><span class="n">i</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="no">DIR_ENTRY_SIZE</span><span class="p">)</span><span class="o">]</span>
151
+ <span class="n">i</span> <span class="o">+=</span> <span class="no">DIR_ENTRY_SIZE</span>
152
+
153
+ <span class="n">did</span> <span class="o">=</span> <span class="vi">@dir_entry_list</span><span class="o">.</span><span class="n">length</span>
154
+ <span class="n">sz</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">64</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">66</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;C&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
155
+
156
+ <span class="k">if</span> <span class="n">sz</span> <span class="o">&gt;</span> <span class="mi">0</span>
157
+ <span class="nb">name</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="p">(</span><span class="n">sz</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">]</span> <span class="c1"># TODO unicode</span>
158
+ <span class="k">else</span>
159
+ <span class="nb">name</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
160
+ <span class="k">end</span>
161
+
162
+ <span class="n">t</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">66</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">67</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;C&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
163
+ <span class="n">c</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">67</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">68</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;C&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
164
+ <span class="n">did_left</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">68</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">72</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
165
+ <span class="n">did_right</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">72</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">76</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
166
+ <span class="n">did_root</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">76</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">80</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
167
+ <span class="n">dentry_start_sid</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">116</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">120</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
168
+ <span class="n">stream_size</span> <span class="o">=</span> <span class="n">dentry</span><span class="o">[</span><span class="mi">120</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="mi">124</span><span class="o">].</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
169
+
170
+ <span class="vi">@dir_entry_list</span> <span class="o">&lt;&lt;</span> <span class="o">[</span><span class="n">did</span><span class="p">,</span> <span class="n">sz</span><span class="p">,</span> <span class="nb">name</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">dentry_start_sid</span><span class="p">,</span> <span class="n">stream_size</span><span class="o">]</span>
171
+ <span class="k">end</span>
172
+ <span class="k">end</span>
173
+
174
+ <span class="k">def</span> <span class="nf">build_short_sectors_data</span>
175
+ <span class="n">did</span><span class="p">,</span> <span class="n">sz</span><span class="p">,</span> <span class="nb">name</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">dentry_start_sid</span><span class="p">,</span> <span class="n">stream_size</span> <span class="o">=</span> <span class="vi">@dir_entry_list</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
176
+ <span class="k">raise</span> <span class="k">unless</span> <span class="n">t</span> <span class="o">==</span> <span class="mh">0x05</span> <span class="c1"># Short-Stream Container Stream (SSCS) resides in Root Storage</span>
177
+
178
+ <span class="k">if</span> <span class="n">stream_size</span> <span class="o">==</span> <span class="mi">0</span>
179
+ <span class="vi">@short_sectors_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
180
+ <span class="k">else</span>
181
+ <span class="vi">@short_sectors_data</span> <span class="o">=</span> <span class="n">stream_data</span><span class="p">(</span><span class="vi">@data</span><span class="p">,</span> <span class="vi">@sat</span><span class="p">,</span> <span class="n">dentry_start_sid</span><span class="p">,</span> <span class="vi">@sect_size</span><span class="p">)</span>
182
+ <span class="k">end</span>
183
+ <span class="k">end</span>
184
+
185
+ <span class="k">def</span> <span class="nf">stream_data</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">sat</span><span class="p">,</span> <span class="n">start_sid</span><span class="p">,</span> <span class="n">sect_size</span><span class="p">)</span>
186
+ <span class="n">sid</span> <span class="o">=</span> <span class="n">start_sid</span>
187
+ <span class="n">chunks</span> <span class="o">=</span> <span class="o">[[</span><span class="n">sid</span><span class="p">,</span> <span class="n">sid</span><span class="o">]]</span>
188
+ <span class="n">stream_data</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
189
+ <span class="k">while</span> <span class="n">sat</span><span class="o">[</span><span class="n">sid</span><span class="o">]</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="k">do</span>
190
+ <span class="n">next_in_chain</span> <span class="o">=</span> <span class="n">sat</span><span class="o">[</span><span class="n">sid</span><span class="o">]</span>
191
+ <span class="n">last_chunk_start</span><span class="p">,</span> <span class="n">last_chunk_finish</span> <span class="o">=</span> <span class="n">chunks</span><span class="o">[-</span><span class="mi">1</span><span class="o">]</span>
192
+ <span class="k">if</span> <span class="n">next_in_chain</span> <span class="o">==</span> <span class="n">last_chunk_finish</span> <span class="o">+</span> <span class="mi">1</span>
193
+ <span class="n">chunks</span><span class="o">[-</span><span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="n">last_chunk_start</span><span class="p">,</span> <span class="n">next_in_chain</span>
194
+ <span class="k">else</span>
195
+ <span class="n">chunks</span> <span class="o">&lt;&lt;</span> <span class="o">[</span><span class="n">next_in_chain</span><span class="p">,</span> <span class="n">next_in_chain</span><span class="o">]</span>
196
+ <span class="k">end</span>
197
+ <span class="n">sid</span> <span class="o">=</span> <span class="n">next_in_chain</span>
198
+ <span class="k">end</span>
199
+
200
+ <span class="n">chunks</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">s</span><span class="p">,</span> <span class="n">f</span><span class="o">|</span>
201
+ <span class="n">stream_data</span> <span class="o">+=</span> <span class="n">data</span><span class="o">[</span><span class="n">s</span><span class="o">*</span><span class="n">sect_size</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="p">(</span><span class="n">f</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">sect_size</span><span class="o">]</span>
202
+ <span class="k">end</span>
203
+ <span class="n">stream_data</span>
204
+ <span class="k">end</span>
205
+ <span class="k">end</span>
206
+
207
+
208
+ <span class="c1"># This implementation writes only &#39;Root Entry&#39;, &#39;Workbook&#39; streams</span>
209
+ <span class="c1"># and 2 empty streams for aligning directory stream on sector boundary</span>
210
+ <span class="c1"># </span>
211
+ <span class="c1"># LAYOUT:</span>
212
+ <span class="c1"># 0 header</span>
213
+ <span class="c1"># 76 MSAT (1st part: 109 SID)</span>
214
+ <span class="c1"># 512 workbook stream</span>
215
+ <span class="c1"># ... additional MSAT sectors if streams&#39; size &gt; about 7 Mb == (109*512 * 128)</span>
216
+ <span class="c1"># ... SAT</span>
217
+ <span class="c1"># ... directory stream</span>
218
+ <span class="c1">#</span>
219
+ <span class="c1"># NOTE: this layout is &quot;ad hoc&quot;. It can be more general. RTFM</span>
220
+ <span class="k">class</span> <span class="nc">ExcelDocument</span>
221
+ <span class="no">SECTOR_SIZE</span> <span class="o">=</span> <span class="mh">0x0200</span>
222
+ <span class="no">MIN_LIMIT</span> <span class="o">=</span> <span class="mh">0x1000</span>
223
+
224
+ <span class="no">SID_FREE_SECTOR</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
225
+ <span class="no">SID_END_OF_CHAIN</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span>
226
+ <span class="no">SID_USED_BY_SAT</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span>
227
+ <span class="no">SID_USED_BY_MSAT</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span>
228
+
229
+ <span class="k">def</span> <span class="nf">initialize</span>
230
+ <span class="vi">@book_stream_sect</span> <span class="o">=</span> <span class="o">[]</span>
231
+ <span class="vi">@dir_stream_sect</span> <span class="o">=</span> <span class="o">[]</span>
232
+
233
+ <span class="vi">@packed_sat</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
234
+ <span class="vi">@sat_sect</span> <span class="o">=</span> <span class="o">[]</span>
235
+
236
+ <span class="vi">@packed_msat_1st</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
237
+ <span class="vi">@packed_msat_2nd</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
238
+ <span class="vi">@msat_sect_2nd</span> <span class="o">=</span> <span class="o">[]</span>
239
+ <span class="vi">@header</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
240
+ <span class="k">end</span>
241
+
242
+ <span class="k">def</span> <span class="nf">build_directory</span>
243
+ <span class="vi">@dir_stream</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
244
+
245
+ <span class="nb">name</span> <span class="o">=</span> <span class="s1">&#39;Root Entry&#39;</span>
246
+ <span class="nb">type</span> <span class="o">=</span> <span class="mh">0x05</span> <span class="c1"># root storage</span>
247
+ <span class="n">colour</span> <span class="o">=</span> <span class="mh">0x01</span> <span class="c1"># black</span>
248
+ <span class="n">did_left</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
249
+ <span class="n">did_right</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
250
+ <span class="n">did_root</span> <span class="o">=</span> <span class="mi">1</span>
251
+ <span class="n">start_sid</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span>
252
+ <span class="n">stream_sz</span> <span class="o">=</span> <span class="mi">0</span>
253
+ <span class="vi">@dir_stream</span> <span class="o">+=</span> <span class="n">pack_directory</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">colour</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">start_sid</span><span class="p">,</span> <span class="n">stream_sz</span><span class="p">)</span>
254
+
255
+ <span class="nb">name</span> <span class="o">=</span> <span class="s1">&#39;Workbook&#39;</span>
256
+ <span class="nb">type</span> <span class="o">=</span> <span class="mh">0x02</span> <span class="c1"># user stream</span>
257
+ <span class="n">colour</span> <span class="o">=</span> <span class="mh">0x01</span> <span class="c1"># black</span>
258
+ <span class="n">did_left</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
259
+ <span class="n">did_right</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
260
+ <span class="n">did_root</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
261
+ <span class="n">start_sid</span> <span class="o">=</span> <span class="mi">0</span>
262
+ <span class="n">stream_sz</span> <span class="o">=</span> <span class="vi">@book_stream_len</span>
263
+ <span class="vi">@dir_stream</span> <span class="o">+=</span> <span class="n">pack_directory</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">colour</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">start_sid</span><span class="p">,</span> <span class="n">stream_sz</span><span class="p">)</span>
264
+ <span class="c1"># padding</span>
265
+ <span class="nb">name</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
266
+ <span class="nb">type</span> <span class="o">=</span> <span class="mh">0x00</span> <span class="c1"># empty</span>
267
+ <span class="n">colour</span> <span class="o">=</span> <span class="mh">0x01</span> <span class="c1"># black</span>
268
+ <span class="n">did_left</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
269
+ <span class="n">did_right</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
270
+ <span class="n">did_root</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
271
+ <span class="n">start_sid</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span>
272
+ <span class="n">stream_sz</span> <span class="o">=</span> <span class="mi">0</span>
273
+ <span class="vi">@dir_stream</span> <span class="o">+=</span> <span class="n">pack_directory</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">colour</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">start_sid</span><span class="p">,</span> <span class="n">stream_sz</span><span class="p">)</span> <span class="o">*</span> <span class="mi">2</span>
274
+ <span class="k">end</span>
275
+
276
+ <span class="k">def</span> <span class="nf">pack_directory</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">colour</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="n">start_sid</span><span class="p">,</span> <span class="n">stream_sz</span><span class="p">)</span>
277
+ <span class="n">encoded_name</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
278
+ <span class="mi">0</span><span class="o">.</span><span class="n">upto</span><span class="p">(</span><span class="nb">name</span><span class="o">.</span><span class="n">length</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
279
+ <span class="n">encoded_name</span> <span class="o">&lt;&lt;</span> <span class="nb">name</span><span class="o">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\000</span><span class="s2">&quot;</span>
280
+ <span class="k">end</span>
281
+ <span class="n">encoded_name</span> <span class="o">&lt;&lt;</span> <span class="s2">&quot;</span><span class="se">\000</span><span class="s2">&quot;</span>
282
+ <span class="n">name_sz</span> <span class="o">=</span> <span class="n">encoded_name</span><span class="o">.</span><span class="n">length</span>
283
+
284
+ <span class="n">args</span> <span class="o">=</span> <span class="o">[</span><span class="n">encoded_name</span><span class="p">,</span> <span class="n">name_sz</span><span class="p">,</span> <span class="nb">type</span><span class="p">,</span> <span class="n">colour</span><span class="p">,</span> <span class="n">did_left</span><span class="p">,</span> <span class="n">did_right</span><span class="p">,</span> <span class="n">did_root</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">start_sid</span><span class="p">,</span> <span class="n">stream_sz</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span>
285
+ <span class="n">args</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;a64 v C2 V3 V9 V V2&#39;</span><span class="p">)</span>
286
+ <span class="k">end</span>
287
+
288
+ <span class="k">def</span> <span class="nf">build_sat</span>
289
+ <span class="n">book_sect_count</span> <span class="o">=</span> <span class="vi">@book_stream_len</span> <span class="o">&gt;&gt;</span> <span class="mi">9</span>
290
+ <span class="n">dir_sect_count</span> <span class="o">=</span> <span class="vi">@dir_stream</span><span class="o">.</span><span class="n">length</span> <span class="o">&gt;&gt;</span> <span class="mi">9</span>
291
+ <span class="n">total_sect_count</span> <span class="o">=</span> <span class="n">book_sect_count</span> <span class="o">+</span> <span class="n">dir_sect_count</span>
292
+ <span class="n">sat_sect_count</span> <span class="o">=</span> <span class="mi">0</span>
293
+ <span class="n">msat_sect_count</span> <span class="o">=</span> <span class="mi">0</span>
294
+ <span class="n">sat_sect_count_limit</span> <span class="o">=</span> <span class="mi">109</span>
295
+
296
+ <span class="k">while</span> <span class="p">(</span><span class="n">total_sect_count</span> <span class="o">&gt;</span> <span class="mi">128</span><span class="o">*</span><span class="n">sat_sect_count</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">sat_sect_count</span> <span class="o">&gt;</span> <span class="n">sat_sect_count_limit</span><span class="p">)</span> <span class="k">do</span>
297
+ <span class="n">sat_sect_count</span> <span class="o">+=</span> <span class="mi">1</span>
298
+ <span class="n">total_sect_count</span> <span class="o">+=</span> <span class="mi">1</span>
299
+ <span class="k">if</span> <span class="n">sat_sect_count</span> <span class="o">&gt;</span> <span class="n">sat_sect_count_limit</span>
300
+ <span class="n">msat_sect_count</span> <span class="o">+=</span> <span class="mi">1</span>
301
+ <span class="n">total_sect_count</span> <span class="o">+=</span> <span class="mi">1</span>
302
+ <span class="n">sat_sect_count_limit</span> <span class="o">+=</span> <span class="mi">127</span>
303
+ <span class="k">end</span>
304
+ <span class="k">end</span>
305
+
306
+ <span class="c1"># initialize the sat array to be filled with the &quot;empty&quot; character specified by SID_FREE_SECTOR</span>
307
+ <span class="n">sat</span> <span class="o">=</span> <span class="o">[</span><span class="no">SID_FREE_SECTOR</span><span class="o">]*</span><span class="mi">128</span><span class="o">*</span><span class="n">sat_sect_count</span>
308
+
309
+ <span class="n">sect</span> <span class="o">=</span> <span class="mi">0</span>
310
+ <span class="k">while</span> <span class="n">sect</span> <span class="o">&lt;</span> <span class="n">book_sect_count</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">do</span>
311
+ <span class="vi">@book_stream_sect</span> <span class="o">&lt;&lt;</span> <span class="n">sect</span>
312
+ <span class="n">sat</span><span class="o">[</span><span class="n">sect</span><span class="o">]</span> <span class="o">=</span> <span class="n">sect</span> <span class="o">+</span> <span class="mi">1</span>
313
+ <span class="n">sect</span> <span class="o">+=</span> <span class="mi">1</span>
314
+ <span class="k">end</span>
315
+ <span class="vi">@book_stream_sect</span> <span class="o">&lt;&lt;</span> <span class="n">sect</span>
316
+ <span class="n">sat</span><span class="o">[</span><span class="n">sect</span><span class="o">]</span> <span class="o">=</span> <span class="no">SID_END_OF_CHAIN</span>
317
+ <span class="n">sect</span> <span class="o">+=</span> <span class="mi">1</span>
318
+
319
+ <span class="k">while</span> <span class="n">sect</span> <span class="o">&lt;</span> <span class="n">book_sect_count</span> <span class="o">+</span> <span class="n">msat_sect_count</span> <span class="k">do</span>
320
+ <span class="vi">@msat_sect_2nd</span> <span class="o">&lt;&lt;</span> <span class="n">sect</span>
321
+ <span class="n">sat</span><span class="o">[</span><span class="n">sect</span><span class="o">]</span> <span class="o">=</span> <span class="no">SID_USED_BY_MSAT</span>
322
+ <span class="n">sect</span> <span class="o">+=</span> <span class="mi">1</span>
323
+ <span class="k">end</span>
324
+
325
+ <span class="k">while</span> <span class="n">sect</span> <span class="o">&lt;</span> <span class="n">book_sect_count</span> <span class="o">+</span> <span class="n">msat_sect_count</span> <span class="o">+</span> <span class="n">sat_sect_count</span> <span class="k">do</span>
326
+ <span class="vi">@sat_sect</span> <span class="o">&lt;&lt;</span> <span class="n">sect</span>
327
+ <span class="n">sat</span><span class="o">[</span><span class="n">sect</span><span class="o">]</span> <span class="o">=</span> <span class="no">SID_USED_BY_SAT</span>
328
+ <span class="n">sect</span> <span class="o">+=</span> <span class="mi">1</span>
329
+ <span class="k">end</span>
330
+
331
+ <span class="k">while</span> <span class="n">sect</span> <span class="o">&lt;</span> <span class="n">book_sect_count</span> <span class="o">+</span> <span class="n">msat_sect_count</span> <span class="o">+</span> <span class="n">sat_sect_count</span> <span class="o">+</span> <span class="n">dir_sect_count</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">do</span>
332
+ <span class="vi">@dir_stream_sect</span> <span class="o">&lt;&lt;</span> <span class="n">sect</span>
333
+ <span class="n">sat</span><span class="o">[</span><span class="n">sect</span><span class="o">]</span> <span class="o">=</span> <span class="n">sect</span> <span class="o">+</span> <span class="mi">1</span>
334
+ <span class="n">sect</span> <span class="o">+=</span> <span class="mi">1</span>
335
+ <span class="k">end</span>
336
+
337
+ <span class="vi">@dir_stream_sect</span> <span class="o">&lt;&lt;</span> <span class="n">sect</span>
338
+ <span class="n">sat</span><span class="o">[</span><span class="n">sect</span><span class="o">]</span> <span class="o">=</span> <span class="no">SID_END_OF_CHAIN</span>
339
+ <span class="n">sect</span> <span class="o">+=</span> <span class="mi">1</span>
340
+
341
+ <span class="vi">@packed_sat</span> <span class="o">=</span> <span class="n">sat</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V*&#39;</span><span class="p">)</span>
342
+
343
+ <span class="n">msat_1st</span> <span class="o">=</span> <span class="o">[]</span>
344
+ <span class="mi">109</span><span class="o">.</span><span class="n">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
345
+ <span class="n">msat_1st</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">=</span> <span class="vi">@sat_sect</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">||</span> <span class="no">SID_FREE_SECTOR</span>
346
+ <span class="k">end</span>
347
+ <span class="vi">@packed_msat_1st</span> <span class="o">=</span> <span class="n">msat_1st</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V*&#39;</span><span class="p">)</span>
348
+
349
+ <span class="n">msat_2nd</span> <span class="o">=</span> <span class="o">[</span><span class="no">SID_FREE_SECTOR</span><span class="o">]</span> <span class="o">*</span> <span class="mi">128</span> <span class="o">*</span> <span class="n">msat_sect_count</span>
350
+ <span class="n">msat_2nd</span><span class="o">[-</span><span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="no">SID_END_OF_CHAIN</span> <span class="k">if</span> <span class="n">msat_sect_count</span> <span class="o">&gt;</span> <span class="mi">0</span>
351
+
352
+ <span class="n">i</span> <span class="o">=</span> <span class="mi">109</span>
353
+ <span class="n">msat_sect</span> <span class="o">=</span> <span class="mi">0</span>
354
+ <span class="n">sid_num</span> <span class="o">=</span> <span class="mi">0</span>
355
+
356
+ <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">sat_sect_count</span> <span class="k">do</span>
357
+ <span class="k">if</span> <span class="p">(</span><span class="n">sid_num</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="mi">128</span> <span class="o">==</span> <span class="mi">0</span>
358
+ <span class="n">msat_sect</span> <span class="o">+=</span> <span class="mi">1</span>
359
+ <span class="n">msat_2nd</span><span class="o">[</span><span class="n">sid_num</span><span class="o">]</span> <span class="o">=</span> <span class="vi">@msat_sect_2nd</span><span class="o">[</span><span class="n">msat_sect</span><span class="o">]</span> <span class="k">if</span> <span class="n">msat_sect</span> <span class="o">&lt;</span> <span class="vi">@msat_sect_2nd</span><span class="o">.</span><span class="n">length</span>
360
+ <span class="k">else</span>
361
+ <span class="n">msat_2nd</span><span class="o">[</span><span class="n">sid_num</span><span class="o">]</span> <span class="o">=</span> <span class="vi">@sat_sect</span><span class="o">[</span><span class="n">i</span><span class="o">]</span>
362
+ <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
363
+ <span class="k">end</span>
364
+ <span class="n">sid_num</span> <span class="o">+=</span> <span class="mi">1</span>
365
+ <span class="k">end</span>
366
+
367
+ <span class="vi">@packed_msat_2nd</span> <span class="o">=</span> <span class="n">msat_2nd</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V*&#39;</span><span class="p">)</span>
368
+ <span class="k">end</span>
369
+
370
+ <span class="k">def</span> <span class="nf">build_header</span>
371
+ <span class="n">doc_magic</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\320\317\021\340\241\261\032\341</span><span class="s2">&quot;</span>
372
+ <span class="n">file_uid</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\000</span><span class="s2">&quot;</span> <span class="o">*</span> <span class="mi">16</span>
373
+ <span class="n">rev_num</span> <span class="o">=</span> <span class="s2">&quot;&gt;</span><span class="se">\000</span><span class="s2">&quot;</span>
374
+ <span class="n">ver_num</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\003\000</span><span class="s2">&quot;</span>
375
+ <span class="n">byte_order</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\376\377</span><span class="s2">&quot;</span>
376
+ <span class="n">log_sect_size</span> <span class="o">=</span> <span class="o">[</span><span class="mi">9</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;v&#39;</span><span class="p">)</span>
377
+ <span class="n">log_short_sect_size</span> <span class="o">=</span> <span class="o">[</span><span class="mi">6</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;v&#39;</span><span class="p">)</span>
378
+ <span class="n">not_used0</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\000</span><span class="s2">&quot;</span><span class="o">*</span><span class="mi">10</span>
379
+ <span class="n">total_sat_sectors</span> <span class="o">=</span> <span class="o">[</span><span class="vi">@sat_sect</span><span class="o">.</span><span class="n">length</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
380
+ <span class="n">dir_start_sid</span> <span class="o">=</span> <span class="o">[</span><span class="vi">@dir_stream_sect</span><span class="o">[</span><span class="mi">0</span><span class="o">]].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
381
+ <span class="n">not_used1</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\000</span><span class="s2">&quot;</span><span class="o">*</span><span class="mi">4</span>
382
+ <span class="n">min_stream_size</span> <span class="o">=</span> <span class="o">[</span><span class="mh">0x1000</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
383
+ <span class="n">ssat_start_sid</span> <span class="o">=</span> <span class="o">[-</span><span class="mi">2</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
384
+ <span class="n">total_ssat_sectors</span> <span class="o">=</span> <span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
385
+
386
+ <span class="k">if</span> <span class="vi">@msat_sect_2nd</span><span class="o">.</span><span class="n">length</span> <span class="o">==</span> <span class="mi">0</span>
387
+ <span class="n">msat_start_sid</span> <span class="o">=</span> <span class="o">[-</span><span class="mi">2</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
388
+ <span class="k">else</span>
389
+ <span class="n">msat_start_sid</span> <span class="o">=</span> <span class="o">[</span><span class="vi">@msat_sect_2nd</span><span class="o">[</span><span class="mi">0</span><span class="o">]].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
390
+ <span class="k">end</span>
391
+
392
+ <span class="n">total_msat_sectors</span> <span class="o">=</span> <span class="o">[</span><span class="vi">@msat_sect_2nd</span><span class="o">.</span><span class="n">length</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s1">&#39;V&#39;</span><span class="p">)</span>
393
+
394
+ <span class="vi">@header</span> <span class="o">=</span> <span class="o">[</span>
395
+ <span class="n">doc_magic</span><span class="p">,</span>
396
+ <span class="n">file_uid</span><span class="p">,</span>
397
+ <span class="n">rev_num</span><span class="p">,</span>
398
+ <span class="n">ver_num</span><span class="p">,</span>
399
+ <span class="n">byte_order</span><span class="p">,</span>
400
+ <span class="n">log_sect_size</span><span class="p">,</span>
401
+ <span class="n">log_short_sect_size</span><span class="p">,</span>
402
+ <span class="n">not_used0</span><span class="p">,</span>
403
+ <span class="n">total_sat_sectors</span><span class="p">,</span>
404
+ <span class="n">dir_start_sid</span><span class="p">,</span>
405
+ <span class="n">not_used1</span><span class="p">,</span>
406
+ <span class="n">min_stream_size</span><span class="p">,</span>
407
+ <span class="n">ssat_start_sid</span><span class="p">,</span>
408
+ <span class="n">total_ssat_sectors</span><span class="p">,</span>
409
+ <span class="n">msat_start_sid</span><span class="p">,</span>
410
+ <span class="n">total_msat_sectors</span>
411
+ <span class="o">].</span><span class="n">join</span>
412
+ <span class="k">end</span>
413
+
414
+ <span class="k">def</span> <span class="nf">data</span><span class="p">(</span><span class="n">stream</span><span class="p">)</span>
415
+ <span class="n">distance_to_end_of_next_sector_boundary</span> <span class="o">=</span> <span class="mh">0x1000</span> <span class="o">-</span> <span class="p">(</span><span class="n">stream</span><span class="o">.</span><span class="n">length</span> <span class="o">%</span> <span class="mh">0x1000</span><span class="p">)</span>
416
+ <span class="vi">@book_stream_len</span> <span class="o">=</span> <span class="n">stream</span><span class="o">.</span><span class="n">length</span> <span class="o">+</span> <span class="n">distance_to_end_of_next_sector_boundary</span>
417
+ <span class="n">padding</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\000</span><span class="s2">&quot;</span> <span class="o">*</span> <span class="n">distance_to_end_of_next_sector_boundary</span>
418
+
419
+ <span class="n">build_directory</span>
420
+ <span class="n">build_sat</span>
421
+ <span class="n">build_header</span>
422
+
423
+ <span class="n">s</span> <span class="o">=</span> <span class="no">StringIO</span><span class="o">.</span><span class="n">new</span>
424
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="vi">@header</span><span class="p">)</span>
425
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="vi">@packed_msat_1st</span><span class="p">)</span>
426
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">stream</span><span class="p">)</span>
427
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">padding</span><span class="p">)</span>
428
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="vi">@packed_msat_2nd</span><span class="p">)</span>
429
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="vi">@packed_sat</span><span class="p">)</span>
430
+ <span class="n">s</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="vi">@dir_stream</span><span class="p">)</span>
431
+ <span class="n">s</span><span class="o">.</span><span class="n">rewind</span>
432
+ <span class="n">s</span>
433
+ <span class="k">end</span>
434
+
435
+ <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">stream</span><span class="p">)</span>
436
+ <span class="n">we_own_it</span> <span class="o">=</span> <span class="o">!</span><span class="n">file</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="ss">:write</span><span class="p">)</span>
437
+ <span class="n">file</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="n">we_own_it</span>
438
+ <span class="n">file</span><span class="o">.</span><span class="n">write</span> <span class="n">data</span><span class="p">(</span><span class="n">stream</span><span class="p">)</span><span class="o">.</span><span class="n">read</span>
439
+ <span class="n">file</span><span class="o">.</span><span class="n">close</span> <span class="k">if</span> <span class="n">we_own_it</span>
440
+ <span class="k">end</span>
441
+ <span class="k">end</span>
442
+ </pre></div>
443
+
444
+
445
+ </div>
446
+ <div id="right">
447
+ <ul id="nav">
448
+ <li><a href="surpass-manual-0-0-5.pdf">Download PDF Manual</a></li>
449
+ <li><a href="http://rubyforge.org/projects/surpass">Rubyforge Project Page</a></li>
450
+ </ul>
451
+ <div class="box">
452
+ <h2 style="margin-top:17px">Latest News</h2>
453
+ <ul>
454
+ <li>...</li>
455
+ </ul>
456
+ </div>
457
+ </div>
458
+ <div id="clear"></div></div>
459
+ <div id="footer">
460
+ <p>Site template designed by <a href="http://loadfoo.org/" rel="external">LoadFoO</a>. Valid <a href="http://jigsaw.w3.org/css-validator/check/referer" rel="external">CSS</a> &amp; <a href="http://validator.w3.org/check?uri=referer" rel="external">XHTML</a></p>
461
+ </div>
462
+ </div>
463
+
464
+ </body>
465
+ </html>