You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2012/12/19 21:34:58 UTC

svn commit: r1424091 [6/9] - in /qpid/trunk/qpid/cpp/src: ./ qpid/legacystore/ qpid/legacystore/jrnl/

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,382 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jdir.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::jdir (%journal data
+ * directory), used for controlling and manipulating %journal data
+ * directories and files. See class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jdir_hpp
+#define mrg_journal_jdir_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jdir;
+}
+}
+
+#include "jrnl/jinf.hpp"
+#include <dirent.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+    /**
+    * \class jdir
+    * \brief Class to manage the %journal directory
+    */
+    class jdir
+    {
+    private:
+        std::string _dirname;
+        std::string _base_filename;
+
+    public:
+
+        /**
+        * \brief Sole constructor
+        *
+        * \param dirname Name of directory to be managed.
+        * \param base_filename Filename root used in the creation of %journal files
+        *     and sub-directories.
+        */
+        jdir(const std::string& dirname, const std::string& base_filename);
+
+        virtual ~jdir();
+
+
+        /**
+        * \brief Create %journal directory as set in the dirname parameter of the constructor.
+        *     Recursive creation is supported.
+        *
+        * \exception jerrno::JERR_JDIR_MKDIR The creation of dirname failed.
+        */
+        void create_dir();
+
+        /**
+        * \brief Static function to create a directory. Recursive creation is supported.
+        *
+        * \param dirname C-string containing name of directory.
+        *
+        * \exception jerrno::JERR_JDIR_MKDIR The creation of dirname failed.
+        */
+        static void create_dir(const char* dirname);
+
+        /**
+        * \brief Static function to create a directory. Recursive creation is supported.
+        *
+        * \param dirname String containing name of directory.
+        *
+        * \exception jerrno::JERR_JDIR_MKDIR The creation of dirname failed.
+        */
+        static void create_dir(const std::string& dirname);
+
+
+        /**
+        * \brief Clear the %journal directory of files matching the base filename
+        *     by moving them into a subdirectory. This fn uses the dirname and base_filename
+        *     that were set on construction.
+        *
+        * \param create_flag If set, create dirname if it is non-existent, otherwise throw
+        *     exception.
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_FMOVE Moving the files from the %journal directory to the created backup
+        *     directory failed.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        */
+        void clear_dir(const bool create_flag = true);
+
+        /**
+        * \brief Clear the directory dirname of %journal files matching base_filename
+        *     by moving them into a subdirectory.
+        *
+        * \param dirname C-string containing name of %journal directory.
+        * \param base_filename C-string containing base filename of %journal files to be matched
+        *     for moving into subdirectory.
+        * \param create_flag If set, create dirname if it is non-existent, otherwise throw
+        *     exception
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_FMOVE Moving the files from the %journal directory to the created backup
+        *     directory failed.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        */
+        static void clear_dir(const char* dirname, const char* base_filename,
+                const bool create_flag = true);
+
+        /**
+        * \brief Clear the directory dirname of %journal files matching base_filename
+        *     by moving them into a subdirectory.
+        *
+        * \param dirname String containing name of %journal directory.
+        * \param base_filename String containing base filename of %journal files to be matched
+        *     for moving into subdirectory.
+        * \param create_flag If set, create dirname if it is non-existent, otherwise throw
+        *     exception
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_FMOVE Moving the files from the %journal directory to the created backup
+        *     directory failed.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        */
+        static void clear_dir(const std::string& dirname, const std::string& base_filename,
+                const bool create_flag = true);
+
+
+
+        /**
+         * \brief Move (push down) the directory target_dir located in directory dirname into a backup directory
+         * named _bak_dir_base.XXXX (note prepended underscore), where XXXX is an increasing hex serial number
+         * starting at 0000.
+         *
+         * \param dirname Full path to directory containing directory to be pushed down.
+         * \param target_dir Name of directory in dirname to be pushed down.
+         * \param bak_dir_base Base name for backup directory to be created in dirname, into which target_dir will be moved.
+         * \return Name of backup dir into which target_dir was pushed.
+         */
+        static std::string push_down(const std::string& dirname, const std::string& target_dir, const std::string& bak_dir_base);
+
+
+        /**
+        * \brief Verify that dirname is a valid %journal directory.
+        *
+        * The validation reads the .%jinf file, and using this information verifies that all the expected %journal
+        * (.jdat) files are present.
+        *
+        * \exception jerrno::JERR_JDIR_NOTDIR dirname is not a directory
+        * \exception jerrno::JERR_JDIR_STAT Could not stat dirname
+        * \exception jerrno::JERR__FILEIO Error reading %jinf file
+        * \exception jerrno::JERR_JINF_CVALIDFAIL Error validating %jinf file
+        * \exception jerrno::JERR_JDIR_NOSUCHFILE Expected jdat file is missing
+        */
+        void verify_dir();
+
+        /**
+        * \brief Verify that dirname is a valid %journal directory.
+        *
+        * The validation reads the .%jinf file, and using this information verifies that all the expected %journal
+        * (.jdat) files are present.
+        *
+        * \param dirname C-string containing name of %journal directory.
+        * \param base_filename C-string containing base filename of %journal files to be matched for moving into sub-directory.
+        *
+        * \exception jerrno::JERR_JDIR_NOTDIR dirname is not a directory
+        * \exception jerrno::JERR_JDIR_STAT Could not stat dirname
+        * \exception jerrno::JERR__FILEIO Error reading %jinf file
+        * \exception jerrno::JERR_JINF_CVALIDFAIL Error validating %jinf file
+        * \exception jerrno::JERR_JDIR_NOSUCHFILE Expected jdat file is missing
+        */
+        static void verify_dir(const char* dirname, const char* base_filename);
+
+        /**
+        * \brief Verify that dirname is a valid %journal directory.
+        *
+        * The validation reads the .%jinf file, and using this information verifies that all the expected %journal
+        * (.jdat) files are present.
+        *
+        * \param dirname String containing name of %journal directory.
+        * \param base_filename String containing base filename of %journal files to be matched for moving into sub-directory.
+        *
+        * \exception jerrno::JERR_JDIR_NOTDIR dirname is not a directory
+        * \exception jerrno::JERR_JDIR_STAT Could not stat dirname
+        * \exception jerrno::JERR__FILEIO Error reading %jinf file
+        * \exception jerrno::JERR_JINF_CVALIDFAIL Error validating %jinf file
+        * \exception jerrno::JERR_JDIR_NOSUCHFILE Expected jdat file is missing
+        */
+        static void verify_dir(const std::string& dirname, const std::string& base_filename);
+
+        /**
+        * \brief Delete the %journal directory and all files and sub--directories that it may
+        *     contain. This is equivilent of rm -rf.
+        *
+        * FIXME: links are not handled correctly.
+        *
+        * \param children_only If true, delete only children of dirname, but leave dirname itself.
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat dirname.
+        * \exception jerrno::JERR_JDIR_UNLINK A file could not be deleted.
+        * \exception jerrno::JERR_JDIR_BADFTYPE A dir entry is neiter a file nor a dir.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        * \exception jerrno::JERR_JDIR_RMDIR A directory could not be deleted.
+        */
+        void delete_dir(bool children_only = false );
+
+        /**
+        * \brief Delete the %journal directory and all files and sub--directories that it may
+        *     contain. This is equivilent of rm -rf.
+        *
+        * FIXME: links are not handled correctly.
+        *
+        * \param dirname C-string containing name of directory to be deleted.
+        * \param children_only If true, delete only children of dirname, but leave dirname itself.
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat dirname.
+        * \exception jerrno::JERR_JDIR_UNLINK A file could not be deleted.
+        * \exception jerrno::JERR_JDIR_BADFTYPE A dir entry is neiter a file nor a dir.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        * \exception jerrno::JERR_JDIR_RMDIR A directory could not be deleted.
+        */
+        static void delete_dir(const char* dirname, bool children_only = false);
+
+        /**
+        * \brief Delete the %journal directory and all files and sub--directories that it may
+        *     contain. This is equivilent of rm -rf.
+        *
+        * FIXME: links are not handled correctly.
+        *
+        * \param dirname String containing name of directory to be deleted.
+        * \param children_only If true, delete only children of dirname, but leave dirname itself.
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat dirname.
+        * \exception jerrno::JERR_JDIR_UNLINK A file could not be deleted.
+        * \exception jerrno::JERR_JDIR_BADFTYPE A dir entry is neiter a file nor a dir.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        * \exception jerrno::JERR_JDIR_RMDIR A directory could not be deleted.
+        */
+        static void delete_dir(const std::string& dirname, bool children_only = false);
+
+        /**
+        * \brief Create bakup directory that is next in sequence and move all %journal files
+        *     matching base_filename into it.
+        *
+        * In directory dirname, search for existing backup directory using pattern
+        * "_basename.bak.XXXX" where XXXX is a hexadecimal sequence, and create next directory
+        * based on highest number found. Move all %journal files which match the base_fileaname
+        * parameter into this new backup directory.
+        *
+        * \param dirname String containing name of %journal directory.
+        * \param base_filename String containing base filename of %journal files to be matched
+        *     for moving into subdirectory.
+        *
+        * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+        * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+        * \exception jerrno::JERR_JDIR_MKDIR The backup directory could not be deleted.
+        */
+        static std::string create_bak_dir(const std::string& dirname,
+                const std::string& base_filename);
+
+        /**
+        * \brief Return the directory name as a string.
+        */
+        inline const std::string& dirname() const { return _dirname; }
+
+        /**
+        * \brief Return the %journal base filename name as a string.
+        */
+        inline const std::string& base_filename() const { return _base_filename; }
+
+        /**
+        * \brief Test whether the named file is a directory.
+        *
+        * \param name Name of file to be tested.
+        * \return <b><i>true</i></b> if the named file is a directory; <b><i>false</i></b>
+        *     otherwise.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+        */
+        static bool is_dir(const char* name);
+
+        /**
+        * \brief Test whether the named file is a directory.
+        *
+        * \param name Name of file to be tested.
+        * \return <b><i>true</i></b> if the named file is a directory; <b><i>false</i></b>
+        *     otherwise.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+        */
+        static bool is_dir(const std::string& name);
+
+
+        /**
+        * \brief Test whether the named entity exists on the filesystem.
+        *
+        * If stat() fails with error ENOENT, then this will return <b><i>false</i></b>. If
+        * stat() succeeds, then <b><i>true</i></b> is returned, irrespective of the file type.
+        * If stat() fails with any other error, an exception is thrown.
+        *
+        * \param name Name of entity to be tested.
+        * \return <b><i>true</i></b> if the named entity exists; <b><i>false</i></b>
+        *     otherwise.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+        */
+        static bool exists(const char* name);
+
+        /**
+        * \brief Test whether the named entity exists on the filesystem.
+        *
+        * If stat() fails with error ENOENT, then this will return <b><i>false</i></b>. If
+        * stat() succeeds, then <b><i>true</i></b> is returned, irrespective of the file type.
+        * If stat() fails with any other error, an exception is thrown.
+        *
+        * \param name Name of entity to be tested.
+        * \return <b><i>true</i></b> if the named entity exists; <b><i>false</i></b>
+        *     otherwise.
+        * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+        */
+        static bool exists(const std::string& name);
+
+        /**
+        * \brief Stream operator
+        */
+        friend std::ostream& operator<<(std::ostream& os, const jdir& jdir);
+
+        /**
+        * \brief Stream operator
+        */
+        friend std::ostream& operator<<(std::ostream& os, const jdir* jdirPtr);
+
+    private:
+        /**
+         * \brief Check for error, if non-zero close DIR handle and throw JERR_JDIR_READDIR
+         *
+         * \exception jerrno::JERR_JDIR_READDIR Error while reading contents of dir.
+         */
+        static void check_err(const int err_num, DIR* dir, const std::string& dir_name, const std::string& fn_name);
+
+        /**
+         * \brief Close a DIR handle, throw JERR_JDIR_CLOSEDIR if error occurs during close
+         *
+         * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+         */
+        static void close_dir(DIR* dir, const std::string& dir_name, const std::string& fn_name);
+    };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jdir_hpp

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,256 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jerrno.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::jerrno (journal error
+ * codes). See comments in file jerrno.hpp for details.
+ *
+ * See file jerrno.hpp for class details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jerrno.hpp"
+
+namespace mrg
+{
+namespace journal
+{
+
+std::map<u_int32_t, const char*> jerrno::_err_map;
+std::map<u_int32_t, const char*>::iterator jerrno::_err_map_itr;
+bool jerrno::_initialized = jerrno::__init();
+
+// generic errors
+const u_int32_t jerrno::JERR__MALLOC            = 0x0100;
+const u_int32_t jerrno::JERR__UNDERFLOW         = 0x0101;
+const u_int32_t jerrno::JERR__NINIT             = 0x0102;
+const u_int32_t jerrno::JERR__AIO               = 0x0103;
+const u_int32_t jerrno::JERR__FILEIO            = 0x0104;
+const u_int32_t jerrno::JERR__RTCLOCK           = 0x0105;
+const u_int32_t jerrno::JERR__PTHREAD           = 0x0106;
+const u_int32_t jerrno::JERR__TIMEOUT           = 0x0107;
+const u_int32_t jerrno::JERR__UNEXPRESPONSE     = 0x0108;
+const u_int32_t jerrno::JERR__RECNFOUND         = 0x0109;
+const u_int32_t jerrno::JERR__NOTIMPL           = 0x010a;
+
+// class jcntl
+const u_int32_t jerrno::JERR_JCNTL_STOPPED      = 0x0200;
+const u_int32_t jerrno::JERR_JCNTL_READONLY     = 0x0201;
+const u_int32_t jerrno::JERR_JCNTL_AIOCMPLWAIT  = 0x0202;
+const u_int32_t jerrno::JERR_JCNTL_UNKNOWNMAGIC = 0x0203;
+const u_int32_t jerrno::JERR_JCNTL_NOTRECOVERED = 0x0204;
+const u_int32_t jerrno::JERR_JCNTL_RECOVERJFULL = 0x0205;
+const u_int32_t jerrno::JERR_JCNTL_OWIMISMATCH  = 0x0206;
+
+// class jdir
+const u_int32_t jerrno::JERR_JDIR_NOTDIR        = 0x0300;
+const u_int32_t jerrno::JERR_JDIR_MKDIR         = 0x0301;
+const u_int32_t jerrno::JERR_JDIR_OPENDIR       = 0x0302;
+const u_int32_t jerrno::JERR_JDIR_READDIR       = 0x0303;
+const u_int32_t jerrno::JERR_JDIR_CLOSEDIR      = 0x0304;
+const u_int32_t jerrno::JERR_JDIR_RMDIR         = 0x0305;
+const u_int32_t jerrno::JERR_JDIR_NOSUCHFILE    = 0x0306;
+const u_int32_t jerrno::JERR_JDIR_FMOVE         = 0x0307;
+const u_int32_t jerrno::JERR_JDIR_STAT          = 0x0308;
+const u_int32_t jerrno::JERR_JDIR_UNLINK        = 0x0309;
+const u_int32_t jerrno::JERR_JDIR_BADFTYPE      = 0x030a;
+
+// class fcntl
+const u_int32_t jerrno::JERR_FCNTL_OPENWR       = 0x0400;
+const u_int32_t jerrno::JERR_FCNTL_WRITE        = 0x0401;
+const u_int32_t jerrno::JERR_FCNTL_CLOSE        = 0x0402;
+const u_int32_t jerrno::JERR_FCNTL_FILEOFFSOVFL = 0x0403;
+const u_int32_t jerrno::JERR_FCNTL_CMPLOFFSOVFL = 0x0404;
+const u_int32_t jerrno::JERR_FCNTL_RDOFFSOVFL   = 0x0405;
+
+// class lfmgr
+const u_int32_t jerrno::JERR_LFMGR_BADAEFNUMLIM = 0x0500;
+const u_int32_t jerrno::JERR_LFMGR_AEFNUMLIMIT  = 0x0501;
+const u_int32_t jerrno::JERR_LFMGR_AEDISABLED   = 0x0502;
+
+// class rrfc
+const u_int32_t jerrno::JERR_RRFC_OPENRD        = 0x0600;
+
+// class jrec, enq_rec, deq_rec, txn_rec
+const u_int32_t jerrno::JERR_JREC_BADRECHDR     = 0x0700;
+const u_int32_t jerrno::JERR_JREC_BADRECTAIL    = 0x0701;
+
+// class wmgr
+const u_int32_t jerrno::JERR_WMGR_BADPGSTATE    = 0x0801;
+const u_int32_t jerrno::JERR_WMGR_BADDTOKSTATE  = 0x0802;
+const u_int32_t jerrno::JERR_WMGR_ENQDISCONT    = 0x0803;
+const u_int32_t jerrno::JERR_WMGR_DEQDISCONT    = 0x0804;
+const u_int32_t jerrno::JERR_WMGR_DEQRIDNOTENQ  = 0x0805;
+
+// class rmgr
+const u_int32_t jerrno::JERR_RMGR_UNKNOWNMAGIC  = 0x0900;
+const u_int32_t jerrno::JERR_RMGR_RIDMISMATCH   = 0x0901;
+//const u_int32_t jerrno::JERR_RMGR_FIDMISMATCH   = 0x0902;
+const u_int32_t jerrno::JERR_RMGR_ENQSTATE      = 0x0903;
+const u_int32_t jerrno::JERR_RMGR_BADRECTYPE    = 0x0904;
+
+// class data_tok
+const u_int32_t jerrno::JERR_DTOK_ILLEGALSTATE  = 0x0a00;
+// const u_int32_t jerrno::JERR_DTOK_RIDNOTSET     = 0x0a01;
+
+// class enq_map, txn_map
+const u_int32_t jerrno::JERR_MAP_DUPLICATE      = 0x0b00;
+const u_int32_t jerrno::JERR_MAP_NOTFOUND       = 0x0b01;
+const u_int32_t jerrno::JERR_MAP_LOCKED         = 0x0b02;
+
+// class jinf
+const u_int32_t jerrno::JERR_JINF_CVALIDFAIL    = 0x0c00;
+const u_int32_t jerrno::JERR_JINF_NOVALUESTR    = 0x0c01;
+const u_int32_t jerrno::JERR_JINF_BADVALUESTR   = 0x0c02;
+const u_int32_t jerrno::JERR_JINF_JDATEMPTY     = 0x0c03;
+const u_int32_t jerrno::JERR_JINF_TOOMANYFILES  = 0x0c04;
+const u_int32_t jerrno::JERR_JINF_INVALIDFHDR   = 0x0c05;
+const u_int32_t jerrno::JERR_JINF_STAT          = 0x0c06;
+const u_int32_t jerrno::JERR_JINF_NOTREGFILE    = 0x0c07;
+const u_int32_t jerrno::JERR_JINF_BADFILESIZE   = 0x0c08;
+const u_int32_t jerrno::JERR_JINF_OWIBAD        = 0x0c09;
+const u_int32_t jerrno::JERR_JINF_ZEROLENFILE   = 0x0c0a;
+
+// Negative returns for some functions
+const int32_t jerrno::AIO_TIMEOUT               = -1;
+const int32_t jerrno::LOCK_TAKEN                = -2;
+
+
+// static initialization fn
+
+bool
+jerrno::__init()
+{
+    // generic errors
+    _err_map[JERR__MALLOC] = "JERR__MALLOC: Buffer memory allocation failed.";
+    _err_map[JERR__UNDERFLOW] = "JERR__UNDERFLOW: Underflow error";
+    _err_map[JERR__NINIT] = "JERR__NINIT: Operation on uninitialized class.";
+    _err_map[JERR__AIO] = "JERR__AIO: AIO error.";
+    _err_map[JERR__FILEIO] = "JERR__FILEIO: File read or write failure.";
+    _err_map[JERR__RTCLOCK] = "JERR__RTCLOCK: Reading real-time clock failed.";
+    _err_map[JERR__PTHREAD] = "JERR__PTHREAD: pthread failure.";
+    _err_map[JERR__TIMEOUT] = "JERR__TIMEOUT: Timeout waiting for event.";
+    _err_map[JERR__UNEXPRESPONSE] = "JERR__UNEXPRESPONSE: Unexpected response to call or event.";
+    _err_map[JERR__RECNFOUND] = "JERR__RECNFOUND: Record not found.";
+    _err_map[JERR__NOTIMPL] = "JERR__NOTIMPL: Not implemented";
+
+    // class jcntl
+    _err_map[JERR_JCNTL_STOPPED] = "JERR_JCNTL_STOPPED: Operation on stopped journal.";
+    _err_map[JERR_JCNTL_READONLY] = "JERR_JCNTL_READONLY: Write operation on read-only journal (during recovery).";
+    _err_map[JERR_JCNTL_AIOCMPLWAIT] = "JERR_JCNTL_AIOCMPLWAIT: Timeout waiting for AIOs to complete.";
+    _err_map[JERR_JCNTL_UNKNOWNMAGIC] = "JERR_JCNTL_UNKNOWNMAGIC: Found record with unknown magic.";
+    _err_map[JERR_JCNTL_NOTRECOVERED] = "JERR_JCNTL_NOTRECOVERED: Operation requires recover() to be run first.";
+    _err_map[JERR_JCNTL_RECOVERJFULL] = "JERR_JCNTL_RECOVERJFULL: Journal data files full, cannot write.";
+    _err_map[JERR_JCNTL_OWIMISMATCH] = "JERR_JCNTL_OWIMISMATCH: Overwrite Indicator (OWI) change found in unexpected location.";
+
+    // class jdir
+    _err_map[JERR_JDIR_NOTDIR] = "JERR_JDIR_NOTDIR: Directory name exists but is not a directory.";
+    _err_map[JERR_JDIR_MKDIR] = "JERR_JDIR_MKDIR: Directory creation failed.";
+    _err_map[JERR_JDIR_OPENDIR] = "JERR_JDIR_OPENDIR: Directory open failed.";
+    _err_map[JERR_JDIR_READDIR] = "JERR_JDIR_READDIR: Directory read failed.";
+    _err_map[JERR_JDIR_CLOSEDIR] = "JERR_JDIR_CLOSEDIR: Directory close failed.";
+    _err_map[JERR_JDIR_RMDIR] = "JERR_JDIR_RMDIR: Directory delete failed.";
+    _err_map[JERR_JDIR_NOSUCHFILE] = "JERR_JDIR_NOSUCHFILE: File does not exist.";
+    _err_map[JERR_JDIR_FMOVE] = "JERR_JDIR_FMOVE: File move failed.";
+    _err_map[JERR_JDIR_STAT] = "JERR_JDIR_STAT: File stat failed.";
+    _err_map[JERR_JDIR_UNLINK] = "JERR_JDIR_UNLINK: File delete failed.";
+    _err_map[JERR_JDIR_BADFTYPE] = "JERR_JDIR_BADFTYPE: Bad or unknown file type (stat mode).";
+
+    // class fcntl
+    _err_map[JERR_FCNTL_OPENWR] = "JERR_FCNTL_OPENWR: Unable to open file for write.";
+    _err_map[JERR_FCNTL_WRITE] = "JERR_FCNTL_WRITE: Unable to write to file.";
+    _err_map[JERR_FCNTL_CLOSE] = "JERR_FCNTL_CLOSE: File close failed.";
+    _err_map[JERR_FCNTL_FILEOFFSOVFL] = "JERR_FCNTL_FILEOFFSOVFL: Attempted increase file offset past file size.";
+    _err_map[JERR_FCNTL_CMPLOFFSOVFL] = "JERR_FCNTL_CMPLOFFSOVFL: Attempted increase completed file offset past submitted offset.";
+    _err_map[JERR_FCNTL_RDOFFSOVFL] = "JERR_FCNTL_RDOFFSOVFL: Attempted increase read offset past write offset.";
+
+    // class lfmgr
+    _err_map[JERR_LFMGR_BADAEFNUMLIM] = "JERR_LFMGR_BADAEFNUMLIM: Auto-expand file number limit lower than initial number of journal files.";
+    _err_map[JERR_LFMGR_AEFNUMLIMIT] = "JERR_LFMGR_AEFNUMLIMIT: Exceeded auto-expand file number limit.";
+    _err_map[JERR_LFMGR_AEDISABLED] = "JERR_LFMGR_AEDISABLED: Attempted to expand with auto-expand disabled.";
+
+    // class rrfc
+    _err_map[JERR_RRFC_OPENRD] = "JERR_RRFC_OPENRD: Unable to open file for read.";
+
+    // class jrec, enq_rec, deq_rec, txn_rec
+    _err_map[JERR_JREC_BADRECHDR] = "JERR_JREC_BADRECHDR: Invalid data record header.";
+    _err_map[JERR_JREC_BADRECTAIL] = "JERR_JREC_BADRECTAIL: Invalid data record tail.";
+
+    // class wmgr
+    _err_map[JERR_WMGR_BADPGSTATE] = "JERR_WMGR_BADPGSTATE: Page buffer in illegal state for operation.";
+    _err_map[JERR_WMGR_BADDTOKSTATE] = "JERR_WMGR_BADDTOKSTATE: Data token in illegal state for operation.";
+    _err_map[JERR_WMGR_ENQDISCONT] = "JERR_WMGR_ENQDISCONT: Enqueued new dtok when previous enqueue returned partly completed (state ENQ_PART).";
+    _err_map[JERR_WMGR_DEQDISCONT] = "JERR_WMGR_DEQDISCONT: Dequeued new dtok when previous dequeue returned partly completed (state DEQ_PART).";
+    _err_map[JERR_WMGR_DEQRIDNOTENQ] = "JERR_WMGR_DEQRIDNOTENQ: Dequeue rid is not enqueued.";
+
+    // class rmgr
+    _err_map[JERR_RMGR_UNKNOWNMAGIC] = "JERR_RMGR_UNKNOWNMAGIC: Found record with unknown magic.";
+    _err_map[JERR_RMGR_RIDMISMATCH] = "JERR_RMGR_RIDMISMATCH: RID mismatch between current record and dtok RID";
+    //_err_map[JERR_RMGR_FIDMISMATCH] = "JERR_RMGR_FIDMISMATCH: FID mismatch between emap and rrfc";
+    _err_map[JERR_RMGR_ENQSTATE] = "JERR_RMGR_ENQSTATE: Attempted read when data token wstate was not ENQ";
+    _err_map[JERR_RMGR_BADRECTYPE] = "JERR_RMGR_BADRECTYPE: Attempted operation on inappropriate record type";
+
+    // class data_tok
+    _err_map[JERR_DTOK_ILLEGALSTATE] = "JERR_MTOK_ILLEGALSTATE: Attempted to change to illegal state.";
+    //_err_map[JERR_DTOK_RIDNOTSET] = "JERR_DTOK_RIDNOTSET: Record ID not set.";
+
+    // class enq_map, txn_map
+    _err_map[JERR_MAP_DUPLICATE] = "JERR_MAP_DUPLICATE: Attempted to insert record into map using duplicate key.";
+    _err_map[JERR_MAP_NOTFOUND] = "JERR_MAP_NOTFOUND: Key not found in map.";
+    _err_map[JERR_MAP_LOCKED] = "JERR_MAP_LOCKED: Record ID locked by a pending transaction.";
+
+    // class jinf
+    _err_map[JERR_JINF_CVALIDFAIL] = "JERR_JINF_CVALIDFAIL: Journal compatibility validation failure.";
+    _err_map[JERR_JINF_NOVALUESTR] = "JERR_JINF_NOVALUESTR: No value attribute found in jinf file.";
+    _err_map[JERR_JINF_BADVALUESTR] = "JERR_JINF_BADVALUESTR: Bad format for value attribute in jinf file";
+    _err_map[JERR_JINF_JDATEMPTY] = "JERR_JINF_JDATEMPTY: Journal data files empty.";
+    _err_map[JERR_JINF_TOOMANYFILES] = "JERR_JINF_TOOMANYFILES: Too many journal data files.";
+    _err_map[JERR_JINF_INVALIDFHDR] = "JERR_JINF_INVALIDFHDR: Invalid journal data file header";
+    _err_map[JERR_JINF_STAT] = "JERR_JINF_STAT: Error while trying to stat a journal data file";
+    _err_map[JERR_JINF_NOTREGFILE] = "JERR_JINF_NOTREGFILE: Target journal data file is not a regular file";
+    _err_map[JERR_JINF_BADFILESIZE] = "JERR_JINF_BADFILESIZE: Journal data file is of incorrect or unexpected size";
+    _err_map[JERR_JINF_OWIBAD] = "JERR_JINF_OWIBAD: Journal data files have inconsistent OWI flags; >1 transition found in non-auto-expand or min-size journal";
+    _err_map[JERR_JINF_ZEROLENFILE] = "JERR_JINF_ZEROLENFILE: Journal info file zero length";
+
+    //_err_map[] = "";
+
+    return true;
+}
+
+const char*
+jerrno::err_msg(const u_int32_t err_no) throw ()
+{
+    _err_map_itr = _err_map.find(err_no);
+    if (_err_map_itr == _err_map.end())
+        return "<Unknown error code>";
+    return _err_map_itr->second;
+}
+
+} // namespace journal
+} // namespace mrg

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,176 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jerrno.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::jerrno (journal error
+ * codes). See class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jerrno_hpp
+#define mrg_journal_jerrno_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jerrno;
+}
+}
+
+#include <map>
+#include <string>
+#include <sys/types.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+    /**
+    * \class jerrno
+    * \brief Class containing static error definitions and static map for error messages.
+    */
+    class jerrno
+    {
+        static std::map<u_int32_t, const char*> _err_map; ///< Map of error messages
+        static std::map<u_int32_t, const char*>::iterator _err_map_itr; ///< Iterator
+        static bool _initialized;                       ///< Dummy flag, used to initialise map.
+
+    public:
+        // generic errors
+        static const u_int32_t JERR__MALLOC;            ///< Buffer memory allocation failed
+        static const u_int32_t JERR__UNDERFLOW;         ///< Underflow error
+        static const u_int32_t JERR__NINIT;             ///< Operation on uninitialized class
+        static const u_int32_t JERR__AIO;               ///< AIO failure
+        static const u_int32_t JERR__FILEIO;            ///< File read or write failure
+        static const u_int32_t JERR__RTCLOCK;           ///< Reading real-time clock failed
+        static const u_int32_t JERR__PTHREAD;           ///< pthread failure
+        static const u_int32_t JERR__TIMEOUT;           ///< Timeout waiting for an event
+        static const u_int32_t JERR__UNEXPRESPONSE;     ///< Unexpected response to call or event
+        static const u_int32_t JERR__RECNFOUND;         ///< Record not found
+        static const u_int32_t JERR__NOTIMPL;           ///< Not implemented
+
+        // class jcntl
+        static const u_int32_t JERR_JCNTL_STOPPED;      ///< Operation on stopped journal
+        static const u_int32_t JERR_JCNTL_READONLY;     ///< Write operation on read-only journal
+        static const u_int32_t JERR_JCNTL_AIOCMPLWAIT;  ///< Timeout waiting for AIOs to complete
+        static const u_int32_t JERR_JCNTL_UNKNOWNMAGIC; ///< Found record with unknown magic
+        static const u_int32_t JERR_JCNTL_NOTRECOVERED; ///< Req' recover() to be called first
+        static const u_int32_t JERR_JCNTL_RECOVERJFULL; ///< Journal data files full, cannot write
+        static const u_int32_t JERR_JCNTL_OWIMISMATCH;  ///< OWI change found in unexpected location
+
+        // class jdir
+        static const u_int32_t JERR_JDIR_NOTDIR;        ///< Exists but is not a directory
+        static const u_int32_t JERR_JDIR_MKDIR;         ///< Directory creation failed
+        static const u_int32_t JERR_JDIR_OPENDIR;       ///< Directory open failed
+        static const u_int32_t JERR_JDIR_READDIR;       ///< Directory read failed
+        static const u_int32_t JERR_JDIR_CLOSEDIR;      ///< Directory close failed
+        static const u_int32_t JERR_JDIR_RMDIR;         ///< Directory delete failed
+        static const u_int32_t JERR_JDIR_NOSUCHFILE;    ///< File does not exist
+        static const u_int32_t JERR_JDIR_FMOVE;         ///< File move failed
+        static const u_int32_t JERR_JDIR_STAT;          ///< File stat failed
+        static const u_int32_t JERR_JDIR_UNLINK;        ///< File delete failed
+        static const u_int32_t JERR_JDIR_BADFTYPE;      ///< Bad or unknown file type (stat mode)
+
+        // class fcntl
+        static const u_int32_t JERR_FCNTL_OPENWR;       ///< Unable to open file for write
+        static const u_int32_t JERR_FCNTL_WRITE;        ///< Unable to write to file
+        static const u_int32_t JERR_FCNTL_CLOSE;        ///< File close failed
+        static const u_int32_t JERR_FCNTL_FILEOFFSOVFL; ///< Increased offset past file size
+        static const u_int32_t JERR_FCNTL_CMPLOFFSOVFL; ///< Increased cmpl offs past subm offs
+        static const u_int32_t JERR_FCNTL_RDOFFSOVFL;   ///< Increased read offs past write offs
+
+        // class lfmgr
+        static const u_int32_t JERR_LFMGR_BADAEFNUMLIM; ///< Bad auto-expand file number limit
+        static const u_int32_t JERR_LFMGR_AEFNUMLIMIT;  ///< Exceeded auto-expand file number limit
+        static const u_int32_t JERR_LFMGR_AEDISABLED;   ///< Attempted to expand with auto-expand disabled
+
+        // class rrfc
+        static const u_int32_t JERR_RRFC_OPENRD;        ///< Unable to open file for read
+
+        // class jrec, enq_rec, deq_rec, txn_rec
+        static const u_int32_t JERR_JREC_BADRECHDR;     ///< Invalid data record header
+        static const u_int32_t JERR_JREC_BADRECTAIL;    ///< Invalid data record tail
+
+        // class wmgr
+        static const u_int32_t JERR_WMGR_BADPGSTATE;    ///< Page buffer in illegal state.
+        static const u_int32_t JERR_WMGR_BADDTOKSTATE;  ///< Data token in illegal state.
+        static const u_int32_t JERR_WMGR_ENQDISCONT;    ///< Enq. new dtok when previous part compl.
+        static const u_int32_t JERR_WMGR_DEQDISCONT;    ///< Deq. new dtok when previous part compl.
+        static const u_int32_t JERR_WMGR_DEQRIDNOTENQ;  ///< Deq. rid not enqueued
+
+        // class rmgr
+        static const u_int32_t JERR_RMGR_UNKNOWNMAGIC;  ///< Found record with unknown magic
+        static const u_int32_t JERR_RMGR_RIDMISMATCH;   ///< RID mismatch between rec and dtok
+        //static const u_int32_t JERR_RMGR_FIDMISMATCH;   ///< FID mismatch between emap and rrfc
+        static const u_int32_t JERR_RMGR_ENQSTATE;      ///< Attempted read when wstate not ENQ
+        static const u_int32_t JERR_RMGR_BADRECTYPE;    ///< Attempted op on incorrect rec type
+
+        // class data_tok
+        static const u_int32_t JERR_DTOK_ILLEGALSTATE;  ///< Attempted to change to illegal state
+//         static const u_int32_t JERR_DTOK_RIDNOTSET;     ///< Record ID not set
+
+        // class enq_map, txn_map
+        static const u_int32_t JERR_MAP_DUPLICATE;      ///< Attempted to insert using duplicate key
+        static const u_int32_t JERR_MAP_NOTFOUND;       ///< Key not found in map
+        static const u_int32_t JERR_MAP_LOCKED;         ///< rid locked by pending txn
+
+        // class jinf
+        static const u_int32_t JERR_JINF_CVALIDFAIL;    ///< Compatibility validation failure
+        static const u_int32_t JERR_JINF_NOVALUESTR;    ///< No value attr found in jinf file
+        static const u_int32_t JERR_JINF_BADVALUESTR;   ///< Bad format for value attr in jinf file
+        static const u_int32_t JERR_JINF_JDATEMPTY;     ///< Journal data files empty
+        static const u_int32_t JERR_JINF_TOOMANYFILES;  ///< Too many journal data files
+        static const u_int32_t JERR_JINF_INVALIDFHDR;   ///< Invalid file header
+        static const u_int32_t JERR_JINF_STAT;          ///< Error while trying to stat a file
+        static const u_int32_t JERR_JINF_NOTREGFILE;    ///< Target file is not a regular file
+        static const u_int32_t JERR_JINF_BADFILESIZE;   ///< File is of incorrect or unexpected size
+        static const u_int32_t JERR_JINF_OWIBAD;        ///< OWI inconsistent (>1 transition in non-ae journal)
+        static const u_int32_t JERR_JINF_ZEROLENFILE;   ///< Journal info file is zero length (empty).
+
+        // Negative returns for some functions
+        static const int32_t AIO_TIMEOUT;               ///< Timeout waiting for AIO return
+        static const int32_t LOCK_TAKEN;                ///< Attempted to take lock, but it was taken by another thread
+        /**
+        * \brief Method to access error message from known error number.
+        */
+        static const char* err_msg(const u_int32_t err_no) throw ();
+
+    private:
+        /**
+        * \brief Static function to initialize map.
+        */
+        static bool __init();
+    };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jerrno_hpp

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,186 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jexception.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * Generic journal exception class mrg::journal::jexception. See comments
+ * in file jexception.hpp for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jexception.hpp"
+
+#include <iomanip>
+#include <sstream>
+#include "jrnl/jerrno.hpp"
+
+#define CATLEN(p) MAX_MSG_SIZE - std::strlen(p) - 1
+
+namespace mrg
+{
+namespace journal
+{
+
+jexception::jexception() throw ():
+        std::exception(),
+        _err_code(0)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code) throw ():
+        std::exception(),
+        _err_code(err_code)
+{
+    format();
+}
+
+jexception::jexception(const char* additional_info) throw ():
+        std::exception(),
+        _err_code(0),
+        _additional_info(additional_info)
+{
+    format();
+}
+
+jexception::jexception(const std::string& additional_info) throw ():
+        std::exception(),
+        _err_code(0),
+        _additional_info(additional_info)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code, const char* additional_info) throw ():
+        std::exception(),
+        _err_code(err_code),
+        _additional_info(additional_info)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code, const std::string& additional_info) throw ():
+        std::exception(),
+        _err_code(err_code),
+        _additional_info(additional_info)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code, const char* throwing_class,
+        const char* throwing_fn) throw ():
+        std::exception(),
+        _err_code(err_code),
+        _throwing_class(throwing_class),
+        _throwing_fn(throwing_fn)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code, const std::string& throwing_class,
+        const std::string& throwing_fn) throw ():
+        std::exception(),
+        _err_code(err_code),
+        _throwing_class(throwing_class),
+        _throwing_fn(throwing_fn)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code, const char* additional_info,
+        const char* throwing_class, const char* throwing_fn) throw ():
+        std::exception(),
+        _err_code(err_code),
+        _additional_info(additional_info),
+        _throwing_class(throwing_class),
+        _throwing_fn(throwing_fn)
+{
+    format();
+}
+
+jexception::jexception(const u_int32_t err_code, const std::string& additional_info,
+        const std::string& throwing_class, const std::string& throwing_fn) throw ():
+        std::exception(),
+        _err_code(err_code),
+        _additional_info(additional_info),
+        _throwing_class(throwing_class),
+        _throwing_fn(throwing_fn)
+{
+    format();
+}
+
+jexception::~jexception() throw ()
+{}
+
+void
+jexception::format()
+{
+    const bool ai = !_additional_info.empty();
+    const bool tc = !_throwing_class.empty();
+    const bool tf = !_throwing_fn.empty();
+    std::ostringstream oss;
+    oss << "jexception 0x" << std::hex << std::setfill('0') << std::setw(4) << _err_code << " ";
+    if (tc)
+    {
+        oss << _throwing_class;
+        if (tf)
+            oss << "::";
+        else
+            oss << " ";
+    }
+    if (tf)
+        oss << _throwing_fn << "() ";
+    if (tc || tf)
+        oss << "threw " << jerrno::err_msg(_err_code);
+    if (ai)
+        oss << " (" << _additional_info << ")";
+    _what.assign(oss.str());
+}
+
+const char*
+jexception::what() const throw ()
+{
+    return _what.c_str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const jexception& je)
+{
+    os << je.what();
+    return os;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const jexception* jePtr)
+{
+    os << jePtr->what();
+    return os;
+}
+
+} // namespace journal
+} // namespace mrg

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,145 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jexception.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * Generic journal exception class mrg::journal::jexception (derived
+ * from class std::exception). Intended to serve as a common exception
+ * class for all more speicalized exceptions in the message journal. See
+ * class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jrnl_exception_hpp
+#define mrg_journal_jrnl_exception_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jexception;
+}
+}
+
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <exception>
+#include "jrnl/jerrno.hpp"
+#include <sstream>
+#include <string>
+#include <sys/types.h>
+
+// Macro for formatting commom system errors
+#define FORMAT_SYSERR(errno) " errno=" << errno << " (" << std::strerror(errno) << ")"
+
+#define MALLOC_CHK(ptr, var, cls, fn) if(ptr == 0) { \
+    clean(); \
+    std::ostringstream oss; \
+    oss << var << ": malloc() failed: " << FORMAT_SYSERR(errno); \
+    throw jexception(jerrno::JERR__MALLOC, oss.str(), cls, fn); \
+    }
+
+// TODO: The following is a temporary bug-tracking aid which forces a core.
+// Replace with the commented out version below when BZ484048 is resolved.
+#define PTHREAD_CHK(err, pfn, cls, fn) if(err != 0) { \
+    std::ostringstream oss; \
+    oss << cls << "::" << fn << "(): " << pfn; \
+    errno = err; \
+    ::perror(oss.str().c_str()); \
+    ::abort(); \
+    }
+/*
+#define PTHREAD_CHK(err, pfn, cls, fn) if(err != 0) { \
+    std::ostringstream oss; \
+    oss << pfn << " failed: " << FORMAT_SYSERR(err); \
+    throw jexception(jerrno::JERR__PTHREAD, oss.str(), cls, fn); \
+    }
+*/
+
+#define ASSERT(cond, msg) if(cond == 0) { \
+    std::cerr << msg << std::endl; \
+    ::abort(); \
+    }
+
+namespace mrg
+{
+namespace journal
+{
+    /**
+    * \class jexception
+    * \brief Generic journal exception class
+    */
+    class jexception : public std::exception
+    {
+    private:
+        u_int32_t _err_code;
+        std::string _additional_info;
+        std::string _throwing_class;
+        std::string _throwing_fn;
+        std::string _what;
+        void format();
+
+    public:
+        jexception() throw ();
+
+        jexception(const u_int32_t err_code) throw ();
+
+        jexception(const char* additional_info) throw ();
+        jexception(const std::string& additional_info) throw ();
+
+        jexception(const u_int32_t err_code, const char* additional_info) throw ();
+        jexception(const u_int32_t err_code, const std::string& additional_info) throw ();
+
+        jexception(const u_int32_t err_code, const char* throwing_class, const char* throwing_fn)
+                throw ();
+        jexception(const u_int32_t err_code, const std::string& throwing_class,
+                const std::string& throwing_fn) throw ();
+
+        jexception(const u_int32_t err_code, const char* additional_info,
+                const char* throwing_class, const char* throwing_fn) throw ();
+        jexception(const u_int32_t err_code, const std::string& additional_info,
+                const std::string& throwing_class, const std::string& throwing_fn) throw ();
+
+        virtual ~jexception() throw ();
+        virtual const char* what() const throw (); // override std::exception::what()
+
+        inline u_int32_t err_code() const throw () { return _err_code; }
+        inline const std::string additional_info() const throw () { return _additional_info; }
+        inline const std::string throwing_class() const throw () { return _throwing_class; }
+        inline const std::string throwing_fn() const throw () { return _throwing_fn; }
+
+        friend std::ostream& operator<<(std::ostream& os, const jexception& je);
+        friend std::ostream& operator<<(std::ostream& os, const jexception* jePtr);
+    }; // class jexception
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jrnl_exception_hpp

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,543 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jinf.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * This file contains the code for the mrg::journal::jinf class.
+ *
+ * See jinf.hpp comments for details of this class.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jinf.hpp"
+
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <fstream>
+#include "jrnl/file_hdr.hpp"
+#include "jrnl/jcntl.hpp"
+#include "jrnl/jerrno.hpp"
+#include "jrnl/lp_map.hpp"
+#include <sstream>
+#include <sys/stat.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+jinf::jinf(const std::string& jinf_filename, bool validate_flag):
+        _jver(0),
+        _filename(jinf_filename),
+        _num_jfiles(0),
+        _ae(false),
+        _ae_max_jfiles(0),
+        _jfsize_sblks(0),
+        _sblk_size_dblks(0),
+        _dblk_size(0),
+        _wcache_pgsize_sblks(0),
+        _wcache_num_pages(0),
+        _rcache_pgsize_sblks(0),
+        _rcache_num_pages(0),
+        _tm_ptr(0),
+        _valid_flag(false),
+        _analyzed_flag(false),
+        _initial_owi(false),
+        _frot(false)
+{
+    read(_filename);
+    if (validate_flag)
+        validate();
+}
+
+jinf::jinf(const std::string& jid, const std::string& jdir, const std::string& base_filename, const u_int16_t num_jfiles,
+        const bool auto_expand, const u_int16_t ae_max_jfiles, const u_int32_t jfsize_sblks,
+        const u_int32_t wcache_pgsize_sblks, const u_int16_t wcache_num_pages, const timespec& ts):
+        _jver(RHM_JDAT_VERSION),
+        _jid(jid),
+        _jdir(jdir),
+        _base_filename(base_filename),
+        _ts(ts),
+        _num_jfiles(num_jfiles),
+        _ae(auto_expand),
+        _ae_max_jfiles(ae_max_jfiles),
+        _jfsize_sblks(jfsize_sblks),
+        _sblk_size_dblks(JRNL_SBLK_SIZE),
+        _dblk_size(JRNL_DBLK_SIZE),
+        _wcache_pgsize_sblks(wcache_pgsize_sblks),
+        _wcache_num_pages(wcache_num_pages),
+        _rcache_pgsize_sblks(JRNL_RMGR_PAGE_SIZE),
+        _rcache_num_pages(JRNL_RMGR_PAGES),
+        _tm_ptr(std::localtime(&ts.tv_sec)),
+        _valid_flag(false),
+        _analyzed_flag(false),
+        _initial_owi(false)
+{
+    set_filename();
+}
+
+jinf::~jinf()
+{}
+
+void
+jinf::validate()
+{
+    bool err = false;
+    std::ostringstream oss;
+    if (_jver != RHM_JDAT_VERSION)
+    {
+        oss << "File \"" << _filename << "\": ";
+        oss << "RHM_JDAT_VERSION mismatch: found=" << (int)_jver;
+        oss << "; required=" << RHM_JDAT_VERSION << std::endl;
+        err = true;
+    }
+    if (_num_jfiles < JRNL_MIN_NUM_FILES)
+    {
+        oss << "File \"" << _filename << "\": ";
+        oss << "Number of journal files too small: found=" << _num_jfiles;
+        oss << "; minimum=" << JRNL_MIN_NUM_FILES << std::endl;
+        err = true;
+    }
+    if (_num_jfiles > JRNL_MAX_NUM_FILES)
+    {
+        oss << "File \"" << _filename << "\": ";
+        oss << "Number of journal files too large: found=" << _num_jfiles;
+        oss << "; maximum=" << JRNL_MAX_NUM_FILES << std::endl;
+        err = true;
+    }
+    if (_ae)
+    {
+        if (_ae_max_jfiles < _num_jfiles)
+        {
+            oss << "File \"" << _filename << "\": ";
+            oss << "Number of journal files exceeds auto-expansion limit: found=" << _num_jfiles;
+            oss << "; maximum=" << _ae_max_jfiles;
+            err = true;
+        }
+        if (_ae_max_jfiles > JRNL_MAX_NUM_FILES)
+        {
+            oss << "File \"" << _filename << "\": ";
+            oss << "Auto-expansion file limit too large: found=" << _ae_max_jfiles;
+            oss << "; maximum=" << JRNL_MAX_NUM_FILES;
+            err = true;
+        }
+    }
+    if (_jfsize_sblks < JRNL_MIN_FILE_SIZE)
+    {
+        oss << "File \"" << _filename << "\": ";
+        oss << "Journal file size too small: found=" << _jfsize_sblks;
+        oss << "; minimum=" << JRNL_MIN_FILE_SIZE << " (sblks)" << std::endl;
+        err = true;
+    }
+    if (_sblk_size_dblks != JRNL_SBLK_SIZE)
+    {
+        oss << "File \"" << _filename << "\": ";
+        oss << "JRNL_SBLK_SIZE mismatch: found=" << _sblk_size_dblks;
+        oss << "; required=" << JRNL_SBLK_SIZE << std::endl;
+        err = true;
+    }
+    if (_dblk_size != JRNL_DBLK_SIZE)
+    {
+        oss << "File \"" << _filename << "\": ";
+        oss << "JRNL_DBLK_SIZE mismatch: found=" << _dblk_size;
+        oss << "; required=" << JRNL_DBLK_SIZE << std::endl;
+        err = true;
+    }
+    if (err)
+        throw jexception(jerrno::JERR_JINF_CVALIDFAIL, oss.str(), "jinf", "validate");
+    _valid_flag = true;
+}
+
+void
+jinf::analyze()
+{
+    lp_map early_map;   // map for all owi flags same as pfid 0
+    lp_map late_map;    // map for all owi flags opposite to pfid 0
+    bool late_latch = false; // latch for owi switchover
+
+    if (!_valid_flag)
+        validate();
+    bool done = false;
+    for (u_int16_t pfid=0; pfid<_num_jfiles && !done; pfid++)
+    {
+        std::ostringstream oss;
+        if (_jdir.at(_jdir.size() - 1) == '/')
+            oss << _jdir << _base_filename << ".";
+        else
+            oss << _jdir << "/" << _base_filename << ".";
+        oss << std::setw(4) << std::setfill('0') << std::hex << pfid;
+        oss << "." << JRNL_DATA_EXTENSION;
+
+        // Check size of each file is consistent and expected
+        u_int32_t fsize = get_filesize(oss.str());
+        if (fsize != (_jfsize_sblks + 1) * _sblk_size_dblks * _dblk_size)
+        {
+            std::ostringstream oss1;
+            oss1 << "File \"" << oss.str() << "\": size=" << fsize << "; expected=" << ((_jfsize_sblks + 1) * _sblk_size_dblks * _dblk_size);
+            throw jexception(jerrno::JERR_JINF_BADFILESIZE, oss1.str(), "jinf", "analyze");
+        }
+
+        std::ifstream jifs(oss.str().c_str());
+        if (!jifs.good())
+            throw jexception(jerrno::JERR__FILEIO, oss.str(), "jinf", "analyze");
+        file_hdr fhdr;
+        jifs.read((char*)&fhdr, sizeof(fhdr));
+        if (fhdr._magic != RHM_JDAT_FILE_MAGIC) // No file header
+        {
+            if (fhdr._magic != 0)
+                throw jexception(jerrno::JERR_JINF_INVALIDFHDR, oss.str(), "jinf", "analyze");
+            if (!pfid) // pfid 0 == lid 0 cannot be empty
+                throw jexception(jerrno::JERR_JINF_JDATEMPTY, oss.str(), "jinf", "analyze");
+            _frot = true;
+            done = true;
+        }
+        else
+        {
+            assert(pfid == fhdr._pfid);
+            if (pfid == 0)
+            {
+                _initial_owi = fhdr.get_owi();
+                early_map.insert(fhdr._lfid, pfid);
+            }
+            else
+            {
+                if (_initial_owi == fhdr.get_owi())
+                {
+                    early_map.insert(fhdr._lfid, pfid);
+                    if (late_latch && (!_ae || _num_jfiles == JRNL_MIN_NUM_FILES))
+                        throw jexception(jerrno::JERR_JINF_OWIBAD, oss.str(), "jinf", "analyze");
+                }
+                else
+                {
+                    late_map.insert(fhdr._lfid, pfid);
+                    late_latch = true;
+                }
+            }
+        }
+        jifs.close();
+    } // for (pfid)
+
+    // If this is not the first rotation, all files should be in either early or late maps
+    if (!_frot) assert(early_map.size() + late_map.size() == _num_jfiles);
+
+    _pfid_list.clear();
+    late_map.get_pfid_list(_pfid_list);
+    early_map.get_pfid_list(_pfid_list);
+
+    // Check OWI consistency
+//    for (u_int16_t lfid=0; lfid<_num_jfiles && !done; lfid++)
+//    {
+//        throw jexception(jerrno::JERR_JINF_OWIBAD, oss.str(), "jinf", "analyze");
+//    }
+
+    _analyzed_flag = true;
+}
+
+void
+jinf::write()
+{
+    std::ostringstream oss;
+    oss << _jdir << "/" << _base_filename << "." << JRNL_INFO_EXTENSION;
+    std::ofstream of(oss.str().c_str(), std::ofstream::out | std::ofstream::trunc);
+    if (!of.good())
+        throw jexception(jerrno::JERR__FILEIO, oss.str(), "jinf", "write");
+    of << xml_str();
+    of.close();
+}
+
+u_int16_t
+jinf::incr_num_jfiles()
+{
+    if (_num_jfiles >= JRNL_MAX_NUM_FILES)
+        throw jexception(jerrno::JERR_JINF_TOOMANYFILES, "jinf", "incr_num_jfiles");
+    return ++_num_jfiles;
+}
+
+u_int16_t
+jinf::get_first_pfid()
+{
+    if (!_analyzed_flag)
+        analyze();
+    return *_pfid_list.begin();
+}
+
+u_int16_t
+jinf::get_last_pfid()
+{
+    if (!_analyzed_flag)
+        analyze();
+    return *_pfid_list.rbegin();
+}
+
+jinf::pfid_list&
+jinf::get_pfid_list()
+{
+    if (!_analyzed_flag)
+        analyze();
+    return _pfid_list;
+}
+
+void
+jinf::get_normalized_pfid_list(pfid_list& pfid_list)
+{
+    if (!_analyzed_flag)
+        analyze();
+    pfid_list.clear();
+    u_int16_t s = _pfid_list.size();
+    u_int16_t iz = 0; // index of 0 value
+    while (_pfid_list[iz] && iz < s)
+        iz++;
+    assert(_pfid_list[iz] == 0);
+    for (u_int16_t i = iz; i < iz + s; i++)
+        pfid_list.push_back(_pfid_list[i % s]);
+    assert(pfid_list[0] == 0);
+    assert(pfid_list.size() == s);
+}
+
+bool
+jinf::get_initial_owi()
+{
+    if (!_analyzed_flag)
+        analyze();
+    return _initial_owi;
+}
+
+bool
+jinf::get_frot()
+{
+    if (!_analyzed_flag)
+        analyze();
+    return _frot;
+}
+
+std::string
+jinf::to_string() const
+{
+    std::ostringstream oss;
+    oss << std::setfill('0');
+    oss << "Journal ID \"" << _jid << "\" initialized " << (_tm_ptr->tm_year + 1900) << "/";
+    oss << std::setw(2) << (_tm_ptr->tm_mon + 1) << "/" << std::setw(2) << _tm_ptr->tm_mday << " ";
+    oss << std::setw(2) << _tm_ptr->tm_hour << ":" << std::setw(2) << _tm_ptr->tm_min << ":";
+    oss << std::setw(2) << _tm_ptr->tm_sec << "." << std::setw(9) << _ts.tv_nsec << ":" << std::endl;
+    oss << "  Journal directory: \"" << _jdir << "\"" << std::endl;
+    oss << "  Journal base filename: \"" << _base_filename << "\"" << std::endl;
+    oss << "  Journal version: " << (unsigned)_jver << std::endl;
+    oss << "  Number of journal files: " << _num_jfiles << std::endl;
+// TODO: Uncomment these lines when auto-expand is enabled.
+//    oss << "  Auto-expand mode: " << (_ae ? "enabled" : "disabled") << std::endl;
+//    if (_ae) oss << "  Max. number of journal files (in auto-expand mode): " << _ae_max_jfiles << std::endl;
+    oss << "  Journal file size: " << _jfsize_sblks << " sblks" << std::endl;
+    oss << "  Softblock size (JRNL_SBLK_SIZE): " << _sblk_size_dblks << " dblks" << std::endl;
+    oss << "  Datablock size (JRNL_DBLK_SIZE): " << _dblk_size << " bytes" << std::endl;
+    oss << "  Write page size: " << _wcache_pgsize_sblks << " sblks" << std::endl;
+    oss << "  Number of write pages: " << _wcache_num_pages << std::endl;
+    oss << "  Read page size (JRNL_RMGR_PAGE_SIZE): " << _rcache_pgsize_sblks << " sblks" << std::endl;
+    oss << "  Number of read pages (JRNL_RMGR_PAGES): " << _rcache_num_pages << std::endl;
+    return oss.str();
+}
+
+std::string
+jinf::xml_str() const
+{
+    // TODO: This is *not* an XML writer, rather for simplicity, it uses literals. I'm sure a more elegant way can be
+    // found to do this using the real thing...
+
+    std::ostringstream oss;
+    oss << std::setfill('0');
+    oss << "<?xml version=\"1.0\" ?>" << std::endl;
+    oss << "<jrnl>" << std::endl;
+    oss << "  <journal_version value=\"" << (unsigned)_jver << "\" />" << std::endl;
+    oss << "  <journal_id>" << std::endl;
+    oss << "    <id_string value=\"" << _jid << "\" />" << std::endl;
+    oss << "    <directory value=\"" << _jdir << "\" />" << std::endl;
+    oss << "    <base_filename value=\"" << _base_filename << "\" />" << std::endl;
+    oss << "  </journal_id>" << std::endl;
+    oss << "  <creation_time>" << std::endl;
+    oss << "    <seconds value=\"" << _ts.tv_sec << "\" />" << std::endl;
+    oss << "    <nanoseconds value=\"" << _ts.tv_nsec << "\" />" << std::endl;
+    oss << "    <string value=\"" << (_tm_ptr->tm_year + 1900) << "/";
+    oss << std::setw(2) << (_tm_ptr->tm_mon + 1) << "/" << std::setw(2) << _tm_ptr->tm_mday << " ";
+    oss << std::setw(2) << _tm_ptr->tm_hour << ":" << std::setw(2) << _tm_ptr->tm_min << ":";
+    oss << std::setw(2) << _tm_ptr->tm_sec << "." << std::setw(9) << _ts.tv_nsec;
+    oss << "\" />" << std::endl;
+    oss << "  </creation_time>" << std::endl;
+    oss << "  <journal_file_geometry>" << std::endl;
+    oss << "    <number_jrnl_files value=\"" << _num_jfiles << "\" />" << std::endl;
+    oss << "    <auto_expand value=\"" << (_ae ? "true" : "false") << "\" />" << std::endl;
+    if (_ae) oss << "    <auto_expand_max_jrnl_files value=\"" << _ae_max_jfiles << "\" />" << std::endl;
+    oss << "    <jrnl_file_size_sblks value=\"" << _jfsize_sblks << "\" />" << std::endl;
+    oss << "    <JRNL_SBLK_SIZE value=\"" << _sblk_size_dblks << "\" />" << std::endl;
+    oss << "    <JRNL_DBLK_SIZE value=\"" << _dblk_size << "\" />" << std::endl;
+    oss << "  </journal_file_geometry>" << std::endl;
+    oss << "  <cache_geometry>" << std::endl;
+    oss << "    <wcache_pgsize_sblks value=\"" << _wcache_pgsize_sblks << "\" />" << std::endl;
+    oss << "    <wcache_num_pages value=\"" << _wcache_num_pages << "\" />" << std::endl;
+    oss << "    <JRNL_RMGR_PAGE_SIZE value=\"" << _rcache_pgsize_sblks << "\" />" << std::endl;
+    oss << "    <JRNL_RMGR_PAGES value=\"" << _rcache_num_pages << "\" />" << std::endl;
+    oss << "  </cache_geometry>" << std::endl;
+    oss << "</jrnl>" << std::endl;
+    return oss.str();
+}
+
+void
+jinf::set_filename()
+{
+    std::ostringstream oss;
+    oss << _jdir << "/" << _base_filename << "." << JRNL_INFO_EXTENSION;
+    _filename = oss.str().c_str();
+}
+
+void
+jinf::read(const std::string& jinf_filename)
+{
+    // TODO: This is *not* an XML reader, rather for simplicity, it is a brute-force line reader which relies on string
+    // recognition. It relies on the format of xml_str() above; it will not handle a XML restructuring.
+    // *** Can it be replaced cheaply by a real XML reader? Should it be, or is this sufficient? ***
+
+    char buff[1024]; // limit of line input length
+    std::ifstream jinfs(jinf_filename.c_str());
+    if (!jinfs.good())
+        throw jexception(jerrno::JERR__FILEIO, jinf_filename.c_str(), "jinf", "read");
+    u_int32_t charcnt = 0;
+    while (jinfs.good())
+    {
+        jinfs.getline(buff, 1023);
+        charcnt += std::strlen(buff);
+        if (std::strstr(buff, "journal_version"))
+            _jver = u_int16_value(buff);
+        else if(std::strstr(buff, "id_string"))
+            string_value(_jid, buff);
+        else if(std::strstr(buff, "directory"))
+            string_value(_jdir, buff);
+        else if(std::strstr(buff, "base_filename"))
+            string_value(_base_filename, buff);
+        else if(std::strstr(buff, "number_jrnl_files"))
+            _num_jfiles = u_int16_value(buff);
+        else if(std::strstr(buff, "auto_expand_max_jrnl_files"))
+            _ae_max_jfiles = u_int16_value(buff);
+        else if(std::strstr(buff, "auto_expand"))
+            _ae = bool_value(buff);
+        else if(std::strstr(buff, "jrnl_file_size_sblks"))
+            _jfsize_sblks = u_int32_value(buff);
+        else if(std::strstr(buff, "JRNL_SBLK_SIZE"))
+            _sblk_size_dblks = u_int16_value(buff);
+        else if(std::strstr(buff, "JRNL_DBLK_SIZE"))
+            _dblk_size = u_int32_value(buff);
+        else if(std::strstr(buff, "wcache_pgsize_sblks"))
+            _wcache_pgsize_sblks = u_int32_value(buff);
+        else if(std::strstr(buff, "wcache_num_pages"))
+            _wcache_num_pages = u_int32_value(buff);
+        else if(std::strstr(buff, "JRNL_RMGR_PAGE_SIZE"))
+            _rcache_pgsize_sblks = u_int32_value(buff);
+        else if(std::strstr(buff, "JRNL_RMGR_PAGES"))
+            _rcache_num_pages = u_int32_value(buff);
+        else if(std::strstr(buff, "nanoseconds"))
+            _ts.tv_nsec = u_int32_value(buff);
+        else if(std::strstr(buff, "seconds"))
+        {
+            _ts.tv_sec = u_int32_value(buff);
+            _tm_ptr = std::localtime(&_ts.tv_sec);
+        }
+    }
+    jinfs.close();
+    if (charcnt == 0)
+        throw jexception(jerrno::JERR_JINF_ZEROLENFILE, jinf_filename.c_str(), "jinf", "read");
+}
+
+bool
+jinf::bool_value(char* line) const
+{
+    return std::strcmp(find_value(line), "true") == 0;
+}
+
+u_int16_t
+jinf::u_int16_value(char* line) const
+{
+    return std::atoi(find_value(line));
+}
+
+u_int32_t
+jinf::u_int32_value(char* line) const
+{
+    return std::atol(find_value(line));
+}
+
+std::string&
+jinf::string_value(std::string& str, char* line) const
+{
+    str.assign(find_value(line));
+    return str;
+}
+
+char*
+jinf::find_value(char* line) const
+{
+    const char* target1_str = "value=\"";
+    int target2_char = '\"';
+    char* t1 = std::strstr(line, target1_str);
+    if (t1 == 0)
+    {
+        std::ostringstream oss;
+        oss << "File \"" << _filename << "\": line=" << line;
+        throw jexception(jerrno::JERR_JINF_NOVALUESTR, oss.str(), "jinf", "find_value");
+    }
+    t1 += std::strlen(target1_str);
+
+    char* t2 = std::strchr(t1, target2_char);
+    if (t2 == 0)
+    {
+        std::ostringstream oss;
+        oss << "File \"" << _filename << "\": line=" << line;
+        throw jexception(jerrno::JERR_JINF_BADVALUESTR, oss.str(), "jinf", "find_value");
+    }
+    *t2 = '\0';
+    return t1;
+}
+
+u_int32_t
+jinf::get_filesize(const std::string& file_name) const
+{
+    struct stat s;
+    if (::stat(file_name.c_str(), &s))
+    {
+        std::ostringstream oss;
+        oss << "stat: file=\"" << file_name << "\"" << FORMAT_SYSERR(errno);
+        throw jexception(jerrno::JERR_JINF_STAT, oss.str(), "jinf", "get_filesize");
+    }
+    if (!S_ISREG(s.st_mode)) // not a regular file,
+    {
+        std::ostringstream oss;
+        oss << "File \"" << file_name << "\" is not a regular file: mode=0x" << std::hex << s.st_mode;
+        throw jexception(jerrno::JERR_JINF_NOTREGFILE, oss.str(), "jinf", "get_filesize");
+    }
+    return u_int32_t(s.st_size);
+}
+
+} // namespace journal
+} // namespace mrg

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jinf.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * This file contains the code for the mrg::journal::jinf class.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jinf_hpp
+#define mrg_journal_jinf_hpp
+
+#include <ctime>
+#include <string>
+#include <sys/types.h>
+#include <vector>
+
+namespace mrg
+{
+namespace journal
+{
+    /**
+    * \class jinf
+    * \brief Class to handle the journal information file &lt;basename&gt;.jinf.
+    */
+    class jinf
+    {
+    public:
+        typedef std::vector<u_int16_t> pfid_list; // pfids
+        typedef pfid_list::const_iterator pfidl_citr;
+
+    private:
+        u_int8_t _jver;
+        std::string _jid;
+        std::string _jdir;
+        std::string _base_filename;
+        std::string _filename;
+        timespec _ts;
+        u_int16_t _num_jfiles;
+        bool _ae;
+        u_int32_t _ae_max_jfiles;
+        u_int32_t _jfsize_sblks;
+        u_int16_t _sblk_size_dblks;
+        u_int32_t _dblk_size;
+        u_int32_t _wcache_pgsize_sblks;
+        u_int16_t _wcache_num_pages;
+        u_int32_t _rcache_pgsize_sblks;
+        u_int16_t _rcache_num_pages;
+        std::tm* _tm_ptr;
+        bool _valid_flag;
+        bool _analyzed_flag;
+        pfid_list _pfid_list;
+        bool _initial_owi;
+        bool _frot;
+
+    public:
+        // constructor for reading existing jinf file
+        jinf(const std::string& jinf_filename, bool validate_flag);
+        // constructor for writing jinf file
+        jinf(const std::string& jid, const std::string& jdir, const std::string& base_filename,
+                const u_int16_t num_jfiles, const bool auto_expand, const u_int16_t ae_max_jfiles,
+                const u_int32_t jfsize_sblks, const u_int32_t wcache_pgsize_sblks, const u_int16_t wcache_num_pages,
+                const timespec& ts);
+        virtual ~jinf();
+
+        void validate();
+        void analyze();
+        void write();
+
+        inline u_int8_t jver() const { return _jver; }
+        inline const std::string& jid() const { return _jid; }
+        inline const std::string& jdir() const { return _jdir; }
+        inline void set_jdir(const std::string& jdir) { _jdir = jdir; }
+        inline const std::string& base_filename() const { return _base_filename; }
+        inline const timespec& ts() const { return _ts; }
+        inline u_int16_t num_jfiles() const { return _num_jfiles; }
+        u_int16_t incr_num_jfiles();
+        inline bool is_ae() const { return _ae; }
+        inline u_int16_t ae_max_jfiles() const { return _ae_max_jfiles; }
+        inline u_int32_t jfsize_sblks() const { return _jfsize_sblks; }
+        inline u_int16_t sblk_size_dblks() const { return _sblk_size_dblks; }
+        inline u_int32_t dblk_size() const { return _dblk_size; }
+        inline u_int32_t wcache_pgsize_sblks() const { return _wcache_pgsize_sblks; }
+        inline u_int16_t wcache_num_pages() const { return _wcache_num_pages; }
+        inline u_int32_t rcache_pgsize_sblks() const { return _rcache_pgsize_sblks; }
+        inline u_int16_t rcache_num_pages() const { return _rcache_num_pages; }
+        u_int16_t get_first_pfid();
+        u_int16_t get_last_pfid();
+        pfid_list& get_pfid_list();
+        void get_normalized_pfid_list(pfid_list& pfid_list);
+        bool get_initial_owi();
+        bool get_frot();
+
+        std::string to_string() const;
+        std::string xml_str() const;
+
+    private:
+        void set_filename();
+        void read(const std::string& jinf_filename);
+        bool bool_value(char* line) const;
+        u_int16_t u_int16_value(char* line) const;
+        u_int32_t u_int32_value(char* line) const;
+        std::string& string_value(std::string& str, char* line) const;
+        char* find_value(char* line) const;
+        u_int32_t get_filesize(const std::string& file_name) const;
+    };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jinf_hpp

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,122 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jrec.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing source code for class mrg::journal::jrec (abstract journal
+ * jrecord). See comments in file jrec.hpp for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jrec.hpp"
+
+#include <iomanip>
+#include "jrnl/jerrno.hpp"
+#include "jrnl/jexception.hpp"
+#include <sstream>
+
+namespace mrg
+{
+namespace journal
+{
+
+jrec::jrec() {}
+jrec::~jrec() {}
+
+void
+jrec::chk_hdr(const rec_hdr& hdr)
+{
+    if (hdr._magic == 0)
+    {
+        std::ostringstream oss;
+        oss << std::hex << std::setfill('0');
+        oss << "enq magic NULL: rid=0x" << hdr._rid;
+        throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+    }
+    if (hdr._version != RHM_JDAT_VERSION)
+    {
+        std::ostringstream oss;
+        oss << std::hex << std::setfill('0');
+        oss << "version: rid=0x" << hdr._rid;
+        oss << ": expected=0x" << std::setw(2) << (int)RHM_JDAT_VERSION;
+        oss << " read=0x" << std::setw(2) << (int)hdr._version;
+        throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+    }
+#if defined (JRNL_LITTLE_ENDIAN)
+    u_int8_t endian_flag = RHM_LENDIAN_FLAG;
+#else
+    u_int8_t endian_flag = RHM_BENDIAN_FLAG;
+#endif
+    if (hdr._eflag != endian_flag)
+    {
+        std::ostringstream oss;
+        oss << std::hex << std::setfill('0');
+        oss << "endian_flag: rid=" << hdr._rid;
+        oss << ": expected=0x" << std::setw(2) << (int)endian_flag;
+        oss << " read=0x" << std::setw(2) << (int)hdr._eflag;
+        throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+    }
+}
+
+void
+jrec::chk_rid(const rec_hdr& hdr, const u_int64_t rid)
+{
+    if (hdr._rid != rid)
+    {
+        std::ostringstream oss;
+        oss << std::hex << std::setfill('0');
+        oss << "rid mismatch: expected=0x" << rid;
+        oss << " read=0x" << hdr._rid;
+        throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+    }
+}
+
+void
+jrec::chk_tail(const rec_tail& tail, const rec_hdr& hdr)
+{
+    if (tail._xmagic != ~hdr._magic)
+    {
+        std::ostringstream oss;
+        oss << std::hex << std::setfill('0');
+        oss << "magic: rid=0x" << hdr._rid;
+        oss << ": expected=0x" << ~hdr._magic;
+        oss << " read=0x" << tail._xmagic;
+        throw jexception(jerrno::JERR_JREC_BADRECTAIL, oss.str(), "jrec", "chk_tail");
+    }
+    if (tail._rid != hdr._rid)
+    {
+        std::ostringstream oss;
+        oss << std::hex << std::setfill('0');
+        oss << "rid: rid=0x" << hdr._rid;
+        oss << ": read=0x" << tail._rid;
+        throw jexception(jerrno::JERR_JREC_BADRECTAIL, oss.str(), "jrec", "chk_tail");
+    }
+}
+
+} // namespace journal
+} // namespace mrg

Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,186 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jrec.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing source code for class mrg::journal::jrec (abstract journal
+ * jrecord). See class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jrec_hpp
+#define mrg_journal_jrec_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jrec;
+}
+}
+
+#include <cstddef>
+#include <fstream>
+#include "jrnl/rec_hdr.hpp"
+#include "jrnl/rec_tail.hpp"
+#include <string>
+#include <sys/types.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+    /**
+    * \class jrec
+    * \brief Abstract class for all file jrecords, both data and log. This class establishes
+    *     the common data format and structure for these jrecords.
+    */
+    class jrec
+    {
+    public:
+        jrec();
+        virtual ~jrec();
+
+        /**
+        * \brief Encode this instance of jrec into the write buffer at the disk-block-aligned
+        *   pointer wptr starting at position rec_offs_dblks in the encoded record to a
+        *   maximum size of max_size_dblks.
+        *
+        * This call encodes the content of the data contianed in this instance of jrec into a
+        * disk-softblock-aligned (defined by JRNL_SBLK_SIZE) buffer pointed to by parameter
+        * wptr. No more than paramter max_size_dblks data-blocks may be written to the buffer.
+        * The parameter rec_offs_dblks is the offset in data-blocks within the fully encoded
+        * data block this instance represents at which to start encoding.
+        *
+        * Encoding entails writing the record header (struct enq_hdr), the data and the record tail
+        * (struct enq_tail). The record must be data-block-aligned (defined by JRNL_DBLK_SIZE),
+        * thus any remaining space in the final data-block is ignored; the returned value is the
+        * number of data-blocks consumed from the page by the encode action. Provided the initial
+        * alignment requirements are met, records may be of arbitrary size and may span multiple
+        * data-blocks, disk-blocks and/or pages.
+        *
+        * Since the record size in data-blocks is known, the general usage pattern is to call
+        * encode() as many times as is needed to fully encode the data. Each call to encode()
+        * will encode as much of the record as it can to what remains of the current page cache,
+        * and will return the number of data-blocks actually encoded.
+        *
+        * <b>Example:</b> Assume that record r1 was previously written to page 0, and that this
+        * is an instance representing record r2. Being larger than the page size ps, r2 would span
+        * multiple pages as follows:
+        * <pre>
+        *       |<---ps--->|
+        *       +----------+----------+----------+----...
+        *       |      |r2a|   r2b    |  r2c   | |
+        *       |<-r1-><----------r2---------->  |
+        *       +----------+----------+----------+----...
+        * page:      p0         p1         p2
+        * </pre>
+        * Encoding record r2 will require multiple calls to encode; one for each page which
+        * is involved. Record r2 is divided logically into sections r2a, r2b and r2c at the
+        * points where the page boundaries intersect with the record. Assuming a page size
+        * of ps, the page boundary pointers are represented by their names p0, p1... and the
+        * sizes of the record segments are represented by their names r1, r2a, r2b..., the calls
+        * should be as follows:
+        * <pre>
+        * encode(p0+r1, 0, ps-r1); (returns r2a data-blocks)
+        * encode(p1, r2a, ps);     (returns r2b data-blocks which equals ps)
+        * encode(p2, r2a+r2b, ps); (returns r2c data-blocks)
+        * </pre>
+        *
+        * \param wptr Data-block-aligned pointer to position in page buffer where encoding is to
+        *   take place.
+        * \param rec_offs_dblks Offset in data-blocks within record from which to start encoding.
+        * \param max_size_dblks Maximum number of data-blocks to write to pointer wptr.
+        * \returns Number of data-blocks encoded.
+        */
+        virtual u_int32_t encode(void* wptr, u_int32_t rec_offs_dblks,
+                u_int32_t max_size_dblks) = 0;
+
+        /**
+        * \brief Decode into this instance of jrec from the read buffer at the disk-block-aligned
+        *   pointer rptr starting at position jrec_offs_dblks in the encoded record to a
+        *   maximum size of max_size_blks.
+        *
+        * This call decodes a record in the page buffer pointed to by the data-block-aligned
+        * (defined by JRNL_DBLK_SIZE) parameter rptr into this instance of jrec. No more than
+        * paramter max_size_dblks data-blocks may be read from the buffer. The parameter
+        * jrec_offs_dblks is the offset in data-blocks within the encoded record at which to start
+        * decoding.
+        *
+        * Decoding entails reading the record header, the data and the tail. The record is
+        * data-block-aligned (defined by JRNL_DBLK_SIZE); the returned value is the number of
+        * data-blocks read from the buffer by the decode action. As the record data size is only
+        * known once the header is read, the number of calls required to complete reading the
+        * record will depend on the vlaues within this instance which are set when the
+        * header is decoded.
+        *
+        * A non-zero value for jrec_offs_dblks implies that this is not the first call to
+        * decode and the record data will be appended at this offset.
+        *
+        * \param h Reference to instance of struct hdr, already read from page buffer and used
+        *   to determine record type
+        * \param rptr Data-block-aligned pointer to position in page buffer where decoding is to
+        *   begin.
+        * \param rec_offs_dblks Offset within record from which to start appending the decoded
+        *   record.
+        * \param max_size_dblks Maximum number of data-blocks to read from pointer rptr.
+        * \returns Number of data-blocks read (consumed).
+        */
+        virtual u_int32_t decode(rec_hdr& h, void* rptr, u_int32_t rec_offs_dblks,
+                u_int32_t max_size_dblks) = 0;
+
+        virtual bool rcv_decode(rec_hdr h, std::ifstream* ifsp, std::size_t& rec_offs) = 0;
+
+        virtual std::string& str(std::string& str) const = 0;
+        virtual std::size_t data_size() const = 0;
+        virtual std::size_t xid_size() const = 0;
+        virtual std::size_t rec_size() const = 0;
+        inline virtual u_int32_t rec_size_dblks() const { return size_dblks(rec_size()); }
+        static inline u_int32_t size_dblks(const std::size_t size)
+                { return size_blks(size, JRNL_DBLK_SIZE); }
+        static inline u_int32_t size_sblks(const std::size_t size)
+                { return size_blks(size, JRNL_DBLK_SIZE * JRNL_SBLK_SIZE); }
+        static inline u_int32_t size_blks(const std::size_t size, const std::size_t blksize)
+                { return (size + blksize - 1)/blksize; }
+        virtual u_int64_t rid() const = 0;
+
+    protected:
+        virtual void chk_hdr() const = 0;
+        virtual void chk_hdr(u_int64_t rid) const = 0;
+        virtual void chk_tail() const = 0;
+        static void chk_hdr(const rec_hdr& hdr);
+        static void chk_rid(const rec_hdr& hdr, u_int64_t rid);
+        static void chk_tail(const rec_tail& tail, const rec_hdr& hdr);
+        virtual void clean() = 0;
+    }; // class jrec
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jrec_hpp



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