Advertisement
Guest User

Untitled

a guest
Feb 25th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.47 KB | None | 0 0
  1. #!/afs/cats.ucsc.edu/courses/cmps112-wm/usr/smalltalk/bin/gst -f
  2. "$Id: tree.st,v 1.10 2012-02-23 18:57:51-08 - - $"
  3.  
  4. nl := Character nl.
  5.  
  6.  
  7.  
  8. FileStream extend [
  9. |bitIndex currentChar|
  10.  
  11. nextBit [
  12. |bit|
  13. bitIndex isNil ifTrue: [bitIndex := 0].
  14. bitIndex = 0 ifTrue: [
  15. bitIndex := 8.
  16. currentChar := self next.
  17. ].
  18. bit := currentChar value bitAt: bitIndex.
  19. bitIndex := bitIndex - 1.
  20. ^ bit
  21. ]
  22.  
  23. atBitEnd [
  24. ^ (bitIndex isNil | (bitIndex = 0)) & self atEnd
  25. ]
  26.  
  27. ]
  28. "------------------------------------------------------------"
  29. Object subclass: OutBits [
  30. |bitIndex currentByte myStream|
  31. OutBits class >> new [
  32. self shouldNotImplement.
  33. ]
  34. OutBits class >> new: fileStream [
  35. |result|
  36. result := super new.
  37. result init: fileStream.
  38. ^result
  39. ]
  40. clearByte [
  41. bitIndex := 8.
  42. currentByte := 0.
  43. ]
  44. init: fileStream [
  45. myStream := fileStream.
  46. self clearByte.
  47. ]
  48. flushByte [
  49. bitIndex = 8 ifFalse: [
  50. myStream nextPutByte: currentByte.
  51. self clearByte.
  52. ]
  53. ]
  54. writeBit: bit [
  55. currentByte := currentByte bitAt: bitIndex put: bit.
  56. bitIndex := bitIndex - 1.
  57. bitIndex = 0 ifTrue: [self flushByte].
  58. ]
  59. ]
  60.  
  61. "----------------------------------------------------------"
  62. Object subclass: Leaf [
  63. |char count|
  64. char [ ^ char ]
  65. count [ ^ count ]
  66.  
  67. Leaf class >> new [
  68. self shouldNotImplement
  69. ]
  70.  
  71. Leaf class >> new: aChar count: aCount [
  72. |result|
  73. result := super new.
  74. result setChar: aChar andCount: aCount.
  75. ^result
  76. ]
  77.  
  78. setChar: aChar andCount: aCount [
  79. char := aChar.
  80. count := aCount.
  81. ]
  82.  
  83. <= other [
  84. ^ (count < other count)
  85. | ((count = other count) & (char <= other char))
  86. ]
  87.  
  88. printBase: aStream [
  89. ^ aStream << self class << '(' << char << ',' << count
  90. ]
  91.  
  92. printOn: aStream [
  93. (self printBase: aStream) << ')'.
  94. ]
  95.  
  96. inorder: visitor prefix: string [
  97. visitor value: char value: string.
  98. ]
  99.  
  100.  
  101. treeAsBit: visitor sum: qlength queue: stackq [
  102. stackq nextPut: 1.
  103.  
  104. stackq nextPut: ((char asInteger) bitAt: 8).
  105. stackq nextPut: ((char asInteger) bitAt: 7).
  106. stackq nextPut: ((char asInteger) bitAt: 6).
  107. stackq nextPut: ((char asInteger) bitAt: 5).
  108. stackq nextPut: ((char asInteger) bitAt: 4).
  109. stackq nextPut: ((char asInteger) bitAt: 3).
  110. stackq nextPut: ((char asInteger) bitAt: 2).
  111. stackq nextPut: ((char asInteger) bitAt: 1).
  112.  
  113. ^ 9.
  114.  
  115. ]
  116.  
  117. isLeaf [
  118. ^1
  119. ]
  120. ]
  121.  
  122. Leaf subclass: Tree [
  123. |left right|
  124.  
  125. Tree class >> new: aChar count: aCount [
  126. self shouldNotImplement
  127. ]
  128.  
  129. Tree class >> new: aChar count: aCount left: aLeft right: aRight [
  130. |result|
  131. result := super new: aChar count: aCount.
  132. result setLeft: aLeft andRight: aRight.
  133. ^ result
  134. ]
  135.  
  136. setLeft: aLeft andRight: aRight [
  137. left := aLeft.
  138. right := aRight.
  139. ]
  140.  
  141. left [
  142. ^ left
  143. ]
  144.  
  145. right [
  146. ^ right
  147. ]
  148.  
  149. printOn: aStream [
  150. (self printBase: aStream) << ',' << left << ',' << right << ')'.
  151. ]
  152.  
  153. inorder: visitor prefix: string [
  154. left inorder: visitor prefix: string, '0'.
  155. right inorder: visitor prefix: string, '1'.
  156. ]
  157.  
  158. treeAsBit: visitor sum: qlength queue: stackq[
  159. |sum1 sum2 sum |
  160. sum1 := left treeAsBit: visitor sum: qlength queue: stackq.
  161. sum2 := right treeAsBit: visitor sum: qlength queue: stackq.
  162. sum := sum1 + sum2.
  163. sum := sum + 1.
  164. stackq nextPut: 0.
  165. ^ sum
  166. ]
  167.  
  168.  
  169. isLeaf [
  170. ^0
  171. ]
  172.  
  173. ]
  174.  
  175.  
  176. "----------------------------------------------------------------------"
  177.  
  178. Character extend [
  179. isPrint [
  180. ^ (Character space <= self) & (self <= $~)
  181. ]
  182. visible [
  183. self isPrint ifTrue: [^ '$', self asString]
  184. ifFalse: [^ self asInteger printStringRadix: 8]
  185. ]
  186. ]
  187.  
  188. Object subclass: ZeroArray [
  189. |theArray|
  190.  
  191. ZeroArray class >> new [
  192. self shouldNotImplement.
  193. ]
  194.  
  195. ZeroArray class >> new: size [
  196. |result|
  197. result := super new.
  198. result init: size.
  199. ^ result
  200. ]
  201.  
  202. init: size [
  203. theArray := Array new: size.
  204. ]
  205.  
  206. size [
  207. ^ theArray size.
  208. ]
  209.  
  210. at: index [
  211. ^ theArray at: index + 1.
  212. ]
  213.  
  214. at: index put: value [
  215. ^ theArray at: index + 1 put: value.
  216. ]
  217.  
  218. incr: index [
  219. (self at: index) isNil
  220. ifTrue: [ self at: index put: 0].
  221. self at: index put: (self at: index) + 1.
  222. ]
  223.  
  224. keysAndValuesDo: aBlock [
  225. (0 to: (self size) - 1) do: [:index |
  226. aBlock value: index value: (self at: index).
  227. ]
  228. ]
  229.  
  230.  
  231.  
  232. ]
  233. "-------------------------------------------------------------------"
  234.  
  235.  
  236. d := 0.
  237. t := 0.
  238. c := 0.
  239. u := 0.
  240.  
  241.  
  242. Smalltalk arguments: '-d -t -c -u'
  243. do: [:opt :arg |
  244. opt = $d ifTrue: [ d :=1. ].
  245. opt = $t ifTrue: [ t :=1. ].
  246. opt = $c ifTrue: [ c :=1. ].
  247. opt = $u ifTrue: [ u :=1. ].
  248. ]
  249. ifError: [
  250. 'Error: invalid option' displayNl.
  251. ].
  252.  
  253.  
  254. freqtable := ZeroArray new: 257.
  255.  
  256. c = 1 ifTrue: [ "compressing"
  257.  
  258.  
  259. infile := FileStream open: (Smalltalk arguments at: 2)
  260. mode: FileStream read.
  261.  
  262. [infile atEnd not] whileTrue: [
  263. |ordChar|
  264. ordChar := infile next asInteger.
  265. stdout << ordChar << nl.
  266. freqtable incr: ordChar.
  267. ].
  268. freqtable at: 256 put: 1.
  269.  
  270. infile close.
  271.  
  272. sortcol := SortedCollection new.
  273. chars_in_file := SortedCollection new.
  274.  
  275. freqtable keysAndValuesDo: [:key :value |
  276. (value notNil and: [value > 0]) ifTrue: [
  277. val := Leaf new: key asCharacter count: value.
  278. sortcol add: val.
  279. chars_in_file add: key
  280. ]
  281. ].
  282.  
  283.  
  284. [sortcol size > 1] whileTrue: [
  285. |first second t|
  286. first := sortcol removeFirst.
  287. second := sortcol removeFirst.
  288. t := Tree new: (second char) count: (first count + second count) left: first right: second.
  289. sortcol add: t.
  290. ].
  291. root := sortcol removeFirst.
  292.  
  293. encode_table := ZeroArray new: 257.
  294. root inorder: [:char :string |
  295. encode_table at: char asInteger put: string.
  296. ] prefix: ''.
  297.  
  298. formatOutput := [:let :freq :bits|
  299. let asString size to: 3 do: [:skip| stdout << ' '].
  300. stdout << let.
  301. freq asString size to: 5 do: [:skip| stdout << ' '].
  302. stdout << freq << ' ' << bits << nl.
  303. ].
  304.  
  305. arraylen := 0.
  306.  
  307. encode_table keysAndValuesDo: [:key :value |
  308. (value notNil and: [value > 0]) ifTrue: [
  309. arraylen := arraylen + ((freqtable at: key)*(value size)).
  310. ]
  311. ].
  312.  
  313.  
  314.  
  315.  
  316.  
  317. stackq := SharedQueue new.
  318. qlength := 0.
  319. qlength := root treeAsBit: [:char :string ] sum: qlength queue: stackq.
  320. qlength := qlength + 1.
  321. stackq nextPut: 0.
  322.  
  323.  
  324.  
  325.  
  326.  
  327. bitArray := Array new: (arraylen+qlength).
  328.  
  329. index := 1.
  330.  
  331.  
  332. [stackq isEmpty not] whileTrue: [
  333. |bit|
  334. bit := stackq next.
  335. bitArray at: index put: bit.
  336. index := index + 1.
  337. ].
  338.  
  339. infile := FileStream open: (Smalltalk arguments at: 2)
  340. mode: FileStream read.
  341.  
  342. [infile atEnd not] whileTrue: [
  343. |ordChar|
  344. ordChar := infile next asInteger.
  345.  
  346. index to: (index+((encode_table at: ordChar) size))-1 do:
  347. [ :x |
  348. bit := 0.
  349. (((encode_table at: ordChar) at: ((x-index)+1)) = $1) ifTrue: [bit:= 1.].
  350. bitArray at: x put: bit.
  351. ].
  352.  
  353. index := (index+((encode_table at: ordChar) size)).
  354. ].
  355.  
  356. "so at this point we want to add our EOF character to our BitArray"
  357. index to: (index+((encode_table at: 256) size))-1 do:
  358. [ :x |
  359. bit := 0.
  360. (((encode_table at: 256) at: ((x-index)+1)) = $1) ifTrue: [bit:= 1.].
  361. bitArray at: x put: bit.
  362. ].
  363.  
  364.  
  365. "filling up our bit array"
  366.  
  367.  
  368.  
  369. writeEncodedOutFile := [:outfile|
  370. |outBytes|
  371. outBytes := OutBits new: outfile.
  372. bitArray do: [:bit| outBytes writeBit: bit.].
  373. outBytes flushByte.
  374. ].
  375.  
  376. Smalltalk arguments size = 2
  377. ifTrue: [writeEncodedOutFile value: stdout]
  378. ifFalse: [
  379. |outfilename|
  380. outfilename := Smalltalk arguments at: 3.
  381. [ |outfile|
  382. outfile := FileStream open: outfilename mode: FileStream write.
  383. writeEncodedOutFile value: outfile.
  384. outfile close.
  385. ] on: SystemExceptions.FileError do: [:signal |
  386. |errno|
  387. errno := File errno.
  388. stdout flush.
  389. stderr << execname << ': ' << filename << ': '
  390. << signal messageText << nl.
  391. stderr flush.
  392. ]
  393. ].
  394.  
  395. d = 1 ifTrue: [
  396. stdout << 'DEBUG STMTS: '<<nl.
  397. root inspect.
  398. bitArray do: [:bit| stdout <<bit.].
  399. stdout << nl. ].
  400. ].
  401. "-----------------------------------------------------------------"
  402. "decompression----------------------------------------------------"
  403. u = 1
  404. ifTrue: [
  405.  
  406.  
  407.  
  408. infile := FileStream open: (Smalltalk arguments at: 2)
  409. mode: FileStream read.
  410.  
  411.  
  412.  
  413. treeq := OrderedCollection new.
  414. priority := 1000.
  415. endOfTree := 1.
  416.  
  417. [infile atBitEnd not and: [endOfTree = 1]] whileTrue: [
  418. | bit |
  419. bit := infile nextBit.
  420. bit = 1 ifTrue: [ "if we see a one"
  421. | char count |
  422. char := 255.
  423. count := 8.
  424. [count > 0 ] whileTrue: [
  425. count := count - 1.
  426. infile nextBit = 0 ifTrue: [
  427. num := 2 raisedTo: count.
  428. char := char - num.
  429. ]
  430. ].
  431. val := Leaf new: char asCharacter count: priority.
  432. priority := priority - 10.
  433. treeq addFirst: val.
  434. ]
  435. ifFalse: [ "for when we see a zero"
  436. treeq size = 1
  437. ifTrue: [
  438. endOfTree := 0. ]
  439. ifFalse: [
  440. |first second t|
  441. first := treeq removeFirst.
  442. second := treeq removeFirst.
  443.  
  444. t := Tree new: (first char) count: priority left: second right: first.
  445. priority := priority - 10.
  446. treeq addFirst: t.
  447. ].
  448.  
  449. ].
  450.  
  451. ].
  452.  
  453. root := treeq removeFirst.
  454. encode_table := ZeroArray new: 256.
  455.  
  456.  
  457. "creating an encoding table based of tree we created above ^"
  458. root inorder: [:char :string |
  459. encode_table at: char asInteger put: string.
  460. ] prefix: ''.
  461.  
  462.  
  463. t_current := root.
  464. result := OrderedCollection new.
  465.  
  466. root isLeaf = 1 ifTrue: [
  467. result addLast: 2.
  468. result addLast: 0.
  469. result addLast: 0.
  470. result addLast: 0.
  471. result addLast: 0.
  472.  
  473. result addLast: 0.
  474. result addLast: 0.
  475. result addLast: 0.
  476. result addLast: 0. ].
  477.  
  478.  
  479. EOFCount := 2.
  480. [root isLeaf = 0 and: [infile atBitEnd not]] whileTrue: [
  481. | bit |
  482. t_current isLeaf = 1
  483. ifTrue: [
  484.  
  485. t_current char asInteger = 0 ifTrue: [
  486. stdout << 'EOFCount added as: '<<EOFCount<<nl.
  487. result addLast: EOFCount.
  488. EOFCount := EOFCount + 1.
  489. ]
  490. ifFalse: [freqtable incr: (t_current char asInteger) ].
  491. stdout <<t_current char asInteger << nl.
  492. result addLast: ((t_current char asInteger) bitAt: 8).
  493. result addLast: ((t_current char asInteger) bitAt: 7).
  494. result addLast: ((t_current char asInteger) bitAt: 6).
  495. result addLast: ((t_current char asInteger) bitAt: 5).
  496. result addLast: ((t_current char asInteger) bitAt: 4).
  497. result addLast: ((t_current char asInteger) bitAt: 3).
  498. result addLast: ((t_current char asInteger) bitAt: 2).
  499. result addLast: ((t_current char asInteger) bitAt: 1).
  500. t_current := root.
  501. ]
  502. ifFalse: [
  503. bit := infile nextBit.
  504. bit = 1 ifTrue: [
  505. t_current := t_current right.
  506. ]
  507. ifFalse: [
  508. t_current := t_current left.
  509. ].
  510. ].
  511.  
  512. ].
  513. EOFCount := EOFCount - 1.
  514. infile close.
  515. stdout << 'Final EOFCount: '<<EOFCount<<nl.
  516. stdout <<'-----------------------------------------------'<<nl.
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523. d = 1 ifTrue: [
  524. infile := FileStream open: (Smalltalk arguments at: 2)
  525. mode: FileStream read.
  526.  
  527. [infile atBitEnd not] whileTrue: [
  528. bit := infile nextBit.
  529. stdout << bit.
  530. ].
  531. stdout <<nl.
  532.  
  533. infile close.
  534. ].
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541. writeDecodedOutFile := [:outfile|
  542. |outBytes|
  543. flag := 1.
  544. outBytes := OutBits new: outfile.
  545.  
  546. [ flag = 1 and: [result size > 9]] whileTrue: [
  547. | bit |
  548. bit := result removeFirst.
  549.  
  550. bit > 1
  551. ifTrue: [
  552. stdout << result size << ' '<<bit<<nl.
  553. bit = EOFCount
  554. ifTrue: [ flag := 0. ].]
  555. ifFalse: [outBytes writeBit: bit].
  556. ].
  557.  
  558. outBytes flushByte.
  559. ].
  560.  
  561. Smalltalk arguments size = 2
  562. ifTrue: [writeDecodedOutFile value: stdout]
  563. ifFalse: [
  564. |outfilename|
  565. outfilename := Smalltalk arguments at: 3.
  566. [ |outfile|
  567. outfile := FileStream open: outfilename mode: FileStream write.
  568. writeDecodedOutFile value: outfile.
  569. outfile close.
  570. ] on: SystemExceptions.FileError do: [:signal |
  571. |errno|
  572. errno := File errno.
  573. stdout flush.
  574. stderr << execname << ': ' << filename << ': '
  575. << signal messageText << nl.
  576. stderr flush.
  577. ]
  578. ].
  579.  
  580. ].
  581.  
  582. "-----------------------------------------------------------------"
  583. "table writing----------------------------------------------------"
  584. t = 1
  585. ifTrue: [
  586.  
  587. formatOutput := [:let :freq :bits| "if let < 128"
  588. let asString size to: 3 do: [:skip| stdout << ' '].
  589. stdout << let.
  590. freq asString size to: 5 do: [:skip| stdout << ' '].
  591. stdout << freq << ' ' << bits << nl.
  592. ].
  593.  
  594.  
  595. encode_table keysAndValuesDo: [:key :value |
  596. (value notNil and: [value > 0]) ifTrue: [
  597. formatOutput value: (key asCharacter visible) value: (freqtable at: key) value: value.
  598. ]
  599. ].
  600.  
  601. ].
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement