Revision: 44687
          http://brlcad.svn.sourceforge.net/brlcad/?rev=44687&view=rev
Author:   davidloman
Date:     2011-05-25 18:18:07 +0000 (Wed, 25 May 2011)

Log Message:
-----------
Flesh out BrlcadDB implementation a bit by adding isValidPath() and list() 
along with other support functions like open() close() etc...

Modified Paths:
--------------
    geomcore/trunk/include/BrlcadDb.h
    geomcore/trunk/src/GS/BrlcadDb.cxx

Modified: geomcore/trunk/include/BrlcadDb.h
===================================================================
--- geomcore/trunk/include/BrlcadDb.h   2011-05-25 18:15:27 UTC (rev 44686)
+++ geomcore/trunk/include/BrlcadDb.h   2011-05-25 18:18:07 UTC (rev 44687)
@@ -25,12 +25,74 @@
 #define __BRLCADDB_H__
 
 #include <string>
+#include <list>
 
 class BrlcadDb {
 public:
-  BrlcadDb(std::string path);
-  virtual
-  ~BrlcadDb();
+  static int FS_PATH_NOT_VALID;
+  static int G_PATH_NOT_VALID;
+  static int CORRUPT_OBJ_DATA;
+
+  /**
+   * Factory method.  Returns valid BrlcadDb object on success, NULL on 
failure.
+   */
+  static BrlcadDb* makeDb(const std::string path);
+
+  virtual ~BrlcadDb();
+
+  /**
+   * Opens the DB, checks if the provided 'path' is valid or not, then closes 
the DB.
+   */
+  const bool isValidPath(const std::string path);
+
+  /**
+   * Using provided database 'path' to a db object,
+   * fill 'list' with the names children objects
+   *
+   * Return value:
+   *  >=0 number of children objs added to 'list'
+   *  <0 error:
+   *     -1 filesystem Path not valid.
+   *     -2 geometry Path not valid.
+   *     -3 Valid path, but corrupt Object Data.
+   */
+  const int list(const std::string path, std::list<std::string>* list);
+
+private:
+  std::string path;
+  struct db_i* dbip;
+
+  /**
+   * Default constructor.  Accessed via BrlcadDb::makeDB to allow for file 
system
+   * path validation and .g file validation.
+   */
+  BrlcadDb(const std::string path);
+
+  /**
+   * Opens the DB.  (db_open) Optional boolean argument for opening in 
ReadOnly mode.
+   * Default is false, thus default is read/write mode.
+   *
+   * Return status is whether the db_open succeeded or not.
+   */
+  const bool open(const bool readOnly = false);
+
+  /**
+   * Closes the database. (db_close)
+   */
+  void close();
+
+  /**
+   * Performs the actual path validation. To be used internally only.
+   * NOTE:  Does not call open() or close().  See isValidPath() that.
+   */
+  const bool _isValidPath(const std::string path);
+
+  /**
+   * Performs the actual list lookup. To be used internally only.
+   * NOTE:  Does not call open() or close().  See list() that.
+   */
+  const int _list(const std::string path, std::list<std::string>* list);
+
 };
 
 #endif /* __BRLCADDB_H__ */

Modified: geomcore/trunk/src/GS/BrlcadDb.cxx
===================================================================
--- geomcore/trunk/src/GS/BrlcadDb.cxx  2011-05-25 18:15:27 UTC (rev 44686)
+++ geomcore/trunk/src/GS/BrlcadDb.cxx  2011-05-25 18:18:07 UTC (rev 44687)
@@ -22,20 +22,205 @@
  */
 
 #include "BrlcadDb.h"
+#include "StringUtils.h"
+
 #include "db.h"
 #include "raytrace.h"
 
