read_write.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package rle
  2. import (
  3. "bytes"
  4. "errors"
  5. "github.com/ethereum/go-ethereum/crypto"
  6. )
  7. const (
  8. token byte = 0xfe
  9. emptyShaToken = 0xfd
  10. emptyListShaToken = 0xfe
  11. tokenToken = 0xff
  12. )
  13. var empty = crypto.Sha3([]byte(""))
  14. var emptyList = crypto.Sha3([]byte{0x80})
  15. func Decompress(dat []byte) ([]byte, error) {
  16. buf := new(bytes.Buffer)
  17. for i := 0; i < len(dat); i++ {
  18. if dat[i] == token {
  19. if i+1 < len(dat) {
  20. switch dat[i+1] {
  21. case emptyShaToken:
  22. buf.Write(empty)
  23. case emptyListShaToken:
  24. buf.Write(emptyList)
  25. case tokenToken:
  26. buf.WriteByte(token)
  27. default:
  28. buf.Write(make([]byte, int(dat[i+1]-2)))
  29. }
  30. i++
  31. } else {
  32. return nil, errors.New("error reading bytes. token encountered without proceeding bytes")
  33. }
  34. } else {
  35. buf.WriteByte(dat[i])
  36. }
  37. }
  38. return buf.Bytes(), nil
  39. }
  40. func Compress(dat []byte) []byte {
  41. buf := new(bytes.Buffer)
  42. for i := 0; i < len(dat); i++ {
  43. if dat[i] == token {
  44. buf.Write([]byte{token, tokenToken})
  45. } else if i+1 < len(dat) {
  46. if dat[i] == 0x0 && dat[i+1] == 0x0 {
  47. j := 0
  48. for j <= 254 && i+j < len(dat) {
  49. if dat[i+j] != 0 {
  50. break
  51. }
  52. j++
  53. }
  54. buf.Write([]byte{token, byte(j + 2)})
  55. i += (j - 1)
  56. } else if len(dat[i:]) >= 32 {
  57. if dat[i] == empty[0] && bytes.Compare(dat[i:i+32], empty) == 0 {
  58. buf.Write([]byte{token, emptyShaToken})
  59. i += 31
  60. } else if dat[i] == emptyList[0] && bytes.Compare(dat[i:i+32], emptyList) == 0 {
  61. buf.Write([]byte{token, emptyListShaToken})
  62. i += 31
  63. } else {
  64. buf.WriteByte(dat[i])
  65. }
  66. } else {
  67. buf.WriteByte(dat[i])
  68. }
  69. } else {
  70. buf.WriteByte(dat[i])
  71. }
  72. }
  73. return buf.Bytes()
  74. }