qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@apache.org
Subject svn commit: r1351532 - in /qpid/proton/trunk: proton-c/ proton-c/bindings/python/ proton-c/include/proton/ proton-c/src/ proton-c/src/codec/ proton-c/src/engine/ proton-c/src/message/ tests/proton_tests/
Date Mon, 18 Jun 2012 23:33:38 GMT
Author: rhs
Date: Mon Jun 18 23:33:37 2012
New Revision: 1351532

URL: http://svn.apache.org/viewvc?rev=1351532&view=rev
Log:
split out scanner and parser from codec.c; added message sections; tweaked linked list macros

Added:
    qpid/proton/trunk/proton-c/include/proton/parser.h
    qpid/proton/trunk/proton-c/include/proton/scanner.h
    qpid/proton/trunk/proton-c/src/parser.c
    qpid/proton/trunk/proton-c/src/scanner.c
Modified:
    qpid/proton/trunk/proton-c/CMakeLists.txt
    qpid/proton/trunk/proton-c/bindings/python/python.i
    qpid/proton/trunk/proton-c/include/proton/codec.h
    qpid/proton/trunk/proton-c/include/proton/message.h
    qpid/proton/trunk/proton-c/src/codec/codec.c
    qpid/proton/trunk/proton-c/src/driver.c
    qpid/proton/trunk/proton-c/src/engine/engine-internal.h
    qpid/proton/trunk/proton-c/src/engine/engine.c
    qpid/proton/trunk/proton-c/src/message/message.c
    qpid/proton/trunk/proton-c/src/proton.c
    qpid/proton/trunk/proton-c/src/util.c
    qpid/proton/trunk/proton-c/src/util.h
    qpid/proton/trunk/tests/proton_tests/message.py

