github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/ppapi/websocket_nacl.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ppapi
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"unsafe"
    11  )
    12  
    13  var (
    14  	errCreateWebsocketFailed = errors.New("could not create websocket")
    15  )
    16  
    17  type WebsocketConn struct {
    18  	Resource
    19  	closed bool
    20  }
    21  
    22  func (inst Instance) createWebsocketConn() (ws *WebsocketConn, err error) {
    23  	id := ppb_websocket_create(inst.id)
    24  	if id == 0 {
    25  		err = errCreateWebsocketFailed
    26  		return
    27  	}
    28  	return &WebsocketConn{
    29  		Resource: Resource{
    30  			id: id,
    31  		},
    32  	}, nil
    33  }
    34  
    35  func (ws *WebsocketConn) connect(url string) error {
    36  	urlVar := VarFromString(url)
    37  	defer urlVar.Release()
    38  	code := ppb_websocket_connect(ws.id, pp_Var(urlVar), (*pp_Var)(unsafe.Pointer(uintptr(0))), uint32(0), ppNullCompletionCallback)
    39  	return decodeError(Error(code))
    40  }
    41  
    42  func (ws *WebsocketConn) Close() error {
    43  	code := ppb_websocket_close(ws.id, uint16(PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED), pp_Var(VarUndefined), ppNullCompletionCallback)
    44  	return decodeError(Error(code))
    45  }
    46  
    47  func (ws *WebsocketConn) sendMessageInternal(message Var) error {
    48  	if ws.closed {
    49  		return fmt.Errorf("Cannot send on closed connection")
    50  	}
    51  	code := ppb_websocket_send_message(ws.id, pp_Var(message))
    52  	return decodeError(Error(code))
    53  }
    54  
    55  // Sends a message as a utf-8 string.
    56  func (ws *WebsocketConn) SendMessageUtf8String(m string) error {
    57  	v := VarFromString(m)
    58  	defer v.Release()
    59  	return ws.sendMessageInternal(v)
    60  }
    61  
    62  // Sends a byte slice as a message (treating the contents as an array buffer).
    63  func (ws *WebsocketConn) SendMessage(m []byte) error {
    64  	v := VarFromByteSlice(m)
    65  	defer v.Release()
    66  	return ws.sendMessageInternal(v)
    67  }
    68  
    69  func (ws *WebsocketConn) receiveMessageInternal() (Var, error) {
    70  	if ws.closed {
    71  		return Var{}, fmt.Errorf("Cannot send on closed connection")
    72  	}
    73  	var pv pp_Var
    74  	code := ppb_websocket_receive_message(ws.id, &pv, ppNullCompletionCallback)
    75  	return Var(pv), decodeError(Error(code))
    76  }
    77  
    78  // Reads a message as a utf-8 string (blocking).
    79  func (ws *WebsocketConn) ReceiveMessageUtf8String() (string, error) {
    80  	v, err := ws.receiveMessageInternal()
    81  	if err != nil {
    82  		return "", err
    83  	}
    84  	defer v.Release()
    85  	return v.AsString()
    86  }
    87  
    88  // Reads a message as a byte slice (blocking).
    89  func (ws *WebsocketConn) ReceiveMessage() ([]byte, error) {
    90  	v, err := ws.receiveMessageInternal()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	defer v.Release()
    95  	return v.AsByteSlice()
    96  }
    97  
    98  // Url must start with "ws:".
    99  func (inst Instance) DialWebsocket(url string) (*WebsocketConn, error) {
   100  	ws, err := inst.createWebsocketConn()
   101  	if err != nil {
   102  		return ws, err
   103  	}
   104  
   105  	err = ws.connect(url)
   106  	return ws, err
   107  }