Index: trunk/src/core/RpEncode.cc
===================================================================
--- trunk/src/core/RpEncode.cc	(revision 671)
+++ trunk/src/core/RpEncode.cc	(revision 671)
@@ -0,0 +1,179 @@
+/*
+ * ----------------------------------------------------------------------
+ *  Rappture::encoding
+ *
+ *  The encoding module for rappture used to zip and b64 encode data.
+ * ======================================================================
+ *  AUTHOR:  Derrick Kearney, Purdue University
+ *  Copyright (c) 2004-2007  Purdue Research Foundation
+ *
+ *  See the file "license.terms" for information on usage and
+ *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * ======================================================================
+ */
+#include "RpEncode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // ifdef __cplusplus
+
+using namespace Rappture::encoding;
+
+/**********************************************************************/
+// FUNCTION: Rappture::encoding::isbinary()
+/// isbinary checks to see if given string is binary.
+/**
+ * Checks to see if any of size characters in *buf are binary
+ * Full function call:
+ * Rappture::encoding::isbinary(buf,size);
+ *
+ */
+
+int
+isbinary(const char* buf, int size)
+{
+    int index = 0;
+
+    if (size == -1) {
+        size = strlen(buf);
+    }
+
+    for (index = 0; index < size; index++) {
+        if (((buf[index] >= '\000') && (buf[index] <= '\010')) ||
+            ((buf[index] >= '\013') && (buf[index] <= '\014')) ||
+            ((buf[index] >= '\016') && (buf[index] <= '\037')) ||
+            ((buf[index] >= '\177') && (buf[index] <= '\377')) ) {
+            // data is binary
+            return index+1;
+        }
+
+    }
+    return 0;
+}
+
+
+
+
+
+/**********************************************************************/
+// FUNCTION: Rappture::encoding::encode()
+/// Rappture::encoding::encode function encodes provided string
+/**
+ * Encode a string by compressing it with zlib and then base64 encoding it.
+ *
+ * Full function call:
+ * Rappture::encoding::encode(buf,flags)
+ */
+
+Rappture::Outcome
+encode (Rappture::Buffer& buf, int flags)
+{
+
+    int compress              = 0;
+    int base64                = 0;
+    int addHeader             = 0;
+    Rappture::Outcome err;
+    Rappture::Buffer outData;
+
+    if ((flags & RPENC_Z) == RPENC_Z ) {
+        compress = 1;
+    }
+    if ((flags & RPENC_B64) == RPENC_B64 ) {
+        base64 = 1;
+    }
+    if ((flags & RPENC_HDR) == RPENC_HDR ) {
+        addHeader = 1;
+    }
+
+    outData.append(buf.bytes(),buf.size());
+    err = outData.encode(compress,base64);
+    if (!err) {
+        buf.clear();
+        if (addHeader == 1) {
+            if ((compress == 1) && (base64 == 0)) {
+                buf.append("@@RP-ENC:z\n",11);
+            }
+            else if ((compress == 0) && (base64 == 1)) {
+                buf.append("@@RP-ENC:b64\n",13);
+            }
+            else if ((compress == 1) && (base64 == 1)) {
+                buf.append("@@RP-ENC:zb64\n",14);
+            }
+            else {
+                // do nothing
+            }
+        }
+        else {
+            // do nothing
+        }
+        buf.append(outData.bytes(),outData.size());
+    }
+
+    return err;
+}
+
+/**********************************************************************/
+// FUNCTION: Rappture::encoding::decode()
+/// Rappture::encoding::decode function decodes provided string
+/**
+ * Decode a string by uncompressing it with zlib and base64 decoding it.
+ * If binary data is provided, the data is base64 decoded and uncompressed.
+ * Rappture::encoding::isbinary is used to qualify binary data.
+ *
+ * Full function call:
+ * Rappture::encoding::decode (buf,flags)
+ */
+
+Rappture::Outcome
+decode (Rappture::Buffer& buf, int flags)
+{
+
+    int decompress            = 0;
+    int base64                = 0;
+    Rappture::Outcome err;
+    Rappture::Buffer outData;
+
+    if ((flags & RPENC_Z) == RPENC_Z ) {
+        decompress = 1;
+    }
+    if ((flags & RPENC_B64) == RPENC_B64 ) {
+        base64 = 1;
+    }
+
+    if (strncmp(buf.bytes(),"@@RP-ENC:z\n",11) == 0) {
+        outData.append(buf.bytes()+11,buf.size()-11);
+        if ( (decompress == 0) && (base64 == 0) ) {
+            decompress = 1;
+            base64 = 0;
+        }
+    }
+    else if (strncmp(buf.bytes(),"@@RP-ENC:b64\n",13) == 0) {
+        outData.append(buf.bytes()+13,buf.size()-13);
+        if ( (decompress == 0) && (base64 == 0) ) {
+            decompress = 0;
+            base64 = 1;
+        }
+    }
+    else if (strncmp(buf.bytes(),"@@RP-ENC:zb64\n",14) == 0) {
+        outData.append(buf.bytes()+14,buf.size()-14);
+        if ( (decompress == 0) && (base64 == 0) ) {
+            decompress = 1;
+            base64 = 1;
+        }
+    }
+    else {
+        // no special recognized tags
+        outData.append(buf.bytes(),buf.size());
+    }
+
+    err = outData.decode(decompress,base64);
+    if (!err) {
+        buf.move(outData);
+    }
+
+    return err;
+}
+
+#ifdef __cplusplus
+}
+#endif // ifdef __cplusplus
Index: trunk/src/core/RpEncode.h
===================================================================
--- trunk/src/core/RpEncode.h	(revision 671)
+++ trunk/src/core/RpEncode.h	(revision 671)
@@ -0,0 +1,41 @@
+/*
+ * ======================================================================
+ *  Rappture::encoding
+ *
+ *  AUTHOR:  Derrick Kearney, Purdue University
+ *
+ *  Copyright (c) 2004-2007  Purdue Research Foundation
+ * ----------------------------------------------------------------------
+ *  See the file "license.terms" for information on usage and
+ *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * ======================================================================
+ */
+
+#ifndef RAPPTURE_ENCODE_H
+#define RAPPTURE_ENCODE_H
+
+// #include "rappture.h"
+#include "RpBuffer.h"
+#include "Outcome.h"
+
+#define RPENC_Z      1
+#define RPENC_B64    2
+#define RPENC_HDR    4
+
+#ifdef __cplusplus
+extern "C" {
+namespace Rappture {
+    namespace encoding {
+#endif // ifdef __cplusplus
+
+int isbinary(const char* buf, int size);
+Rappture::Outcome encode (Rappture::Buffer& buf, int flags);
+Rappture::Outcome decode (Rappture::Buffer& buf, int flags);
+
+#ifdef __cplusplus
+    } // namespace encoding
+} // namespace Rappture
+} // extern C
+#endif // ifdef __cplusplus
+
+#endif // RAPPTURE_ENCODE_H
Index: trunk/src/core/RpLibrary.cc
===================================================================
--- trunk/src/core/RpLibrary.cc	(revision 665)
+++ trunk/src/core/RpLibrary.cc	(revision 671)
@@ -14,4 +14,5 @@
 #include "RpLibrary.h"
 #include "RpEntityRef.h"
+#include "RpEncode.h"
 #include <algorithm>
 #include <iostream>
@@ -48,4 +49,5 @@
         freeRoot    (1)
 {
+    std::stringstream msg;
 
     if (filePath.length() != 0) {
@@ -63,10 +65,6 @@
             printf("Unable to load file (error #%d: %s)\n", code,
                    scew_error_string(code));
-
-            /*
-            std::cout << "Unable to load file (error #" \
-                      << code << ": " << scew_error_string(code) \
-                      << ")\n" << std::endl;
-            */
+            msg << "Unable to load file (error #" << code
+                << ": " << scew_error_string(code) << ")\n";
 
             if (code == scew_error_expat)
@@ -79,12 +77,19 @@
                        scew_error_expat_column(parser),
                        scew_error_expat_string(expat_code));
-            }
-            // should probably exit program or something
-            // return EXIT_FAILURE;
+                msg << "Expat error #" << expat_code << " (line "
+                    << scew_error_expat_line(parser) << ", column "
+                    << scew_error_expat_column(parser) << "): "
+                    << "\n";
+            }
+
             fflush(stdout);
             scew_parser_free(parser);
             parser = NULL;
-        }
-        else 
+
+            // update the status of the call
+            status.error(msg.str().c_str());
+            status.addContext("RpLibrary::RpLibrary()");
+        }
+        else
         {
             tree = scew_parser_tree(parser);
@@ -111,4 +116,5 @@
       freeRoot  (1)
 {
+    std::stringstream msg;
     std::string buffer;
     int buffLen;
@@ -132,4 +138,6 @@
             printf("Unable to load buffer (error #%d: %s)\n", code,
                    scew_error_string(code));
+            msg << "Unable to load file (error #" << code
+                << ": " << scew_error_string(code) << ")\n";
 
             if (code == scew_error_expat)
@@ -142,4 +150,8 @@
                        scew_error_expat_column(parser),
                        scew_error_expat_string(expat_code));
+                msg << "Expat error #" << expat_code << " (line "
+                    << scew_error_expat_line(parser) << ", column "
+                    << scew_error_expat_column(parser) << "): "
+                    << "\n";
             }
 
