You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2015/03/13 22:36:06 UTC

[1/2] qpid-proton git commit: PROTON-827: go binding - send.go, listen.go examples with implementation stubs.

Repository: qpid-proton
Updated Branches:
  refs/heads/master faf925c4a -> 695f8e5b9


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/unmarshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/unmarshal.go b/proton-c/bindings/go/src/qpid.apache.org/proton/unmarshal.go
new file mode 100644
index 0000000..fb09d0f
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/unmarshal.go
@@ -0,0 +1,517 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+oor more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"bytes"
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+const minDecode = 256
+
+//
+// Decoding from a pn_data_t
+//
+// NOTE: we use panic() to signal a decoding error, simplifies decoding logic.
+// We recover() at the highest possible level - i.e. in the exported Unmarshal or Decode.
+//
+
+// Decoder decodes AMQP values from an io.Reader.
+//
+type Decoder struct {
+	reader io.Reader
+	buffer bytes.Buffer
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder has it's own buffer and may read more data than required for the
+// AMQP values requested.  Use Buffered to see if there is data left in the
+// buffer.
+//
+func NewDecoder(r io.Reader) *Decoder {
+	return &Decoder{r, bytes.Buffer{}}
+}
+
+// Buffered returns a reader of the data remaining in the Decoder's buffer. The
+// reader is valid until the next call to Decode.
+//
+func (d *Decoder) Buffered() io.Reader {
+	return bytes.NewReader(d.buffer.Bytes())
+}
+
+// Decode reads the next AMQP value from the Reader and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about the conversion of AMQP into a Go value.
+//
+func (d *Decoder) Decode(v interface{}) (err error) {
+	defer doRecover(&err)
+	data := C.pn_data(0)
+	defer C.pn_data_free(data)
+	var n int
+	for n == 0 && err == nil {
+		n = unmarshal(data, d.buffer.Bytes(), v)
+		if n == 0 { // n == 0 means not enough data, read more
+			err = d.more()
+			if err != nil {
+				return
+			}
+		}
+	}
+	d.buffer.Next(n)
+	return
+}
+
+/*
+Unmarshal decodes AMQP-encoded bytes and stores the result in the value pointed to by v.
+Types are converted as follows:
+
+ +---------------------------+----------------------------------------------------------------------+
+ |To Go types                |From AMQP types                                                       |
+ +===========================+======================================================================+
+ |bool                       |bool                                                                  |
+ +---------------------------+----------------------------------------------------------------------+
+ |int, int8, int16,          |Equivalent or smaller signed integer type: char, byte, short, int,    |
+ |int32, int64               |long.                                                                 |
+ +---------------------------+----------------------------------------------------------------------+
+ |uint, uint8, uint16,       |Equivalent or smaller unsigned integer type: char, ubyte, ushort,     |
+ |uint32, uint64 types       |uint, ulong                                                           |
+ +---------------------------+----------------------------------------------------------------------+
+ |float32, float64           |Equivalent or smaller float or double.                                |
+ +---------------------------+----------------------------------------------------------------------+
+ |string, []byte             |string, symbol or binary.                                             |
+ +---------------------------+----------------------------------------------------------------------+
+ |map[K]T                    |map, provided all keys and values can unmarshal to types K, T         |
+ +---------------------------+----------------------------------------------------------------------+
+ |Map|map, any AMQP map                                                     |
+ +---------------------------+----------------------------------------------------------------------+
+ |interface{}                |Any AMQP value can be unmarshaled to an interface{} as follows:       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |AMQP Type               |Go Type in interface{}                       |
+ |                           +========================+=============================================+
+ |                           |bool                    |bool                                         |
+ |                           +------------------------+---------------------------------------------+
+ |                           |char                    |unint8                                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |byte,short,int,long     |int8,int16,int32,int64                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |ubyte,ushort,uint,ulong |uint8,uint16,uint32,uint64                   |
+ |                           +------------------------+---------------------------------------------+
+ |                           |float, double           |float32, float64                             |
+ |                           +------------------------+---------------------------------------------+
+ |                           |string, symbol          |string                                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |binary                  |byte[]                                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |map                     |Map                                          |
+ |                           +------------------------+---------------------------------------------+
+ |                           |list                    |List                                         |
+ +---------------------------+------------------------+---------------------------------------------+
+
+The following Go types cannot be unmarshaled: complex64/128, uintptr, function, interface, channel.
+
+TODO types
+
+AMQP: null, timestamp, decimal32/64/128, uuid, described, array.
+
+Go: array, struct.
+
+*/
+func Unmarshal(bytes []byte, v interface{}) (n int, err error) {
+	defer doRecover(&err)
+	data := C.pn_data(0)
+	defer C.pn_data_free(data)
+	n = unmarshal(data, bytes, v)
+	if n == 0 {
+		err = errorf("not enough data")
+	}
+	return
+}
+
+// more reads more data when we can't parse a complete AMQP type
+func (d *Decoder) more() error {
+	var readSize int64 = minDecode
+	if int64(d.buffer.Len()) > readSize { // Grow by doubling
+		readSize = int64(d.buffer.Len())
+	}
+	var n int64
+	n, err := d.buffer.ReadFrom(io.LimitReader(d.reader, readSize))
+	if n == 0 && err == nil { // ReadFrom won't report io.EOF, just returns 0
+		err = io.EOF
+	}
+	return err
+}
+
+// unmarshal decodes from bytes and converts into the value pointed to by v.
+// Used by Unmarshal and Decode
+//
+// Returns the number of bytes decoded or 0 if not enough data.
+//
+func unmarshal(data *C.pn_data_t, bytes []byte, v interface{}) (n int) {
+	n = decode(data, bytes)
+	if n == 0 {
+		return 0
+	}
+	get(data, v)
+	return
+}
+
+// Get value v from data
+func get(data *C.pn_data_t, v interface{}) {
+
+	pnType := C.pn_data_type(data)
+
+	switch v := v.(type) {
+	case *bool:
+		switch pnType {
+		case C.PN_BOOL:
+			*v = bool(C.pn_data_get_bool(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	case *int8:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int8(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int8(C.pn_data_get_byte(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	case *uint8:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint8(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint8(C.pn_data_get_ubyte(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	case *int16:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int16(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int16(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int16(C.pn_data_get_short(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	case *uint16:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint16(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint16(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint16(C.pn_data_get_ushort(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	case *int32:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int32(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int32(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int32(C.pn_data_get_short(data))
+		case C.PN_INT:
+			*v = int32(C.pn_data_get_int(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	case *uint32:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint32(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint32(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint32(C.pn_data_get_ushort(data))
+		case C.PN_UINT:
+			*v = uint32(C.pn_data_get_uint(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *int64:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int64(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int64(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int64(C.pn_data_get_short(data))
+		case C.PN_INT:
+			*v = int64(C.pn_data_get_int(data))
+		case C.PN_LONG:
+			*v = int64(C.pn_data_get_long(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *uint64:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint64(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint64(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint64(C.pn_data_get_ushort(data))
+		case C.PN_ULONG:
+			*v = uint64(C.pn_data_get_ulong(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *int:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int(C.pn_data_get_short(data))
+		case C.PN_INT:
+			*v = int(C.pn_data_get_int(data))
+		case C.PN_LONG:
+			if unsafe.Sizeof(0) == 8 {
+				*v = int(C.pn_data_get_long(data))
+			} else {
+				panic(newBadUnmarshal(pnType, v))
+			}
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *uint:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint(C.pn_data_get_ushort(data))
+		case C.PN_UINT:
+			*v = uint(C.pn_data_get_uint(data))
+		case C.PN_ULONG:
+			if unsafe.Sizeof(0) == 8 {
+				*v = uint(C.pn_data_get_ulong(data))
+			} else {
+				panic(newBadUnmarshal(pnType, v))
+			}
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *float32:
+		switch pnType {
+		case C.PN_FLOAT:
+			*v = float32(C.pn_data_get_float(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *float64:
+		switch pnType {
+		case C.PN_FLOAT:
+			*v = float64(C.pn_data_get_float(data))
+		case C.PN_DOUBLE:
+			*v = float64(C.pn_data_get_double(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *string:
+		switch pnType {
+		case C.PN_STRING:
+			*v = goString(C.pn_data_get_string(data))
+		case C.PN_SYMBOL:
+			*v = goString(C.pn_data_get_symbol(data))
+		case C.PN_BINARY:
+			*v = goString(C.pn_data_get_binary(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *[]byte:
+		switch pnType {
+		case C.PN_STRING:
+			*v = goBytes(C.pn_data_get_string(data))
+		case C.PN_SYMBOL:
+			*v = goBytes(C.pn_data_get_symbol(data))
+		case C.PN_BINARY:
+			*v = goBytes(C.pn_data_get_binary(data))
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+
+	case *interface{}:
+		getInterface(data, v)
+
+	default:
+		if reflect.TypeOf(v).Kind() != reflect.Ptr {
+			panic(newBadUnmarshal(pnType, v))
+		}
+		switch reflect.TypeOf(v).Elem().Kind() {
+		case reflect.Map:
+			getMap(data, v)
+		case reflect.Slice:
+			getList(data, v)
+		default:
+			panic(newBadUnmarshal(pnType, v))
+		}
+	}
+	err := pnDataError(data)
+	if err != "" {
+		panic(errorf("unmarshal %s", err))
+	}
+	return
+}
+
+// Getting into an interface is driven completely by the AMQP type, since the interface{}
+// target is type-neutral.
+func getInterface(data *C.pn_data_t, v *interface{}) {
+	pnType := C.pn_data_type(data)
+	switch pnType {
+	case C.PN_BOOL:
+		*v = bool(C.pn_data_get_bool(data))
+	case C.PN_UBYTE:
+		*v = uint8(C.pn_data_get_ubyte(data))
+	case C.PN_BYTE:
+		*v = int8(C.pn_data_get_byte(data))
+	case C.PN_USHORT:
+		*v = uint16(C.pn_data_get_ushort(data))
+	case C.PN_SHORT:
+		*v = int16(C.pn_data_get_short(data))
+	case C.PN_UINT:
+		*v = uint32(C.pn_data_get_uint(data))
+	case C.PN_INT:
+		*v = int32(C.pn_data_get_int(data))
+	case C.PN_CHAR:
+		*v = uint8(C.pn_data_get_char(data))
+	case C.PN_ULONG:
+		*v = uint64(C.pn_data_get_ulong(data))
+	case C.PN_LONG:
+		*v = int64(C.pn_data_get_long(data))
+	case C.PN_FLOAT:
+		*v = float32(C.pn_data_get_float(data))
+	case C.PN_DOUBLE:
+		*v = float64(C.pn_data_get_double(data))
+	case C.PN_BINARY:
+		*v = goBytes(C.pn_data_get_binary(data))
+	case C.PN_STRING:
+		*v = goString(C.pn_data_get_string(data))
+	case C.PN_SYMBOL:
+		*v = goString(C.pn_data_get_symbol(data))
+	case C.PN_MAP:
+		m := make(Map)
+		get(data, &m)
+		*v = m // FIXME aconway 2015-03-13: avoid the copy?
+	case C.PN_LIST:
+		l := make(List, 0)
+		get(data, &l)
+		*v = l
+	default:
+		panic(newBadUnmarshal(pnType, v))
+	}
+}
+
+func getMap(data *C.pn_data_t, v interface{}) {
+	pnType := C.pn_data_type(data)
+	if pnType != C.PN_MAP {
+		panic(newBadUnmarshal(pnType, v))
+	}
+	mapValue := reflect.ValueOf(v).Elem()
+	mapValue.Set(reflect.MakeMap(mapValue.Type())) // Clear the map
+	count := int(C.pn_data_get_map(data))
+	if bool(C.pn_data_enter(data)) {
+		for i := 0; i < count/2; i++ {
+			if bool(C.pn_data_next(data)) {
+				key := reflect.New(mapValue.Type().Key())
+				get(data, key.Interface())
+				if bool(C.pn_data_next(data)) {
+					val := reflect.New(mapValue.Type().Elem())
+					get(data, val.Interface())
+					mapValue.SetMapIndex(key.Elem(), val.Elem())
+				}
+			}
+		}
+		C.pn_data_exit(data)
+	}
+}
+
+func getList(data *C.pn_data_t, v interface{}) {
+	pnType := C.pn_data_type(data)
+	if pnType != C.PN_LIST {
+		panic(newBadUnmarshal(pnType, v))
+	}
+	count := int(C.pn_data_get_list(data))
+	listValue := reflect.MakeSlice(reflect.TypeOf(v).Elem(), count, count)
+	if bool(C.pn_data_enter(data)) {
+		for i := 0; i < count; i++ {
+			if bool(C.pn_data_next(data)) {
+				val := reflect.New(listValue.Type().Elem())
+				get(data, val.Interface())
+				listValue.Index(i).Set(val.Elem())
+			}
+		}
+		C.pn_data_exit(data)
+	}
+	reflect.ValueOf(v).Elem().Set(listValue)
+}
+
+// decode from bytes.
+// Return bytes decoded or 0 if we could not decode a complete object.
+//
+func decode(data *C.pn_data_t, bytes []byte) int {
+	if len(bytes) == 0 {
+		return 0
+	}
+	cBuf := (*C.char)(unsafe.Pointer(&bytes[0]))
+	n := int(C.pn_data_decode(data, cBuf, C.size_t(len(bytes))))
+	if n == int(C.PN_EOS) {
+		return 0
+	} else if n <= 0 {
+		panic(errorf("unmarshal %s", pnErrorName(n)))
+	}
+	return n
+}
+
+func goBytes(cBytes C.pn_bytes_t) (bytes []byte) {
+	if cBytes.start != nil {
+		bytes = C.GoBytes(unsafe.Pointer(cBytes.start), C.int(cBytes.size))
+	}
+	return
+}
+
+func goString(cBytes C.pn_bytes_t) (str string) {
+	if cBytes.start != nil {
+		str = C.GoStringN(cBytes.start, C.int(cBytes.size))
+	}
+	return
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/url.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/url.go b/proton-c/bindings/go/src/qpid.apache.org/proton/url.go
new file mode 100644
index 0000000..079dfb2
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/url.go
@@ -0,0 +1,96 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+/*
+#cgo LDFLAGS: -lqpid-proton
+#include <stdlib.h>
+#include <string.h>
+#include <proton/url.h>
+
+// Helper function for setting URL fields.
+typedef void (*setter_fn)(pn_url_t* url, const char* value);
+inline void	set(pn_url_t *url, setter_fn s, const char* value) {
+  s(url, value);
+}
+*/
+import "C"
+
+import (
+	"net"
+	"net/url"
+	"unsafe"
+)
+
+const (
+	amqp  string = "amqp"
+	amqps        = "amqps"
+)
+
+// ParseUrl parses an AMQP URL string and returns a net/url.Url.
+//
+// It is more forgiving than net/url.Parse and allows most of the parts of the
+// URL to be missing, assuming AMQP defaults.
+//
+func ParseURL(s string) (u *url.URL, err error) {
+	cstr := C.CString(s)
+	defer C.free(unsafe.Pointer(cstr))
+	pnUrl := C.pn_url_parse(cstr)
+	if pnUrl == nil {
+		return nil, errorf("bad URL %#v", s)
+	}
+	defer C.pn_url_free(pnUrl)
+
+	scheme := C.GoString(C.pn_url_get_scheme(pnUrl))
+	username := C.GoString(C.pn_url_get_username(pnUrl))
+	password := C.GoString(C.pn_url_get_password(pnUrl))
+	host := C.GoString(C.pn_url_get_host(pnUrl))
+	port := C.GoString(C.pn_url_get_port(pnUrl))
+	path := C.GoString(C.pn_url_get_path(pnUrl))
+
+	if err != nil {
+		return nil, errorf("bad URL %#v: %s", s, err)
+	}
+	if scheme == "" {
+		scheme = amqp
+	}
+	if port == "" {
+		if scheme == amqps {
+			port = amqps
+		} else {
+			port = amqp
+		}
+	}
+	var user *url.Userinfo
+	if password != "" {
+		user = url.UserPassword(username, password)
+	} else if username != "" {
+		user = url.User(username)
+	}
+
+	u = &url.URL{
+		Scheme: scheme,
+		User:   user,
+		Host:   net.JoinHostPort(host, port),
+		Path:   path,
+	}
+
+	return u, nil
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/url_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/url_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/url_test.go
new file mode 100644
index 0000000..7315511
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/url_test.go
@@ -0,0 +1,51 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+import (
+	"fmt"
+)
+
+func ExampleParseURL() {
+	for _, s := range []string{
+		"amqp://username:password@host:1234/path",
+		"host:1234",
+		"host",
+		":1234",
+		"host/path",
+		"amqps://host",
+		"",
+	} {
+		u, err := ParseURL(s)
+		if err != nil {
+			fmt.Println(err)
+		} else {
+			fmt.Println(u)
+		}
+	}
+	// Output:
+	// amqp://username:password@host:1234/path
+	// amqp://host:1234
+	// amqp://host:amqp
+	// amqp://:1234
+	// amqp://host:amqp/path
+	// amqps://host:amqps
+	// proton: bad URL ""
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[2/2] qpid-proton git commit: PROTON-827: go binding - send.go, listen.go examples with implementation stubs.

Posted by ac...@apache.org.
PROTON-827: go binding - send.go, listen.go examples with implementation stubs.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/695f8e5b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/695f8e5b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/695f8e5b

Branch: refs/heads/master
Commit: 695f8e5b96c75640bcf10fb12252a0130b70d0a0
Parents: faf925c
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Mar 13 15:36:44 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Mar 13 17:35:10 2015 -0400

----------------------------------------------------------------------
 examples/go/README.md                           |  17 +
 examples/go/listen.go                           |  64 +++
 examples/go/send.go                             |  77 +++
 proton-c/bindings/go/README.md                  |   3 +-
 .../bindings/go/src/apache.org/proton/doc.go    |  33 --
 .../bindings/go/src/apache.org/proton/error.go  |  96 ----
 .../go/src/apache.org/proton/interop_test.go    | 290 -----------
 .../go/src/apache.org/proton/marshal.go         | 206 --------
 .../bindings/go/src/apache.org/proton/types.go  | 137 -----
 .../go/src/apache.org/proton/unmarshal.go       | 515 ------------------
 .../bindings/go/src/apache.org/proton/url.go    |  96 ----
 .../go/src/apache.org/proton/url_test.go        |  51 --
 .../go/src/qpid.apache.org/proton/doc.go        |  33 ++
 .../go/src/qpid.apache.org/proton/error.go      |  96 ++++
 .../src/qpid.apache.org/proton/interop_test.go  | 290 +++++++++++
 .../go/src/qpid.apache.org/proton/marshal.go    | 210 ++++++++
 .../go/src/qpid.apache.org/proton/types.go      | 151 ++++++
 .../go/src/qpid.apache.org/proton/unfinished.go |  53 ++
 .../go/src/qpid.apache.org/proton/unmarshal.go  | 517 +++++++++++++++++++
 .../go/src/qpid.apache.org/proton/url.go        |  96 ++++
 .../go/src/qpid.apache.org/proton/url_test.go   |  51 ++
 21 files changed, 1656 insertions(+), 1426 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/examples/go/README.md
----------------------------------------------------------------------
diff --git a/examples/go/README.md b/examples/go/README.md
new file mode 100644
index 0000000..0d86a62
--- /dev/null
+++ b/examples/go/README.md
@@ -0,0 +1,17 @@
+# *EXPERIMENTAL* Go examples for proton.
+
+See ../../proton-c/bindings/go/README.md
+
+These are sketches of examples for the experimental Go binding.
+
+They don't have sufficient error handling.
+
+They compile and run but do nothing as the binding implementation is just stubs right now.
+
+- listen.go: listens on a port, prints any messages it receives.
+- send.go: sends command-line arguments as messages with string bodies.
+
+You can use the two together, e.g. to listen/send on port 1234:
+
+go run listen.go -addr :1234
+go run send.go -addr :1234 foo bar 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/examples/go/listen.go
----------------------------------------------------------------------
diff --git a/examples/go/listen.go b/examples/go/listen.go
new file mode 100644
index 0000000..95285dd
--- /dev/null
+++ b/examples/go/listen.go
@@ -0,0 +1,64 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"net"
+	"os"
+	"qpid.apache.org/proton"
+)
+
+// A message handler type
+type Receiver struct{}
+
+// OnMessage is called when an AMQP message is received.
+func (r *Receiver) OnMessage(e *proton.Event) {
+	fmt.Printf("%#v\n", e.Message)
+}
+
+var addr = flag.String("addr", ":amqp", "Listening address, e.g. localhost:1234")
+
+func main() {
+	flag.Usage = func() {
+		fmt.Fprintln(os.Stderr, "Listen for AMQP messages and print them to stdout until killed.")
+		flag.PrintDefaults()
+	}
+	flag.Parse()
+
+	// Listen for and accept connections using the standard Go net package.
+	listener, err := net.Listen("tcp", *addr)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Listen error: %s\n", err)
+		os.Exit(1)
+	}
+	for {
+		conn, err := listener.Accept()
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Accept error: %s\n", err)
+			continue
+		}
+		fmt.Printf("Accepted connection %s<-%s\n", conn.LocalAddr(), conn.RemoteAddr())
+		// Run processes an AMQP connection and invokes the supplied handler.
+		// In this case it will call (*Receiver) OnMessage when a message is received.
+		go proton.Run(conn, &Receiver{})
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/examples/go/send.go
----------------------------------------------------------------------
diff --git a/examples/go/send.go b/examples/go/send.go
new file mode 100644
index 0000000..13d749d
--- /dev/null
+++ b/examples/go/send.go
@@ -0,0 +1,77 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"net"
+	"os"
+	"qpid.apache.org/proton"
+)
+
+// A message handler type
+type Sender struct {
+	Messages       []string
+	Sent, Accepted int
+	Sender         *proton.Sender
+}
+
+// Called when proton.Run is first called on a connection.
+func (s *Sender) OnStart(e *proton.Event) {
+	// Create a sender
+	// FIXME aconway 2015-03-13: Creating sendders on other connections?
+	s.Sender = e.Connection().NewSender("sender")
+}
+
+// Called when a sender has credit to send messages. Send all of flag.Args()
+func (s *Sender) OnSendable(e *proton.Event) {
+	for e.Sender().Credit() > 0 && s.Sent < len(flag.Args()) {
+		// FIXME aconway 2015-03-13: error handling
+		e.Sender().Send(&proton.Message{Body: s.Messages[s.Sent]})
+		s.Sent++
+	}
+}
+
+func (s *Sender) OnAccepted(e *proton.Event) {
+	s.Accepted++
+	if s.Accepted == len(flag.Args()) {
+		e.Connection().Close()
+	}
+}
+
+var addr = flag.String("addr", ":amqp", "Listening address, e.g. localhost:1234")
+
+func main() {
+	flag.Usage = func() {
+		fmt.Fprintln(os.Stderr, "Send AMQP messages with string bodies, one for each argument.")
+		flag.PrintDefaults()
+	}
+	flag.Parse()
+
+	conn, err := net.Dial("tcp", *addr)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Dial error: %s\n", err)
+		os.Exit(1)
+	}
+	// Run processes an AMQP connection and invokes the supplied handler.
+	// In this case it will call OnStart.
+	proton.Run(conn, &Sender{Messages: flag.Args()})
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/README.md b/proton-c/bindings/go/README.md
index 8ffa700..8f31b54 100644
--- a/proton-c/bindings/go/README.md
+++ b/proton-c/bindings/go/README.md
@@ -35,8 +35,7 @@ cross-language developers but idiomatic Go is the overriding consideration.
 
 ## Status
 
-So just a simple Go `Url` type using `pn_url_t`.  This establishes the basics of
-using cgo to call into proton code.
+Marshal and unmarshal most of the AMQP types (TODO: described, array)
 
 ## Layout
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/doc.go b/proton-c/bindings/go/src/apache.org/proton/doc.go
deleted file mode 100644
index 34f85fe..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/doc.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/*
-Package proton is a Go binding for the proton AMQP protocol engine.
-
-It alows you to construct and parse AMQP messages, and to implement AMQP
-clients, servers and intermediaries that can exchange messages with any
-AMQP 1.0 compliant endpoint.
-
-Encoding and decoding AMQP data follows the pattern of the standard
-encoding/json and encoding/xml packages.The mapping between AMQP and Go types is
-described in the documentation of the Marshal and Unmarshal functions.
-*/
-package proton
-
-// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/error.go b/proton-c/bindings/go/src/apache.org/proton/error.go
deleted file mode 100644
index f9cc948..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/error.go
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package proton
-
-// #include <proton/error.h>
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"fmt"
-	"reflect"
-	"runtime"
-)
-
-var pnErrorNames = map[int]string{
-	C.PN_EOS:        "end of data",
-	C.PN_ERR:        "error",
-	C.PN_OVERFLOW:   "overflow",
-	C.PN_UNDERFLOW:  "underflow",
-	C.PN_STATE_ERR:  "bad state",
-	C.PN_ARG_ERR:    "invalid argument",
-	C.PN_TIMEOUT:    "timeout",
-	C.PN_INTR:       "interrupted",
-	C.PN_INPROGRESS: "in progress",
-}
-
-func pnErrorName(code int) string {
-	name := pnErrorNames[code]
-	if name != "" {
-		return name
-	} else {
-		return "unknown error code"
-	}
-}
-
-type BadUnmarshal struct {
-	AMQPType C.pn_type_t
-	GoType   reflect.Type
-}
-
-func newBadUnmarshal(pnType C.pn_type_t, v interface{}) *BadUnmarshal {
-	return &BadUnmarshal{pnType, reflect.TypeOf(v)}
-}
-
-func (e BadUnmarshal) Error() string {
-	if e.GoType.Kind() != reflect.Ptr {
-		return fmt.Sprintf("proton: cannot unmarshal to type %s, not a pointer", e.GoType)
-	} else {
-		return fmt.Sprintf("proton: cannot unmarshal AMQP %s to %s", getPnType(e.AMQPType), e.GoType)
-	}
-}
-
-// errorf creates an error with a formatted message
-func errorf(format string, a ...interface{}) error {
-	return fmt.Errorf("proton: %s", fmt.Sprintf(format, a...))
-}
-
-func pnDataError(data *C.pn_data_t) string {
-	err := C.pn_data_error(data)
-	if err != nil && int(C.pn_error_code(err)) != 0 {
-		return C.GoString(C.pn_error_text(err))
-	}
-	return ""
-}
-
-// doRecover is called to recover from internal panics
-func doRecover(err *error) {
-	r := recover()
-	switch r := r.(type) {
-	case nil:
-		return
-	case runtime.Error:
-		panic(r)
-	case error:
-		*err = r
-	default:
-		panic(r)
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/interop_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/interop_test.go b/proton-c/bindings/go/src/apache.org/proton/interop_test.go
deleted file mode 100644
index c51d74a..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/interop_test.go
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-// Test that conversion of Go type to/from AMQP is compatible with other
-// bindings.
-//
-package proton
-
-import (
-	"bytes"
-	"io"
-	"io/ioutil"
-	"os"
-	"reflect"
-	"strings"
-	"testing"
-)
-
-func assertEqual(want interface{}, got interface{}) {
-	if !reflect.DeepEqual(want, got) {
-		panic(errorf("%#v != %#v", want, got))
-	}
-}
-
-func assertNil(err interface{}) {
-	if err != nil {
-		panic(err)
-	}
-}
-
-func getReader(name string) (r io.Reader) {
-	r, err := os.Open("../../../../../../tests/interop/" + name + ".amqp")
-	if err != nil {
-		panic(errorf("Can't open %#v: %v", name, err))
-	}
-	return
-}
-
-func remaining(d *Decoder) string {
-	remainder, _ := ioutil.ReadAll(io.MultiReader(d.Buffered(), d.reader))
-	return string(remainder)
-}
-
-// assertDecode: want is the expected value, gotPtr is a pointer to a
-// instance of the same type for Decode.
-func assertDecode(d *Decoder, want interface{}, gotPtr interface{}) {
-
-	assertNil(d.Decode(gotPtr))
-
-	got := reflect.ValueOf(gotPtr).Elem().Interface()
-	assertEqual(want, got)
-
-	// Try round trip encoding
-	bytes, err := Marshal(want)
-	assertNil(err)
-	n, err := Unmarshal(bytes, gotPtr)
-	assertNil(err)
-	assertEqual(n, len(bytes))
-	got = reflect.ValueOf(gotPtr).Elem().Interface()
-	assertEqual(want, got)
-}
-
-func TestUnmarshal(t *testing.T) {
-	bytes, err := ioutil.ReadAll(getReader("strings"))
-	if err != nil {
-		t.Error(err)
-	}
-	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
-		var got string
-		n, err := Unmarshal(bytes, &got)
-		if err != nil {
-			t.Error(err)
-		}
-		if want != got {
-			t.Errorf("%#v != %#v", want, got)
-		}
-		bytes = bytes[n:]
-	}
-}
-
-func TestPrimitivesExact(t *testing.T) {
-	d := NewDecoder(getReader("primitives"))
-	// Decoding into exact types
-	var b bool
-	assertDecode(d, true, &b)
-	assertDecode(d, false, &b)
-	var u8 uint8
-	assertDecode(d, uint8(42), &u8)
-	var u16 uint16
-	assertDecode(d, uint16(42), &u16)
-	var i16 int16
-	assertDecode(d, int16(-42), &i16)
-	var u32 uint32
-	assertDecode(d, uint32(12345), &u32)
-	var i32 int32
-	assertDecode(d, int32(-12345), &i32)
-	var u64 uint64
-	assertDecode(d, uint64(12345), &u64)
-	var i64 int64
-	assertDecode(d, int64(-12345), &i64)
-	var f32 float32
-	assertDecode(d, float32(0.125), &f32)
-	var f64 float64
-	assertDecode(d, float64(0.125), &f64)
-}
-
-func TestPrimitivesCompatible(t *testing.T) {
-	d := NewDecoder(getReader("primitives"))
-	// Decoding into compatible types
-	var b bool
-	var i int
-	var u uint
-	var f float64
-	assertDecode(d, true, &b)
-	assertDecode(d, false, &b)
-	assertDecode(d, uint(42), &u)
-	assertDecode(d, uint(42), &u)
-	assertDecode(d, -42, &i)
-	assertDecode(d, uint(12345), &u)
-	assertDecode(d, -12345, &i)
-	assertDecode(d, uint(12345), &u)
-	assertDecode(d, -12345, &i)
-	assertDecode(d, 0.125, &f)
-	assertDecode(d, 0.125, &f)
-}
-
-// assertDecodeValue: want is the expected value, decode into a reflect.Value
-func assertDecodeInterface(d *Decoder, want interface{}) {
-
-	var got, got2 interface{}
-	assertNil(d.Decode(&got))
-
-	assertEqual(want, got)
-
-	// Try round trip encoding
-	bytes, err := Marshal(got)
-	assertNil(err)
-	n, err := Unmarshal(bytes, &got2)
-	assertNil(err)
-	assertEqual(n, len(bytes))
-	assertEqual(want, got2)
-}
-
-func TestPrimitivesInterface(t *testing.T) {
-	d := NewDecoder(getReader("primitives"))
-	assertDecodeInterface(d, true)
-	assertDecodeInterface(d, false)
-	assertDecodeInterface(d, uint8(42))
-	assertDecodeInterface(d, uint16(42))
-	assertDecodeInterface(d, int16(-42))
-	assertDecodeInterface(d, uint32(12345))
-	assertDecodeInterface(d, int32(-12345))
-	assertDecodeInterface(d, uint64(12345))
-	assertDecodeInterface(d, int64(-12345))
-	assertDecodeInterface(d, float32(0.125))
-	assertDecodeInterface(d, float64(0.125))
-}
-
-func TestStrings(t *testing.T) {
-	d := NewDecoder(getReader("strings"))
-	// Test decoding as plain Go strings
-	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
-		var got string
-		assertDecode(d, want, &got)
-	}
-	remains := remaining(d)
-	if remains != "" {
-		t.Errorf("leftover: %s", remains)
-	}
-
-	// Test decoding as specific string types
-	d = NewDecoder(getReader("strings"))
-	var bytes []byte
-	var str, sym string
-	assertDecode(d, []byte("abc\000defg"), &bytes)
-	assertDecode(d, "abcdefg", &str)
-	assertDecode(d, "abcdefg", &sym)
-	assertDecode(d, make([]byte, 0), &bytes)
-	assertDecode(d, "", &str)
-	assertDecode(d, "", &sym)
-	remains = remaining(d)
-	if remains != "" {
-		panic(errorf("leftover: %s", remains))
-	}
-
-	// Test some error handling
-	d = NewDecoder(getReader("strings"))
-	var s string
-	err := d.Decode(s)
-	if err == nil {
-		t.Fatal("Expected error")
-	}
-	if !strings.Contains(err.Error(), "not a pointer") {
-		t.Error(err)
-	}
-	var i int
-	err = d.Decode(&i)
-	if !strings.Contains(err.Error(), "cannot unmarshal") {
-		t.Error(err)
-	}
-	_, err = Unmarshal([]byte{}, nil)
-	if !strings.Contains(err.Error(), "not enough data") {
-		t.Error(err)
-	}
-	_, err = Unmarshal([]byte("foobar"), nil)
-	if !strings.Contains(err.Error(), "invalid argument") {
-		t.Error(err)
-	}
-}
-
-func TestEncodeDecode(t *testing.T) {
-	type data struct {
-		s  string
-		i  int
-		u8 uint8
-		b  bool
-		f  float32
-		v  interface{}
-	}
-
-	in := data{"foo", 42, 9, true, 1.234, "thing"}
-
-	buf := bytes.Buffer{}
-	e := NewEncoder(&buf)
-	e.Encode(in.s)
-	e.Encode(in.i)
-	e.Encode(in.u8)
-	e.Encode(in.b)
-	e.Encode(in.f)
-	e.Encode(in.v)
-
-	var out data
-	d := NewDecoder(&buf)
-	d.Decode(&out.s)
-	d.Decode(&out.i)
-	d.Decode(&out.u8)
-	d.Decode(&out.b)
-	d.Decode(&out.f)
-	d.Decode(&out.v)
-
-	assertEqual(in, out)
-}
-
-func TestMap(t *testing.T) {
-	d := NewDecoder(getReader("maps"))
-
-	// Generic map
-	var m Map
-	assertDecode(d, Map{"one": int32(1), "two": int32(2), "three": int32(3)}, &m)
-
-	// Interface as map
-	var i interface{}
-	assertDecode(d, Map{int32(1): "one", int32(2): "two", int32(3): "three"}, &i)
-
-	d = NewDecoder(getReader("maps"))
-	// Specific typed map
-	var m2 map[string]int
-	assertDecode(d, map[string]int{"one": 1, "two": 2, "three": 3}, &m2)
-
-	// Round trip a nested map
-	m = Map{int64(1): "one", "two": int32(2), true: Map{uint8(1): true, uint8(2): false}}
-	bytes, err := Marshal(m)
-	assertNil(err)
-	_, err = Unmarshal(bytes, &i)
-	assertNil(err)
-	assertEqual(m, i)
-}
-
-func TestList(t *testing.T) {
-	d := NewDecoder(getReader("lists"))
-	var l List
-	assertDecode(d, List{int32(32), "foo", true}, &l)
-	assertDecode(d, List{}, &l)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/marshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/marshal.go b/proton-c/bindings/go/src/apache.org/proton/marshal.go
deleted file mode 100644
index 674a25f..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/marshal.go
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package proton
-
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"io"
-	"reflect"
-	"unsafe"
-)
-
-const minEncode = 256
-
-/*
-Marshal encodes a value as AMQP.
-
-Go types are encoded as follows
-
- +-------------------------------------+--------------------------------------------+
- |Go type                              |AMQP type                                   |
- +-------------------------------------+--------------------------------------------+
- |bool                                 |bool                                        |
- +-------------------------------------+--------------------------------------------+
- |int8, int16, int32, int64 (int)      |byte, short, int, long (int or long)        |
- +-------------------------------------+--------------------------------------------+
- |uint8, uint16, uint32, uint64 (uint) |ubyte, ushort, uint, ulong (uint or ulong)  |
- +-------------------------------------+--------------------------------------------+
- |float32, float64                     |float, double.                              |
- +-------------------------------------+--------------------------------------------+
- |string                               |string                                      |
- +-------------------------------------+--------------------------------------------+
- |[]byte                               |binary                                      |
- +-------------------------------------+--------------------------------------------+
- |interface{}                          |as to the contained type                    |
- +-------------------------------------+--------------------------------------------+
- |map[K]T                              |map with K and T converted as above         |
- +-------------------------------------+--------------------------------------------+
- |Map                                  |map may have mixed types for keys and values|
- +-------------------------------------+--------------------------------------------+
-
-TODO types
-
-Go: array, slice, struct
-
-Go types that cannot be marshaled
-
-complex64/128, uintptr, function, interface, channel
-
-*/
-func Marshal(v interface{}) (bytes []byte, err error) {
-	return marshal(make([]byte, minEncode), v)
-}
-
-func marshal(bytesIn []byte, v interface{}) (bytes []byte, err error) {
-	defer doRecover(&err)
-	data := C.pn_data(0)
-	defer C.pn_data_free(data)
-	put(data, v)
-	// FIXME aconway 2015-03-11: get size from proton.
-	bytes = bytesIn
-	for {
-		n := int(C.pn_data_encode(data, (*C.char)(unsafe.Pointer(&bytes[0])), C.size_t(cap(bytes))))
-		if n != int(C.PN_EOS) {
-			if n < 0 {
-				err = errorf(pnErrorName(n))
-			} else {
-				bytes = bytes[0:n]
-			}
-			return
-		}
-		bytes = make([]byte, cap(bytes)*2)
-	}
-	return
-}
-
-func put(data *C.pn_data_t, v interface{}) {
-	switch v := v.(type) {
-	case bool:
-		C.pn_data_put_bool(data, C.bool(v))
-	case int8:
-		C.pn_data_put_byte(data, C.int8_t(v))
-	case int16:
-		C.pn_data_put_short(data, C.int16_t(v))
-	case int32:
-		C.pn_data_put_int(data, C.int32_t(v))
-	case int64:
-		C.pn_data_put_long(data, C.int64_t(v))
-	case int:
-		if unsafe.Sizeof(0) == 8 {
-			C.pn_data_put_long(data, C.int64_t(v))
-		} else {
-			C.pn_data_put_int(data, C.int32_t(v))
-		}
-	case uint8:
-		C.pn_data_put_ubyte(data, C.uint8_t(v))
-	case uint16:
-		C.pn_data_put_ushort(data, C.uint16_t(v))
-	case uint32:
-		C.pn_data_put_uint(data, C.uint32_t(v))
-	case uint64:
-		C.pn_data_put_ulong(data, C.uint64_t(v))
-	case uint:
-		if unsafe.Sizeof(0) == 8 {
-			C.pn_data_put_ulong(data, C.uint64_t(v))
-		} else {
-			C.pn_data_put_uint(data, C.uint32_t(v))
-		}
-	case float32:
-		C.pn_data_put_float(data, C.float(v))
-	case float64:
-		C.pn_data_put_double(data, C.double(v))
-	case string:
-		C.pn_data_put_string(data, toPnBytes([]byte(v)))
-	case []byte:
-		C.pn_data_put_binary(data, toPnBytes(v))
-	case Map: // Special map type
-		C.pn_data_put_map(data)
-		C.pn_data_enter(data)
-		for key, val := range v {
-			put(data, key)
-			put(data, val)
-		}
-		C.pn_data_exit(data)
-	default:
-		switch reflect.TypeOf(v).Kind() {
-		case reflect.Map:
-			putMap(data, v)
-		case reflect.Slice:
-			putList(data, v)
-		default:
-			panic(errorf("cannot marshal %s to AMQP", reflect.TypeOf(v)))
-		}
-	}
-	err := pnDataError(data)
-	if err != "" {
-		panic(errorf("marshal %s", err))
-	}
-	return
-}
-
-func putMap(data *C.pn_data_t, v interface{}) {
-	mapValue := reflect.ValueOf(v)
-	C.pn_data_put_map(data)
-	C.pn_data_enter(data)
-	for _, key := range mapValue.MapKeys() {
-		put(data, key.Interface())
-		put(data, mapValue.MapIndex(key).Interface())
-	}
-	C.pn_data_exit(data)
-}
-
-func putList(data *C.pn_data_t, v interface{}) {
-	listValue := reflect.ValueOf(v)
-	C.pn_data_put_list(data)
-	C.pn_data_enter(data)
-	for i := 0; i < listValue.Len(); i++ {
-		put(data, listValue.Index(i).Interface())
-	}
-	C.pn_data_exit(data)
-}
-
-// Encoder encodes AMQP values to an io.Writer
-type Encoder struct {
-	writer io.Writer
-	buffer []byte
-}
-
-// New encoder returns a new encoder that writes to w.
-func NewEncoder(w io.Writer) *Encoder {
-	return &Encoder{w, make([]byte, minEncode)}
-}
-
-func (e *Encoder) Encode(v interface{}) (err error) {
-	e.buffer, err = marshal(e.buffer, v)
-	if err == nil {
-		e.writer.Write(e.buffer)
-	}
-	return
-}
-
-func toPnBytes(b []byte) C.pn_bytes_t {
-	if len(b) == 0 {
-		return C.pn_bytes_t{0, nil}
-	} else {
-		return C.pn_bytes_t{C.size_t(len(b)), (*C.char)(unsafe.Pointer(&b[0]))}
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/types.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/types.go b/proton-c/bindings/go/src/apache.org/proton/types.go
deleted file mode 100644
index f8c5560..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/types.go
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package proton
-
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"bytes"
-	"fmt"
-	"reflect"
-)
-
-type pnGet func(data *C.pn_data_t) reflect.Value
-type pnPut func(data *C.pn_data_t, v interface{})
-
-// Information about a proton type
-type pnType struct {
-	code C.pn_type_t // AMQP type code
-	name string      // AMQP type name
-}
-
-func (pt *pnType) String() string { return pt.name }
-
-// pnType definitions for each proton type.
-var (
-	pnNull       = pnType{code: C.PN_NULL, name: "null"}
-	pnBool       = pnType{code: C.PN_BOOL, name: "bool"}
-	pnUbyte      = pnType{code: C.PN_UBYTE, name: "ubyte"}
-	pnByte       = pnType{code: C.PN_BYTE, name: "byte"}
-	pnUshort     = pnType{code: C.PN_USHORT, name: "ushort"}
-	pnShort      = pnType{code: C.PN_SHORT, name: "short"}
-	pnChar       = pnType{code: C.PN_CHAR, name: "char"}
-	pnUint       = pnType{code: C.PN_UINT, name: "uint"}
-	pnInt        = pnType{code: C.PN_INT, name: "int"}
-	pnUlong      = pnType{code: C.PN_ULONG, name: "ulong"}
-	pnLong       = pnType{code: C.PN_LONG, name: "long"}
-	pnTimestamp  = pnType{code: C.PN_TIMESTAMP, name: "timestamp"}
-	pnFloat      = pnType{code: C.PN_FLOAT, name: "float"}
-	pnDouble     = pnType{code: C.PN_DOUBLE, name: "double"}
-	pnDecimal32  = pnType{code: C.PN_DECIMAL32, name: "decimal32"}
-	pnDecimal64  = pnType{code: C.PN_DECIMAL64, name: "decimal64"}
-	pnDecimal128 = pnType{code: C.PN_DECIMAL128, name: "decimal128"}
-	pnUuid       = pnType{code: C.PN_UUID, name: "uuid"}
-	pnBinary     = pnType{code: C.PN_BINARY, name: "binary"}
-	pnString     = pnType{code: C.PN_STRING, name: "string"}
-	pnSymbol     = pnType{code: C.PN_SYMBOL, name: "symbol"}
-	pnDescribed  = pnType{code: C.PN_DESCRIBED, name: "described"}
-	pnArray      = pnType{code: C.PN_ARRAY, name: "array"}
-	pnList       = pnType{code: C.PN_LIST, name: "list"}
-	pnMap        = pnType{code: C.PN_MAP, name: "map"}
-)
-
-// Map from pn_type_t codes to pnType structs
-var pnTypes = map[C.pn_type_t]*pnType{
-	C.PN_NULL:       &pnNull,
-	C.PN_BOOL:       &pnBool,
-	C.PN_UBYTE:      &pnUbyte,
-	C.PN_BYTE:       &pnByte,
-	C.PN_USHORT:     &pnUshort,
-	C.PN_SHORT:      &pnShort,
-	C.PN_UINT:       &pnUint,
-	C.PN_INT:        &pnInt,
-	C.PN_CHAR:       &pnChar,
-	C.PN_ULONG:      &pnUlong,
-	C.PN_LONG:       &pnLong,
-	C.PN_TIMESTAMP:  &pnTimestamp,
-	C.PN_FLOAT:      &pnFloat,
-	C.PN_DOUBLE:     &pnDouble,
-	C.PN_DECIMAL32:  &pnDecimal32,
-	C.PN_DECIMAL64:  &pnDecimal64,
-	C.PN_DECIMAL128: &pnDecimal128,
-	C.PN_UUID:       &pnUuid,
-	C.PN_BINARY:     &pnBinary,
-	C.PN_STRING:     &pnString,
-	C.PN_SYMBOL:     &pnSymbol,
-	C.PN_DESCRIBED:  &pnDescribed,
-	C.PN_ARRAY:      &pnArray,
-	C.PN_LIST:       &pnList,
-	C.PN_MAP:        &pnMap,
-}
-
-// Get the pnType for a pn_type_t code, panic if unknown code.
-func getPnType(code C.pn_type_t) *pnType {
-	pt, ok := pnTypes[code]
-	if !ok {
-		panic(errorf("unknown AMQP type code %v", code))
-	}
-	return pt
-}
-
-// Go types
-var (
-	bytesType = reflect.TypeOf([]byte{})
-	valueType = reflect.TypeOf(reflect.Value{})
-)
-
-// Map is a generic map that can have mixed key and value types and so can represent any AMQP map
-//
-type Map map[interface{}]interface{}
-
-// List is a generic list that can hold mixed values and can represent any AMQP list.
-//
-type List []interface{}
-
-// GoString for Map prints values with their types, useful for debugging.
-func (m Map) GoString() string {
-	out := &bytes.Buffer{}
-	fmt.Fprintf(out, "%s{", reflect.TypeOf(m))
-	i := len(m)
-	for k, v := range m {
-		fmt.Fprintf(out, "%T(%#v): %T(%#v)", k, k, v, v)
-		i--
-		if i > 0 {
-			fmt.Fprint(out, ", ")
-		}
-	}
-	fmt.Fprint(out, "}")
-	return out.String()
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/unmarshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/unmarshal.go b/proton-c/bindings/go/src/apache.org/proton/unmarshal.go
deleted file mode 100644
index a003019..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/unmarshal.go
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-oor more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package proton
-
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"bytes"
-	"io"
-	"reflect"
-	"unsafe"
-)
-
-const minDecode = 256
-
-//
-// Decoding from a pn_data_t
-//
-// NOTE: we use panic() to signal a decoding error, simplifies decoding logic.
-// We recover() at the highest possible level - i.e. in the exported Unmarshal or Decode.
-//
-
-// Decoder decodes AMQP values from an io.Reader.
-//
-type Decoder struct {
-	reader io.Reader
-	buffer bytes.Buffer
-}
-
-// NewDecoder returns a new decoder that reads from r.
-//
-// The decoder has it's own buffer and may read more data than required for the
-// AMQP values requested.  Use Buffered to see if there is data left in the
-// buffer.
-//
-func NewDecoder(r io.Reader) *Decoder {
-	return &Decoder{r, bytes.Buffer{}}
-}
-
-// Buffered returns a reader of the data remaining in the Decoder's buffer. The
-// reader is valid until the next call to Decode.
-//
-func (d *Decoder) Buffered() io.Reader {
-	return bytes.NewReader(d.buffer.Bytes())
-}
-
-// Decode reads the next AMQP value from the Reader and stores it in the value pointed to by v.
-//
-// See the documentation for Unmarshal for details about the conversion of AMQP into a Go value.
-//
-func (d *Decoder) Decode(v interface{}) (err error) {
-	defer doRecover(&err)
-	data := C.pn_data(0)
-	defer C.pn_data_free(data)
-	var n int
-	for n == 0 && err == nil {
-		n = unmarshal(data, d.buffer.Bytes(), v)
-		if n == 0 { // n == 0 means not enough data, read more
-			err = d.more()
-			if err != nil {
-				return
-			}
-		}
-	}
-	d.buffer.Next(n)
-	return
-}
-
-/*
-Unmarshal decodes AMQP-encoded bytes and stores the result in the value pointed to by v.
-Types are converted as follows:
-
- +---------------------------+----------------------------------------------------------------------+
- |To Go types                |From AMQP types                                                       |
- +===========================+======================================================================+
- |bool                       |bool                                                                  |
- +---------------------------+----------------------------------------------------------------------+
- |int, int8, int16,          |Equivalent or smaller signed integer type: char, byte, short, int,    |
- |int32, int64               |long.                                                                 |
- +---------------------------+----------------------------------------------------------------------+
- |uint, uint8, uint16,       |Equivalent or smaller unsigned integer type: char, ubyte, ushort,     |
- |uint32, uint64 types       |uint, ulong                                                           |
- +---------------------------+----------------------------------------------------------------------+
- |float32, float64           |Equivalent or smaller float or double.                                |
- +---------------------------+----------------------------------------------------------------------+
- |string, []byte             |string, symbol or binary.                                             |
- +---------------------------+----------------------------------------------------------------------+
- |map[K]T                    |map, provided all keys and values can unmarshal to types K, T         |
- +---------------------------+----------------------------------------------------------------------+
- |Map|map, any AMQP map                                                     |
- +---------------------------+----------------------------------------------------------------------+
- |interface{}                |Any AMQP value can be unmarshaled to an interface{} as follows:       |
- |                           +------------------------+---------------------------------------------+
- |                           |AMQP Type               |Go Type in interface{}                       |
- |                           +========================+=============================================+
- |                           |bool                    |bool                                         |
- |                           +------------------------+---------------------------------------------+
- |                           |char                    |unint8                                       |
- |                           +------------------------+---------------------------------------------+
- |                           |byte,short,int,long     |int8,int16,int32,int64                       |
- |                           +------------------------+---------------------------------------------+
- |                           |ubyte,ushort,uint,ulong |uint8,uint16,uint32,uint64                   |
- |                           +------------------------+---------------------------------------------+
- |                           |float, double           |float32, float64                             |
- |                           +------------------------+---------------------------------------------+
- |                           |string, symbol          |string                                       |
- |                           +------------------------+---------------------------------------------+
- |                           |binary                  |byte[]                                       |
- |                           +------------------------+---------------------------------------------+
- |                           |map                     |Map                  |
- +---------------------------+------------------------+---------------------------------------------+
-
-The following Go types cannot be unmarshaled: complex64/128, uintptr, function, interface, channel.
-
-ODO types
-
-AMQP: null, timestamp, decimal32/64/128, uuid, described, array, list.
-
-Go: array, slice, struct.
-
-*/
-func Unmarshal(bytes []byte, v interface{}) (n int, err error) {
-	defer doRecover(&err)
-	data := C.pn_data(0)
-	defer C.pn_data_free(data)
-	n = unmarshal(data, bytes, v)
-	if n == 0 {
-		err = errorf("not enough data")
-	}
-	return
-}
-
-// more reads more data when we can't parse a complete AMQP type
-func (d *Decoder) more() error {
-	var readSize int64 = minDecode
-	if int64(d.buffer.Len()) > readSize { // Grow by doubling
-		readSize = int64(d.buffer.Len())
-	}
-	var n int64
-	n, err := d.buffer.ReadFrom(io.LimitReader(d.reader, readSize))
-	if n == 0 && err == nil { // ReadFrom won't report io.EOF, just returns 0
-		err = io.EOF
-	}
-	return err
-}
-
-// unmarshal decodes from bytes and converts into the value pointed to by v.
-// Used by Unmarshal and Decode
-//
-// Returns the number of bytes decoded or 0 if not enough data.
-//
-func unmarshal(data *C.pn_data_t, bytes []byte, v interface{}) (n int) {
-	n = decode(data, bytes)
-	if n == 0 {
-		return 0
-	}
-	get(data, v)
-	return
-}
-
-// Get value v from data
-func get(data *C.pn_data_t, v interface{}) {
-
-	pnType := C.pn_data_type(data)
-
-	switch v := v.(type) {
-	case *bool:
-		switch pnType {
-		case C.PN_BOOL:
-			*v = bool(C.pn_data_get_bool(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	case *int8:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int8(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int8(C.pn_data_get_byte(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	case *uint8:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint8(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint8(C.pn_data_get_ubyte(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	case *int16:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int16(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int16(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int16(C.pn_data_get_short(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	case *uint16:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint16(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint16(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint16(C.pn_data_get_ushort(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	case *int32:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int32(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int32(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int32(C.pn_data_get_short(data))
-		case C.PN_INT:
-			*v = int32(C.pn_data_get_int(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	case *uint32:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint32(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint32(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint32(C.pn_data_get_ushort(data))
-		case C.PN_UINT:
-			*v = uint32(C.pn_data_get_uint(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *int64:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int64(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int64(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int64(C.pn_data_get_short(data))
-		case C.PN_INT:
-			*v = int64(C.pn_data_get_int(data))
-		case C.PN_LONG:
-			*v = int64(C.pn_data_get_long(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *uint64:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint64(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint64(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint64(C.pn_data_get_ushort(data))
-		case C.PN_ULONG:
-			*v = uint64(C.pn_data_get_ulong(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *int:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int(C.pn_data_get_short(data))
-		case C.PN_INT:
-			*v = int(C.pn_data_get_int(data))
-		case C.PN_LONG:
-			if unsafe.Sizeof(0) == 8 {
-				*v = int(C.pn_data_get_long(data))
-			} else {
-				panic(newBadUnmarshal(pnType, v))
-			}
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *uint:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint(C.pn_data_get_ushort(data))
-		case C.PN_UINT:
-			*v = uint(C.pn_data_get_uint(data))
-		case C.PN_ULONG:
-			if unsafe.Sizeof(0) == 8 {
-				*v = uint(C.pn_data_get_ulong(data))
-			} else {
-				panic(newBadUnmarshal(pnType, v))
-			}
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *float32:
-		switch pnType {
-		case C.PN_FLOAT:
-			*v = float32(C.pn_data_get_float(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *float64:
-		switch pnType {
-		case C.PN_FLOAT:
-			*v = float64(C.pn_data_get_float(data))
-		case C.PN_DOUBLE:
-			*v = float64(C.pn_data_get_double(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *string:
-		switch pnType {
-		case C.PN_STRING:
-			*v = goString(C.pn_data_get_string(data))
-		case C.PN_SYMBOL:
-			*v = goString(C.pn_data_get_symbol(data))
-		case C.PN_BINARY:
-			*v = goString(C.pn_data_get_binary(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *[]byte:
-		switch pnType {
-		case C.PN_STRING:
-			*v = goBytes(C.pn_data_get_string(data))
-		case C.PN_SYMBOL:
-			*v = goBytes(C.pn_data_get_symbol(data))
-		case C.PN_BINARY:
-			*v = goBytes(C.pn_data_get_binary(data))
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-
-	case *interface{}:
-		getInterface(data, v)
-
-	default:
-		if reflect.TypeOf(v).Kind() != reflect.Ptr {
-			panic(newBadUnmarshal(pnType, v))
-		}
-		switch reflect.TypeOf(v).Elem().Kind() {
-		case reflect.Map:
-			getMap(data, v)
-		case reflect.Slice:
-			getList(data, v)
-		default:
-			panic(newBadUnmarshal(pnType, v))
-		}
-	}
-	err := pnDataError(data)
-	if err != "" {
-		panic(errorf("unmarshal %s", err))
-	}
-	return
-}
-
-// Getting into an interface is driven completely by the AMQP type, since the interface{}
-// target is type-neutral.
-func getInterface(data *C.pn_data_t, v *interface{}) {
-	pnType := C.pn_data_type(data)
-	switch pnType {
-	case C.PN_BOOL:
-		*v = bool(C.pn_data_get_bool(data))
-	case C.PN_UBYTE:
-		*v = uint8(C.pn_data_get_ubyte(data))
-	case C.PN_BYTE:
-		*v = int8(C.pn_data_get_byte(data))
-	case C.PN_USHORT:
-		*v = uint16(C.pn_data_get_ushort(data))
-	case C.PN_SHORT:
-		*v = int16(C.pn_data_get_short(data))
-	case C.PN_UINT:
-		*v = uint32(C.pn_data_get_uint(data))
-	case C.PN_INT:
-		*v = int32(C.pn_data_get_int(data))
-	case C.PN_CHAR:
-		*v = uint8(C.pn_data_get_char(data))
-	case C.PN_ULONG:
-		*v = uint64(C.pn_data_get_ulong(data))
-	case C.PN_LONG:
-		*v = int64(C.pn_data_get_long(data))
-	case C.PN_FLOAT:
-		*v = float32(C.pn_data_get_float(data))
-	case C.PN_DOUBLE:
-		*v = float64(C.pn_data_get_double(data))
-	case C.PN_BINARY:
-		*v = goBytes(C.pn_data_get_binary(data))
-	case C.PN_STRING:
-		*v = goString(C.pn_data_get_string(data))
-	case C.PN_SYMBOL:
-		*v = goString(C.pn_data_get_symbol(data))
-	case C.PN_MAP:
-		m := make(Map)
-		get(data, &m)
-		*v = m // FIXME aconway 2015-03-13: avoid the copy?
-	case C.PN_LIST:
-		l := make(List, 0)
-		get(data, &l)
-		*v = l
-	default:
-		panic(newBadUnmarshal(pnType, v))
-	}
-}
-
-func getMap(data *C.pn_data_t, v interface{}) {
-	pnType := C.pn_data_type(data)
-	if pnType != C.PN_MAP {
-		panic(newBadUnmarshal(pnType, v))
-	}
-	mapValue := reflect.ValueOf(v).Elem()
-	mapValue.Set(reflect.MakeMap(mapValue.Type())) // Clear the map
-	count := int(C.pn_data_get_map(data))
-	if bool(C.pn_data_enter(data)) {
-		for i := 0; i < count/2; i++ {
-			if bool(C.pn_data_next(data)) {
-				key := reflect.New(mapValue.Type().Key())
-				get(data, key.Interface())
-				if bool(C.pn_data_next(data)) {
-					val := reflect.New(mapValue.Type().Elem())
-					get(data, val.Interface())
-					mapValue.SetMapIndex(key.Elem(), val.Elem())
-				}
-			}
-		}
-		C.pn_data_exit(data)
-	}
-}
-
-func getList(data *C.pn_data_t, v interface{}) {
-	pnType := C.pn_data_type(data)
-	if pnType != C.PN_LIST {
-		panic(newBadUnmarshal(pnType, v))
-	}
-	count := int(C.pn_data_get_list(data))
-	listValue := reflect.MakeSlice(reflect.TypeOf(v).Elem(), count, count)
-	if bool(C.pn_data_enter(data)) {
-		for i := 0; i < count; i++ {
-			if bool(C.pn_data_next(data)) {
-				val := reflect.New(listValue.Type().Elem())
-				get(data, val.Interface())
-				listValue.Index(i).Set(val.Elem())
-			}
-		}
-		C.pn_data_exit(data)
-	}
-	reflect.ValueOf(v).Elem().Set(listValue)
-}
-
-// decode from bytes.
-// Return bytes decoded or 0 if we could not decode a complete object.
-//
-func decode(data *C.pn_data_t, bytes []byte) int {
-	if len(bytes) == 0 {
-		return 0
-	}
-	cBuf := (*C.char)(unsafe.Pointer(&bytes[0]))
-	n := int(C.pn_data_decode(data, cBuf, C.size_t(len(bytes))))
-	if n == int(C.PN_EOS) {
-		return 0
-	} else if n <= 0 {
-		panic(errorf("unmarshal %s", pnErrorName(n)))
-	}
-	return n
-}
-
-func goBytes(cBytes C.pn_bytes_t) (bytes []byte) {
-	if cBytes.start != nil {
-		bytes = C.GoBytes(unsafe.Pointer(cBytes.start), C.int(cBytes.size))
-	}
-	return
-}
-
-func goString(cBytes C.pn_bytes_t) (str string) {
-	if cBytes.start != nil {
-		str = C.GoStringN(cBytes.start, C.int(cBytes.size))
-	}
-	return
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/url.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/url.go b/proton-c/bindings/go/src/apache.org/proton/url.go
deleted file mode 100644
index 079dfb2..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/url.go
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package proton
-
-/*
-#cgo LDFLAGS: -lqpid-proton
-#include <stdlib.h>
-#include <string.h>
-#include <proton/url.h>
-
-// Helper function for setting URL fields.
-typedef void (*setter_fn)(pn_url_t* url, const char* value);
-inline void	set(pn_url_t *url, setter_fn s, const char* value) {
-  s(url, value);
-}
-*/
-import "C"
-
-import (
-	"net"
-	"net/url"
-	"unsafe"
-)
-
-const (
-	amqp  string = "amqp"
-	amqps        = "amqps"
-)
-
-// ParseUrl parses an AMQP URL string and returns a net/url.Url.
-//
-// It is more forgiving than net/url.Parse and allows most of the parts of the
-// URL to be missing, assuming AMQP defaults.
-//
-func ParseURL(s string) (u *url.URL, err error) {
-	cstr := C.CString(s)
-	defer C.free(unsafe.Pointer(cstr))
-	pnUrl := C.pn_url_parse(cstr)
-	if pnUrl == nil {
-		return nil, errorf("bad URL %#v", s)
-	}
-	defer C.pn_url_free(pnUrl)
-
-	scheme := C.GoString(C.pn_url_get_scheme(pnUrl))
-	username := C.GoString(C.pn_url_get_username(pnUrl))
-	password := C.GoString(C.pn_url_get_password(pnUrl))
-	host := C.GoString(C.pn_url_get_host(pnUrl))
-	port := C.GoString(C.pn_url_get_port(pnUrl))
-	path := C.GoString(C.pn_url_get_path(pnUrl))
-
-	if err != nil {
-		return nil, errorf("bad URL %#v: %s", s, err)
-	}
-	if scheme == "" {
-		scheme = amqp
-	}
-	if port == "" {
-		if scheme == amqps {
-			port = amqps
-		} else {
-			port = amqp
-		}
-	}
-	var user *url.Userinfo
-	if password != "" {
-		user = url.UserPassword(username, password)
-	} else if username != "" {
-		user = url.User(username)
-	}
-
-	u = &url.URL{
-		Scheme: scheme,
-		User:   user,
-		Host:   net.JoinHostPort(host, port),
-		Path:   path,
-	}
-
-	return u, nil
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/apache.org/proton/url_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/apache.org/proton/url_test.go b/proton-c/bindings/go/src/apache.org/proton/url_test.go
deleted file mode 100644
index 7315511..0000000
--- a/proton-c/bindings/go/src/apache.org/proton/url_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package proton
-
-import (
-	"fmt"
-)
-
-func ExampleParseURL() {
-	for _, s := range []string{
-		"amqp://username:password@host:1234/path",
-		"host:1234",
-		"host",
-		":1234",
-		"host/path",
-		"amqps://host",
-		"",
-	} {
-		u, err := ParseURL(s)
-		if err != nil {
-			fmt.Println(err)
-		} else {
-			fmt.Println(u)
-		}
-	}
-	// Output:
-	// amqp://username:password@host:1234/path
-	// amqp://host:1234
-	// amqp://host:amqp
-	// amqp://:1234
-	// amqp://host:amqp/path
-	// amqps://host:amqps
-	// proton: bad URL ""
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go b/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
new file mode 100644
index 0000000..34f85fe
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
@@ -0,0 +1,33 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+Package proton is a Go binding for the proton AMQP protocol engine.
+
+It alows you to construct and parse AMQP messages, and to implement AMQP
+clients, servers and intermediaries that can exchange messages with any
+AMQP 1.0 compliant endpoint.
+
+Encoding and decoding AMQP data follows the pattern of the standard
+encoding/json and encoding/xml packages.The mapping between AMQP and Go types is
+described in the documentation of the Marshal and Unmarshal functions.
+*/
+package proton
+
+// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/error.go b/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
new file mode 100644
index 0000000..f9cc948
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
@@ -0,0 +1,96 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+// #include <proton/error.h>
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"fmt"
+	"reflect"
+	"runtime"
+)
+
+var pnErrorNames = map[int]string{
+	C.PN_EOS:        "end of data",
+	C.PN_ERR:        "error",
+	C.PN_OVERFLOW:   "overflow",
+	C.PN_UNDERFLOW:  "underflow",
+	C.PN_STATE_ERR:  "bad state",
+	C.PN_ARG_ERR:    "invalid argument",
+	C.PN_TIMEOUT:    "timeout",
+	C.PN_INTR:       "interrupted",
+	C.PN_INPROGRESS: "in progress",
+}
+
+func pnErrorName(code int) string {
+	name := pnErrorNames[code]
+	if name != "" {
+		return name
+	} else {
+		return "unknown error code"
+	}
+}
+
+type BadUnmarshal struct {
+	AMQPType C.pn_type_t
+	GoType   reflect.Type
+}
+
+func newBadUnmarshal(pnType C.pn_type_t, v interface{}) *BadUnmarshal {
+	return &BadUnmarshal{pnType, reflect.TypeOf(v)}
+}
+
+func (e BadUnmarshal) Error() string {
+	if e.GoType.Kind() != reflect.Ptr {
+		return fmt.Sprintf("proton: cannot unmarshal to type %s, not a pointer", e.GoType)
+	} else {
+		return fmt.Sprintf("proton: cannot unmarshal AMQP %s to %s", getPnType(e.AMQPType), e.GoType)
+	}
+}
+
+// errorf creates an error with a formatted message
+func errorf(format string, a ...interface{}) error {
+	return fmt.Errorf("proton: %s", fmt.Sprintf(format, a...))
+}
+
+func pnDataError(data *C.pn_data_t) string {
+	err := C.pn_data_error(data)
+	if err != nil && int(C.pn_error_code(err)) != 0 {
+		return C.GoString(C.pn_error_text(err))
+	}
+	return ""
+}
+
+// doRecover is called to recover from internal panics
+func doRecover(err *error) {
+	r := recover()
+	switch r := r.(type) {
+	case nil:
+		return
+	case runtime.Error:
+		panic(r)
+	case error:
+		*err = r
+	default:
+		panic(r)
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/interop_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/interop_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/interop_test.go
new file mode 100644
index 0000000..c51d74a
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/interop_test.go
@@ -0,0 +1,290 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+// Test that conversion of Go type to/from AMQP is compatible with other
+// bindings.
+//
+package proton
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func assertEqual(want interface{}, got interface{}) {
+	if !reflect.DeepEqual(want, got) {
+		panic(errorf("%#v != %#v", want, got))
+	}
+}
+
+func assertNil(err interface{}) {
+	if err != nil {
+		panic(err)
+	}
+}
+
+func getReader(name string) (r io.Reader) {
+	r, err := os.Open("../../../../../../tests/interop/" + name + ".amqp")
+	if err != nil {
+		panic(errorf("Can't open %#v: %v", name, err))
+	}
+	return
+}
+
+func remaining(d *Decoder) string {
+	remainder, _ := ioutil.ReadAll(io.MultiReader(d.Buffered(), d.reader))
+	return string(remainder)
+}
+
+// assertDecode: want is the expected value, gotPtr is a pointer to a
+// instance of the same type for Decode.
+func assertDecode(d *Decoder, want interface{}, gotPtr interface{}) {
+
+	assertNil(d.Decode(gotPtr))
+
+	got := reflect.ValueOf(gotPtr).Elem().Interface()
+	assertEqual(want, got)
+
+	// Try round trip encoding
+	bytes, err := Marshal(want)
+	assertNil(err)
+	n, err := Unmarshal(bytes, gotPtr)
+	assertNil(err)
+	assertEqual(n, len(bytes))
+	got = reflect.ValueOf(gotPtr).Elem().Interface()
+	assertEqual(want, got)
+}
+
+func TestUnmarshal(t *testing.T) {
+	bytes, err := ioutil.ReadAll(getReader("strings"))
+	if err != nil {
+		t.Error(err)
+	}
+	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
+		var got string
+		n, err := Unmarshal(bytes, &got)
+		if err != nil {
+			t.Error(err)
+		}
+		if want != got {
+			t.Errorf("%#v != %#v", want, got)
+		}
+		bytes = bytes[n:]
+	}
+}
+
+func TestPrimitivesExact(t *testing.T) {
+	d := NewDecoder(getReader("primitives"))
+	// Decoding into exact types
+	var b bool
+	assertDecode(d, true, &b)
+	assertDecode(d, false, &b)
+	var u8 uint8
+	assertDecode(d, uint8(42), &u8)
+	var u16 uint16
+	assertDecode(d, uint16(42), &u16)
+	var i16 int16
+	assertDecode(d, int16(-42), &i16)
+	var u32 uint32
+	assertDecode(d, uint32(12345), &u32)
+	var i32 int32
+	assertDecode(d, int32(-12345), &i32)
+	var u64 uint64
+	assertDecode(d, uint64(12345), &u64)
+	var i64 int64
+	assertDecode(d, int64(-12345), &i64)
+	var f32 float32
+	assertDecode(d, float32(0.125), &f32)
+	var f64 float64
+	assertDecode(d, float64(0.125), &f64)
+}
+
+func TestPrimitivesCompatible(t *testing.T) {
+	d := NewDecoder(getReader("primitives"))
+	// Decoding into compatible types
+	var b bool
+	var i int
+	var u uint
+	var f float64
+	assertDecode(d, true, &b)
+	assertDecode(d, false, &b)
+	assertDecode(d, uint(42), &u)
+	assertDecode(d, uint(42), &u)
+	assertDecode(d, -42, &i)
+	assertDecode(d, uint(12345), &u)
+	assertDecode(d, -12345, &i)
+	assertDecode(d, uint(12345), &u)
+	assertDecode(d, -12345, &i)
+	assertDecode(d, 0.125, &f)
+	assertDecode(d, 0.125, &f)
+}
+
+// assertDecodeValue: want is the expected value, decode into a reflect.Value
+func assertDecodeInterface(d *Decoder, want interface{}) {
+
+	var got, got2 interface{}
+	assertNil(d.Decode(&got))
+
+	assertEqual(want, got)
+
+	// Try round trip encoding
+	bytes, err := Marshal(got)
+	assertNil(err)
+	n, err := Unmarshal(bytes, &got2)
+	assertNil(err)
+	assertEqual(n, len(bytes))
+	assertEqual(want, got2)
+}
+
+func TestPrimitivesInterface(t *testing.T) {
+	d := NewDecoder(getReader("primitives"))
+	assertDecodeInterface(d, true)
+	assertDecodeInterface(d, false)
+	assertDecodeInterface(d, uint8(42))
+	assertDecodeInterface(d, uint16(42))
+	assertDecodeInterface(d, int16(-42))
+	assertDecodeInterface(d, uint32(12345))
+	assertDecodeInterface(d, int32(-12345))
+	assertDecodeInterface(d, uint64(12345))
+	assertDecodeInterface(d, int64(-12345))
+	assertDecodeInterface(d, float32(0.125))
+	assertDecodeInterface(d, float64(0.125))
+}
+
+func TestStrings(t *testing.T) {
+	d := NewDecoder(getReader("strings"))
+	// Test decoding as plain Go strings
+	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
+		var got string
+		assertDecode(d, want, &got)
+	}
+	remains := remaining(d)
+	if remains != "" {
+		t.Errorf("leftover: %s", remains)
+	}
+
+	// Test decoding as specific string types
+	d = NewDecoder(getReader("strings"))
+	var bytes []byte
+	var str, sym string
+	assertDecode(d, []byte("abc\000defg"), &bytes)
+	assertDecode(d, "abcdefg", &str)
+	assertDecode(d, "abcdefg", &sym)
+	assertDecode(d, make([]byte, 0), &bytes)
+	assertDecode(d, "", &str)
+	assertDecode(d, "", &sym)
+	remains = remaining(d)
+	if remains != "" {
+		panic(errorf("leftover: %s", remains))
+	}
+
+	// Test some error handling
+	d = NewDecoder(getReader("strings"))
+	var s string
+	err := d.Decode(s)
+	if err == nil {
+		t.Fatal("Expected error")
+	}
+	if !strings.Contains(err.Error(), "not a pointer") {
+		t.Error(err)
+	}
+	var i int
+	err = d.Decode(&i)
+	if !strings.Contains(err.Error(), "cannot unmarshal") {
+		t.Error(err)
+	}
+	_, err = Unmarshal([]byte{}, nil)
+	if !strings.Contains(err.Error(), "not enough data") {
+		t.Error(err)
+	}
+	_, err = Unmarshal([]byte("foobar"), nil)
+	if !strings.Contains(err.Error(), "invalid argument") {
+		t.Error(err)
+	}
+}
+
+func TestEncodeDecode(t *testing.T) {
+	type data struct {
+		s  string
+		i  int
+		u8 uint8
+		b  bool
+		f  float32
+		v  interface{}
+	}
+
+	in := data{"foo", 42, 9, true, 1.234, "thing"}
+
+	buf := bytes.Buffer{}
+	e := NewEncoder(&buf)
+	e.Encode(in.s)
+	e.Encode(in.i)
+	e.Encode(in.u8)
+	e.Encode(in.b)
+	e.Encode(in.f)
+	e.Encode(in.v)
+
+	var out data
+	d := NewDecoder(&buf)
+	d.Decode(&out.s)
+	d.Decode(&out.i)
+	d.Decode(&out.u8)
+	d.Decode(&out.b)
+	d.Decode(&out.f)
+	d.Decode(&out.v)
+
+	assertEqual(in, out)
+}
+
+func TestMap(t *testing.T) {
+	d := NewDecoder(getReader("maps"))
+
+	// Generic map
+	var m Map
+	assertDecode(d, Map{"one": int32(1), "two": int32(2), "three": int32(3)}, &m)
+
+	// Interface as map
+	var i interface{}
+	assertDecode(d, Map{int32(1): "one", int32(2): "two", int32(3): "three"}, &i)
+
+	d = NewDecoder(getReader("maps"))
+	// Specific typed map
+	var m2 map[string]int
+	assertDecode(d, map[string]int{"one": 1, "two": 2, "three": 3}, &m2)
+
+	// Round trip a nested map
+	m = Map{int64(1): "one", "two": int32(2), true: Map{uint8(1): true, uint8(2): false}}
+	bytes, err := Marshal(m)
+	assertNil(err)
+	_, err = Unmarshal(bytes, &i)
+	assertNil(err)
+	assertEqual(m, i)
+}
+
+func TestList(t *testing.T) {
+	d := NewDecoder(getReader("lists"))
+	var l List
+	assertDecode(d, List{int32(32), "foo", true}, &l)
+	assertDecode(d, List{}, &l)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/marshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/marshal.go b/proton-c/bindings/go/src/qpid.apache.org/proton/marshal.go
new file mode 100644
index 0000000..fcd414c
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/marshal.go
@@ -0,0 +1,210 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+const minEncode = 256
+
+/*
+Marshal encodes a value as AMQP.
+
+Go types are encoded as follows
+
+ +-------------------------------------+--------------------------------------------+
+ |Go type                              |AMQP type                                   |
+ +-------------------------------------+--------------------------------------------+
+ |bool                                 |bool                                        |
+ +-------------------------------------+--------------------------------------------+
+ |int8, int16, int32, int64 (int)      |byte, short, int, long (int or long)        |
+ +-------------------------------------+--------------------------------------------+
+ |uint8, uint16, uint32, uint64 (uint) |ubyte, ushort, uint, ulong (uint or ulong)  |
+ +-------------------------------------+--------------------------------------------+
+ |float32, float64                     |float, double.                              |
+ +-------------------------------------+--------------------------------------------+
+ |string                               |string                                      |
+ +-------------------------------------+--------------------------------------------+
+ |[]byte                               |binary                                      |
+ +-------------------------------------+--------------------------------------------+
+ |interface{}                          |as to the contained type                    |
+ +-------------------------------------+--------------------------------------------+
+ |map[K]T                              |map with K and T converted as above         |
+ +-------------------------------------+--------------------------------------------+
+ |Map                                  |map, may have mixed types for keys, values  |
+ +-------------------------------------+--------------------------------------------+
+ |[]T                                  |list with T converted as above              |
+ +-------------------------------------+--------------------------------------------+
+ |List                                 |list, may have mixed types  values          |
+ +-------------------------------------+--------------------------------------------+
+
+TODO types
+
+Go: array, slice, struct
+
+Go types that cannot be marshaled
+
+complex64/128, uintptr, function, interface, channel
+
+*/
+func Marshal(v interface{}) (bytes []byte, err error) {
+	return marshal(make([]byte, minEncode), v)
+}
+
+func marshal(bytesIn []byte, v interface{}) (bytes []byte, err error) {
+	defer doRecover(&err)
+	data := C.pn_data(0)
+	defer C.pn_data_free(data)
+	put(data, v)
+	// FIXME aconway 2015-03-11: get size from proton.
+	bytes = bytesIn
+	for {
+		n := int(C.pn_data_encode(data, (*C.char)(unsafe.Pointer(&bytes[0])), C.size_t(cap(bytes))))
+		if n != int(C.PN_EOS) {
+			if n < 0 {
+				err = errorf(pnErrorName(n))
+			} else {
+				bytes = bytes[0:n]
+			}
+			return
+		}
+		bytes = make([]byte, cap(bytes)*2)
+	}
+	return
+}
+
+func put(data *C.pn_data_t, v interface{}) {
+	switch v := v.(type) {
+	case bool:
+		C.pn_data_put_bool(data, C.bool(v))
+	case int8:
+		C.pn_data_put_byte(data, C.int8_t(v))
+	case int16:
+		C.pn_data_put_short(data, C.int16_t(v))
+	case int32:
+		C.pn_data_put_int(data, C.int32_t(v))
+	case int64:
+		C.pn_data_put_long(data, C.int64_t(v))
+	case int:
+		if unsafe.Sizeof(0) == 8 {
+			C.pn_data_put_long(data, C.int64_t(v))
+		} else {
+			C.pn_data_put_int(data, C.int32_t(v))
+		}
+	case uint8:
+		C.pn_data_put_ubyte(data, C.uint8_t(v))
+	case uint16:
+		C.pn_data_put_ushort(data, C.uint16_t(v))
+	case uint32:
+		C.pn_data_put_uint(data, C.uint32_t(v))
+	case uint64:
+		C.pn_data_put_ulong(data, C.uint64_t(v))
+	case uint:
+		if unsafe.Sizeof(0) == 8 {
+			C.pn_data_put_ulong(data, C.uint64_t(v))
+		} else {
+			C.pn_data_put_uint(data, C.uint32_t(v))
+		}
+	case float32:
+		C.pn_data_put_float(data, C.float(v))
+	case float64:
+		C.pn_data_put_double(data, C.double(v))
+	case string:
+		C.pn_data_put_string(data, toPnBytes([]byte(v)))
+	case []byte:
+		C.pn_data_put_binary(data, toPnBytes(v))
+	case Map: // Special map type
+		C.pn_data_put_map(data)
+		C.pn_data_enter(data)
+		for key, val := range v {
+			put(data, key)
+			put(data, val)
+		}
+		C.pn_data_exit(data)
+	default:
+		switch reflect.TypeOf(v).Kind() {
+		case reflect.Map:
+			putMap(data, v)
+		case reflect.Slice:
+			putList(data, v)
+		default:
+			panic(errorf("cannot marshal %s to AMQP", reflect.TypeOf(v)))
+		}
+	}
+	err := pnDataError(data)
+	if err != "" {
+		panic(errorf("marshal %s", err))
+	}
+	return
+}
+
+func putMap(data *C.pn_data_t, v interface{}) {
+	mapValue := reflect.ValueOf(v)
+	C.pn_data_put_map(data)
+	C.pn_data_enter(data)
+	for _, key := range mapValue.MapKeys() {
+		put(data, key.Interface())
+		put(data, mapValue.MapIndex(key).Interface())
+	}
+	C.pn_data_exit(data)
+}
+
+func putList(data *C.pn_data_t, v interface{}) {
+	listValue := reflect.ValueOf(v)
+	C.pn_data_put_list(data)
+	C.pn_data_enter(data)
+	for i := 0; i < listValue.Len(); i++ {
+		put(data, listValue.Index(i).Interface())
+	}
+	C.pn_data_exit(data)
+}
+
+// Encoder encodes AMQP values to an io.Writer
+type Encoder struct {
+	writer io.Writer
+	buffer []byte
+}
+
+// New encoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{w, make([]byte, minEncode)}
+}
+
+func (e *Encoder) Encode(v interface{}) (err error) {
+	e.buffer, err = marshal(e.buffer, v)
+	if err == nil {
+		e.writer.Write(e.buffer)
+	}
+	return
+}
+
+func toPnBytes(b []byte) C.pn_bytes_t {
+	if len(b) == 0 {
+		return C.pn_bytes_t{0, nil}
+	} else {
+		return C.pn_bytes_t{C.size_t(len(b)), (*C.char)(unsafe.Pointer(&b[0]))}
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/types.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/types.go b/proton-c/bindings/go/src/qpid.apache.org/proton/types.go
new file mode 100644
index 0000000..561ac9a
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/types.go
@@ -0,0 +1,151 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+)
+
+type pnGet func(data *C.pn_data_t) reflect.Value
+type pnPut func(data *C.pn_data_t, v interface{})
+
+// Information about a proton type
+type pnType struct {
+	code C.pn_type_t // AMQP type code
+	name string      // AMQP type name
+}
+
+func (pt *pnType) String() string { return pt.name }
+
+// pnType definitions for each proton type.
+var (
+	pnNull       = pnType{code: C.PN_NULL, name: "null"}
+	pnBool       = pnType{code: C.PN_BOOL, name: "bool"}
+	pnUbyte      = pnType{code: C.PN_UBYTE, name: "ubyte"}
+	pnByte       = pnType{code: C.PN_BYTE, name: "byte"}
+	pnUshort     = pnType{code: C.PN_USHORT, name: "ushort"}
+	pnShort      = pnType{code: C.PN_SHORT, name: "short"}
+	pnChar       = pnType{code: C.PN_CHAR, name: "char"}
+	pnUint       = pnType{code: C.PN_UINT, name: "uint"}
+	pnInt        = pnType{code: C.PN_INT, name: "int"}
+	pnUlong      = pnType{code: C.PN_ULONG, name: "ulong"}
+	pnLong       = pnType{code: C.PN_LONG, name: "long"}
+	pnTimestamp  = pnType{code: C.PN_TIMESTAMP, name: "timestamp"}
+	pnFloat      = pnType{code: C.PN_FLOAT, name: "float"}
+	pnDouble     = pnType{code: C.PN_DOUBLE, name: "double"}
+	pnDecimal32  = pnType{code: C.PN_DECIMAL32, name: "decimal32"}
+	pnDecimal64  = pnType{code: C.PN_DECIMAL64, name: "decimal64"}
+	pnDecimal128 = pnType{code: C.PN_DECIMAL128, name: "decimal128"}
+	pnUuid       = pnType{code: C.PN_UUID, name: "uuid"}
+	pnBinary     = pnType{code: C.PN_BINARY, name: "binary"}
+	pnString     = pnType{code: C.PN_STRING, name: "string"}
+	pnSymbol     = pnType{code: C.PN_SYMBOL, name: "symbol"}
+	pnDescribed  = pnType{code: C.PN_DESCRIBED, name: "described"}
+	pnArray      = pnType{code: C.PN_ARRAY, name: "array"}
+	pnList       = pnType{code: C.PN_LIST, name: "list"}
+	pnMap        = pnType{code: C.PN_MAP, name: "map"}
+)
+
+// Map from pn_type_t codes to pnType structs
+var pnTypes = map[C.pn_type_t]*pnType{
+	C.PN_NULL:       &pnNull,
+	C.PN_BOOL:       &pnBool,
+	C.PN_UBYTE:      &pnUbyte,
+	C.PN_BYTE:       &pnByte,
+	C.PN_USHORT:     &pnUshort,
+	C.PN_SHORT:      &pnShort,
+	C.PN_UINT:       &pnUint,
+	C.PN_INT:        &pnInt,
+	C.PN_CHAR:       &pnChar,
+	C.PN_ULONG:      &pnUlong,
+	C.PN_LONG:       &pnLong,
+	C.PN_TIMESTAMP:  &pnTimestamp,
+	C.PN_FLOAT:      &pnFloat,
+	C.PN_DOUBLE:     &pnDouble,
+	C.PN_DECIMAL32:  &pnDecimal32,
+	C.PN_DECIMAL64:  &pnDecimal64,
+	C.PN_DECIMAL128: &pnDecimal128,
+	C.PN_UUID:       &pnUuid,
+	C.PN_BINARY:     &pnBinary,
+	C.PN_STRING:     &pnString,
+	C.PN_SYMBOL:     &pnSymbol,
+	C.PN_DESCRIBED:  &pnDescribed,
+	C.PN_ARRAY:      &pnArray,
+	C.PN_LIST:       &pnList,
+	C.PN_MAP:        &pnMap,
+}
+
+// Get the pnType for a pn_type_t code, panic if unknown code.
+func getPnType(code C.pn_type_t) *pnType {
+	pt, ok := pnTypes[code]
+	if !ok {
+		panic(errorf("unknown AMQP type code %v", code))
+	}
+	return pt
+}
+
+// Go types
+var (
+	bytesType = reflect.TypeOf([]byte{})
+	valueType = reflect.TypeOf(reflect.Value{})
+)
+
+// Map is a generic map that can have mixed key and value types and so can represent any AMQP map
+//
+type Map map[interface{}]interface{}
+
+// List is a generic list that can hold mixed values and can represent any AMQP list.
+//
+type List []interface{}
+
+// GoString for Map prints values with their types, useful for debugging.
+func (m Map) GoString() string {
+	out := &bytes.Buffer{}
+	fmt.Fprintf(out, "%T{", m)
+	i := len(m)
+	for k, v := range m {
+		fmt.Fprintf(out, "%T(%#v): %T(%#v)", k, k, v, v)
+		i--
+		if i > 0 {
+			fmt.Fprint(out, ", ")
+		}
+	}
+	fmt.Fprint(out, "}")
+	return out.String()
+}
+
+// GoString for List prints values with their types, useful for debugging.
+func (l List) GoString() string {
+	out := &bytes.Buffer{}
+	fmt.Fprintf(out, "%T{", l)
+	for i := 0; i < len(l); i++ {
+		fmt.Fprintf(out, "%T(%#v)", l[i], l[i])
+		if i == len(l)-1 {
+			fmt.Fprint(out, ", ")
+		}
+	}
+	fmt.Fprint(out, "}")
+	return out.String()
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/695f8e5b/proton-c/bindings/go/src/qpid.apache.org/proton/unfinished.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/unfinished.go b/proton-c/bindings/go/src/qpid.apache.org/proton/unfinished.go
new file mode 100644
index 0000000..f9ba50a
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/unfinished.go
@@ -0,0 +1,53 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package proton
+
+import (
+	"net"
+)
+
+type Acceptor struct{}
+
+type Event struct {
+	Container *Container
+	Message   *Message
+}
+
+type Connection struct{}
+
+func (e *Event) Connection() *Connection { return nil }
+
+func (e *Event) Sender() *Sender { return nil }
+
+func (c *Connection) NewSender(name string) *Sender { return nil }
+
+func (c *Connection) Close() {}
+
+type Container struct{}
+
+type Sender struct{}
+
+func (s *Sender) Credit() int { return 0 }
+
+func (s *Sender) Send(m *Message) {}
+
+func Run(connection net.Conn, handler interface{}) error { return nil }
+
+type Message struct{ Body interface{} }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org