package node import ( "bytes" "sync" core "dappco.re/go/core" ) // bufferPool provides reusable byte buffers for JSON encoding in hot paths. // This reduces allocation overhead in message serialization. var bufferPool = sync.Pool{ New: func() any { return bytes.NewBuffer(make([]byte, 0, 1024)) }, } func getBuffer() *bytes.Buffer { buffer := bufferPool.Get().(*bytes.Buffer) buffer.Reset() return buffer } func putBuffer(buffer *bytes.Buffer) { // Don't pool buffers that grew too large (>64KB) if buffer.Cap() <= 65536 { bufferPool.Put(buffer) } } // MarshalJSON encodes a value to JSON using Core's JSON primitive and then // restores the historical no-EscapeHTML behaviour expected by the node package. // Returns a copy of the encoded bytes (safe to use after the function returns). // // data, err := MarshalJSON(value) func MarshalJSON(value any) ([]byte, error) { encoded := core.JSONMarshal(value) if !encoded.OK { return nil, encoded.Value.(error) } data := encoded.Value.([]byte) data = bytes.ReplaceAll(data, []byte(`\u003c`), []byte("<")) data = bytes.ReplaceAll(data, []byte(`\u003e`), []byte(">")) data = bytes.ReplaceAll(data, []byte(`\u0026`), []byte("&")) // Return a copy since callers may retain the slice after subsequent calls. out := make([]byte, len(data)) copy(out, data) return out, nil }