-BrlcadDb::BrlcadDb(std::string path)
-{
-  // TODO Auto-generated constructor stub
+int BrlcadDb::FS_PATH_NOT_VALID = -1;
+int BrlcadDb::G_PATH_NOT_VALID = -2;
+int BrlcadDb::CORRUPT_OBJ_DATA = -3;
 
+BrlcadDb*
+BrlcadDb::makeDb(const std::string path) {
+  struct db_i *dbip;
+
+ /* Test by attempting to open */
+  if ((dbip = db_open(path.c_str(), "r")) == DBI_NULL) {
+      return NULL;
+  }
+  db_close(dbip);
+
+  return new BrlcadDb(path);
 }
 
+BrlcadDb::BrlcadDb(const std::string path) :
+  path(path), dbip(DBI_NULL)
+{
+}
+
 BrlcadDb::~BrlcadDb()
 {
-  // TODO Auto-generated destructor stub
+  this->close();
 }
 
+const bool
+BrlcadDb::open(const bool readOnly) {
+  this->dbip = db_open(this->path.c_str(), (readOnly ? "r" : ""));
+  if (this->dbip == DBI_NULL)
+      return false;
+
+  if (db_dirbuild(this->dbip)) {
+      this->close();
+      return false;
+  }
+  db_update_nref(dbip, &rt_uniresource);
+  return true;
+}
+
+void
+BrlcadDb::close() {
+  if (this->dbip != DBI_NULL){
+    db_close(dbip);
+    this->dbip = DBI_NULL;
+  }
+}
+
+const bool
+BrlcadDb::isValidPath(const std::string path) {
+  if (this->open() == false)
+    return false;
+  bool retVal = this->_isValidPath(path);
+  this->close();
+  return retVal;
+}
+
+const bool
+BrlcadDb::_isValidPath(const std::string path) {
+  /* Assume that 'path' is formatted to be a BRLCAD DB path */
+  std::list<std::string> pathStack;
+  StringUtils::splitPath(path, &pathStack);
+  std::list<std::string>::const_iterator it = pathStack.begin();
+
+  std::string pathSoFar = "";
+  std::string pathStep = "";
+  struct directory *dp;
+  struct db_full_path dfp;
+  int dbStep = 0;
+  int exists = 0;
+
+  for (; it != pathStack.end(); ++it)
+    {
+      pathStep = (std::string) *it;
+      pathSoFar += pathStep;
+
+      db_full_path_init(&dfp);
+      exists = db_string_to_path(&dfp, this->dbip, pathSoFar.c_str());
+      db_free_full_path(&dfp);
+
+      if (exists != 0)
+          return false;
+
+      pathSoFar += PATH_DELIM;
+      ++dbStep;
+    }
+
+  return true;
+}
+
+const int
+BrlcadDb::list(const std::string path, std::list<std::string>* list)
+{
+  if (this->open() == false) return G_PATH_NOT_VALID;
+
+  const int retVal = this->_list(path, list);
+  this->close();
+  return retVal;
+}
+
+const int
+BrlcadDb::_list(const std::string path, std::list<std::string>* items)
+{
+  struct directory *dp;
+  struct db_full_path dfp;
+  int dbStep = 0;
+  int exists = 0;
+  int itemsAdded = 0;
+
+  /* If we are getting TOPS of the file... */
+  if ((path.length() == 0 || path == "/")) {
+    for (int i = 0; i < RT_DBNHASH; i++)
+      for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw)
+        if (dp->d_nref == 0 && !(dp->d_flags & RT_DIR_HIDDEN) && (dp->d_addr 
!= RT_DIR_PHONY_ADDR)) {
+          items->push_back(std::string(dp->d_namep));
+          ++itemsAdded;
+        }
+    return itemsAdded;
+  }
+  /* If not TOPS, then look it up! */
+
+  /* Check to see if we have a valid path, or just a objectName */
+  std::string objName = StringUtils::getLastStepOfPath(path);
+
+  dp = db_lookup(this->dbip, objName.c_str(), 0);
+  if (dp == RT_DIR_NULL)  return G_PATH_NOT_VALID;
+
+  struct rt_db_internal in;
+  struct rt_comb_internal *comb;
+
+  if (rt_db_get_internal5(&in, dp, dbip, NULL, &rt_uniresource) < 0)
+    return CORRUPT_OBJ_DATA;
+
+  comb = (struct rt_comb_internal *) in.idb_ptr;
+
+  size_t i;
+  size_t node_count;
+  struct rt_tree_array *rt_tree_array;
+  union tree *ntp;
+
+  RT_CK_RESOURCE(&rt_uniresource);
+
+  /* TODO No tree?  Error or just return no children? */
+  if (!comb->tree) {
+      rt_db_free_internal(&in);
+      return 0;
+  }
+  RT_CK_TREE(comb->tree);
+
+  node_count = db_tree_nleaves(comb->tree);
+  if (node_count == 0) {
+      rt_db_free_internal(&in);
+      return 0;
+  }
+
+  ntp = db_dup_subtree(comb->tree, &rt_uniresource);
+  RT_CK_TREE(ntp);
+
+  /* Convert to "v4 / GIFT style", so that the flatten makes sense. */
+  if (db_ck_v4gift_tree(ntp) < 0)
+          db_non_union_push(ntp, &rt_uniresource);
+  RT_CK_TREE(ntp);
+
+  node_count = db_tree_nleaves(ntp);
+  rt_tree_array = (struct rt_tree_array *) bu_calloc(node_count,
+                  sizeof(struct rt_tree_array), "rt_tree_array");
+
+  /*
+   * free=0 means that the tree won't have any leaf nodes freed.
+   */
+  (void) db_flatten_tree(rt_tree_array, ntp, OP_UNION, 0, &rt_uniresource);
+
+  union tree *itp = NULL;
+  for (i = 0; i < node_count; i++)
+    {
+      itp = rt_tree_array[i].tl_tree;
+
+      RT_CK_TREE(itp);
+      BU_ASSERT_LONG(itp->tr_op, ==, OP_DB_LEAF);
+      BU_ASSERT_PTR(itp->tr_l.tl_name, !=, NULL);
+
+      items->push_back(std::string(itp->tr_l.tl_name));
+    }
+
+  if (rt_tree_array)
+          bu_free((genptr_t) rt_tree_array, "rt_tree_array");
+  db_free_tree(ntp, &rt_uniresource);
+
+  rt_db_free_internal(&in);
+
+  return node_count;
+}
+
 // Local Variables:
 // tab-width: 8
 // mode: C++


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
vRanger cuts backup time in half-while increasing security.
With the market-leading solution for virtual backup and recovery, 
you get blazing-fast, flexible, and affordable data protection.
Download your free trial now. 
http://p.sf.net/sfu/quest-d2dcopy1
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to