summaryrefslogtreecommitdiffstats
path: root/src/rbd_replay/rbd_loc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rbd_replay/rbd_loc.cc')
-rw-r--r--src/rbd_replay/rbd_loc.cc130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/rbd_replay/rbd_loc.cc b/src/rbd_replay/rbd_loc.cc
new file mode 100644
index 000000000..ce6e8e6ed
--- /dev/null
+++ b/src/rbd_replay/rbd_loc.cc
@@ -0,0 +1,130 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2014 Adam Crume <adamcrume@gmail.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include "rbd_loc.hpp"
+#include "include/ceph_assert.h"
+
+
+using namespace std;
+using namespace rbd_replay;
+
+
+rbd_loc::rbd_loc() {
+}
+
+rbd_loc::rbd_loc(const string &pool, const string &image, const string &snap)
+ : pool(pool),
+ image(image),
+ snap(snap) {
+}
+
+bool rbd_loc::parse(string name_string) {
+ int field = 0;
+ string fields[3];
+ bool read_slash = false;
+ bool read_at = false;
+ for (size_t i = 0, n = name_string.length(); i < n; i++) {
+ char c = name_string[i];
+ switch (c) {
+ case '/':
+ if (read_slash || read_at) {
+ return false;
+ }
+ ceph_assert(field == 0);
+ field++;
+ read_slash = true;
+ break;
+ case '@':
+ if (read_at) {
+ return false;
+ }
+ ceph_assert(field < 2);
+ field++;
+ read_at = true;
+ break;
+ case '\\':
+ if (i == n - 1) {
+ return false;
+ }
+ fields[field].push_back(name_string[++i]);
+ break;
+ default:
+ fields[field].push_back(c);
+ }
+ }
+
+ if (read_slash) {
+ pool = fields[0];
+ image = fields[1];
+ // note that if read_at is false, then fields[2] is the empty string,
+ // so this is still correct
+ snap = fields[2];
+ } else {
+ pool = "";
+ image = fields[0];
+ // note that if read_at is false, then fields[1] is the empty string,
+ // so this is still correct
+ snap = fields[1];
+ }
+ return true;
+}
+
+
+static void write(const string &in, string *out) {
+ for (size_t i = 0, n = in.length(); i < n; i++) {
+ char c = in[i];
+ if (c == '@' || c == '/' || c == '\\') {
+ out->push_back('\\');
+ }
+ out->push_back(c);
+ }
+}
+
+string rbd_loc::str() const {
+ string out;
+ if (!pool.empty()) {
+ write(pool, &out);
+ out.push_back('/');
+ }
+ write(image, &out);
+ if (!snap.empty()) {
+ out.push_back('@');
+ write(snap, &out);
+ }
+ return out;
+}
+
+int rbd_loc::compare(const rbd_loc& rhs) const {
+ int c = pool.compare(rhs.pool);
+ if (c) {
+ return c;
+ }
+ c = image.compare(rhs.image);
+ if (c) {
+ return c;
+ }
+ c = snap.compare(rhs.snap);
+ if (c) {
+ return c;
+ }
+ return 0;
+}
+
+bool rbd_loc::operator==(const rbd_loc& rhs) const {
+ return compare(rhs) == 0;
+}
+
+bool rbd_loc::operator<(const rbd_loc& rhs) const {
+ return compare(rhs) < 0;
+}