node_buffer.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package core
  2. import (
  3. "errors"
  4. "github.com/dop251/goja"
  5. )
  6. type BufferObj struct {
  7. vm *goja.Runtime
  8. }
  9. func (b *BufferObj) From(v interface{}, EF string) *Buffer {
  10. var buffer []byte
  11. switch v := v.(type) {
  12. case string:
  13. if EF != "" {
  14. buffer = Convert(b.vm, v, EF, "bytes").([]byte)
  15. } else {
  16. buffer = []byte(v)
  17. }
  18. case []byte:
  19. if EF != "" {
  20. buffer = Convert(b.vm, v, EF, "bytes").([]byte)
  21. } else {
  22. buffer = v
  23. }
  24. case int:
  25. buffer = make([]byte, v)
  26. case int64:
  27. buffer = make([]byte, v)
  28. default:
  29. panic(b.vm.NewTypeError("invalid argument type"))
  30. }
  31. return &Buffer{
  32. vm: b.vm,
  33. value: buffer,
  34. }
  35. }
  36. func (b *BufferObj) Alloc(v int) *Buffer {
  37. return &Buffer{
  38. vm: b.vm,
  39. value: make([]byte, v),
  40. }
  41. }
  42. type Buffer struct {
  43. value []byte
  44. vm *goja.Runtime
  45. }
  46. func (b *Buffer) Length() int {
  47. return len(b.value)
  48. }
  49. func (b *Buffer) Write(value interface{}, offset int, length int) int {
  50. var buf []byte
  51. switch value := value.(type) {
  52. case string:
  53. buf = []byte(value)
  54. case []byte:
  55. buf = value
  56. default:
  57. panic(b.vm.NewTypeError("invalid argument type"))
  58. }
  59. if offset+length > len(b.value) {
  60. panic(b.vm.NewGoError(errors.New("out of range")))
  61. }
  62. copy(b.value[offset:], buf[:length])
  63. return len(b.value)
  64. }
  65. func (b *Buffer) ToString(EF string) interface{} {
  66. if EF != "" {
  67. return Convert(b.vm, b.value, "", EF)
  68. }
  69. return string(b.value)
  70. }
  71. func (b *Buffer) Slice(start int, end int) *Buffer {
  72. if start < 0 {
  73. start += len(b.value)
  74. }
  75. if end <= 0 {
  76. end += len(b.value)
  77. }
  78. if end > len(b.value) {
  79. end = len(b.value)
  80. }
  81. if start >= end || start >= len(b.value) {
  82. return nil
  83. }
  84. return &Buffer{
  85. value: b.value[start:end],
  86. }
  87. }
  88. func (b *Buffer) Copy(target []byte, sourceStart int, targetStart int, sourceEnd int) int {
  89. if sourceStart < 0 {
  90. sourceStart += len(b.value)
  91. }
  92. if sourceEnd < 0 {
  93. sourceEnd += len(b.value)
  94. }
  95. if targetStart < 0 {
  96. targetStart += len(target)
  97. }
  98. if sourceEnd > len(b.value) {
  99. sourceEnd = len(b.value)
  100. }
  101. if sourceStart >= sourceEnd || sourceStart >= len(b.value) {
  102. return 0
  103. }
  104. return copy(target[targetStart:], b.value[sourceStart:sourceEnd])
  105. }
  106. func (b *Buffer) Join(sep []byte, buffers ...[]byte) []byte {
  107. var totalLen int
  108. for _, buf := range buffers {
  109. totalLen += len(buf)
  110. }
  111. if len(sep) > 0 && len(buffers) > 1 {
  112. totalLen += len(sep) * (len(buffers) - 1)
  113. }
  114. result := make([]byte, totalLen)
  115. offset := 0
  116. for i, buf := range buffers {
  117. copy(result[offset:], buf)
  118. offset += len(buf)
  119. if i < len(buffers)-1 && len(sep) > 0 {
  120. copy(result[offset:], sep)
  121. offset += len(sep)
  122. }
  123. }
  124. return result
  125. }
  126. func bufferModule(vm *goja.Runtime, module *goja.Object) {
  127. o := module.Get("exports").(*goja.Object)
  128. o.Set("Buffer", &BufferObj{vm: vm})
  129. }