good morning!!!!

Skip to content
Snippets Groups Projects
wsjson.go 1.77 KiB
Newer Older
  • Learn to ignore specific revisions
  • Anmol Sethi's avatar
    Anmol Sethi committed
    // Package wsjson provides helpers for reading and writing JSON messages.
    
    a's avatar
    a committed
    package wsjson // import "gfx.cafe/open/websocket/wsjson"
    
    
    import (
    	"context"
    	"encoding/json"
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    
    
    a's avatar
    a committed
    	"gfx.cafe/open/websocket"
    	"gfx.cafe/open/websocket/internal/bpool"
    	"gfx.cafe/open/websocket/internal/errd"
    
    a's avatar
    a  
    a committed
    	"gfx.cafe/open/websocket/internal/util"
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    // Read reads a JSON message from c into v.
    // It will reuse buffers in between calls to avoid allocations.
    
    func Read(ctx context.Context, c *websocket.Conn, v interface{}) error {
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    	return read(ctx, c, v)
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    func read(ctx context.Context, c *websocket.Conn, v interface{}) (err error) {
    	defer errd.Wrap(&err, "failed to read JSON message")
    
    
    	_, r, err := c.Reader(ctx)
    
    	if err != nil {
    		return err
    	}
    
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    	b := bpool.Get()
    	defer bpool.Put(b)
    
    
    	_, err = b.ReadFrom(r)
    	if err != nil {
    		return err
    	}
    
    	err = json.Unmarshal(b.Bytes(), v)
    
    	if err != nil {
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    		c.Close(websocket.StatusInvalidFramePayloadData, "failed to unmarshal JSON")
    
    		return fmt.Errorf("failed to unmarshal JSON: %w", err)
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    // Write writes the JSON message v to c.
    // It will reuse buffers in between calls to avoid allocations.
    
    func Write(ctx context.Context, c *websocket.Conn, v interface{}) error {
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    	return write(ctx, c, v)
    
    Anmol Sethi's avatar
    Anmol Sethi committed
    func write(ctx context.Context, c *websocket.Conn, v interface{}) (err error) {
    	defer errd.Wrap(&err, "failed to write JSON message")
    
    	// json.Marshal cannot reuse buffers between calls as it has to return
    	// a copy of the byte slice but Encoder does as it directly writes to w.
    
    	err = json.NewEncoder(util.WriterFunc(func(p []byte) (int, error) {
    		err := c.Write(ctx, websocket.MessageText, p)
    		if err != nil {
    			return 0, err
    		}
    		return len(p), nil
    	})).Encode(v)
    
    	if err != nil {
    
    		return fmt.Errorf("failed to marshal JSON: %w", err)