Modified: qpid/proton/trunk/proton-c/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/CMakeLists.txt?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/CMakeLists.txt (original)
+++ qpid/proton/trunk/proton-c/CMakeLists.txt Mon Jun 18 23:33:37 2012
@@ -32,6 +32,8 @@ add_library (
   src/driver.c
   src/error.c
   src/buffer.c
+  src/parser.c
+  src/scanner.c
   src/types.c
 
   src/framing/framing.c

Modified: qpid/proton/trunk/proton-c/bindings/python/python.i
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/python/python.i?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/python/python.i (original)
+++ qpid/proton/trunk/proton-c/bindings/python/python.i Mon Jun 18 23:33:37 2012
@@ -40,6 +40,9 @@ typedef int int32_t;
 int pn_message_encode(pn_message_t *msg, pn_format_t format, char *OUTPUT, size_t *OUTPUT_SIZE);
 %ignore pn_message_encode;
 
+int pn_section_save(pn_section_t *section, char *OUTPUT, size_t *OUTPUT_SIZE);
+%ignore pn_section_save;
+
 ssize_t pn_send(pn_link_t *transport, char *STRING, size_t LENGTH);
 %ignore pn_send;
 

Modified: qpid/proton/trunk/proton-c/include/proton/codec.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/codec.h?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/codec.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/codec.h Mon Jun 18 23:33:37 2012
@@ -91,20 +91,11 @@ int pn_format_atom(pn_bytes_t *bytes, pn
 
 int pn_fill_atoms(pn_atoms_t *atoms, const char *fmt, ...);
 int pn_vfill_atoms(pn_atoms_t *atoms, const char *fmt, va_list ap);
+int pn_ifill_atoms(pn_atoms_t *atoms, const char *fmt, ...);
+int pn_vifill_atoms(pn_atoms_t *atoms, const char *fmt, va_list ap);
 int pn_scan_atoms(const pn_atoms_t *atoms, const char *fmt, ...);
 int pn_vscan_atoms(const pn_atoms_t *atoms, const char *fmt, va_list ap);
 
-// JSON
-
-typedef struct pn_json_t pn_json_t;
-
-pn_json_t *pn_json();
-int pn_json_parse(pn_json_t *json, const char *str, pn_atoms_t *atoms);
-int pn_json_render(pn_json_t *json, pn_atoms_t *atoms, char *output, size_t *size);
-int pn_json_error_code(pn_json_t *json);
-const char *pn_json_error_str(pn_json_t *json);
-void pn_json_free(pn_json_t *json);
-
 // data
 
 typedef struct pn_data_t pn_data_t;
@@ -112,6 +103,7 @@ typedef struct pn_data_t pn_data_t;
 pn_data_t *pn_data(size_t capacity);
 void pn_data_free(pn_data_t *data);
 int pn_data_clear(pn_data_t *data);
+int pn_data_grow(pn_data_t *data);
 int pn_data_decode(pn_data_t *data, char *bytes, size_t *size);
 int pn_data_encode(pn_data_t *data, char *bytes, size_t *size);
 int pn_data_vfill(pn_data_t *data, const char *fmt, va_list ap);
@@ -119,6 +111,9 @@ int pn_data_fill(pn_data_t *data, const 
 int pn_data_vscan(pn_data_t *data, const char *fmt, va_list ap);
 int pn_data_scan(pn_data_t *data, const char *fmt, ...);
 int pn_data_print(pn_data_t *data);
+pn_atoms_t pn_data_atoms(pn_data_t *data);
+pn_atoms_t pn_data_available(pn_data_t *data);
 int pn_data_format(pn_data_t *data, char *bytes, size_t *size);
+int pn_data_resize(pn_data_t *data, size_t size);
 
 #endif /* codec.h */

Modified: qpid/proton/trunk/proton-c/include/proton/message.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/message.h?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/message.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/message.h Mon Jun 18 23:33:37 2012
@@ -118,6 +118,27 @@ int pn_message_idecode(pn_message_t *msg
 int pn_message_iencode(pn_message_t *msg, pn_format_t format, char *bytes, size_t *size);
 */
 
+typedef struct pn_section_t pn_section_t;
+
+pn_section_t *pn_section(pn_message_t *msg);
+void pn_section_free(pn_section_t *section);
+void pn_section_clear(pn_section_t *section);
+const char *pn_section_error(pn_section_t *section);
+
+pn_format_t pn_section_get_format(pn_section_t *section);
+int pn_section_set_format(pn_section_t *section, pn_format_t format);
+int pn_section_load(pn_section_t *section, const char *data);
+int pn_section_save(pn_section_t *section, char *data, size_t *size);
+
+// TODO:
+// bind vars
+//int pn_section_set(pn_section_t *section, int i, pn_atom_t *atom);
+//pn_atom_t *pn_section_get(pn_section_t *section, int i);
+// querying
+// could separate query from getting results
+//int pn_section_scan(pn_section_t *section, const char *query, pn_atom_t *atom);
+// multisection
+
 // full decode/encode
 int pn_message_decode(pn_message_t *msg, pn_format_t format, const char *bytes, size_t size);
 int pn_message_encode(pn_message_t *msg, pn_format_t format, char *bytes, size_t *size);

Added: qpid/proton/trunk/proton-c/include/proton/parser.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/parser.h?rev=1351532&view=auto
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/parser.h (added)
+++ qpid/proton/trunk/proton-c/include/proton/parser.h Mon Jun 18 23:33:37 2012
@@ -0,0 +1,35 @@
+#ifndef _PROTON_PARSER_H
+#define _PROTON_PARSER_H 1
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <proton/codec.h>
+
+typedef struct pn_parser_t pn_parser_t;
+
+pn_parser_t *pn_parser();
+int pn_parser_parse(pn_parser_t *parser, const char *str, pn_atoms_t *atoms);
+int pn_parser_errno(pn_parser_t *parser);
+const char *pn_parser_error(pn_parser_t *parser);
+void pn_parser_free(pn_parser_t *parser);
+
+#endif /* parser.h */

Added: qpid/proton/trunk/proton-c/include/proton/scanner.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/scanner.h?rev=1351532&view=auto
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/scanner.h (added)
+++ qpid/proton/trunk/proton-c/include/proton/scanner.h Mon Jun 18 23:33:37 2012
@@ -0,0 +1,73 @@
+#ifndef _PROTON_SCANNER_H
+#define _PROTON_SCANNER_H 1
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <sys/types.h>
+#include <stdarg.h>
+
+typedef enum {
+  PN_TOK_LBRACE,
+  PN_TOK_RBRACE,
+  PN_TOK_LBRACKET,
+  PN_TOK_RBRACKET,
+  PN_TOK_EQUAL,
+  PN_TOK_COMMA,
+  PN_TOK_POS,
+  PN_TOK_NEG,
+  PN_TOK_DOT,
+  PN_TOK_AT,
+  PN_TOK_DOLLAR,
+  PN_TOK_BINARY,
+  PN_TOK_STRING,
+  PN_TOK_SYMBOL,
+  PN_TOK_ID,
+  PN_TOK_FLOAT,
+  PN_TOK_INT,
+  PN_TOK_TRUE,
+  PN_TOK_FALSE,
+  PN_TOK_NULL,
+  PN_TOK_EOS,
+  PN_TOK_ERR
+} pn_token_type_t;
+
+typedef struct pn_scanner_t pn_scanner_t;
+
+typedef struct {
+  pn_token_type_t type;
+  const char *start;
+  size_t size;
+} pn_token_t;
+
+pn_scanner_t *pn_scanner();
+void pn_scanner_free(pn_scanner_t *scanner);
+pn_token_t pn_scanner_token(pn_scanner_t *scanner);
+int pn_scanner_err(pn_scanner_t *scanner, int code, const char *fmt, ...);
+int pn_scanner_verr(pn_scanner_t *scanner, int code, const char *fmt, va_list ap);
+void pn_scanner_line_info(pn_scanner_t *scanner, int *line, int *col);
+int pn_scanner_errno(pn_scanner_t *scanner);
+const char *pn_scanner_error(pn_scanner_t *scanner);
+int pn_scanner_start(pn_scanner_t *scanner, const char *input);
+int pn_scanner_scan(pn_scanner_t *scanner);
+int pn_scanner_shift(pn_scanner_t *scanner);
+
+#endif /* scanner.h */

Modified: qpid/proton/trunk/proton-c/src/codec/codec.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/codec/codec.c?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/codec/codec.c (original)
+++ qpid/proton/trunk/proton-c/src/codec/codec.c Mon Jun 18 23:33:37 2012
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <inttypes.h>
 #include <arpa/inet.h>
+#include <ctype.h>
 #include "encodings.h"
 #include "../util.h"
 
@@ -81,7 +82,7 @@ int pn_bytes_format(pn_bytes_t *bytes, c
   va_end(ap);
   if (n >= bytes->size) {
     return PN_OVERFLOW;
-  } else if (n > 0) {
+  } else if (n >= 0) {
     pn_bytes_ltrim(bytes, n);
     return 0;
   } else {
@@ -135,9 +136,9 @@ int pn_format_atom(pn_bytes_t *bytes, pn
   case PN_LONG:
     return pn_bytes_format(bytes, "%li", atom.u.as_long);
   case PN_FLOAT:
-    return pn_bytes_format(bytes, "%f", atom.u.as_float);
+    return pn_bytes_format(bytes, "%g", atom.u.as_float);
   case PN_DOUBLE:
-    return pn_bytes_format(bytes, "%f", atom.u.as_double);
+    return pn_bytes_format(bytes, "%g", atom.u.as_double);
   case PN_BINARY:
   case PN_STRING:
   case PN_SYMBOL:
@@ -145,29 +146,41 @@ int pn_format_atom(pn_bytes_t *bytes, pn
       int err;
       const char *pfx;
       pn_bytes_t bin;
+      bool quote;
       switch (atom.type) {
       case PN_BINARY:
         pfx = "b";
         bin = atom.u.as_binary;
+        quote = true;
         break;
       case PN_STRING:
-        pfx = "u";
+        pfx = "";
         bin = atom.u.as_string;
+        quote = true;
         break;
       case PN_SYMBOL:
-        pfx = "";
+        pfx = ":";
         bin = atom.u.as_symbol;
+        quote = false;
+        for (int i = 0; i < bin.size; i++) {
+          if (!isalpha(bin.start[i])) {
+            quote = true;
+            break;
+          }
+        }
         break;
       default:
         pn_fatal("XXX");
         return PN_ERR;
       }
 
-      if ((err = pn_bytes_format(bytes, "%s\"", pfx))) return err;
+      if ((err = pn_bytes_format(bytes, "%s", pfx))) return err;
+      if (quote) if ((err = pn_bytes_format(bytes, "\""))) return err;
       ssize_t n = pn_quote_data(bytes->start, bytes->size, bin.start, bin.size);
       if (n < 0) return n;
       pn_bytes_ltrim(bytes, n);
-      return pn_bytes_format(bytes, "\"");
+      if (quote) if ((err = pn_bytes_format(bytes, "\""))) return err;
+      return 0;
     }
   case PN_DESCRIPTOR:
     return pn_bytes_format(bytes, "descriptor");
@@ -222,10 +235,10 @@ int pn_format_atoms_one(pn_bytes_t *byte
 
   switch (atom->type) {
   case PN_DESCRIPTOR:
+    if ((err = pn_bytes_format(bytes, "@"))) return err;
     if ((err = pn_format_atoms_one(bytes, atoms, level + 1))) return err;
-    if ((err = pn_bytes_format(bytes, "("))) return err;
+    if ((err = pn_bytes_format(bytes, " "))) return err;
     if ((err = pn_format_atoms_one(bytes, atoms, level + 1))) return err;
-    if ((err = pn_bytes_format(bytes, ")"))) return err;
     return 0;
   case PN_ARRAY:
     count = atom->u.count;
@@ -259,7 +272,7 @@ int pn_format_atoms_one(pn_bytes_t *byte
             if ((err = pn_bytes_format(bytes, ", "))) return err;
           }
         } else {
-          if ((err = pn_bytes_format(bytes, ": "))) return err;
+          if ((err = pn_bytes_format(bytes, "="))) return err;
         }
       }
     }
@@ -1159,19 +1172,25 @@ int pn_fill_atoms(pn_atoms_t *atoms, con
   return n;
 }
 
-int pn_ifill_atoms(pn_atoms_t *atoms, const char *fmt, ...)
+int pn_vifill_atoms(pn_atoms_t *atoms, const char *fmt, va_list ap)
 {
-  va_list ap;
-  va_start(ap, fmt);
   pn_atoms_t copy = *atoms;
   int err = pn_vfill_atoms(&copy, fmt, ap);
-  va_end(ap);
   if (err) return err;
   atoms->start = copy.start + copy.size;
   atoms->size -= copy.size;
   return 0;
 }
 
+int pn_ifill_atoms(pn_atoms_t *atoms, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  int err = pn_vifill_atoms(atoms, fmt, ap);
+  va_end(ap);
+  return err;
+}
+
 int pn_skip(pn_atoms_t *atoms, size_t n)
 {
   for (int i = 0; i < n; i++) {
@@ -1593,678 +1612,6 @@ int pn_vscan_atoms(const pn_atoms_t *ato
   return 0;
 }
 
-// JSON
-
-typedef enum {
-  PN_JTOK_LBRACE,
-  PN_JTOK_RBRACE,
-  PN_JTOK_LBRACKET,
-  PN_JTOK_RBRACKET,
-  PN_JTOK_COLON,
-  PN_JTOK_COMMA,
-  PN_JTOK_POS,
-  PN_JTOK_NEG,
-  PN_JTOK_DOT,
-  PN_JTOK_STRING,
-  PN_JTOK_FLOAT,
-  PN_JTOK_INT,
-  PN_JTOK_TRUE,
-  PN_JTOK_FALSE,
-  PN_JTOK_NULL,
-  PN_JTOK_EXP,
-  PN_JTOK_EOS,
-  PN_JTOK_ERR
-} pn_token_type_t;
-
-typedef struct {
-  pn_token_type_t type;
-  const char *start;
-  size_t size;
-} pn_token_t;
-
-#define ERROR_SIZE (1024)
-
-struct pn_json_t {
-  const char *input;
-  const char *position;
-  pn_token_t token;
-  int error_code;
-  char *atoms;
-  size_t size;
-  size_t capacity;
-  char error_str[ERROR_SIZE];
-};
-
-const char *pn_token_type(pn_token_type_t type)
-{
-  switch (type)
-  {
-  case PN_JTOK_LBRACE: return "LBRACE";
-  case PN_JTOK_RBRACE: return "RBRACE";
-  case PN_JTOK_LBRACKET: return "LBRACKET";
-  case PN_JTOK_RBRACKET: return "RBRACKET";
-  case PN_JTOK_COLON: return "COLON";
-  case PN_JTOK_COMMA: return "COMMA";
-  case PN_JTOK_POS: return "POS";
-  case PN_JTOK_NEG: return "NEG";
-  case PN_JTOK_DOT: return "DOT";
-  case PN_JTOK_STRING: return "STRING";
-  case PN_JTOK_FLOAT: return "FLOAT";
-  case PN_JTOK_INT: return "INT";
-  case PN_JTOK_TRUE: return "TRUE";
-  case PN_JTOK_FALSE: return "FALSE";
-  case PN_JTOK_NULL: return "NULL";
-  case PN_JTOK_EXP: return "EXP";
-  case PN_JTOK_EOS: return "EOS";
-  case PN_JTOK_ERR: return "ERR";
-  default: return "<UNKNOWN>";
-  }
-}
-
-pn_json_t *pn_json()
-{
-  pn_json_t *json = malloc(sizeof(pn_json_t));
-  json->input = NULL;
-  json->error_code = 0;
-  json->error_str[0] = '\0';
-  json->atoms = NULL;
-  json->size = 0;
-  json->capacity = 0;
-  return json;
-}
-
-void pn_json_ensure(pn_json_t *json, size_t size)
-{
-  while (json->capacity - json->size < size) {
-    json->capacity = json->capacity ? 2 * json->capacity : 1024;
-    json->atoms = realloc(json->atoms, json->capacity);
-  }
-}
-
-void pn_json_line_info(pn_json_t *json, int *line, int *col)
-{
-  *line = 1;
-  *col = 0;
-
-  for (const char *c = json->input; *c && c <= json->token.start; c++) {
-    if (*c == '\n') {
-      *line += 1;
-      *col = -1;
-    } else {
-      *col += 1;
-    }
-  }
-}
-
-int pn_json_error(pn_json_t *json, int code, const char *fmt, ...)
-{
-  json->error_code = code;
-
-  int line, col;
-  pn_json_line_info(json, &line, &col);
-  int size = json->token.size;
-  int ln = snprintf(json->error_str, ERROR_SIZE,
-                    "input line %i column %i %s:'%.*s': ", line, col,
-                    pn_token_type(json->token.type),
-                    size, json->token.start);
-  if (ln >= ERROR_SIZE) {
-    return pn_json_error(json, code, "error info truncated");
-  } else if (ln < 0) {
-    json->error_str[0] = '\0';
-  }
-
-  va_list ap;
-  va_start(ap, fmt);
-  int n = snprintf(json->error_str + ln, ERROR_SIZE - ln, fmt, ap);
-  va_end(ap);
-
-  if (n >= ERROR_SIZE - ln) {
-    return pn_json_error(json, code, "error info truncated");
-  } else if (n < 0) {
-    json->error_str[0] = '\0';
-  }
-
-  return code;
-}
-
-int pn_json_error_code(pn_json_t *json)
-{
-  return json->error_code;
-}
-
-const char *pn_json_error_str(pn_json_t *json)
-{
-  if (json->error_code) {
-    return json->error_str;
-  } else {
-    return NULL;
-  }
-}
-
-void pn_json_free(pn_json_t *json)
-{
-  free(json->atoms);
-  free(json);
-}
-
-void pn_json_token(pn_json_t *json, pn_token_type_t type, const char *start, size_t size)
-{
-  json->token.type = type;
-  json->token.start = start;
-  json->token.size = size;
-}
-
-int pn_json_scan_string(pn_json_t *json, const char *str)
-{
-  bool escape = false;
-
-  for (int i = 1; true; i++) {
-    char c = str[i];
-    if (escape) {
-      escape = false;
-    } else {
-      switch (c) {
-      case '\0':
-      case '"':
-        pn_json_token(json, c ? PN_JTOK_STRING : PN_JTOK_ERR,
-                      str, c ? i + 1 : i);
-        return c ? 0 : PN_ERR;
-      case '\\':
-        escape = true;
-        break;
-      }
-    }
-  }
-}
-
-int pn_json_scan_alpha(pn_json_t *json, const char *str)
-{
-  for (int i = 0; true; i++) {
-    char c = str[i];
-    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
-      pn_token_type_t type;
-      if (!strncmp(str, "true", i)) {
-        type = PN_JTOK_TRUE;
-      } else if (!strncmp(str, "false", i)) {
-        type = PN_JTOK_FALSE;
-      } else if (!strncmp(str, "null", i)) {
-        type = PN_JTOK_NULL;
-      } else if (!strncasecmp(str, "e", i)) {
-        type = PN_JTOK_EXP;
-      } else {
-        type = PN_JTOK_ERR;
-      }
-
-      pn_json_token(json, type, str, i);
-      return type == PN_JTOK_ERR ? PN_ERR : 0;
-    }
-  }
-}
-
-int pn_json_scan_number(pn_json_t *json, const char *str)
-{
-  bool dot = false;
-  bool exp = false;
-
-  int i = 0;
-
-  if (str[i] == '+' || str[i] == '-') {
-    i++;
-  }
-
-  for ( ; true; i++) {
-    char c = str[i];
-    switch (c) {
-    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
-    case '7': case '8': case '9':
-      continue;
-    case '.':
-      if (dot) {
-        pn_json_token(json, PN_JTOK_FLOAT, str, i);
-        return 0;
-      } else {
-        dot = true;
-      }
-      continue;
-    case 'e':
-    case 'E':
-      if (exp) {
-        pn_json_token(json, PN_JTOK_FLOAT, str, i);
-        return 0;
-      } else {
-        dot = true;
-        exp = true;
-        if (str[i+1] == '+' || str[i+1] == '-') {
-          i++;
-        }
-        continue;
-      }
-    default:
-      if (dot || exp) {
-        pn_json_token(json, PN_JTOK_FLOAT, str, i);
-        return 0;
-      } else {
-        pn_json_token(json, PN_JTOK_INT, str, i);
-        return 0;
-      }
-    }
-  }
-}
-
-int pn_json_scan_symbol(pn_json_t *json, const char *str, pn_token_type_t type)
-{
-  pn_json_token(json, type, str, 1);
-  return 0;
-}
-
-int pn_json_scan(pn_json_t *json)
-{
-  const char *str = json->position;
-  char n;
-
-  for (char c; true; str++) {
-    c = *str;
-    switch (c)
-    {
-    case '{':
-      return pn_json_scan_symbol(json, str, PN_JTOK_LBRACE);
-    case '}':
-      return pn_json_scan_symbol(json, str, PN_JTOK_RBRACE);
-    case'[':
-      return pn_json_scan_symbol(json, str, PN_JTOK_LBRACKET);
-    case ']':
-      return pn_json_scan_symbol(json, str, PN_JTOK_RBRACKET);
-    case ':':
-      return pn_json_scan_symbol(json, str, PN_JTOK_COLON);
-    case ',':
-      return pn_json_scan_symbol(json, str, PN_JTOK_COMMA);
-    case '.':
-      n = *(str+1);
-      if ((n >= '0' && n <= '9')) {
-        return pn_json_scan_number(json, str);
-      } else {
-        return pn_json_scan_symbol(json, str, PN_JTOK_DOT);
-      }
-    case '-':
-      n = *(str+1);
-      if ((n >= '0' && n <= '9') || n == '.') {
-        return pn_json_scan_number(json, str);
-      } else {
-        return pn_json_scan_symbol(json, str, PN_JTOK_NEG);
-      }
-    case '+':
-      n = *(str+1);
-      if ((n >= '0' && n <= '9') || n == '.') {
-        return pn_json_scan_number(json, str);
-      } else {
-        return pn_json_scan_symbol(json, str, PN_JTOK_POS);
-      }
-    case ' ': case '\t': case '\r': case '\v': case '\f': case '\n':
-      break;
-    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
-    case '7': case '8': case '9':
-      return pn_json_scan_number(json, str);
-    case '"':
-      return pn_json_scan_string(json, str);
-    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
-    case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
-    case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
-    case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
-    case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
-    case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
-    case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
-    case 'X': case 'Y': case 'Z':
-      return pn_json_scan_alpha(json, str);
-    case '\0':
-      pn_json_token(json, PN_JTOK_EOS, str, 0);
-      return PN_EOS;
-    default:
-      pn_json_token(json, PN_JTOK_ERR, str, 1);
-      return PN_ERR;
-    }
-  }
-}
-
-int pn_json_shift(pn_json_t *json)
-{
-  json->position = json->token.start + json->token.size;
-  int err = pn_json_scan(json);
-  if (err == PN_EOS) {
-    return 0;
-  } else {
-    return err;
-  }
-}
-
-int pn_json_parse_value(pn_json_t *json, pn_atoms_t *atoms);
-
-int pn_json_parse_object(pn_json_t *json, pn_atoms_t *atoms)
-{
-  if (json->token.type == PN_JTOK_LBRACE) {
-    int err = pn_json_shift(json);
-    if (err) return err;
-
-    pn_atom_t *map = atoms->start;
-    err = pn_ifill_atoms(atoms, "{}");
-    if (err) return pn_json_error(json, err, "error writing map atoms");
-
-    int count = 0;
-
-    if (json->token.type != PN_JTOK_RBRACE) {
-      while (true) {
-        err = pn_json_parse_value(json, atoms);
-        if (err) return err;
-        count++;
-
-        if (json->token.type == PN_JTOK_COLON) {
-          err = pn_json_shift(json);
-          if (err) return err;
-        } else {
-          return pn_json_error(json, PN_ERR, "expecting ':'");
-        }
-
-        err = pn_json_parse_value(json, atoms);
-        if (err) return err;
-        count++;
-
-        if (json->token.type == PN_JTOK_COMMA) {
-          err = pn_json_shift(json);
-          if (err) return err;
-        } else {
-          break;
-        }
-      }
-    }
-
-    map->u.count = count;
-
-    if (json->token.type == PN_JTOK_RBRACE) {
-      return pn_json_shift(json);
-    } else {
-      return pn_json_error(json, PN_ERR, "expecting '}'");
-    }
-  } else {
-    return pn_json_error(json, PN_ERR, "expecting '{'");
-  }
-}
-
-int pn_json_parse_array(pn_json_t *json, pn_atoms_t *atoms)
-{
-  int err;
-
-  if (json->token.type == PN_JTOK_LBRACKET) {
-    err = pn_json_shift(json);
-    if (err) return err;
-
-    pn_atom_t *list = atoms->start;
-    int err = pn_ifill_atoms(atoms, "[]");
-    if (err) return pn_json_error(json, err, "error writing list atoms");
-
-    int count = 0;
-
-    if (json->token.type != PN_JTOK_RBRACKET) {
-      while (true) {
-        err = pn_json_parse_value(json, atoms);
-        if (err) return err;
-        count++;
-
-        if (json->token.type == PN_JTOK_COMMA) {
-          err = pn_json_shift(json);
-          if (err) return err;
-        } else {
-          break;
-        }
-      }
-    }
-
-    list->u.count = count;
-
-    if (json->token.type == PN_JTOK_RBRACKET) {
-      return pn_json_shift(json);
-    } else {
-      return pn_json_error(json, PN_ERR, "expecting ']'");
-    }
-  } else {
-    return pn_json_error(json, PN_ERR, "expecting '['");
-  }
-}
-
-void pn_json_append_tok(pn_json_t *json, char *dst, int *idx)
-{
-  memcpy(dst + *idx, json->token.start, json->token.size);
-  *idx += json->token.size;
-}
-
-int pn_json_parse_number(pn_json_t *json, pn_atoms_t *atoms)
-{
-  bool dbl = false;
-  char number[1024];
-  int idx = 0;
-  int err;
-
-  bool negate = false;
-
-  if (json->token.type == PN_JTOK_NEG || json->token.type == PN_JTOK_POS) {
-    if (json->token.type == PN_JTOK_NEG)
-      negate = !negate;
-    err = pn_json_shift(json);
-    if (err) return err;
-  }
-
-  if (json->token.type == PN_JTOK_FLOAT || json->token.type == PN_JTOK_INT) {
-    dbl = json->token.type == PN_JTOK_FLOAT;
-    pn_json_append_tok(json, number, &idx);
-    err = pn_json_shift(json);
-    if (err) return err;
-  } else {
-    return pn_json_error(json, PN_ERR, "expecting FLOAT or INT");
-  }
-
-  number[idx] = '\0';
-
-  if (dbl) {
-    double value = atof(number);
-    if (negate) {
-      value = -value;
-    }
-    err = pn_ifill_atoms(atoms, "d", value);
-    if (err) return pn_json_error(json, err, "error writing double atoms");
-  } else {
-    int64_t value = atoll(number);
-    if (negate) {
-      value = -value;
-    }
-    err = pn_ifill_atoms(atoms, "l", value);
-    if (err) return pn_json_error(json, err, "error writing long atoms");
-  }
-
-  return 0;
-}
-
-int pn_json_unquote(pn_json_t *json, char *dst, const char *src, size_t *n)
-{
-  size_t idx = 0;
-  bool escape = false;
-  for (int i = 1; i < *n - 1; i++)
-  {
-    char c = src[i];
-    if (escape) {
-      switch (c) {
-      case '"':
-      case '\\':
-      case '/':
-        dst[idx++] = c;
-        escape = false;
-        break;
-      case 'b':
-        dst[idx++] = '\b';
-        break;
-      case 'f':
-        dst[idx++] = '\f';
-        break;
-      case 'n':
-        dst[idx++] = '\n';
-        break;
-      case 'r':
-        dst[idx++] = '\r';
-        break;
-      case 't':
-        dst[idx++] = '\t';
-        break;
-      // XXX: need to handle unicode escapes: 'u'
-      default:
-        return pn_json_error(json, PN_ERR, "unrecognized escape code");
-      }
-      escape = false;
-    } else {
-      switch (c)
-      {
-      case '\\':
-        escape = true;
-        break;
-      default:
-        dst[idx++] = c;
-        break;
-      }
-    }
-  }
-  dst[idx++] = '\0';
-  *n = idx;
-  return 0;
-}
-
-int pn_json_parse_value(pn_json_t *json, pn_atoms_t *atoms)
-{
-  int err;
-  size_t n;
-  char *dst;
-
-  switch (json->token.type)
-  {
-  case PN_JTOK_LBRACE:
-    return pn_json_parse_object(json, atoms);
-  case PN_JTOK_LBRACKET:
-    return pn_json_parse_array(json, atoms);
-  case PN_JTOK_STRING:
-    n = json->token.size;
-    pn_json_ensure(json, n);
-    dst = json->atoms + json->size;
-    err = pn_json_unquote(json, dst, json->token.start, &n);
-    if (err) return err;
-    json->size += n;
-    err = pn_ifill_atoms(atoms, "S", dst);
-    if (err) return pn_json_error(json, err, "error writing string atoms");
-    return pn_json_shift(json);
-  case PN_JTOK_POS:
-  case PN_JTOK_NEG:
-  case PN_JTOK_FLOAT:
-  case PN_JTOK_INT:
-    return pn_json_parse_number(json, atoms);
-  case PN_JTOK_TRUE:
-    err = pn_ifill_atoms(atoms, "o", true);
-    if (err) return pn_json_error(json, err, "error writing boolean atoms");
-    return pn_json_shift(json);
-  case PN_JTOK_FALSE:
-    err = pn_ifill_atoms(atoms, "o", false);
-    if (err) return pn_json_error(json, err, "error writing boolean atoms");
-    return pn_json_shift(json);
-  case PN_JTOK_NULL:
-    err = pn_ifill_atoms(atoms, "n");
-    if (err) return pn_json_error(json, err, "error writing null atoms");
-    return pn_json_shift(json);
-  default:
-    return pn_json_error(json, PN_ERR, "expecting one of '[', '{', STRING, "
-                         "true, false, null, NUMBER");
-  }
-}
-
-int pn_json_parse_r(pn_json_t *json, pn_atoms_t *atoms)
-{
-  while (true) {
-    int err;
-    switch (json->token.type)
-    {
-    case PN_JTOK_EOS:
-      return 0;
-    case PN_JTOK_ERR:
-      return PN_ERR;
-    default:
-      err = pn_json_parse_value(json, atoms);
-      if (err) return err;
-    }
-  }
-}
-
-int pn_json_parse(pn_json_t *json, const char *str, pn_atoms_t *atoms)
-{
-  pn_atoms_t copy = *atoms;
-  json->input = str;
-  json->position = json->input;
-  json->size = 0;
-  int err = pn_json_scan(json);
-  if (err) return err;
-  err = pn_json_parse_r(json, &copy);
-  if (err) return err;
-  atoms->size -= copy.size;
-  return 0;
-}
-
-/* XXX: in progress
-int pn_json_render_r(pn_json_t *json, pn_atoms_t *atoms, pn_bytes_t *bytes)
-{
-  if (!atoms->size) {
-    return PN_UNDERFLOW;
-  }
-
-  pn_atom_t *atom = atoms->start;
-  switch (atom->type)
-  {
-  case PN_DESCRIPTOR:
-    return 0;
-  case PN_ARRAY:
-    return 0;
-  case PN_LIST:
-    return 0;
-  case PN_MAP:
-    return 0;
-  case PN_NULL:
-    return 0;
-  case PN_BOOL:
-    return 0;
-  case PN_UBYTE:
-  case PN_USHORT:
-  case PN_UINT:
-  case PN_ULONG:
-  case PN_BYTE:
-  case PN_SHORT:
-  case PN_INT:
-  case PN_LONG:
-    return 0;
-  case PN_FLOAT:
-  case PN_DOUBLE:
-    return 0;
-  case PN_BINARY:
-  case PN_STRING:
-  case PN_SYMBOL:
-    return 0;
-  case PN_TYPE:
-    return 0;
-  }
-
-  return 0;
-}
-
-int pn_json_render(pn_json_t *json, pn_atoms_t *atoms, char *output, size_t *size)
-{
-  pn_atoms_t copy = *atoms;
-  pn_bytes_t bytes = pn_bytes(*size, output);
-  int err = pn_json_render_r(json, &copy, &bytes);
-  if (err) return err;
-  *size -= bytes.size;
-  return 0;
-}
-*/
-
 // data
 
 struct pn_data_t {
@@ -2298,10 +1645,12 @@ void pn_data_free(pn_data_t *data)
 
 int pn_data_clear(pn_data_t *data)
 {
-  data->size = 0;
-  if (data->buf) {
-    int e = pn_buffer_clear(data->buf);
-    if (e) return e;
+  if (data) {
+    data->size = 0;
+    if (data->buf) {
+      int e = pn_buffer_clear(data->buf);
+      if (e) return e;
+    }
   }
   return 0;
 }
@@ -2404,14 +1753,20 @@ int pn_data_print(pn_data_t *data)
   return pn_print_atoms(&atoms);
 }
 
-pn_atoms_t pn_data_atoms(pn_data_t *data, size_t size)
+pn_atoms_t pn_data_atoms(pn_data_t *data)
+{
+  return (pn_atoms_t) {.size=data->size, .start=data->atoms};
+}
+
+pn_atoms_t pn_data_available(pn_data_t *data)
 {
-  return (pn_atoms_t) {.size=size, .start=data->atoms};
+  return (pn_atoms_t) {.size=data->capacity - data->size,
+      .start=data->atoms + data->size};
 }
 
 int pn_data_format(pn_data_t *data, char *bytes, size_t *size)
 {
-  ssize_t sz = pn_format_atoms(bytes, *size, pn_data_atoms(data, data->size));
+  ssize_t sz = pn_format_atoms(bytes, *size, pn_data_atoms(data));
   if (sz < 0) {
     return sz;
   } else {
@@ -2419,3 +1774,10 @@ int pn_data_format(pn_data_t *data, char
     return 0;
   }
 }
+
+int pn_data_resize(pn_data_t *data, size_t size)
+{
+  if (!data || size > data->capacity) return PN_ARG_ERR;
+  data->size = size;
+  return 0;
+}

Modified: qpid/proton/trunk/proton-c/src/driver.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/driver.c?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/driver.c (original)
+++ qpid/proton/trunk/proton-c/src/driver.c Mon Jun 18 23:33:37 2012
@@ -59,8 +59,8 @@ struct pn_driver_t {
 
 struct pn_listener_t {
   pn_driver_t *driver;
-  pn_listener_t *next;
-  pn_listener_t *prev;
+  pn_listener_t *listener_next;
+  pn_listener_t *listener_prev;
   int idx;
   bool pending;
   int fd;
@@ -71,8 +71,8 @@ struct pn_listener_t {
 
 struct pn_connector_t {
   pn_driver_t *driver;
-  pn_connector_t *next;
-  pn_connector_t *prev;
+  pn_connector_t *connector_next;
+  pn_connector_t *connector_prev;
   int idx;
   bool pending_tick;
   bool pending_read;
@@ -108,7 +108,7 @@ struct pn_connector_t {
 static void pn_driver_add_listener(pn_driver_t *d, pn_listener_t *l)
 {
   if (!l->driver) return;
-  LL_ADD(d->listener_head, d->listener_tail, l);
+  LL_ADD(d, listener, l);
   l->driver = d;
   d->listener_count++;
 }
@@ -118,10 +118,10 @@ static void pn_driver_remove_listener(pn
   if (!l->driver) return;
 
   if (l == d->listener_next) {
-    d->listener_next = l->next;
+    d->listener_next = l->listener_next;
   }
 
-  LL_REMOVE(d->listener_head, d->listener_tail, l);
+  LL_REMOVE(d, listener, l);
   l->driver = NULL;
   d->listener_count--;
 }
@@ -176,8 +176,8 @@ pn_listener_t *pn_listener_fd(pn_driver_
   pn_listener_t *l = malloc(sizeof(pn_listener_t));
   if (!l) return NULL;
   l->driver = driver;
-  l->next = NULL;
-  l->prev = NULL;
+  l->listener_next = NULL;
+  l->listener_prev = NULL;
   l->idx = 0;
   l->pending = false;
   l->fd = fd;
@@ -256,7 +256,7 @@ void pn_listener_destroy(pn_listener_t *
 static void pn_driver_add_connector(pn_driver_t *d, pn_connector_t *c)
 {
   if (!c->driver) return;
-  LL_ADD(d->connector_head, d->connector_tail, c);
+  LL_ADD(d, connector, c);
   c->driver = d;
   d->connector_count++;
 }
@@ -266,10 +266,10 @@ static void pn_driver_remove_connector(p
   if (!c->driver) return;
 
   if (c == d->connector_next) {
-    d->connector_next = c->next;
+    d->connector_next = c->connector_next;
   }
 
-  LL_REMOVE(d->connector_head, d->connector_tail, c);
+  LL_REMOVE(d, connector, c);
   c->driver = NULL;
   d->connector_count--;
   if (c->closed) {
@@ -327,8 +327,8 @@ pn_connector_t *pn_connector_fd(pn_drive
   pn_connector_t *c = malloc(sizeof(pn_connector_t));
   if (!c) return NULL;
   c->driver = driver;
-  c->next = NULL;
-  c->prev = NULL;
+  c->connector_next = NULL;
+  c->connector_prev = NULL;
   c->pending_tick = false;
   c->pending_read = false;
   c->pending_write = false;
@@ -744,7 +744,7 @@ static void pn_driver_rebuild(pn_driver_
     d->fds[d->nfds].revents = 0;
     l->idx = d->nfds;
     d->nfds++;
-    l = l->next;
+    l = l->listener_next;
   }
 
   pn_connector_t *c = d->connector_head;
@@ -758,7 +758,7 @@ static void pn_driver_rebuild(pn_driver_
       c->idx = d->nfds;
       d->nfds++;
     }
-    c = c->next;
+    c = c->connector_next;
   }
 }
 
@@ -776,7 +776,7 @@ void pn_driver_wait(pn_driver_t *d, int 
   pn_listener_t *l = d->listener_head;
   while (l) {
     l->pending = (l->idx && d->fds[l->idx].revents & POLLIN);
-    l = l->next;
+    l = l->listener_next;
   }
 
   pn_connector_t *c = d->connector_head;
@@ -790,7 +790,7 @@ void pn_driver_wait(pn_driver_t *d, int 
       c->pending_read = (idx && d->fds[idx].revents & POLLIN);
       c->pending_write = (idx && d->fds[idx].revents & POLLOUT);
     }
-    c = c->next;
+    c = c->connector_next;
   }
 
   d->listener_next = d->listener_head;
@@ -802,7 +802,7 @@ pn_listener_t *pn_driver_listener(pn_dri
 
   while (d->listener_next) {
     pn_listener_t *l = d->listener_next;
-    d->listener_next = l->next;
+    d->listener_next = l->listener_next;
 
     if (l->pending) {
       return l;
@@ -817,7 +817,7 @@ pn_connector_t *pn_driver_connector(pn_d
 
   while (d->connector_next) {
     pn_connector_t *c = d->connector_next;
-    d->connector_next = c->next;
+    d->connector_next = c->connector_next;
 
     if (c->closed || c->pending_read || c->pending_write || c->pending_tick ||
         c->input_size || c->input_eos) {

Modified: qpid/proton/trunk/proton-c/src/engine/engine-internal.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/engine/engine-internal.h?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/engine/engine-internal.h (original)
+++ qpid/proton/trunk/proton-c/src/engine/engine-internal.h Mon Jun 18 23:33:37 2012
@@ -145,8 +145,8 @@ struct pn_link_t {
   char *local_target;
   char *remote_source;
   char *remote_target;
-  pn_delivery_t *head;
-  pn_delivery_t *tail;
+  pn_delivery_t *unsettled_head;
+  pn_delivery_t *unsettled_tail;
   pn_delivery_t *current;
   pn_delivery_t *settled_head;
   pn_delivery_t *settled_tail;
@@ -167,8 +167,10 @@ struct pn_delivery_t {
   bool remote_settled;
   bool updated;
   bool settled; // tracks whether we're in the unsettled list or not
-  pn_delivery_t *link_next;
-  pn_delivery_t *link_prev;
+  pn_delivery_t *unsettled_next;
+  pn_delivery_t *unsettled_prev;
+  pn_delivery_t *settled_next;
+  pn_delivery_t *settled_prev;
   pn_delivery_t *work_next;
   pn_delivery_t *work_prev;
   bool work;

Modified: qpid/proton/trunk/proton-c/src/engine/engine.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/engine/engine.c?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/engine/engine.c (original)
+++ qpid/proton/trunk/proton-c/src/engine/engine.c Mon Jun 18 23:33:37 2012
@@ -315,41 +315,15 @@ void pn_clear_bytes(pn_delivery_t *deliv
   }
 }
 
-void pn_free_deliveries(pn_delivery_t *delivery)
+void pn_free_delivery(pn_delivery_t *delivery)
 {
-  while (delivery)
-  {
-    pn_delivery_t *next = delivery->link_next;
+  if (delivery) {
     pn_clear_tag(delivery);
     pn_clear_bytes(delivery);
     free(delivery);
-    delivery = next;
   }
 }
 
-void pn_dump_deliveries(pn_delivery_t *delivery)
-{
-  if (delivery) {
-    while (delivery)
-    {
-      printf("%p(%.*s)", (void *) delivery, (int) delivery->tag.size,
-             delivery->tag.start);
-      if (delivery->link_next) printf(" -> ");
-      delivery = delivery->link_next;
-    }
-  } else {
-    printf("NULL");
-  }
-}
-
-void pn_link_dump(pn_link_t *link)
-{
-  pn_dump_deliveries(link->settled_head);
-  printf("\n");
-  pn_dump_deliveries(link->head);
-  printf("\n");
-}
-
 void pn_link_open(pn_link_t *link)
 {
   if (link) pn_open((pn_endpoint_t *) link);
@@ -369,8 +343,16 @@ void pn_link_destroy(pn_link_t *link)
   free(link->remote_source);
   free(link->remote_target);
   pn_remove_link(link->session, link);
-  pn_free_deliveries(link->settled_head);
-  pn_free_deliveries(link->head);
+  while (link->settled_head) {
+    pn_delivery_t *d = link->settled_head;
+    LL_POP(link, settled);
+    pn_free_delivery(d);
+  }
+  while (link->unsettled_head) {
+    pn_delivery_t *d = link->unsettled_head;
+    LL_POP(link, unsettled);
+    pn_free_delivery(d);
+  }
   free(link->name);
   free(link);
 }
@@ -386,7 +368,7 @@ void pn_endpoint_init(pn_endpoint_t *end
   endpoint->transport_prev = NULL;
   endpoint->modified = false;
 
-  LL_ADD_PFX(conn->endpoint_head, conn->endpoint_tail, endpoint, endpoint_);
+  LL_ADD(conn, endpoint, endpoint);
 }
 
 pn_connection_t *pn_connection()
@@ -479,7 +461,7 @@ void pn_add_work(pn_connection_t *connec
 {
   if (!delivery->work)
   {
-    LL_ADD_PFX(connection->work_head, connection->work_tail, delivery, work_);
+    LL_ADD(connection, work, delivery);
     delivery->work = true;
   }
 }
@@ -488,7 +470,7 @@ void pn_clear_work(pn_connection_t *conn
 {
   if (delivery->work)
   {
-    LL_REMOVE_PFX(connection->work_head, connection->work_tail, delivery, work_);
+    LL_REMOVE(connection, work, delivery);
     delivery->work = false;
   }
 }
@@ -519,7 +501,7 @@ void pn_add_tpwork(pn_delivery_t *delive
   pn_connection_t *connection = delivery->link->session->connection;
   if (!delivery->tpwork)
   {
-    LL_ADD_PFX(connection->tpwork_head, connection->tpwork_tail, delivery, tpwork_);
+    LL_ADD(connection, tpwork, delivery);
     delivery->tpwork = true;
   }
   pn_modified(connection, &connection->endpoint);
@@ -530,7 +512,7 @@ void pn_clear_tpwork(pn_delivery_t *deli
   pn_connection_t *connection = delivery->link->session->connection;
   if (delivery->tpwork)
   {
-    LL_REMOVE_PFX(connection->tpwork_head, connection->tpwork_tail, delivery, tpwork_);
+    LL_REMOVE(connection, tpwork, delivery);
     delivery->tpwork = false;
   }
 }
@@ -551,7 +533,7 @@ void pn_dump(pn_connection_t *conn)
 void pn_modified(pn_connection_t *connection, pn_endpoint_t *endpoint)
 {
   if (!endpoint->modified) {
-    LL_ADD_PFX(connection->transport_head, connection->transport_tail, endpoint, transport_);
+    LL_ADD(connection, transport, endpoint);
     endpoint->modified = true;
   }
 }
@@ -559,7 +541,7 @@ void pn_modified(pn_connection_t *connec
 void pn_clear_modified(pn_connection_t *connection, pn_endpoint_t *endpoint)
 {
   if (endpoint->modified) {
-    LL_REMOVE_PFX(connection->transport_head, connection->transport_tail, endpoint, transport_);
+    LL_REMOVE(connection, transport, endpoint);
     endpoint->transport_next = NULL;
     endpoint->transport_prev = NULL;
     endpoint->modified = false;
@@ -763,7 +745,7 @@ void pn_link_init(pn_link_t *link, int t
   link->remote_source = NULL;
   link->remote_target = NULL;
   link->settled_head = link->settled_tail = NULL;
-  link->head = link->tail = link->current = NULL;
+  link->unsettled_head = link->unsettled_tail = link->current = NULL;
   link->unsettled_count = 0;
   link->credit = 0;
   link->queued = 0;
@@ -884,7 +866,7 @@ pn_delivery_t *pn_delivery(pn_link_t *li
 {
   if (!link) return NULL;
   pn_delivery_t *delivery = link->settled_head;
-  LL_POP_PFX(link->settled_head, link->settled_tail, link_);
+  LL_POP(link, settled);
   if (!delivery) delivery = malloc(sizeof(pn_delivery_t));
   if (!delivery) return NULL;
   delivery->link = link;
@@ -897,7 +879,7 @@ pn_delivery_t *pn_delivery(pn_link_t *li
   delivery->remote_settled = false;
   delivery->updated = false;
   delivery->settled = false;
-  LL_ADD_PFX(link->head, link->tail, delivery, link_);
+  LL_ADD(link, unsettled, delivery);
   delivery->work_next = NULL;
   delivery->work_prev = NULL;
   delivery->work = false;
@@ -927,12 +909,12 @@ int pn_unsettled(pn_link_t *link)
 
 pn_delivery_t *pn_unsettled_head(pn_link_t *link)
 {
-  return link->head;
+  return link->unsettled_head;
 }
 
 pn_delivery_t *pn_unsettled_next(pn_delivery_t *delivery)
 {
-  return delivery->link_next;
+  return delivery->unsettled_next;
 }
 
 bool pn_is_current(pn_delivery_t *delivery)
@@ -974,14 +956,14 @@ void pn_advance_sender(pn_link_t *link)
   link->queued++;
   link->credit--;
   pn_add_tpwork(link->current);
-  link->current = link->current->link_next;
+  link->current = link->current->unsettled_next;
 }
 
 void pn_advance_receiver(pn_link_t *link)
 {
   link->credit--;
   link->queued--;
-  link->current = link->current->link_next;
+  link->current = link->current->unsettled_next;
 }
 
 bool pn_advance(pn_link_t *link)
@@ -1015,9 +997,9 @@ int pn_queued(pn_link_t *link)
 void pn_real_settle(pn_delivery_t *delivery)
 {
   pn_link_t *link = delivery->link;
-  LL_REMOVE_PFX(link->head, link->tail, delivery, link_);
+  LL_REMOVE(link, unsettled, delivery);
   // TODO: what if we settle the current delivery?
-  LL_ADD_PFX(link->settled_head, link->settled_tail, delivery, link_);
+  LL_ADD(link, settled, delivery);
   pn_clear_tag(delivery);
   pn_clear_bytes(delivery);
   delivery->settled = true;
@@ -1198,8 +1180,8 @@ int pn_do_transfer(pn_dispatcher_t *disp
   pn_link_state_t *link_state = pn_handle_state(ssn_state, handle);
   pn_link_t *link = link_state->link;
   pn_delivery_t *delivery;
-  if (link->tail && !link->tail->done) {
-    delivery = link->tail;
+  if (link->unsettled_tail && !link->unsettled_tail->done) {
+    delivery = link->unsettled_tail;
   } else {
     pn_delivery_buffer_t *incoming = &ssn_state->incoming;
 
@@ -1673,7 +1655,7 @@ int pn_process_flow_sender(pn_transport_
     if ((int16_t) ssn_state->local_channel >= 0 &&
         (int32_t) state->local_handle >= 0 &&
         snd->drain && snd->drained) {
-      pn_delivery_t *tail = state->link->tail;
+      pn_delivery_t *tail = state->link->unsettled_tail;
       if (!tail || !pn_delivery_buffered(tail)) {
         state->delivery_count += state->link_credit;
         state->link_credit = 0;

Modified: qpid/proton/trunk/proton-c/src/message/message.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/message/message.c?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/message/message.c (original)
+++ qpid/proton/trunk/proton-c/src/message/message.c Mon Jun 18 23:33:37 2012
@@ -23,10 +23,12 @@
 #include <proton/buffer.h>
 #include <proton/codec.h>
 #include <proton/errors.h>
+#include <proton/parser.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include "protocol.h"
+#include "../util.h"
 
 ssize_t pn_message_data(char *dst, size_t available, const char *src, size_t size)
 {
@@ -64,6 +66,20 @@ struct pn_message_t {
   pn_buffer_t *reply_to_group_id;
 
   pn_data_t *data;
+
+  pn_parser_t *parser;
+
+  pn_section_t *section_head;
+  pn_section_t *section_tail;
+};
+
+struct pn_section_t {
+  pn_message_t *message;
+  pn_section_t *section_next;
+  pn_section_t *section_prev;
+  pn_format_t format;
+  pn_data_t *data;
+  bool cleared;
 };
 
 pn_message_t *pn_message()
@@ -88,6 +104,9 @@ pn_message_t *pn_message()
   msg->group_sequence = 0;
   msg->reply_to_group_id = NULL;
   msg->data = NULL;
+  msg->parser = NULL;
+  msg->section_head = NULL;
+  msg->section_tail = NULL;
   return msg;
 }
 
@@ -130,6 +149,23 @@ void pn_message_clear(pn_message_t *msg)
   if (msg->data) pn_data_clear(msg->data);
 }
 
+const char *pn_message_error(pn_message_t *msg)
+{
+  if (msg && msg->parser) {
+    return pn_parser_error(msg->parser);
+  } else {
+    return NULL;
+  }
+}
+
+pn_parser_t *pn_message_parser(pn_message_t *msg)
+{
+  if (!msg->parser) {
+    msg->parser = pn_parser();
+  }
+  return msg->parser;
+}
+
 bool pn_message_is_durable(pn_message_t *msg)
 {
   return msg ? msg->durable : false;
@@ -373,12 +409,13 @@ int pn_message_set_reply_to_group_id(pn_
 int pn_message_decode(pn_message_t *msg, pn_format_t format, const char *bytes, size_t size)
 {
   if (!msg || format != PN_AMQP || !bytes || !size) return PN_ARG_ERR;
-  if (!msg->data) {
-    msg->data = pn_data(64);
-  }
 
   while (size) {
+    if (!msg->data) {
+      msg->data = pn_data(64);
+    }
     size_t copy = size;
+    pn_data_clear(msg->data);
     int err = pn_data_decode(msg->data, (char *) bytes, &copy);
     if (err) return err;
     size -= copy;
@@ -387,7 +424,9 @@ int pn_message_decode(pn_message_t *msg,
     uint64_t desc;
     err = pn_data_scan(msg->data, "D?L.", &scanned, &desc);
     if (err) return err;
-    if (!scanned) return PN_ERR;
+    if (!scanned){
+      desc = 0;
+    }
 
     switch (desc) {
     case HEADER:
@@ -424,13 +463,24 @@ int pn_message_decode(pn_message_t *msg,
       }
       break;
     default:
-      return PN_ERR;
+      {
+        pn_section_t *section = msg->section_head;
+        if (!section) {
+          section = pn_section(msg);
+        }
+        pn_data_t *data = section->data;
+        section->data = msg->data;
+        msg->data = data;
+      }
+      break;
     }
   }
 
   return pn_data_clear(msg->data);
 }
 
+int pn_section_encode(pn_section_t *section, char *data, size_t *size);
+
 int pn_message_encode(pn_message_t *msg, pn_format_t format, char *bytes, size_t *size)
 {
   if (!msg || format != PN_AMQP || !bytes || !size || !*size) return PN_ARG_ERR;
@@ -460,5 +510,126 @@ int pn_message_encode(pn_message_t *msg,
                      pn_buffer_str(msg->reply_to_group_id));
   if (err) return err;
 
-  return pn_data_encode(msg->data, bytes, size);
+  size_t remaining = *size;
+  size_t encoded = remaining;
+
+  err = pn_data_encode(msg->data, bytes, &encoded);
+  if (err) return err;
+
+  bytes += encoded;
+  remaining -= encoded;
+
+  pn_section_t *section = msg->section_head;
+  while (section) {
+    encoded = remaining;
+    err = pn_section_encode(section, bytes, &encoded);
+    if (err) return err;
+    bytes += encoded;
+    remaining -= encoded;
+    section = section->section_next;
+  }
+
+  *size -= remaining;
+
+  return 0;
+}
+
+pn_section_t *pn_section(pn_message_t *message)
+{
+  pn_section_t *section = malloc(sizeof(pn_section_t));
+  if (!section) return section;
+  section->message = message;
+  LL_ADD(message, section, section);
+  section->format = PN_AMQP;
+  section->data = NULL;
+  return section;
+}
+
+void pn_section_free(pn_section_t *section)
+{
+  if (section) {
+    LL_REMOVE(section->message, section, section);
+    free(section);
+  }
+}
+
+void pn_section_clear(pn_section_t *section)
+{
+  if (!section) return;
+
+  if (section->data) {
+    pn_data_clear(section->data);
+  }
+}
+
+const char *pn_section_error(pn_section_t *section)
+{
+  if (section) {
+    return pn_message_error(section->message);
+  } else {
+    return NULL;
+  }
+}
+
+pn_format_t pn_section_get_format(pn_section_t *section)
+{
+  return section ? section->format : PN_AMQP;
+}
+
+int pn_section_set_format(pn_section_t *section, pn_format_t format)
+{
+  if (!section) return PN_ARG_ERR;
+
+  section->format = format;
+  return 0;
+}
+
+int pn_section_load(pn_section_t *section, const char *data)
+{
+  if (!section) return PN_ARG_ERR;
+
+  if (!section->data) {
+    section->data = pn_data(16);
+  }
+
+  pn_parser_t *parser = pn_message_parser(section->message);
+
+  while (true) {
+    pn_data_clear(section->data);
+    pn_atoms_t atoms = pn_data_available(section->data);
+    int err = pn_parser_parse(parser, data, &atoms);
+    if (err == PN_OVERFLOW) {
+      err = pn_data_grow(section->data);
+      if (err) return err;
+      continue;
+    } else if (err) {
+      return err;
+    } else {
+      return pn_data_resize(section->data, atoms.size);
+    }
+  }
+}
+
+int pn_section_save(pn_section_t *section, char *data, size_t *size)
+{
+  if (!section) return PN_ARG_ERR;
+
+  if (!section->data) {
+    *size = 0;
+    return 0;
+  }
+
+  return pn_data_format(section->data, data, size);
+}
+
+int pn_section_encode(pn_section_t *section, char *data, size_t *size)
+{
+  if (!section || !data || !size || !*size) return PN_ARG_ERR;
+
+  if (!section->data) {
+    *size = 0;
+    return 0;
+  }
+
+  return pn_data_encode(section->data, data, size);
 }

Added: qpid/proton/trunk/proton-c/src/parser.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/parser.c?rev=1351532&view=auto
==============================================================================
--- qpid/proton/trunk/proton-c/src/parser.c (added)
+++ qpid/proton/trunk/proton-c/src/parser.c Mon Jun 18 23:33:37 2012
@@ -0,0 +1,430 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <proton/parser.h>
+#include <proton/scanner.h>
+#include <proton/errors.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+struct pn_parser_t {
+  pn_scanner_t *scanner;
+  int error_code;
+  char *atoms;
+  size_t size;
+  size_t capacity;
+};
+
+pn_parser_t *pn_parser()
+{
+  pn_parser_t *parser = malloc(sizeof(pn_parser_t));
+  parser->scanner = pn_scanner();
+  parser->atoms = NULL;
+  parser->size = 0;
+  parser->capacity = 0;
+  return parser;
+}
+
+void pn_parser_ensure(pn_parser_t *parser, size_t size)
+{
+  while (parser->capacity - parser->size < size) {
+    parser->capacity = parser->capacity ? 2 * parser->capacity : 1024;
+    parser->atoms = realloc(parser->atoms, parser->capacity);
+  }
+}
+
+void pn_parser_line_info(pn_parser_t *parser, int *line, int *col)
+{
+  pn_scanner_line_info(parser->scanner, line, col);
+}
+
+int pn_parser_err(pn_parser_t *parser, int code, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  int err = pn_scanner_verr(parser->scanner, code, fmt, ap);
+  va_end(ap);
+  return err;
+}
+
+int pn_parser_errno(pn_parser_t *parser)
+{
+  return pn_scanner_errno(parser->scanner);
+}
+
+const char *pn_parser_error(pn_parser_t *parser)
+{
+  return pn_scanner_error(parser->scanner);
+}
+
+void pn_parser_free(pn_parser_t *parser)
+{
+  if (parser) {
+    pn_scanner_free(parser->scanner);
+    free(parser->atoms);
+    free(parser);
+  }
+}
+
+int pn_parser_shift(pn_parser_t *parser)
+{
+  return pn_scanner_shift(parser->scanner);
+}
+
+pn_token_t pn_parser_token(pn_parser_t *parser)
+{
+  return pn_scanner_token(parser->scanner);
+}
+
+int pn_parser_value(pn_parser_t *parser, pn_atoms_t *atoms);
+
+int pn_parser_descriptor(pn_parser_t *parser, pn_atoms_t *atoms)
+{
+  if (pn_parser_token(parser).type == PN_TOK_AT) {
+    int err = pn_parser_shift(parser);
+    if (err) return err;
+
+    pn_atom_t *desc = atoms->start;
+    err = pn_ifill_atoms(atoms, "n");
+    if (err) return pn_parser_err(parser, err,
+                                  "error writing descriptor atoms");
+    desc->type = PN_DESCRIPTOR;
+    err = pn_parser_value(parser, atoms);
+    if (err) return err;
+    return pn_parser_value(parser, atoms);
+  } else {
+    return pn_parser_err(parser, PN_ERR, "expecting '@'");
+  }
+}
+
+int pn_parser_map(pn_parser_t *parser, pn_atoms_t *atoms)
+{
+  if (pn_parser_token(parser).type == PN_TOK_LBRACE) {
+    int err = pn_parser_shift(parser);
+    if (err) return err;
+
+    pn_atom_t *map = atoms->start;
+    err = pn_ifill_atoms(atoms, "{}");
+    if (err) return pn_parser_err(parser, err, "error writing map atoms");
+
+    int count = 0;
+
+    if (pn_parser_token(parser).type != PN_TOK_RBRACE) {
+      while (true) {
+        err = pn_parser_value(parser, atoms);
+        if (err) return err;
+        count++;
+
+        if (pn_parser_token(parser).type == PN_TOK_EQUAL) {
+          err = pn_parser_shift(parser);
+          if (err) return err;
+        } else {
+          return pn_parser_err(parser, PN_ERR, "expecting '='");
+        }
+
+        err = pn_parser_value(parser, atoms);
+        if (err) return err;
+        count++;
+
+        if (pn_parser_token(parser).type == PN_TOK_COMMA) {
+          err = pn_parser_shift(parser);
+          if (err) return err;
+        } else {
+          break;
+        }
+      }
+    }
+
+    map->u.count = count;
+
+    if (pn_parser_token(parser).type == PN_TOK_RBRACE) {
+      return pn_parser_shift(parser);
+    } else {
+      return pn_parser_err(parser, PN_ERR, "expecting '}'");
+    }
+  } else {
+    return pn_parser_err(parser, PN_ERR, "expecting '{'");
+  }
+}
+
+int pn_parser_list(pn_parser_t *parser, pn_atoms_t *atoms)
+{
+  int err;
+
+  if (pn_parser_token(parser).type == PN_TOK_LBRACKET) {
+    err = pn_parser_shift(parser);
+    if (err) return err;
+
+    pn_atom_t *list = atoms->start;
+    int err = pn_ifill_atoms(atoms, "[]");
+    if (err) return pn_parser_err(parser, err, "error writing list atoms");
+
+    int count = 0;
+
+    if (pn_parser_token(parser).type != PN_TOK_RBRACKET) {
+      while (true) {
+        err = pn_parser_value(parser, atoms);
+        if (err) return err;
+        count++;
+
+        if (pn_parser_token(parser).type == PN_TOK_COMMA) {
+          err = pn_parser_shift(parser);
+          if (err) return err;
+        } else {
+          break;
+        }
+      }
+    }
+
+    list->u.count = count;
+
+    if (pn_parser_token(parser).type == PN_TOK_RBRACKET) {
+      return pn_parser_shift(parser);
+    } else {
+      return pn_parser_err(parser, PN_ERR, "expecting ']'");
+    }
+  } else {
+    return pn_parser_err(parser, PN_ERR, "expecting '['");
+  }
+}
+
+void pn_parser_append_tok(pn_parser_t *parser, char *dst, int *idx)
+{
+  memcpy(dst + *idx, pn_parser_token(parser).start, pn_parser_token(parser).size);
+  *idx += pn_parser_token(parser).size;
+}
+
+int pn_parser_number(pn_parser_t *parser, pn_atoms_t *atoms)
+{
+  bool dbl = false;
+  char number[1024];
+  int idx = 0;
+  int err;
+
+  bool negate = false;
+
+  if (pn_parser_token(parser).type == PN_TOK_NEG || pn_parser_token(parser).type == PN_TOK_POS) {
+    if (pn_parser_token(parser).type == PN_TOK_NEG)
+      negate = !negate;
+    err = pn_parser_shift(parser);
+    if (err) return err;
+  }
+
+  if (pn_parser_token(parser).type == PN_TOK_FLOAT || pn_parser_token(parser).type == PN_TOK_INT) {
+    dbl = pn_parser_token(parser).type == PN_TOK_FLOAT;
+    pn_parser_append_tok(parser, number, &idx);
+    err = pn_parser_shift(parser);
+    if (err) return err;
+  } else {
+    return pn_parser_err(parser, PN_ERR, "expecting FLOAT or INT");
+  }
+
+  number[idx] = '\0';
+
+  if (dbl) {
+    double value = atof(number);
+    if (negate) {
+      value = -value;
+    }
+    err = pn_ifill_atoms(atoms, "d", value);
+    if (err) return pn_parser_err(parser, err, "error writing double atoms");
+  } else {
+    int64_t value = atoll(number);
+    if (negate) {
+      value = -value;
+    }
+    err = pn_ifill_atoms(atoms, "l", value);
+    if (err) return pn_parser_err(parser, err, "error writing long atoms");
+  }
+
+  return 0;
+}
+
+int pn_parser_unquote(pn_parser_t *parser, char *dst, const char *src, size_t *n)
+{
+  size_t idx = 0;
+  bool escape = false;
+  int start, end;
+  if (src[0] != '"') {
+    if (src[1] == '"') {
+      start = 2;
+      end = *n - 1;
+    } else {
+      start = 1;
+      end = *n;
+    }
+  } else {
+    start = 1;
+    end = *n - 1;
+  }
+  for (int i = start; i < end; i++)
+  {
+    char c = src[i];
+    if (escape) {
+      switch (c) {
+      case '"':
+      case '\\':
+      case '/':
+        dst[idx++] = c;
+        escape = false;
+        break;
+      case 'b':
+        dst[idx++] = '\b';
+        break;
+      case 'f':
+        dst[idx++] = '\f';
+        break;
+      case 'n':
+        dst[idx++] = '\n';
+        break;
+      case 'r':
+        dst[idx++] = '\r';
+        break;
+      case 't':
+        dst[idx++] = '\t';
+        break;
+      case 'x':
+        {
+          char n1 = toupper(src[i+1]);
+          char n2 = n1 ? toupper(src[i+2]) : 0;
+          if (!n2) {
+            return pn_parser_err(parser, PN_ERR, "truncated escape code");
+          }
+          int d1 = isdigit(n1) ? n1 - '0' : n1 - 'A' + 10;
+          int d2 = isdigit(n2) ? n2 - '0' : n2 - 'A' + 10;
+          dst[idx++] = d1*16 + d2;
+          i += 2;
+        }
+        break;
+      // XXX: need to handle unicode escapes: 'u'
+      default:
+        return pn_parser_err(parser, PN_ERR, "unrecognized escape code");
+      }
+      escape = false;
+    } else {
+      switch (c)
+      {
+      case '\\':
+        escape = true;
+        break;
+      default:
+        dst[idx++] = c;
+        break;
+      }
+    }
+  }
+  dst[idx++] = '\0';
+  *n = idx;
+  return 0;
+}
+
+int pn_parser_value(pn_parser_t *parser, pn_atoms_t *atoms)
+{
+  int err;
+  size_t n;
+  char *dst;
+
+  pn_token_t tok = pn_parser_token(parser);
+
+  switch (tok.type)
+  {
+  case PN_TOK_AT:
+    return pn_parser_descriptor(parser, atoms);
+  case PN_TOK_LBRACE:
+    return pn_parser_map(parser, atoms);
+  case PN_TOK_LBRACKET:
+    return pn_parser_list(parser, atoms);
+  case PN_TOK_BINARY:
+  case PN_TOK_SYMBOL:
+  case PN_TOK_STRING:
+    n = tok.size;
+    pn_parser_ensure(parser, n);
+    dst = parser->atoms + parser->size;
+    err = pn_parser_unquote(parser, dst, tok.start, &n);
+    if (err) return err;
+    parser->size += n;
+    switch (tok.type) {
+    case PN_TOK_BINARY:
+      err = pn_ifill_atoms(atoms, "z", n - 1, dst);
+      break;
+    case PN_TOK_STRING:
+      err = pn_ifill_atoms(atoms, "S", dst);
+      break;
+    case PN_TOK_SYMBOL:
+      err = pn_ifill_atoms(atoms, "s", dst);
+      break;
+    default:
+      return pn_parser_err(parser, PN_ERR, "internal error");
+    }
+    if (err) return pn_parser_err(parser, err, "error writing string atoms");
+    return pn_parser_shift(parser);
+  case PN_TOK_POS:
+  case PN_TOK_NEG:
+  case PN_TOK_FLOAT:
+  case PN_TOK_INT:
+    return pn_parser_number(parser, atoms);
+  case PN_TOK_TRUE:
+    err = pn_ifill_atoms(atoms, "o", true);
+    if (err) return pn_parser_err(parser, err, "error writing boolean atoms");
+    return pn_parser_shift(parser);
+  case PN_TOK_FALSE:
+    err = pn_ifill_atoms(atoms, "o", false);
+    if (err) return pn_parser_err(parser, err, "error writing boolean atoms");
+    return pn_parser_shift(parser);
+  case PN_TOK_NULL:
+    err = pn_ifill_atoms(atoms, "n");
+    if (err) return pn_parser_err(parser, err, "error writing null atoms");
+    return pn_parser_shift(parser);
+  default:
+    return pn_parser_err(parser, PN_ERR, "expecting one of '[', '{', STRING, "
+                         "SYMBOL, BINARY, true, false, null, NUMBER");
+  }
+}
+
+int pn_parser_parse_r(pn_parser_t *parser, pn_atoms_t *atoms)
+{
+  while (true) {
+    int err;
+    switch (pn_parser_token(parser).type)
+    {
+    case PN_TOK_EOS:
+      return 0;
+    case PN_TOK_ERR:
+      return PN_ERR;
+    default:
+      err = pn_parser_value(parser, atoms);
+      if (err) return err;
+    }
+  }
+}
+
+int pn_parser_parse(pn_parser_t *parser, const char *str, pn_atoms_t *atoms)
+{
+  pn_atoms_t copy = *atoms;
+  int err = pn_scanner_start(parser->scanner, str);
+  if (err) return err;
+  parser->size = 0;
+  err = pn_parser_parse_r(parser, &copy);
+  if (err) return err;
+  atoms->size -= copy.size;
+  return 0;
+}

Modified: qpid/proton/trunk/proton-c/src/proton.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/proton.c?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/proton.c (original)
+++ qpid/proton/trunk/proton-c/src/proton.c Mon Jun 18 23:33:37 2012
@@ -31,6 +31,7 @@
 #include "pn_config.h"
 #include <proton/codec.h>
 #include <proton/buffer.h>
+#include <proton/parser.h>
 #include <inttypes.h>
 #include "protocol.h"
 
@@ -144,31 +145,31 @@ int value(int argc, char **argv)
 
   printf("JSON: %s\n", str);
 
-  pn_atom_t jsondata[1024];
-  pn_atoms_t jsond = {1024, jsondata};
+  pn_atom_t parserdata[1024];
+  pn_atoms_t parserd = {1024, parserdata};
 
   printf("\n");
 
-  pn_json_t *json = pn_json();
+  pn_parser_t *parser = pn_parser();
 
-  err = pn_json_parse(json, str, &jsond);
+  err = pn_parser_parse(parser, str, &parserd);
   if (err) {
-    printf("parse err=%s, %s\n", pn_error(err), pn_json_error_str(json));
+    printf("parse err=%s, %s\n", pn_error(err), pn_parser_error(parser));
   } else {
     printf("--\n");
-    for (int i = 0; i < jsond.size; i++) {
-      printf("%s: ", pn_type_str(jsond.start[i].type));
-      err = pn_print_atom(jsond.start[i]);
+    for (int i = 0; i < parserd.size; i++) {
+      printf("%s: ", pn_type_str(parserd.start[i].type));
+      err = pn_print_atom(parserd.start[i]);
       if (err) printf("err=%s", pn_error(err));
       printf("\n");
     }
     printf("--\n");
-    err = pn_print_atoms(&jsond);
+    err = pn_print_atoms(&parserd);
     if (err) printf("print err=%s", pn_error(err));
     printf("\n");
   }
 
-  pn_json_free(json);
+  pn_parser_free(parser);
 
   return 0;
 }

Added: qpid/proton/trunk/proton-c/src/scanner.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/scanner.c?rev=1351532&view=auto
==============================================================================
--- qpid/proton/trunk/proton-c/src/scanner.c (added)
+++ qpid/proton/trunk/proton-c/src/scanner.c Mon Jun 18 23:33:37 2012
@@ -0,0 +1,397 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <proton/scanner.h>
+#include <proton/errors.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+#define ERROR_SIZE (1024)
+
+struct pn_scanner_t {
+  const char *input;
+  const char *position;
+  pn_token_t token;
+  char *atoms;
+  size_t size;
+  size_t capacity;
+  int errno;
+  char error[ERROR_SIZE];
+};
+
+const char *pn_token_type(pn_token_type_t type)
+{
+  switch (type)
+  {
+  case PN_TOK_LBRACE: return "LBRACE";
+  case PN_TOK_RBRACE: return "RBRACE";
+  case PN_TOK_LBRACKET: return "LBRACKET";
+  case PN_TOK_RBRACKET: return "RBRACKET";
+  case PN_TOK_EQUAL: return "EQUAL";
+  case PN_TOK_COMMA: return "COMMA";
+  case PN_TOK_POS: return "POS";
+  case PN_TOK_NEG: return "NEG";
+  case PN_TOK_DOT: return "DOT";
+  case PN_TOK_AT: return "AT";
+  case PN_TOK_DOLLAR: return "DOLLAR";
+  case PN_TOK_BINARY: return "BINARY";
+  case PN_TOK_STRING: return "STRING";
+  case PN_TOK_SYMBOL: return "SYMBOL";
+  case PN_TOK_ID: return "ID";
+  case PN_TOK_FLOAT: return "FLOAT";
+  case PN_TOK_INT: return "INT";
+  case PN_TOK_TRUE: return "TRUE";
+  case PN_TOK_FALSE: return "FALSE";
+  case PN_TOK_NULL: return "NULL";
+  case PN_TOK_EOS: return "EOS";
+  case PN_TOK_ERR: return "ERR";
+  default: return "<UNKNOWN>";
+  }
+}
+
+pn_scanner_t *pn_scanner()
+{
+  pn_scanner_t *scanner = malloc(sizeof(pn_scanner_t));
+  if (scanner) {
+    scanner->input = NULL;
+    scanner->errno = 0;
+    scanner->error[0] = '\0';
+  }
+  return scanner;
+}
+
+void pn_scanner_free(pn_scanner_t *scanner)
+{
+  free(scanner);
+}
+
+pn_token_t pn_scanner_token(pn_scanner_t *scanner)
+{
+  if (scanner) {
+    return scanner->token;
+  } else {
+    return (pn_token_t) {PN_TOK_ERR};
+  }
+}
+
+void pn_scanner_line_info(pn_scanner_t *scanner, int *line, int *col)
+{
+  *line = 1;
+  *col = 0;
+
+  for (const char *c = scanner->input; *c && c <= scanner->token.start; c++) {
+    if (*c == '\n') {
+      *line += 1;
+      *col = -1;
+    } else {
+      *col += 1;
+    }
+  }
+}
+
+int pn_scanner_err(pn_scanner_t *scanner, int code, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  int err = pn_scanner_verr(scanner, code, fmt, ap);
+  va_end(ap);
+  return err;
+}
+
+int pn_scanner_verr(pn_scanner_t *scanner, int code, const char *fmt, va_list ap)
+{
+  scanner->errno = code;
+
+  int line, col;
+  pn_scanner_line_info(scanner, &line, &col);
+  int size = scanner->token.size;
+  int ln = snprintf(scanner->error, ERROR_SIZE,
+                    "input line %i column %i %s:'%.*s': ", line, col,
+                    pn_token_type(scanner->token.type),
+                    size, scanner->token.start);
+  if (ln >= ERROR_SIZE) {
+    return pn_scanner_err(scanner, code, "error info truncated");
+  } else if (ln < 0) {
+    scanner->error[0] = '\0';
+  }
+
+  int n = snprintf(scanner->error + ln, ERROR_SIZE - ln, fmt, ap);
+
+  if (n >= ERROR_SIZE - ln) {
+    return pn_scanner_err(scanner, code, "error info truncated");
+  } else if (n < 0) {
+    scanner->error[0] = '\0';
+  }
+
+  return code;
+}
+
+int pn_scanner_errno(pn_scanner_t *scanner)
+{
+  return scanner->errno;
+}
+
+const char *pn_scanner_error(pn_scanner_t *scanner)
+{
+  if (scanner->errno) {
+    return scanner->error;
+  } else {
+    return NULL;
+  }
+}
+
+void pn_scanner_emit(pn_scanner_t *scanner, pn_token_type_t type, const char *start, size_t size)
+{
+  scanner->token.type = type;
+  scanner->token.start = start;
+  scanner->token.size = size;
+}
+
+int pn_scanner_quoted(pn_scanner_t *scanner, const char *str, int start,
+                      pn_token_type_t type)
+{
+  bool escape = false;
+
+  for (int i = start; true; i++) {
+    char c = str[i];
+    if (escape) {
+      escape = false;
+    } else {
+      switch (c) {
+      case '\0':
+      case '"':
+        pn_scanner_emit(scanner, c ? type : PN_TOK_ERR,
+                        str, c ? i + 1 : i);
+        return c ? 0 : pn_scanner_err(scanner, PN_ERR, "missmatched quote");
+      case '\\':
+        escape = true;
+        break;
+      }
+    }
+  }
+}
+
+int pn_scanner_binary(pn_scanner_t *scanner, const char *str)
+{
+  return pn_scanner_quoted(scanner, str, 2, PN_TOK_BINARY);
+}
+
+int pn_scanner_string(pn_scanner_t *scanner, const char *str)
+{
+  return pn_scanner_quoted(scanner, str, 1, PN_TOK_STRING);
+}
+
+int pn_scanner_alpha_end(pn_scanner_t *scanner, const char *str, int start)
+{
+  for (int i = start; true; i++) {
+    char c = str[i];
+    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
+      return i;
+    }
+  }
+}
+
+int pn_scanner_alpha(pn_scanner_t *scanner, const char *str)
+{
+  int n = pn_scanner_alpha_end(scanner, str, 0);
+  pn_token_type_t type;
+  if (!strncmp(str, "true", n)) {
+    type = PN_TOK_TRUE;
+  } else if (!strncmp(str, "false", n)) {
+    type = PN_TOK_FALSE;
+  } else if (!strncmp(str, "null", n)) {
+    type = PN_TOK_NULL;
+  } else {
+    type = PN_TOK_ID;
+  }
+
+  pn_scanner_emit(scanner, type, str, n);
+  return type == PN_TOK_ERR ? pn_scanner_err(scanner, PN_ERR, "unrecognized keyword") : 0;
+}
+
+int pn_scanner_symbol(pn_scanner_t *scanner, const char *str)
+{
+  char c = str[1];
+
+  if (c == '"') {
+    return pn_scanner_quoted(scanner, str, 2, PN_TOK_SYMBOL);
+  } else {
+    int n = pn_scanner_alpha_end(scanner, str, 1);
+    pn_scanner_emit(scanner, PN_TOK_SYMBOL, str, n);
+    return 0;
+  }
+}
+
+int pn_scanner_number(pn_scanner_t *scanner, const char *str)
+{
+  bool dot = false;
+  bool exp = false;
+
+  int i = 0;
+
+  if (str[i] == '+' || str[i] == '-') {
+    i++;
+  }
+
+  for ( ; true; i++) {
+    char c = str[i];
+    switch (c) {
+    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+    case '7': case '8': case '9':
+      continue;
+    case '.':
+      if (dot) {
+        pn_scanner_emit(scanner, PN_TOK_FLOAT, str, i);
+        return 0;
+      } else {
+        dot = true;
+      }
+      continue;
+    case 'e':
+    case 'E':
+      if (exp) {
+        pn_scanner_emit(scanner, PN_TOK_FLOAT, str, i);
+        return 0;
+      } else {
+        dot = true;
+        exp = true;
+        if (str[i+1] == '+' || str[i+1] == '-') {
+          i++;
+        }
+        continue;
+      }
+    default:
+      if (dot || exp) {
+        pn_scanner_emit(scanner, PN_TOK_FLOAT, str, i);
+        return 0;
+      } else {
+        pn_scanner_emit(scanner, PN_TOK_INT, str, i);
+        return 0;
+      }
+    }
+  }
+}
+
+int pn_scanner_single(pn_scanner_t *scanner, const char *str, pn_token_type_t type)
+{
+  pn_scanner_emit(scanner, type, str, 1);
+  return 0;
+}
+
+int pn_scanner_start(pn_scanner_t *scanner, const char *input)
+{
+  if (!scanner || !input) return PN_ARG_ERR;
+  scanner->input = input;
+  scanner->position = input;
+  return pn_scanner_scan(scanner);
+}
+
+int pn_scanner_scan(pn_scanner_t *scanner)
+{
+  const char *str = scanner->position;
+  char n;
+
+  for (char c; true; str++) {
+    c = *str;
+    switch (c)
+    {
+    case '{':
+      return pn_scanner_single(scanner, str, PN_TOK_LBRACE);
+    case '}':
+      return pn_scanner_single(scanner, str, PN_TOK_RBRACE);
+    case'[':
+      return pn_scanner_single(scanner, str, PN_TOK_LBRACKET);
+    case ']':
+      return pn_scanner_single(scanner, str, PN_TOK_RBRACKET);
+    case '=':
+      return pn_scanner_single(scanner, str, PN_TOK_EQUAL);
+    case ',':
+      return pn_scanner_single(scanner, str, PN_TOK_COMMA);
+    case '.':
+      n = *(str+1);
+      if ((n >= '0' && n <= '9')) {
+        return pn_scanner_number(scanner, str);
+      } else {
+        return pn_scanner_single(scanner, str, PN_TOK_DOT);
+      }
+    case '@':
+      return pn_scanner_single(scanner, str, PN_TOK_AT);
+    case '$':
+      return pn_scanner_single(scanner, str, PN_TOK_DOLLAR);
+    case '-':
+      n = *(str+1);
+      if ((n >= '0' && n <= '9') || n == '.') {
+        return pn_scanner_number(scanner, str);
+      } else {
+        return pn_scanner_single(scanner, str, PN_TOK_NEG);
+      }
+    case '+':
+      n = *(str+1);
+      if ((n >= '0' && n <= '9') || n == '.') {
+        return pn_scanner_number(scanner, str);
+      } else {
+        return pn_scanner_single(scanner, str, PN_TOK_POS);
+      }
+    case ' ': case '\t': case '\r': case '\v': case '\f': case '\n':
+      break;
+    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+    case '7': case '8': case '9':
+      return pn_scanner_number(scanner, str);
+    case ':':
+      return pn_scanner_symbol(scanner, str);
+    case '"':
+      return pn_scanner_string(scanner, str);
+    case 'b':
+      if (str[1] == '"') {
+        return pn_scanner_binary(scanner, str);
+      }
+    case 'a': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
+    case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o':
+    case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v':
+    case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C':
+    case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J':
+    case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q':
+    case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+      return pn_scanner_alpha(scanner, str);
+    case '\0':
+      pn_scanner_emit(scanner, PN_TOK_EOS, str, 0);
+      return PN_EOS;
+    default:
+      pn_scanner_emit(scanner, PN_TOK_ERR, str, 1);
+      return pn_scanner_err(scanner, PN_ERR, "illegal character");
+    }
+  }
+}
+
+int pn_scanner_shift(pn_scanner_t *scanner)
+{
+  scanner->position = scanner->token.start + scanner->token.size;
+  int err = pn_scanner_scan(scanner);
+  if (err == PN_EOS) {
+    return 0;
+  } else {
+    return err;
+  }
+}

Modified: qpid/proton/trunk/proton-c/src/util.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/util.c?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/util.c (original)
+++ qpid/proton/trunk/proton-c/src/util.c Mon Jun 18 23:33:37 2012
@@ -44,8 +44,7 @@ ssize_t pn_quote_data(char *dst, size_t 
       }
     } else {
       if (idx < capacity - 4) {
-        sprintf(dst + idx, "\\x%.2x", c);
-        idx += 4;
+        idx += sprintf(dst + idx, "\\x%.2x", c);
       } else {
         return PN_OVERFLOW;
       }

Modified: qpid/proton/trunk/proton-c/src/util.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/util.h?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/util.h (original)
+++ qpid/proton/trunk/proton-c/src/util.h Mon Jun 18 23:33:37 2012
@@ -52,40 +52,39 @@ bool pn_env_bool(const char *name);
     }                                                                   \
   } while (0)
 
-#define __EMPTY__next next
-#define __EMPTY__prev prev
-#define LL_ADD(HEAD, TAIL, NODE) LL_ADD_PFX(HEAD, TAIL, NODE, __EMPTY__)
-#define LL_ADD_PFX(HEAD, TAIL, NODE, PFX)    \
-  {                                          \
-    (NODE)-> PFX ## next = NULL;             \
-    (NODE)-> PFX ## prev = (TAIL);           \
-    if (TAIL) (TAIL)-> PFX ## next = (NODE); \
-    (TAIL) = (NODE);                         \
-    if (!(HEAD)) (HEAD) = NODE;              \
-  }
 
-#define LL_POP(HEAD, TAIL) LL_POP_PFX(HEAD, TAIL, __EMPTY__)
-#define LL_POP_PFX(HEAD, TAIL, PFX)  \
-  {                                  \
-    if (HEAD) {                      \
-      void *_head = (HEAD);          \
-      (HEAD) = (HEAD)-> PFX ## next; \
-      if (_head == (TAIL))           \
-        (TAIL) = NULL;               \
-    }                                \
+#define LL_HEAD(ROOT, LIST) ((ROOT)-> LIST ## _head)
+#define LL_TAIL(ROOT, LIST) ((ROOT)-> LIST ## _tail)
+#define LL_ADD(ROOT, LIST, NODE)                              \
+  {                                                           \
+    (NODE)-> LIST ## _next = NULL;                            \
+    (NODE)-> LIST ## _prev = (ROOT)-> LIST ## _tail;          \
+    if (LL_TAIL(ROOT, LIST))                                  \
+      LL_TAIL(ROOT, LIST)-> LIST ## _next = (NODE);           \
+    LL_TAIL(ROOT, LIST) = (NODE);                             \
+    if (!LL_HEAD(ROOT, LIST)) LL_HEAD(ROOT, LIST) = (NODE);   \
   }
 
-#define LL_REMOVE(HEAD, TAIL, NODE) LL_REMOVE_PFX(HEAD, TAIL, NODE, __EMPTY__)
-#define LL_REMOVE_PFX(HEAD, TAIL, NODE, PFX)                     \
+#define LL_POP(ROOT, LIST)                                       \
   {                                                              \
-    if ((NODE)-> PFX ## prev)                                    \
-      (NODE)-> PFX ## prev-> PFX ## next = (NODE)-> PFX ## next; \
-    if ((NODE)-> PFX ## next)                                    \
-      (NODE)-> PFX ## next-> PFX ## prev = (NODE)-> PFX ## prev; \
-    if ((NODE) == (HEAD))                                        \
-      (HEAD) = (NODE)-> PFX ## next;                             \
-    if ((NODE) == (TAIL))                                        \
-      (TAIL) = (NODE)-> PFX ## prev;                             \
+    if (LL_HEAD(ROOT, LIST)) {                                   \
+      void *_head = LL_HEAD(ROOT, LIST);                         \
+      LL_HEAD(ROOT, LIST) = LL_HEAD(ROOT, LIST)-> LIST ## _next; \
+      if (_head == LL_TAIL(ROOT, LIST))                          \
+        LL_TAIL(ROOT, LIST) = NULL;                              \
+    }                                                            \
+  }
+
+#define LL_REMOVE(ROOT, LIST, NODE)                                    \
+  {                                                                    \
+    if ((NODE)-> LIST ## _prev)                                        \
+      (NODE)-> LIST ## _prev-> LIST ## _next = (NODE)-> LIST ## _next; \
+    if ((NODE)-> LIST ## _next)                                        \
+      (NODE)-> LIST ## _next-> LIST ## _prev = (NODE)-> LIST ## _prev; \
+    if ((NODE) == LL_HEAD(ROOT, LIST))                                 \
+      LL_HEAD(ROOT, LIST) = (NODE)-> LIST ## _next;                    \
+    if ((NODE) == LL_TAIL(ROOT, LIST))                                 \
+      LL_TAIL(ROOT, LIST) = (NODE)-> LIST ## _prev;                    \
   }
 
 char *pn_strdup(const char *src);

Modified: qpid/proton/trunk/tests/proton_tests/message.py
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/tests/proton_tests/message.py?rev=1351532&r1=1351531&r2=1351532&view=diff
==============================================================================
--- qpid/proton/trunk/tests/proton_tests/message.py (original)
+++ qpid/proton/trunk/tests/proton_tests/message.py Mon Jun 18 23:33:37 2012
@@ -108,15 +108,62 @@ class CodecTest(Test):
     assert not pn_message_set_priority(self.msg, 100)
     assert not pn_message_set_address(self.msg, "address")
     assert not pn_message_set_subject(self.msg, "subject")
+    section = pn_section(self.msg)
+    body = '"test body"'
+    assert section
+    rc = pn_section_load(section, body)
+    assert not rc, rc
 
     cd, data = pn_message_encode(self.msg, PN_AMQP, 1024)
     assert cd == 0, cd
 
     msg2 = pn_message()
     cd = pn_message_decode(msg2, PN_AMQP, data, len(data))
-    assert cd == 0, cd
+    assert cd == 0, (cd, data)
 
     assert pn_message_get_ttl(self.msg) == pn_message_get_ttl(msg2)
     assert pn_message_get_priority(self.msg) == pn_message_get_priority(msg2)
     assert pn_message_get_address(self.msg) == pn_message_get_address(msg2)
     assert pn_message_get_subject(self.msg) == pn_message_get_subject(msg2)
+    cd, saved = pn_section_save(section, 1024)
+    assert not cd, cd
+    assert saved == body, (body, saved)
+
+class SectionTest(Test):
+
+  def _test(self, *bodies):
+    section = pn_section(self.msg)
+    for body in bodies:
+      pn_section_clear(section)
+      cd, saved = pn_section_save(section, 1024)
+      assert  (cd, saved) == (0, ""), (cd, saved)
+      err = pn_section_load(section, body)
+      assert err == 0, (pn_section_error(section), repr(body))
+      cd, saved = pn_section_save(section, 1024)
+      assert cd >= 0, (cd, pn_section_error(section))
+      assert saved == body, (body, saved)
+
+  def testIntegral(self):
+    self._test("0", "1", "-1", "9223372036854775807")
+
+  def testFloating(self):
+    self._test("1.1", "3.14159", "-3.14159", "-1.1")
+
+  def testSymbol(self):
+    self._test(':symbol', ':"quoted symbol"')
+
+  def testString(self):
+    self._test('"string"', '"string with spaces"')
+
+  def testBinary(self):
+    self._test('b"binary"', 'b"binary with spaces and special values: \\x00\\x01\\x02"')
+
+  def testMap(self):
+    self._test('{"one"=1, :two=2, :pi=3.14159}', '{[1, 2, 3]=[3, 2, 1], {1=2}={3=4}}')
+
+  def testList(self):
+    self._test('[1, 2, 3]', '["one", "two", "three"]', '[:one, 2, 3.14159]',
+               '[{1=2}, {3=4}, {5=6}]')
+
+  def testDescriptor(self):
+    self._test('@21 ["one", 2, "three", @:url "http://example.org"]')



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


Mime
View raw message