@@ -148,4 +160,8 @@
 
             parser = NULL;
+
+            // update the status of the call
+            status.error(msg.str().c_str());
+            status.addContext("RpLibrary::RpLibrary()");
         }
         else {
@@ -172,4 +188,5 @@
 RpLibrary::operator= (const RpLibrary& other) {
 
+    std::stringstream msg;
     std::string buffer;
     int buffLen;
@@ -207,4 +224,6 @@
                 printf("Unable to load buffer (error #%d: %s)\n", code,
                        scew_error_string(code));
+                msg << "Unable to load file (error #" << code
+                    << ": " << scew_error_string(code) << ")\n";
 
                 if (code == scew_error_expat)
@@ -217,4 +236,8 @@
                            scew_error_expat_column(parser),
                            scew_error_expat_string(expat_code));
+                    msg << "Expat error #" << expat_code << " (line "
+                        << scew_error_expat_line(parser) << ", column "
+                        << scew_error_expat_column(parser) << "): "
+                        << "\n";
                 }
 
@@ -225,4 +248,8 @@
                 // return this object to its previous state.
                 parser = tmp_parser;
+
+                // update the status of the call
+                status.error(msg.str().c_str());
+                status.addContext("RpLibrary::RpLibrary()");
             }
             else {
@@ -1469,4 +1496,5 @@
     const char* translatedContents = NULL;
     std::string retStr = "";
+    Rappture::Buffer inData;
 
     if (!this->root) {
@@ -1488,16 +1516,28 @@
     }
 
+    inData = Rappture::Buffer(retCStr);
+    status &= Rappture::encoding::decode(inData,0);
+    status.addContext("RpLibrary::getSting");
+    inData.append("\0",1);
+
     if (translateFlag == RPLIB_TRANSLATE) {
-        translatedContents = ERTranslator.decode(retCStr);
+        translatedContents = ERTranslator.decode(inData.bytes());
         if (translatedContents == NULL) {
             // translation failed
-            return retStr;
-        }
-        retStr = std::string(translatedContents);
-        translatedContents = NULL;
+            if (!status) {
+                status.error("Error while translating entity references");
+                status.addContext("RpLibrary::getSting");
+            }
+        }
+        else {
+            retStr = std::string(translatedContents);
+            translatedContents = NULL;
+        }
     }
     else {
-        retStr = std::string(retCStr);
-    }
+        retStr = std::string(inData.bytes());
+    }
+
+    inData.clear();
 
     return retStr;
