[esnacc-dev] [PATCH v3] iomanip: Add an IO Manipulator for C++

Aaron Conole aconole at bytheb.org
Tue Sep 27 14:28:35 UTC 2016


This patch starts on a series adding IO Manipulators for C++ support.
Currently, Print(), and BEnc() are supported.  A future commit will add
support for input streams.

As new Encode/Decode rules are added, it is expected that additional
manipulators will be created to make convenient IO routines.

Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
v1->v2:
* include missing header file

v2->v3:
* include missing automake
* update the automatic tests to assert error

 cxx-examples/src/automatic.cpp |  8 +++++--
 cxx-examples/src/main.cpp      |  1 +
 cxx-lib/automake.mk            |  1 +
 cxx-lib/inc/asn-incl.h         | 13 ++++++-----
 cxx-lib/inc/asn-iomanip.h      | 52 ++++++++++++++++++++++++++++++++++++++++++
 cxx-lib/src/print.cpp          | 23 ++++++++++++++++---
 6 files changed, 87 insertions(+), 11 deletions(-)
 create mode 100644 cxx-lib/inc/asn-iomanip.h

diff --git a/cxx-examples/src/automatic.cpp b/cxx-examples/src/automatic.cpp
index b35f5aa..7c08b91 100644
--- a/cxx-examples/src/automatic.cpp
+++ b/cxx-examples/src/automatic.cpp
@@ -1,4 +1,5 @@
 #include "autotags.h"
+#include <sstream>
 
 static SNACC::Human *
 getHuman(const char *name, int age, bool isBiblical,
@@ -102,10 +103,13 @@ int automaticTests()
             return 1;
         }
 
-        SNACC::AsnBuf benc;
         SNACC::AsnBuf expected((const char *)(t[i].bytes), t[i].byte_len);
         try {
-            h.BEnc(benc);
+            std::stringstream s;
+            s << SNACC::EncodeBER;
+            s << h;
+            SNACC::AsnBuf benc(s.str().c_str(), s.str().length());
+
             if (!(benc == expected)) {
                 fail_enc = true;
             }
diff --git a/cxx-examples/src/main.cpp b/cxx-examples/src/main.cpp
index 30e1680..d650d6e 100644
--- a/cxx-examples/src/main.cpp
+++ b/cxx-examples/src/main.cpp
@@ -183,6 +183,7 @@ int main(int argc, char *argv[])
        fillTest();
        if (automaticTests()) {
            std::cout << "Automatic test failure." << std::endl;
+           return 1;
        }
    } catch (SnaccException &e) {
        std::cout << "\n**** Caught SnaccException ****\n";
diff --git a/cxx-lib/automake.mk b/cxx-lib/automake.mk
index f8d6252..249f2dc 100644
--- a/cxx-lib/automake.mk
+++ b/cxx-lib/automake.mk
@@ -4,6 +4,7 @@ nobase_include_HEADERS += cxx-lib/inc/asn-buf.h \
 	cxx-lib/inc/asn-chartraits.h \
 	cxx-lib/inc/asn-config.h \
 	cxx-lib/inc/asn-incl.h \
+	cxx-lib/inc/asn-iomanip.h \
 	cxx-lib/inc/asn-list.h \
 	cxx-lib/inc/asn-listset.h \
 	cxx-lib/inc/asn-usefultypes.h \
diff --git a/cxx-lib/inc/asn-incl.h b/cxx-lib/inc/asn-incl.h
index ebd04ee..7270f28 100644
--- a/cxx-lib/inc/asn-incl.h
+++ b/cxx-lib/inc/asn-incl.h
@@ -1404,18 +1404,19 @@ extern "C" {
 void SNACCDLL_API SNACC_CleanupMemory();
 }
 
-
 //########################################################################
 //########################################################################
 
-_END_SNACC_NAMESPACE
-
 
-// Overload of operator<< to stream out an AsnType
-SNACCDLL_API std::ostream& operator<<(std::ostream& os,
-									  const SNACC::AsnType& a);
+enum SNACCEncodeDecodeRules {
+    SNACC_ASCII,
+    BER,
+    PER
+};
 
+_END_SNACC_NAMESPACE
 
+#include "asn-iomanip.h"
 #include "snaccexcept.h"
 #include "asn-usefultypes.h"
 
diff --git a/cxx-lib/inc/asn-iomanip.h b/cxx-lib/inc/asn-iomanip.h
new file mode 100644
index 0000000..172e7ed
--- /dev/null
+++ b/cxx-lib/inc/asn-iomanip.h
@@ -0,0 +1,52 @@
+#ifndef __ASN_IOMANIP_H__
+#define __ASN_IOMANIP_H__
+
+_BEGIN_SNACC_NAMESPACE
+
+inline int SNACCDLL_API
+getSNACCEncoderIOSType()
+{
+    static int iDelimIdx = std::ios_base::xalloc();
+    return iDelimIdx;
+}
+
+static inline std::ios_base& SNACCDLL_API
+SNACC_setiosencodetype(std::ios_base &s, SNACCEncodeDecodeRules t)
+{
+    s.iword(getSNACCEncoderIOSType()) = (int)t;
+    return s;
+}
+
+static inline SNACCEncodeDecodeRules SNACCDLL_API
+SNACC_getiosencodetype(std::ios_base &s)
+{
+    return (SNACCEncodeDecodeRules)s.iword(getSNACCEncoderIOSType());
+}
+
+static inline
+std::ios_base & SNACCDLL_API EncodeBER(std::ios_base &s)
+{
+    return SNACC_setiosencodetype(s, BER);
+}
+
+static inline
+std::ios_base & SNACCDLL_API EncodeNORMAL(std::ios_base &s)
+{
+    return SNACC_setiosencodetype(s, SNACC_ASCII);
+}
+
+static inline
+std::ios_base & SNACCDLL_API EncodePER(std::ios_base &s)
+{
+    return SNACC_setiosencodetype(s, PER);
+}
+
+_END_SNACC_NAMESPACE
+
+// Overload of operator<< to stream out an AsnType
+std::ostream& SNACCDLL_API operator<<(std::ostream& os,
+                                      const SNACC::AsnType& a);
+
+
+
+#endif
diff --git a/cxx-lib/src/print.cpp b/cxx-lib/src/print.cpp
index e19b54f..e7fea84 100644
--- a/cxx-lib/src/print.cpp
+++ b/cxx-lib/src/print.cpp
@@ -17,7 +17,7 @@
 //
 
 #include "asn-incl.h"
-
+#include "asn-iomanip.h"
 
 void SNACC::Indent(std::ostream& os, unsigned short i)
 {
@@ -27,6 +27,23 @@ void SNACC::Indent(std::ostream& os, unsigned short i)
 
 std::ostream& operator<<(std::ostream& os, const SNACC::AsnType& v)
 {
-	v.Print(os);
-	return os;
+    switch (SNACC::SNACC_getiosencodetype(os)) {
+    default:
+    case SNACC::SNACC_ASCII:
+        v.Print(os);
+        break;
+    case SNACC::BER:
+        {
+            SNACC::AsnBuf b(os.rdbuf());
+            b.ResetMode(std::ios_base::out);
+            v.BEnc(b);
+        }
+        break;
+    case SNACC::PER:
+        throw SNACC::SnaccException(__FILE__, __LINE__,
+                                    "operator<<",
+                                    "No Proper PER Support at this time");
+        break;
+    }
+    return os;
 }
-- 
2.7.4



More information about the dev mailing list