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/06/18 23:58:24 UTC
[46/50] [abbrv] qpid-proton git commit: PROTON-865: cpp encode/decode
support for complex types.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/693752d3/proton-c/bindings/go/src/qpid.apache.org/proton/go/amqp/interop_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/go/amqp/interop_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/go/amqp/interop_test.go
deleted file mode 100644
index 11049f7..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/go/amqp/interop_test.go
+++ /dev/null
@@ -1,308 +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 amqp
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "reflect"
- "strings"
- "testing"
-)
-
-func assertEqual(want interface{}, got interface{}) {
- if !reflect.DeepEqual(want, got) {
- panic(fmt.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("interop/" + name + ".amqp")
- if err != nil {
- panic(fmt.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, nil)
- 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, nil)
- 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 != "" {
- t.Fatalf("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)
- assertNil(e.Encode(in.s))
- assertNil(e.Encode(in.i))
- assertNil(e.Encode(in.u8))
- assertNil(e.Encode(in.b))
- assertNil(e.Encode(in.f))
- assertNil(e.Encode(in.v))
-
- var out data
- d := NewDecoder(&buf)
- assertNil(d.Decode(&out.s))
- assertNil(d.Decode(&out.i))
- assertNil(d.Decode(&out.u8))
- assertNil(d.Decode(&out.b))
- assertNil(d.Decode(&out.f))
- assertNil(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, nil)
- 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)
-}
-
-func FIXMETestMessage(t *testing.T) {
- // FIXME aconway 2015-04-09: integrate Message encoding under marshal/unmarshal API.
- bytes, err := ioutil.ReadAll(getReader("message"))
- assertNil(err)
- m, err := DecodeMessage(bytes)
- assertNil(err)
- fmt.Printf("%+v\n", m)
- assertEqual(m.Body(), "hello")
-
- bytes2 := make([]byte, len(bytes))
- bytes2, err = m.Encode(bytes2)
- assertNil(err)
- assertEqual(bytes, bytes2)
-}
-
-// FIXME aconway 2015-03-13: finish the full interop test
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/693752d3/proton-c/docs/api/index.md
----------------------------------------------------------------------
diff --git a/proton-c/docs/api/index.md b/proton-c/docs/api/index.md
index 10aea84..8727d9b 100644
--- a/proton-c/docs/api/index.md
+++ b/proton-c/docs/api/index.md
@@ -1,5 +1,9 @@
Proton Documentation {#index}
====================
-The proton library contains two APIs: The [Engine API](@ref engine),
+The proton library contains two C APIs: The [Engine API](@ref engine),
and the [Messenger API](@ref messenger).
+
+There is also a [C++ API](@ref cpp).
+
+@defgroup cpp C++ binding
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/693752d3/proton-c/docs/api/user.doxygen.in
----------------------------------------------------------------------
diff --git a/proton-c/docs/api/user.doxygen.in b/proton-c/docs/api/user.doxygen.in
index 6288764..7c6edf7 100644
--- a/proton-c/docs/api/user.doxygen.in
+++ b/proton-c/docs/api/user.doxygen.in
@@ -642,7 +642,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = @CMAKE_SOURCE_DIR@/proton-c/include @CMAKE_SOURCE_DIR@/proton-c/docs/api
+INPUT = @CMAKE_SOURCE_DIR@/proton-c/include @CMAKE_SOURCE_DIR@/proton-c/docs/api @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/include
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/693752d3/proton-c/include/proton/codec.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/codec.h b/proton-c/include/proton/codec.h
index 4c4d2c3..3ab7f8e 100644
--- a/proton-c/include/proton/codec.h
+++ b/proton-c/include/proton/codec.h
@@ -177,6 +177,9 @@ typedef enum {
PN_MAP = 25
} pn_type_t;
+/** A special invalid type value that is returned when no valid type is available. */
+extern const pn_type_t PN_INVALID;
+
/**
* Return a string name for an AMQP type.
*
@@ -468,8 +471,8 @@ PN_EXTERN bool pn_data_exit(pn_data_t *data);
PN_EXTERN bool pn_data_lookup(pn_data_t *data, const char *name);
/**
- * Access the type of the current node. Returns an undefined value if
- * there is no current node.
+ * Access the type of the current node. Returns PN_INVALID if there is no
+ * current node.
*
* @param data a data object
* @return the type of the current node
@@ -953,7 +956,7 @@ PN_EXTERN bool pn_data_is_array_described(pn_data_t *data);
/**
* Return the array type if the current node points to an array,
- * undefined otherwise.
+ * PN_INVALID otherwise.
*
* @param data a pn_data_t object
* @return the element type of an array node
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/693752d3/proton-c/src/codec/codec.c
----------------------------------------------------------------------
diff --git a/proton-c/src/codec/codec.c b/proton-c/src/codec/codec.c
index 573887e..29204eb 100644
--- a/proton-c/src/codec/codec.c
+++ b/proton-c/src/codec/codec.c
@@ -73,6 +73,8 @@ const char *pn_type_name(pn_type_t type)
return "<UNKNOWN>";
}
+const pn_type_t PN_INVALID = (pn_type_t) -1;
+
static inline void pni_atom_init(pn_atom_t *atom, pn_type_t type)
{
memset(atom, 0, sizeof(pn_atom_t));
@@ -690,7 +692,7 @@ static bool pn_scan_next(pn_data_t *data, pn_type_t *type, bool suspend)
pn_data_exit(data);
return pn_scan_next(data, type, suspend);
} else {
- *type = (pn_type_t) -1;
+ *type = PN_INVALID;
return false;
}
}
@@ -1266,7 +1268,7 @@ pn_type_t pn_data_type(pn_data_t *data)
if (node) {
return node->atom.type;
} else {
- return (pn_type_t) -1;
+ return PN_INVALID;
}
}
@@ -1276,7 +1278,7 @@ pn_type_t pni_data_parent_type(pn_data_t *data)
if (node) {
return node->atom.type;
} else {
- return (pn_type_t) -1;
+ return PN_INVALID;
}
}
@@ -1686,7 +1688,7 @@ pn_type_t pn_data_get_array_type(pn_data_t *data)
if (node && node->atom.type == PN_ARRAY) {
return node->type;
} else {
- return (pn_type_t) -1;
+ return PN_INVALID;
}
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/693752d3/proton-c/src/codec/encoder.c
----------------------------------------------------------------------
diff --git a/proton-c/src/codec/encoder.c b/proton-c/src/codec/encoder.c
index 082bb21..b6651fc 100644
--- a/proton-c/src/codec/encoder.c
+++ b/proton-c/src/codec/encoder.c
@@ -250,17 +250,17 @@ static int pni_encoder_enter(void *ctx, pn_data_t *data, pni_node_t *node)
pn_encoder_t *encoder = (pn_encoder_t *) ctx;
pni_node_t *parent = pn_data_node(data, node->parent);
pn_atom_t *atom = &node->atom;
- uint8_t code;
+ uint8_t code = pn_node2code(encoder, node);
conv_t c;
/** In an array we don't write the code before each element, only the first. */
if (pn_is_in_array(data, parent, node)) {
- code = pn_type2code(encoder, parent->type);
- if (pn_is_first_in_array(data, parent, node)) {
+ uint8_t array_code = pn_type2code(encoder, parent->type);
+ if (code != array_code)
+ return pn_error_format(data->error, PN_ERR, "array element type mismatch");
+ if (pn_is_first_in_array(data, parent, node))
pn_encoder_writef8(encoder, code);
- }
} else {
- code = pn_node2code(encoder, node);
pn_encoder_writef8(encoder, code);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org