@@ -1521,10 +1561,9 @@
     }
 
-    retValStr = this->getString(path); 
+    retValStr = this->getString(path);
+    status.addContext("RpLibrary::getDouble");
     // think about changing this to strtod()
     retValDbl = atof(retValStr.c_str());
 
-    // how do we raise error?
-    // currently we depend on getString to raise the error
     return retValDbl;
 }
@@ -1548,10 +1587,9 @@
     }
 
-    retValStr = this->getString(path); 
+    retValStr = this->getString(path);
+    status.addContext("RpLibrary::getInt");
     // think about changing this to strtod()
     retValInt = atoi(retValStr.c_str());
 
-    // how do we raise error?
-    // currently we depend on getString to raise the error
     return retValInt;
 }
@@ -1577,4 +1615,5 @@
 
     retValStr = this->getString(path);
+    status.addContext("RpLibrary::getBool");
     std::transform (retValStr.begin(),retValStr.end(),retValStr.begin(),tolower);
     retValLen = retValStr.length();
@@ -1599,6 +1638,4 @@
     }
 
-    // how do we raise error?
-    // currently we depend on getString to raise the error
     return retValBool;
 }
@@ -1612,5 +1649,5 @@
 
 Rappture::Buffer
-RpLibrary::getData (std::string path, Rappture::Outcome& status) const
+RpLibrary::getData (std::string path) const
 {
     Rappture::EntityRef ERTranslator;
@@ -1639,6 +1676,5 @@
 
     if (retCStr == NULL) {
-        status.error("element located at path is empty");
-        status.addContext("RpLibrary::getData()");
+        // element located at path is empty
         return buf;
     }
@@ -1648,9 +1684,14 @@
         if (translatedContents == NULL) {
             // translation failed
-            return buf;
-        }
-        len = strlen(translatedContents);
-        buf.append(translatedContents,len);
-        translatedContents = NULL;
+            if (!status) {
+                status.error("Error while translating entity references");
+                status.addContext("RpLibrary::getData()");
+            }
+        }
+        else {
+            len = strlen(translatedContents);
+            buf.append(translatedContents,len);
+            translatedContents = NULL;
+        }
     }
     else {
@@ -1687,4 +1728,11 @@
     }
 
+    // check for binary data
+    if (Rappture::encoding::isbinary(value.c_str(),value.length()) != 0) {
+        putData(path,value.c_str(),value.length(),append);
+        status.addContext("RpLibrary::put() - putString");
+        return *this;
+    }
+
     retNode = _find(path,CREATE_PATH);
 
@@ -1700,16 +1748,28 @@
         if (translateFlag == RPLIB_TRANSLATE) {
             translatedContents = ERTranslator.encode(value.c_str());
-            if (translatedContents == NULL) {
-                // translation failed
-                return *this;
-            }
+        }
+        else {
+            translatedContents = value.c_str();
+        }
+
+        if (translatedContents == NULL) {
+            // entity referene translation failed
+            if (!status) {
+                status.error("Error while translating entity references");
+            }
+        }
+        else {
             scew_element_set_contents(retNode,translatedContents);
             translatedContents = NULL;
         }
-        else {
-            scew_element_set_contents(retNode,value.c_str());
-        }
-    }
-
+    }
+    else {
+        // node not found, set error
+        if (!status) {
+            status.error("Error while searching for node: node not found");
+        }
+    }
+
+    status.addContext("RpLibrary::put() - putString");
     return *this;
 }
@@ -1736,5 +1796,7 @@
     valStr << value;
 
-    return this->put(path,valStr.str(),id,append);
+    put(path,valStr.str(),id,append);
+    status.addContext("RpLibrary::put() - putDouble");
+    return *this;
 }
 
@@ -1829,6 +1891,7 @@
     scew_element* retNode = NULL;
     const char* contents = NULL;
