PHP Classes

File: codec.go

Recommend this page to a friend!
  Classes of Wolfy-J  >  goridge  >  codec.go  >  Download  
File: codec.go
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: goridge
Run Golang code from PHP calling its RPC server
Author: By
Last change:
Date: 3 years ago
Size: 1,994 bytes
 

Contents

Class file image Download
package goridge

import (
	"encoding/json"
	"errors"
	"io"
	"net/rpc"
	"reflect"
)

// Codec represent net/rpc bridge over Goridge socket relay.
type Codec struct {
	relay  Relay
	closed bool
}

// NewCodec initiates new server rpc codec over socket connection.
func NewCodec(rwc io.ReadWriteCloser) *Codec {
	return &Codec{relay: NewSocketRelay(rwc)}
}

// ReadRequestHeader receives
func (c *Codec) ReadRequestHeader(r *rpc.Request) error {
	data, p, err := c.relay.Receive()
	if err != nil {
		return err
	}

	if !p.HasFlag(PayloadControl) {
		return errors.New("invalid request, control data is expected")
	}

	if !p.HasFlag(PayloadRaw) {
		return errors.New("rpc control command must be in {rawData}")
	}

	if !p.HasPayload() {
		return nil
	}

	r.ServiceMethod = string(data)
	return nil
}

// ReadRequestBody fetches prefixed body data and automatically unmarshal it as json. RawBody flag will populate
// []byte lice argument for rpc method.
func (c *Codec) ReadRequestBody(out interface{}) error {
	data, p, err := c.relay.Receive()
	if err != nil {
		return err
	}

	if !p.HasPayload() {
		return nil
	}

	if p.HasFlag(PayloadRaw) {
		if bin, ok := out.(*[]byte); ok {
			*bin = append(*bin, data...)
			return nil
		}

		return errors.New("{rawData} request for " + reflect.ValueOf(out).Elem().Kind().String())
	}

	return json.Unmarshal(data, out)
}

// WriteResponse marshals response, byte slice or error to remote party.
func (c *Codec) WriteResponse(r *rpc.Response, body interface{}) error {
	if r.Error != "" {
		return c.relay.Send([]byte(r.Error), PayloadError|PayloadRaw)
	}

	if bin, ok := body.(*[]byte); ok {
		return c.relay.Send(*bin, PayloadRaw)
	}

	if bin, ok := body.([]byte); ok {
		return c.relay.Send(bin, PayloadRaw)
	}

	packed, err := json.Marshal(body)
	if err != nil {
		return err
	}

	return c.relay.Send(packed, 0)
}

// Close underlying socket.
func (c *Codec) Close() error {
	if c.closed {
		return nil
	}

	c.closed = true
	return c.relay.Close()
}
For more information send a message to info at phpclasses dot org.