Return-Path: X-Original-To: apmail-qpid-commits-archive@www.apache.org Delivered-To: apmail-qpid-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0A51017D73 for ; Wed, 13 May 2015 22:30:44 +0000 (UTC) Received: (qmail 16262 invoked by uid 500); 13 May 2015 22:30:44 -0000 Delivered-To: apmail-qpid-commits-archive@qpid.apache.org Received: (qmail 16215 invoked by uid 500); 13 May 2015 22:30:43 -0000 Mailing-List: contact commits-help@qpid.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@qpid.apache.org Delivered-To: mailing list commits@qpid.apache.org Received: (qmail 16200 invoked by uid 99); 13 May 2015 22:30:43 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 May 2015 22:30:43 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id A98F9DFFEF; Wed, 13 May 2015 22:30:43 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: aconway@apache.org To: commits@qpid.apache.org Date: Wed, 13 May 2015 22:30:43 -0000 Message-Id: <8862e7afd28d43f1869fd910e747393d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/4] qpid-proton git commit: PROTON-827: go binding: enable use of 'go get', reorganize packages names and layout. Repository: qpid-proton Updated Branches: refs/heads/go1 ee2a913ae -> 9088386c1 (forced update) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/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 deleted file mode 100644 index e4f230d..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/marshal.go +++ /dev/null @@ -1,238 +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 -import "C" - -import ( - "io" - "qpid.apache.org/proton/internal" - "reflect" - "unsafe" -) - -func dataError(prefix string, data *C.pn_data_t) error { - err := internal.PnError(unsafe.Pointer(C.pn_data_error(data))) - if err != nil { - err = internal.Errorf("%s: %s", prefix, err.(internal.Error)) - } - return err -} - -/* -Marshal encodes a Go value as AMQP data in buffer. -If buffer is nil, or is not large enough, a new buffer is created. - -Returns the buffer used for encoding with len() adjusted to the actual size of data. - -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 |binary | - +-------------------------------------+--------------------------------------------+ - |Symbol |symbol | - +-------------------------------------+--------------------------------------------+ - |interface{} |the contained type | - +-------------------------------------+--------------------------------------------+ - |nil |null | - +-------------------------------------+--------------------------------------------+ - |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 Go types: array, slice, struct - -Go types that cannot be marshaled: complex64/128, uintptr, function, interface, channel -*/ -func Marshal(v interface{}, buffer []byte) (outbuf []byte, err error) { - defer internal.DoRecover(&err) - data := C.pn_data(0) - defer C.pn_data_free(data) - put(data, v) - encode := func(buf []byte) ([]byte, error) { - n := int(C.pn_data_encode(data, cPtr(buf), cLen(buf))) - switch { - case n == int(C.PN_OVERFLOW): - return buf, overflow - case n < 0: - return buf, dataError("marshal error", data) - default: - return buf[:n], nil - } - } - return encodeGrow(buffer, encode) -} - -const minEncode = 256 - -// overflow is returned when an encoding function can't fit data in the buffer. -var overflow = internal.Errorf("buffer too small") - -// encodeFn encodes into buffer[0:len(buffer)]. -// Returns buffer with length adjusted for data encoded. -// If buffer too small, returns overflow as error. -type encodeFn func(buffer []byte) ([]byte, error) - -// encodeGrow calls encode() into buffer, if it returns overflow grows the buffer. -// Returns the final buffer. -func encodeGrow(buffer []byte, encode encodeFn) ([]byte, error) { - if buffer == nil || len(buffer) == 0 { - buffer = make([]byte, minEncode) - } - var err error - for buffer, err = encode(buffer); err == overflow; buffer, err = encode(buffer) { - buffer = make([]byte, 2*len(buffer)) - } - return buffer, err -} - -func put(data *C.pn_data_t, v interface{}) { - switch v := v.(type) { - case nil: - C.pn_data_put_null(data) - 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, pnBytes([]byte(v))) - case []byte: - C.pn_data_put_binary(data, pnBytes(v)) - case Binary: - C.pn_data_put_binary(data, pnBytes([]byte(v))) - case Symbol: - C.pn_data_put_symbol(data, pnBytes([]byte(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(internal.Errorf("cannot marshal %s to AMQP", reflect.TypeOf(v))) - } - } - err := dataError("marshal", data) - if err != nil { - panic(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(v, e.buffer) - if err == nil { - e.writer.Write(e.buffer) - } - return err -} - -func replace(data *C.pn_data_t, v interface{}) { - C.pn_data_clear(data) - put(data, v) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/message.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/message.go b/proton-c/bindings/go/src/qpid.apache.org/proton/message.go deleted file mode 100644 index 44be51d..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/message.go +++ /dev/null @@ -1,342 +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 -// #include -// #include -import "C" - -import ( - "qpid.apache.org/proton/internal" - "time" - "unsafe" -) - -// FIXME aconway 2015-04-28: Do we need the interface or can we just export the struct? - -// Message is the interface to an AMQP message. -// Instances of this interface contain a pointer to the underlying struct. -type Message interface { - /** - * Inferred indicates how the message content - * is encoded into AMQP sections. If inferred is true then binary and - * list values in the body of the message will be encoded as AMQP DATA - * and AMQP SEQUENCE sections, respectively. If inferred is false, - * then all values in the body of the message will be encoded as AMQP - * VALUE sections regardless of their type. - */ - Inferred() bool - SetInferred(bool) - - /** - * Durable indicates that any parties taking responsibility - * for the message must durably store the content. - */ - Durable() bool - SetDurable(bool) - - /** - * Priority impacts ordering guarantees. Within a - * given ordered context, higher priority messages may jump ahead of - * lower priority messages. - */ - Priority() uint8 - SetPriority(uint8) - - /** - * TTL or Time To Live, a message it may be dropped after this duration - */ - TTL() time.Duration - SetTTL(time.Duration) - - /** - * FirstAcquirer indicates - * that the recipient of the message is the first recipient to acquire - * the message, i.e. there have been no failed delivery attempts to - * other acquirers. Note that this does not mean the message has not - * been delivered to, but not acquired, by other recipients. - */ - FirstAcquirer() bool - SetFirstAcquirer(bool) - - /** - * DeliveryCount tracks how many attempts have been made to - * delivery a message. - */ - DeliveryCount() uint32 - SetDeliveryCount(uint32) - - /** - * MessageId provides a unique identifier for a message. - * it can be an a string, an unsigned long, a uuid or a - * binary value. - */ - MessageId() interface{} - SetMessageId(interface{}) - - UserId() string - SetUserId(string) - - Address() string - SetAddress(string) - - Subject() string - SetSubject(string) - - ReplyTo() string - SetReplyTo(string) - - /** - * CorrelationId is set on correlated request and response messages. It can be an a string, an unsigned long, a uuid or a - * binary value. - */ - CorrelationId() interface{} - SetCorrelationId(interface{}) - - ContentType() string - SetContentType(string) - - ContentEncoding() string - SetContentEncoding(string) - - // ExpiryTime indicates an absoulte time when the message may be dropped. - // A Zero time (i.e. t.isZero() == true) indicates a message never expires. - ExpiryTime() time.Time - SetExpiryTime(time.Time) - - CreationTime() time.Time - SetCreationTime(time.Time) - - GroupId() string - SetGroupId(string) - - GroupSequence() int32 - SetGroupSequence(int32) - - ReplyToGroupId() string - SetReplyToGroupId(string) - - /** - * Instructions can be used to access or modify AMQP delivery instructions. - */ - Instructions() *map[string]interface{} - - /** - * Annotations can be used to access or modify AMQP annotations. - */ - Annotations() *map[string]interface{} - - /** - * Properties can be used to access or modify the application properties of a message. - */ - Properties() *map[string]interface{} - - /** - * Body of the message can be any AMQP encodable type. - */ - Body() interface{} - SetBody(interface{}) - - // Encode encodes the message as AMQP data. If buffer is non-nil and is large enough - // the message is encoded into it, otherwise a new buffer is created. - // Returns the buffer containing the message. - Encode(buffer []byte) ([]byte, error) -} - -// NewMessage creates a new message instance. The returned interface contains a pointer. -func NewMessage() Message { - pn := C.pn_message() // Pick up default setting from C message. - defer C.pn_message_free(pn) - return goMessage(pn) -} - -// Message implementation copies all message data into Go space so it can be proprely -// memory managed. -// -type message struct { - inferred, durable, firstAcquirer bool - priority uint8 - ttl time.Duration - deliveryCount uint32 - messageId interface{} - userId, address, subject, replyTo string - contentType, contentEncoding string - groupId, replyToGroupId string - creationTime, expiryTime time.Time - groupSequence int32 - correlationId interface{} - instructions, annotations, properties map[string]interface{} - body interface{} -} - -func (m *message) Inferred() bool { return m.inferred } -func (m *message) SetInferred(b bool) { m.inferred = b } -func (m *message) Durable() bool { return m.durable } -func (m *message) SetDurable(b bool) { m.durable = b } -func (m *message) Priority() uint8 { return m.priority } -func (m *message) SetPriority(b uint8) { m.priority = b } -func (m *message) TTL() time.Duration { return m.ttl } -func (m *message) SetTTL(d time.Duration) { m.ttl = d } -func (m *message) FirstAcquirer() bool { return m.firstAcquirer } -func (m *message) SetFirstAcquirer(b bool) { m.firstAcquirer = b } -func (m *message) DeliveryCount() uint32 { return m.deliveryCount } -func (m *message) SetDeliveryCount(c uint32) { m.deliveryCount = c } -func (m *message) MessageId() interface{} { return m.messageId } -func (m *message) SetMessageId(id interface{}) { m.messageId = id } -func (m *message) UserId() string { return m.userId } -func (m *message) SetUserId(s string) { m.userId = s } -func (m *message) Address() string { return m.address } -func (m *message) SetAddress(s string) { m.address = s } -func (m *message) Subject() string { return m.subject } -func (m *message) SetSubject(s string) { m.subject = s } -func (m *message) ReplyTo() string { return m.replyTo } -func (m *message) SetReplyTo(s string) { m.replyTo = s } -func (m *message) CorrelationId() interface{} { return m.correlationId } -func (m *message) SetCorrelationId(c interface{}) { m.correlationId = c } -func (m *message) ContentType() string { return m.contentType } -func (m *message) SetContentType(s string) { m.contentType = s } -func (m *message) ContentEncoding() string { return m.contentEncoding } -func (m *message) SetContentEncoding(s string) { m.contentEncoding = s } -func (m *message) ExpiryTime() time.Time { return m.expiryTime } -func (m *message) SetExpiryTime(t time.Time) { m.expiryTime = t } -func (m *message) CreationTime() time.Time { return m.creationTime } -func (m *message) SetCreationTime(t time.Time) { m.creationTime = t } -func (m *message) GroupId() string { return m.groupId } -func (m *message) SetGroupId(s string) { m.groupId = s } -func (m *message) GroupSequence() int32 { return m.groupSequence } -func (m *message) SetGroupSequence(s int32) { m.groupSequence = s } -func (m *message) ReplyToGroupId() string { return m.replyToGroupId } -func (m *message) SetReplyToGroupId(s string) { m.replyToGroupId = s } -func (m *message) Instructions() *map[string]interface{} { return &m.instructions } -func (m *message) Annotations() *map[string]interface{} { return &m.annotations } -func (m *message) Properties() *map[string]interface{} { return &m.properties } -func (m *message) Body() interface{} { return m.body } -func (m *message) SetBody(b interface{}) { m.body = b } - -// rewindGet rewinds and then gets the value from a data object. -func rewindGet(data *C.pn_data_t, v interface{}) { - if data != nil && C.pn_data_size(data) > 0 { - C.pn_data_rewind(data) - C.pn_data_next(data) - get(data, v) - } -} - -// goMessage populates a Go message from a pn_message_t -func goMessage(pn *C.pn_message_t) *message { - m := &message{ - inferred: bool(C.pn_message_is_inferred(pn)), - durable: bool(C.pn_message_is_durable(pn)), - priority: uint8(C.pn_message_get_priority(pn)), - ttl: time.Duration(C.pn_message_get_ttl(pn)) * time.Millisecond, - firstAcquirer: bool(C.pn_message_is_first_acquirer(pn)), - deliveryCount: uint32(C.pn_message_get_delivery_count(pn)), - userId: goString(C.pn_message_get_user_id(pn)), - address: C.GoString(C.pn_message_get_address(pn)), - subject: C.GoString(C.pn_message_get_subject(pn)), - replyTo: C.GoString(C.pn_message_get_reply_to(pn)), - contentType: C.GoString(C.pn_message_get_content_type(pn)), - contentEncoding: C.GoString(C.pn_message_get_content_encoding(pn)), - expiryTime: time.Unix(0, int64(time.Millisecond*time.Duration(C.pn_message_get_expiry_time(pn)))), - creationTime: time.Unix(0, int64(time.Millisecond)*int64(C.pn_message_get_creation_time(pn))), - groupId: C.GoString(C.pn_message_get_group_id(pn)), - groupSequence: int32(C.pn_message_get_group_sequence(pn)), - replyToGroupId: C.GoString(C.pn_message_get_reply_to_group_id(pn)), - messageId: nil, - correlationId: nil, - instructions: make(map[string]interface{}), - annotations: make(map[string]interface{}), - properties: make(map[string]interface{}), - } - rewindGet(C.pn_message_id(pn), &m.messageId) - rewindGet(C.pn_message_correlation_id(pn), &m.correlationId) - rewindGet(C.pn_message_instructions(pn), &m.instructions) - rewindGet(C.pn_message_annotations(pn), &m.annotations) - rewindGet(C.pn_message_properties(pn), &m.properties) - rewindGet(C.pn_message_body(pn), &m.body) - return m -} - -// pnMessage populates a pn_message_t from a Go message. -func (m *message) pnMessage() *C.pn_message_t { - pn := C.pn_message() - C.pn_message_set_inferred(pn, C.bool(m.Inferred())) - C.pn_message_set_durable(pn, C.bool(m.Durable())) - C.pn_message_set_priority(pn, C.uint8_t(m.priority)) - C.pn_message_set_ttl(pn, C.pn_millis_t(m.TTL()/time.Millisecond)) - C.pn_message_set_first_acquirer(pn, C.bool(m.FirstAcquirer())) - C.pn_message_set_delivery_count(pn, C.uint32_t(m.deliveryCount)) - replace(C.pn_message_id(pn), m.MessageId()) - C.pn_message_set_user_id(pn, pnBytes([]byte(m.UserId()))) - C.pn_message_set_address(pn, C.CString(m.Address())) - C.pn_message_set_subject(pn, C.CString(m.Subject())) - C.pn_message_set_reply_to(pn, C.CString(m.ReplyTo())) - replace(C.pn_message_correlation_id(pn), m.CorrelationId()) - C.pn_message_set_content_type(pn, C.CString(m.ContentType())) - C.pn_message_set_content_encoding(pn, C.CString(m.ContentEncoding())) - C.pn_message_set_expiry_time(pn, pnTime(m.ExpiryTime())) - C.pn_message_set_creation_time(pn, pnTime(m.CreationTime())) - C.pn_message_set_group_id(pn, C.CString(m.GroupId())) - C.pn_message_set_group_sequence(pn, C.pn_sequence_t(m.GroupSequence())) - C.pn_message_set_reply_to_group_id(pn, C.CString(m.ReplyToGroupId())) - replace(C.pn_message_instructions(pn), *m.Instructions()) - replace(C.pn_message_annotations(pn), *m.Annotations()) - replace(C.pn_message_properties(pn), *m.Properties()) - replace(C.pn_message_body(pn), m.Body()) - return pn -} - -// FIXME aconway 2015-04-08: Move message encode/decode under Marshal/Unmarshal interfaces. - -// DecodeMessage decodes bytes as a message -func DecodeMessage(data []byte) (Message, error) { - pnMsg := C.pn_message() - defer C.pn_message_free(pnMsg) - if len(data) == 0 { - return nil, internal.Errorf("empty buffer for decode") - } - if C.pn_message_decode(pnMsg, cPtr(data), cLen(data)) < 0 { - return nil, internal.Errorf("decoding message: %s", - internal.PnError(unsafe.Pointer(C.pn_message_error(pnMsg)))) - } - return goMessage(pnMsg), nil -} - -// Encode the message into bufffer. -// If buffer is nil or len(buffer) is not sufficient to encode the message a larger -// buffer will be returned. -func (m *message) Encode(buffer []byte) ([]byte, error) { - pn := m.pnMessage() - defer C.pn_message_free(pn) - encode := func(buf []byte) ([]byte, error) { - len := cLen(buf) - result := C.pn_message_encode(pn, cPtr(buf), &len) - switch { - case result == C.PN_OVERFLOW: - return buf, overflow - case result < 0: - return buf, internal.Errorf("cannot encode message: %s", internal.PnErrorCode(result)) - default: - return buf[:len], nil - } - } - return encodeGrow(buffer, encode) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/message_test.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/message_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/message_test.go deleted file mode 100644 index 2baec22..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/message_test.go +++ /dev/null @@ -1,90 +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 ( - "reflect" - "testing" - "time" -) - -func roundTrip(t *testing.T, m Message) { - buffer, err := m.Encode(nil) - if err != nil { - t.Fatalf("Encode failed: %v", err) - } - m2, err := DecodeMessage(buffer) - if err != nil { - t.Fatalf("Decode failed: %v", err) - } - if !reflect.DeepEqual(m, m2) { - t.Errorf("Message mismatch got\n%#v\nwant\n%#v", m, m2) - } -} - -func TestDefaultMessageRoundTrip(t *testing.T) { - m := NewMessage() - // Check defaults - assertEqual(m.Inferred(), false) - assertEqual(m.Durable(), false) - assertEqual(m.Priority(), uint8(4)) - assertEqual(m.TTL(), time.Duration(0)) - assertEqual(m.UserId(), "") - assertEqual(m.Address(), "") - assertEqual(m.Subject(), "") - assertEqual(m.ReplyTo(), "") - assertEqual(m.ContentType(), "") - assertEqual(m.ContentEncoding(), "") - assertEqual(m.GroupId(), "") - assertEqual(m.GroupSequence(), int32(0)) - assertEqual(m.ReplyToGroupId(), "") - assertEqual(m.MessageId(), nil) - assertEqual(m.CorrelationId(), nil) - assertEqual(*m.Instructions(), map[string]interface{}{}) - assertEqual(*m.Annotations(), map[string]interface{}{}) - assertEqual(*m.Properties(), map[string]interface{}{}) - assertEqual(m.Body(), nil) - - roundTrip(t, m) -} - -func TestMessageRoundTrip(t *testing.T) { - m := NewMessage() - m.SetInferred(false) - m.SetDurable(true) - m.SetPriority(42) - m.SetTTL(0) - m.SetUserId("user") - m.SetAddress("address") - m.SetSubject("subject") - m.SetReplyTo("replyto") - m.SetContentType("content") - m.SetContentEncoding("encoding") - m.SetGroupId("group") - m.SetGroupSequence(42) - m.SetReplyToGroupId("replytogroup") - m.SetMessageId("id") - m.SetCorrelationId("correlation") - *m.Instructions() = map[string]interface{}{"instructions": "foo"} - *m.Annotations() = map[string]interface{}{"annotations": "foo"} - *m.Properties() = map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"} - m.SetBody("hello") - roundTrip(t, m) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/doc.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/doc.go b/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/doc.go deleted file mode 100644 index c815f4e..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/doc.go +++ /dev/null @@ -1,28 +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 messaging provides a procedural, concurrent Go API for exchanging AMQP messages. -*/ -package messaging - -// #cgo LDFLAGS: -lqpid-proton -import "C" - -// Just for package comment http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/example_test.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/example_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/example_test.go deleted file mode 100644 index 02302b6..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/example_test.go +++ /dev/null @@ -1,268 +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. -*/ - -// Tests to verify that example code behaves as expected. -package messaging - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "math/rand" - "net" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "testing" - "time" -) - -func panicIf(err error) { - if err != nil { - panic(err) - } -} - -// A demo broker process -type broker struct { - cmd *exec.Cmd - addr string - runerr chan error - err error -} - -// Try to connect to the broker to verify it is ready, give up after a timeout -func (b *broker) check() error { - dialer := net.Dialer{Deadline: time.Now().Add(time.Second * 10)} - for { - c, err := dialer.Dial("tcp", b.addr) - if err == nil { // Success - c.Close() - return nil - } - select { - case runerr := <-b.runerr: // Broker exited. - return runerr - default: - } - if neterr, ok := err.(net.Error); ok && neterr.Timeout() { // Running but timed out - b.stop() - return fmt.Errorf("timed out waiting for broker") - } - time.Sleep(time.Second / 10) - } -} - -// Start the demo broker, wait till it is listening on *addr. No-op if already started. -func (b *broker) start() error { - build("event/broker.go") - if b.cmd == nil { // Not already started - // FIXME aconway 2015-04-30: better way to pick/configure a broker address. - b.addr = fmt.Sprintf(":%d", rand.Intn(10000)+10000) - b.cmd = exec.Command(exepath("broker"), "-addr", b.addr, "-verbose", "0") - b.runerr = make(chan error) - // Change the -verbose setting above to see broker output on stdout/stderr. - b.cmd.Stderr, b.cmd.Stdout = os.Stderr, os.Stdout - go func() { - b.runerr <- b.cmd.Run() - }() - b.err = b.check() - } - return b.err -} - -func (b *broker) stop() { - if b != nil && b.cmd != nil { - b.cmd.Process.Kill() - b.cmd.Wait() - } -} - -// FIXME aconway 2015-04-30: redo all assert/panic tests with checkEqual style. -func checkEqual(want interface{}, got interface{}) error { - if reflect.DeepEqual(want, got) { - return nil - } - return fmt.Errorf("%#v != %#v", want, got) -} - -// runCommand returns an exec.Cmd to run an example. -func exampleCommand(prog string, arg ...string) *exec.Cmd { - build(prog + ".go") - cmd := exec.Command(exepath(prog), arg...) - cmd.Stderr = os.Stderr - return cmd -} - -// Run an example Go program, return the combined output as a string. -func runExample(prog string, arg ...string) (string, error) { - cmd := exampleCommand(prog, arg...) - out, err := cmd.Output() - return string(out), err -} - -func prefix(prefix string, err error) error { - if err != nil { - return fmt.Errorf("%s: %s", prefix, err) - } - return nil -} - -func runExampleWant(want string, prog string, args ...string) error { - out, err := runExample(prog, args...) - if err != nil { - return fmt.Errorf("%s failed: %s: %s", prog, err, out) - } - return prefix(prog, checkEqual(want, out)) -} - -func exampleArgs(args ...string) []string { - return append(args, testBroker.addr+"/foo", testBroker.addr+"/bar", testBroker.addr+"/baz") -} - -// Send then receive -func TestExampleSendReceive(t *testing.T) { - if testing.Short() { - t.Skip("Skip demo tests in short mode") - } - testBroker.start() - err := runExampleWant( - "send: Received all 15 acknowledgements\n", - "send", - exampleArgs("-count", "5", "-verbose", "1")...) - if err != nil { - t.Fatal(err) - } - err = runExampleWant( - "receive: Listening\nreceive: Received 15 messages\n", - "receive", - exampleArgs("-verbose", "1", "-count", "15")...) - if err != nil { - t.Fatal(err) - } -} - -var ready error - -func init() { ready = fmt.Errorf("Ready") } - -// Run receive in a goroutine. -// Send ready on errchan when it is listening. -// Send final error when it is done. -// Returns the Cmd, caller must Wait() -func goReceiveWant(errchan chan<- error, want string, arg ...string) *exec.Cmd { - cmd := exampleCommand("receive", arg...) - go func() { - pipe, err := cmd.StdoutPipe() - if err != nil { - errchan <- err - return - } - out := bufio.NewReader(pipe) - cmd.Start() - line, err := out.ReadString('\n') - if err != nil && err != io.EOF { - errchan <- err - return - } - listening := "receive: Listening\n" - if line != listening { - errchan <- checkEqual(listening, line) - return - } - errchan <- ready - buf := bytes.Buffer{} - io.Copy(&buf, out) // Collect the rest of the output - errchan <- checkEqual(want, buf.String()) - close(errchan) - }() - return cmd -} - -// Start receiver first, wait till it is running, then send. -func TestExampleReceiveSend(t *testing.T) { - if testing.Short() { - t.Skip("Skip demo tests in short mode") - } - testBroker.start() - recvErr := make(chan error) - recvCmd := goReceiveWant(recvErr, - "receive: Received 15 messages\n", - exampleArgs("-count", "15", "-verbose", "1")...) - defer func() { - recvCmd.Process.Kill() - recvCmd.Wait() - }() - if err := <-recvErr; err != ready { // Wait for receiver ready - t.Fatal(err) - } - err := runExampleWant( - "send: Received all 15 acknowledgements\n", - "send", - exampleArgs("-count", "5", "-verbose", "1")...) - if err != nil { - t.Fatal(err) - } - if err := <-recvErr; err != nil { - t.Fatal(err) - } -} - -func exepath(relative string) string { - if binDir == "" { - panic("bindir not set, cannot run example binaries") - } - return path.Join(binDir, relative) -} - -var testBroker *broker -var binDir, exampleDir string -var built map[string]bool - -func init() { - built = make(map[string]bool) -} - -func build(prog string) { - if !built[prog] { - build := exec.Command("go", "build", path.Join(exampleDir, prog)) - build.Dir = binDir - out, err := build.CombinedOutput() - if err != nil { - panic(fmt.Errorf("%v: %s", err, out)) - } - built[prog] = true - } -} - -func TestMain(m *testing.M) { - var err error - exampleDir, err = filepath.Abs("../../../../../../../examples/go") - panicIf(err) - binDir, err = ioutil.TempDir("", "example_test.go") - panicIf(err) - defer os.Remove(binDir) // Clean up binaries - testBroker = &broker{} // Broker is started on-demand by tests. - defer testBroker.stop() - os.Exit(m.Run()) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/handler.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/handler.go b/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/handler.go deleted file mode 100644 index 514f0cf..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/handler.go +++ /dev/null @@ -1,70 +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 messaging - -import ( - "qpid.apache.org/proton" - "qpid.apache.org/proton/event" -) - -// FIXME aconway 2015-04-28: cleanup - exposing delivery vs. disposition. - -type acksMap map[event.Delivery]chan Disposition -type receiverMap map[event.Link]chan proton.Message - -type handler struct { - connection *Connection - acks acksMap - receivers receiverMap -} - -func newHandler(c *Connection) *handler { - return &handler{c, make(acksMap), make(receiverMap)} -} - -func (h *handler) HandleMessagingEvent(t event.MessagingEventType, e event.Event) error { - switch t { - // FIXME aconway 2015-04-29: handle errors. - case event.MConnectionClosed: - for _, ack := range h.acks { - // FIXME aconway 2015-04-29: communicate error info - close(ack) - } - - case event.MSettled: - ack := h.acks[e.Delivery()] - if ack != nil { - ack <- Disposition(e.Delivery().Remote().Type()) - close(ack) - delete(h.acks, e.Delivery()) - } - - case event.MMessage: - r := h.receivers[e.Link()] - if r != nil { - m, _ := event.DecodeMessage(e) - // FIXME aconway 2015-04-29: hack, direct send, possible blocking. - r <- m - } else { - // FIXME aconway 2015-04-29: Message with no receiver - log? panic? deadletter? drop? - } - } - return nil -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/messaging.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/messaging.go b/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/messaging.go deleted file mode 100644 index d32aada..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/messaging/messaging.go +++ /dev/null @@ -1,250 +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 messaging - -// #include -import "C" - -import ( - "net" - "qpid.apache.org/proton" - "qpid.apache.org/proton/event" -) - -// Connection is a connection to a remote AMQP endpoint. -// -// You can set exported fields to configure the connection before calling -// Connection.Open() -// -type Connection struct { - // Server = true means a the connection will do automatic protocol detection. - Server bool - - // FIXME aconway 2015-04-17: Other parameters to set up SSL, SASL etc. - - handler *handler - pump *event.Pump - session Session -} - -// Make an AMQP connection over a net.Conn connection. -// -// Use Connection.Close() to close the Connection, this will also close conn. -// Using conn.Close() directly will cause an abrupt disconnect rather than an -// orderly AMQP close. -// -func (c *Connection) Open(conn net.Conn) (err error) { - c.handler = newHandler(c) - c.pump, err = event.NewPump(conn, - event.NewMessagingDelegator(c.handler), - ) - if err != nil { - return err - } - if c.Server { - c.pump.Server() - } - go c.pump.Run() - return nil -} - -// Connect opens a default client connection. It is a shortcut for -// c := &Connection -// c.Open() -// -func Connect(conn net.Conn) (*Connection, error) { - c := &Connection{} - err := c.Open(conn) - return c, err -} - -// Close the connection. -// -// Connections must be closed to clean up resources and stop associated goroutines. -func (c *Connection) Close() error { return c.pump.Close() } - -// DefaultSession returns a default session for the connection. -// -// It is created on the first call to DefaultSession() and returned from all subsequent calls. -// Use Session() for more control over creating sessions. -// -func (c *Connection) DefaultSession() (s Session, err error) { - if c.session.e.IsNil() { - c.session, err = c.Session() - } - return c.session, err -} - -type sessionErr struct { - s event.Session - err error -} - -// Session creates a new session. -func (c *Connection) Session() (Session, error) { - connection := c.pump.Connection() - result := make(chan sessionErr) - c.pump.Inject <- func() { - s, err := connection.Session() - if err == nil { - s.Open() - } - result <- sessionErr{s, err} - } - se := <-result - return Session{se.s, c.pump}, se.err -} - -// FIXME aconway 2015-04-27: set sender name, options etc. - -// Sender creates a Sender that will send messages to the address addr. -func (c *Connection) Sender(addr string) (s Sender, err error) { - session, err := c.DefaultSession() - if err != nil { - return Sender{}, err - } - result := make(chan Sender) - c.pump.Inject <- func() { - link := session.e.Sender(linkNames.Next()) - if link.IsNil() { - err = session.e.Error() - } else { - link.Target().SetAddress(addr) - // FIXME aconway 2015-04-27: link options? - link.Open() - } - result <- Sender{Link{c, link}} - } - return <-result, err -} - -// Receiver returns a receiver that will receive messages sent to address addr. -func (c *Connection) Receiver(addr string) (r Receiver, err error) { - // FIXME aconway 2015-04-29: move code to session, in link.go? - session, err := c.DefaultSession() - if err != nil { - return Receiver{}, err - } - result := make(chan Receiver) - c.pump.Inject <- func() { - link := session.e.Receiver(linkNames.Next()) - if link.IsNil() { - err = session.e.Error() - } else { - link.Source().SetAddress(addr) - // FIXME aconway 2015-04-27: link options? - link.Open() - } - // FIXME aconway 2015-04-29: hack to avoid blocking, need proper buffering linked to flow control - rchan := make(chan proton.Message, 1000) - c.handler.receivers[link] = rchan - result <- Receiver{Link{c, link}, rchan} - } - return <-result, err -} - -// FIXME aconway 2015-04-29: counter per session. -var linkNames proton.UidCounter - -// Session is an AMQP session, it contains Senders and Receivers. -// Every Connection has a DefaultSession, you can create additional sessions -// with Connection.Session() -type Session struct { - e event.Session - pump *event.Pump -} - -// FIXME aconway 2015-05-05: REWORK Sender/receiver/session. - -// Disposition indicates the outcome of a settled message delivery. -type Disposition uint64 - -const ( - // Message was accepted by the receiver - Accepted Disposition = C.PN_ACCEPTED - // Message was rejected as invalid by the receiver - Rejected = C.PN_REJECTED - // Message was not processed by the receiver but may be processed by some other receiver. - Released = C.PN_RELEASED -) - -// String human readable name for a Disposition. -func (d Disposition) String() string { - switch d { - case Accepted: - return "Accepted" - case Rejected: - return "Rejected" - case Released: - return "Released" - default: - return "Unknown" - } -} - -// FIXME aconway 2015-04-29: How to signal errors via ack channels. - -// An Acknowledgement is a channel which will receive the Disposition of the message -// when it is acknowledged. The channel is closed after the disposition is sent. -type Acknowledgement <-chan Disposition - -// Link has common data and methods for Sender and Receiver links. -type Link struct { - connection *Connection - elink event.Link -} - -// Sender sends messages. -type Sender struct { - Link -} - -// FIXME aconway 2015-04-28: allow user to specify delivery tag. -// FIXME aconway 2015-04-28: should we provide a sending channel rather than a send function? - -// Send sends a message. If d is not nil, the disposition is retured on d. -// If d is nil the message is sent pre-settled and no disposition is returned. -func (s *Sender) Send(m proton.Message) (ack Acknowledgement, err error) { - ackChan := make(chan Disposition, 1) - ack = ackChan - s.connection.pump.Inject <- func() { - // FIXME aconway 2015-04-28: flow control & credit, buffer or fail? - delivery, err := s.elink.Send(m) - if err == nil { // FIXME aconway 2015-04-28: error handling - s.connection.handler.acks[delivery] = ackChan - } - } - return ack, nil -} - -// Close the sender. -func (s *Sender) Close() error { return nil } // FIXME aconway 2015-04-27: close/free - -// Receiver receives messages via the channel Receive. -type Receiver struct { - Link - // Channel of messag - Receive <-chan proton.Message -} - -// FIXME aconway 2015-04-29: settlement - ReceivedMessage with Settle() method? - -// Close the Receiver. -func (r *Receiver) Close() error { return nil } // FIXME aconway 2015-04-29: close/free http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/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 deleted file mode 100644 index 07f8aea..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/types.go +++ /dev/null @@ -1,193 +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 -// const pn_type_t PN_DATA_TYPE_ERROR = (pn_type_t) -1; -import "C" - -import ( - "bytes" - "fmt" - "reflect" - "time" - "unsafe" -) - -func pnTypeString(pt C.pn_type_t) string { - switch pt { - case C.PN_NULL: - return "null" - case C.PN_BOOL: - return "bool" - case C.PN_UBYTE: - return "ubyte" - case C.PN_BYTE: - return "byte" - case C.PN_USHORT: - return "ushort" - case C.PN_SHORT: - return "short" - case C.PN_CHAR: - return "char" - case C.PN_UINT: - return "uint" - case C.PN_INT: - return "int" - case C.PN_ULONG: - return "ulong" - case C.PN_LONG: - return "long" - case C.PN_TIMESTAMP: - return "timestamp" - case C.PN_FLOAT: - return "float" - case C.PN_DOUBLE: - return "double" - case C.PN_DECIMAL32: - return "decimal32" - case C.PN_DECIMAL64: - return "decimal64" - case C.PN_DECIMAL128: - return "decimal128" - case C.PN_UUID: - return "uuid" - case C.PN_BINARY: - return "binary" - case C.PN_STRING: - return "string" - case C.PN_SYMBOL: - return "symbol" - case C.PN_DESCRIBED: - return "described" - case C.PN_ARRAY: - return "array" - case C.PN_LIST: - return "list" - case C.PN_MAP: - return "map" - case C.PN_DATA_TYPE_ERROR: - return "no-data" - default: - return fmt.Sprintf("unknown-type(%d)", pt) - } -} - -// Go types -var ( - bytesType = reflect.TypeOf([]byte{}) - valueType = reflect.TypeOf(reflect.Value{}) -) - -// FIXME aconway 2015-04-08: can't handle AMQP maps with key types that are not valid Go map keys. - -// 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{} - -// Symbol is a string that is encoded as an AMQP symbol -type Symbol string - -// Binary is a string that is encoded as an AMQP binary. -// It is a string rather than a byte[] because byte[] is not hashable and can't be used as -// a map key, AMQP frequently uses binary types as map keys. It can convert to and from []byte -type Binary string - -// 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() -} - -// pnTime converts Go time.Time to Proton millisecond Unix time. -func pnTime(t time.Time) C.pn_timestamp_t { - secs := t.Unix() - // Note: sub-second accuracy is not guaraunteed if the Unix time in - // nanoseconds cannot be represented by an int64 (sometime around year 2260) - msecs := (t.UnixNano() % int64(time.Second)) / int64(time.Millisecond) - return C.pn_timestamp_t(secs*1000 + msecs) -} - -// goTime converts a pn_timestamp_t to a Go time.Time. -func goTime(t C.pn_timestamp_t) time.Time { - secs := int64(t) / 1000 - nsecs := (int64(t) % 1000) * int64(time.Millisecond) - return time.Unix(secs, nsecs) -} - -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 -} - -func pnBytes(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]))} - } -} - -func cPtr(b []byte) *C.char { - if len(b) == 0 { - return nil - } - return (*C.char)(unsafe.Pointer(&b[0])) -} - -func cLen(b []byte) C.size_t { - return C.size_t(len(b)) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/proton-c/bindings/go/src/qpid.apache.org/proton/uid.go ---------------------------------------------------------------------- diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/uid.go b/proton-c/bindings/go/src/qpid.apache.org/proton/uid.go deleted file mode 100644 index de80846..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/uid.go +++ /dev/null @@ -1,40 +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. -*/ - -// Generating unique IDs for various things. - -package proton - -import ( - "strconv" - "sync/atomic" -) - -// A simple atomic counter to generate unique 64 bit IDs. -type UidCounter struct{ count uint64 } - -// NextInt gets the next uint64 value from the atomic counter. -func (uc *UidCounter) NextInt() uint64 { - return atomic.AddUint64(&uc.count, 1) -} - -// Next gets the next integer value encoded as a base32 string, safe for NUL terminated C strings. -func (uc *UidCounter) Next() string { - return strconv.FormatUint(uc.NextInt(), 32) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/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 deleted file mode 100644 index f904aae..0000000 --- a/proton-c/bindings/go/src/qpid.apache.org/proton/unmarshal.go +++ /dev/null @@ -1,552 +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 -import "C" - -import ( - "bytes" - "fmt" - "io" - "qpid.apache.org/proton/internal" - "reflect" - "unsafe" -) - -const minDecode = 1024 - -// Error returned if AMQP data cannot be unmarshaled as the desired Go type. -type BadUnmarshal struct { - // The name of the AMQP type. - AMQPType string - // The Go type. - GoType reflect.Type -} - -func newBadUnmarshal(pnType C.pn_type_t, v interface{}) *BadUnmarshal { - return &BadUnmarshal{pnTypeString(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", e.AMQPType, e.GoType) - } -} - -// -// 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 internal.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. | - +---------------------------+----------------------------------------------------------------------+ - |Symbol |symbol | - +---------------------------+----------------------------------------------------------------------+ - |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 |string | - | +------------------------+---------------------------------------------+ - | |symbol |Symbol | - | +------------------------+---------------------------------------------+ - | |binary |Binary | - | +------------------------+---------------------------------------------+ - | |nulll |nil | - | +------------------------+---------------------------------------------+ - | |map |Map | - | +------------------------+---------------------------------------------+ - | |list |List | - +---------------------------+------------------------+---------------------------------------------+ - -The following Go types cannot be unmarshaled: complex64/128, uintptr, function, interface, channel. - -TODO types - -AMQP: timestamp, decimal32/64/128, uuid, described, array. - -Go: array, struct. - -Maps: currently we cannot unmarshal AMQP maps with unhashable key types, need an alternate -representation for those. -*/ -func Unmarshal(bytes []byte, v interface{}) (n int, err error) { - defer internal.DoRecover(&err) - data := C.pn_data(0) - defer C.pn_data_free(data) - n = unmarshal(data, bytes, v) - if n == 0 { - err = internal.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 from data into value pointed at by v. -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 *Binary: - switch pnType { - case C.PN_BINARY: - *v = Binary(goBytes(C.pn_data_get_binary(data))) - default: - panic(newBadUnmarshal(pnType, v)) - } - - case *Symbol: - switch pnType { - case C.PN_SYMBOL: - *v = Symbol(goBytes(C.pn_data_get_symbol(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 := dataError("unmarshaling", data) - if err != nil { - panic(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_NULL: - *v = nil - 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 = Binary(goBytes(C.pn_data_get_binary(data))) - case C.PN_STRING: - *v = goString(C.pn_data_get_string(data)) - case C.PN_SYMBOL: - *v = Symbol(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 // FIXME aconway 2015-03-13: avoid the copy? - default: - panic(newBadUnmarshal(pnType, v)) - } -} - -// get into map pointed at by 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) - } - // FIXME aconway 2015-04-09: avoid the copy? - 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 - } - n := int(C.pn_data_decode(data, cPtr(bytes), cLen(bytes))) - if n == int(C.PN_UNDERFLOW) { - C.pn_error_clear(C.pn_data_error(data)) - return 0 - } else if n <= 0 { - panic(internal.Errorf("unmarshal %s", internal.PnErrorCode(n))) - } - return n -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9088386c/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 deleted file mode 100644 index 5bac6ac..0000000 --- a/proton-c/bindings/go/src/qpid.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 - -/* -#include -#include -#include - -// 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" - "qpid.apache.org/proton/internal" - "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, internal.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, internal.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/9088386c/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 deleted file mode 100644 index 7315511..0000000 --- a/proton-c/bindings/go/src/qpid.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 "" -} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org For additional commands, e-mail: commits-help@qpid.apache.org