-    Rappture::Buffer buf;
+    Rappture::Buffer inData;
     unsigned int bytesWritten = 0;
+    int flags = 0;
 
     if (!this->root) {
@@ -1843,18 +1906,30 @@
         if (append == RPLIB_APPEND) {
             if ( (contents = scew_element_contents(retNode)) ) {
-                buf.append(contents);
+                inData.append(contents);
                 // base64 decode and un-gzip the data
-                buf.decode();
-            }
-        }
-
-        buf.append(bytes,nbytes);
+                status &= Rappture::encoding::decode(inData,0);
+                if (int(status) != 0) {
+                    status.addContext("RpLibrary::putData()");
+                    return *this;
+                }
+            }
+        }
+
+        inData.append(bytes,nbytes);
         // gzip and base64 encode the data
-        buf.encode();
-
-        bytesWritten = (unsigned int) buf.size();
-        scew_element_set_contents_binary(retNode,buf.bytes(),&bytesWritten);
-    }
-
+        flags = RPENC_Z|RPENC_B64|RPENC_HDR;
+        status &= Rappture::encoding::encode(inData,flags);
+
+        bytesWritten = (unsigned int) inData.size();
+        scew_element_set_contents_binary(retNode,inData.bytes(),&bytesWritten);
+    }
+    else {
+        // node not found, set error
+        if (!status) {
+            status.error("Error while searching for node: node not found");
+        }
+    }
+
+    status.addContext("RpLibrary::putData()");
     return *this;
 }
@@ -1892,4 +1967,5 @@
         put(path,fileBuf.bytes(),"",append,RPLIB_TRANSLATE);
     }
+    status.addContext("RpLibrary::putFile()");
     return *this;
 }
@@ -2028,4 +2104,16 @@
 
     return _node2path(root);
+}
+
+/**********************************************************************/
+// METHOD: outcome()
+/// Return the status object of this library object.
+/**
+ */
+
+Rappture::Outcome&
+RpLibrary::outcome() const
+{
+    return status;
 }
 
@@ -2040,5 +2128,5 @@
  * ======================================================================
  *  AUTHOR:  Michael McLennan, Purdue University
- *  Copyright (c) 2004-2005
+ *  Copyright (c) 2004-2007
  *  Purdue Research Foundation, West Lafayette, IN
  * ======================================================================
@@ -2058,7 +2146,7 @@
         file.open(outputFile.str().c_str(),std::ios::out);
 
-        put("tool.repository.rappture.date","$Date$");
-        put("tool.repository.rappture.revision","$Rev$");
-        put("tool.repository.rappture.url","$URL$");
+        put("tool.version.rappture.date","$LastChangedDate$");
+        put("tool.version.rappture.revision","$LastChangedRevision$");
+        put("tool.version.rappture.url","$URL$");
 
         // generate a timestamp for the run file
@@ -2085,4 +2173,8 @@
             file.close();
         }
+        else {
+            status.error("Error while opening run file");
+            status.addContext("RpLibrary::result()");
+        }
         std::cout << "=RAPPTURE-RUN=>" << outputFile.str() << std::endl;
     }
Index: trunk/src/core/RpLibrary.h
===================================================================
--- trunk/src/core/RpLibrary.h	(revision 665)
+++ trunk/src/core/RpLibrary.h	(revision 671)
@@ -78,6 +78,5 @@
         int         getInt    ( std::string path = "") const;
         bool        getBool   ( std::string path = "") const;
-        Rappture::Buffer getData ( std::string path,
-                                   Rappture::Outcome& status) const;
+        Rappture::Buffer getData ( std::string path = "") const;
 
         /*
@@ -134,4 +133,6 @@
         std::string nodeComp() const;
         std::string nodePath() const;
+
+        Rappture::Outcome& outcome() const;
 
         void result();
@@ -171,4 +172,5 @@
         int freeRoot;
 
+        mutable Rappture::Outcome status;
 
         RpLibrary ( scew_element* node, scew_tree* tree)
