Add FqInstance class.
FqInstance is a wrapper around FQName to include instance
name as well.
Bug: 73774955
Fixes: 74361197
Test: libhidl-gen-utils_test
Change-Id: I5c064dec8d0e72ad1c90d3a892986f74d77788ce
diff --git a/utils/FqInstance.cpp b/utils/FqInstance.cpp
new file mode 100644
index 0000000..0b2b8f8
--- /dev/null
+++ b/utils/FqInstance.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+#include "FqInstance.h"
+
+#include <sstream>
+
+namespace android {
+
+static const char INSTANCE_SEP = '/';
+
+const std::string& FqInstance::getPackage() const {
+ return mFqName.package();
+}
+
+bool FqInstance::hasPackage() const {
+ return !getPackage().empty();
+}
+
+size_t FqInstance::getMajorVersion() const {
+ return hasVersion() ? mFqName.getPackageMajorVersion() : 0;
+}
+
+size_t FqInstance::getMinorVersion() const {
+ return hasVersion() ? mFqName.getPackageMinorVersion() : 0;
+}
+
+std::pair<size_t, size_t> FqInstance::getVersion() const {
+ return {getMajorVersion(), getMinorVersion()};
+}
+
+bool FqInstance::hasVersion() const {
+ return mFqName.hasVersion();
+}
+
+const std::string& FqInstance::getInterface() const {
+ return mFqName.getInterfaceName();
+}
+
+bool FqInstance::hasInterface() const {
+ return mFqName.isInterfaceName();
+}
+
+const std::string& FqInstance::getInstance() const {
+ return mInstance;
+}
+
+bool FqInstance::hasInstance() const {
+ return !mInstance.empty();
+}
+
+bool FqInstance::setTo(const std::string& s) {
+ auto pos = s.find(INSTANCE_SEP);
+ if (!mFqName.setTo(s.substr(0, pos))) return false;
+ mInstance = pos == std::string::npos ? std::string{} : s.substr(pos + 1);
+
+ bool hasPkg = hasPackage();
+ bool hasVer = hasVersion();
+ bool hasIntf = hasInterface();
+ bool hasInst = hasInstance();
+
+ // android.hardware.foo@1.0::IFoo/default
+ if (hasPkg && hasVer && hasIntf && hasInst) {
+ return true;
+ }
+
+ // @1.0::IFoo/default
+ if (!hasPkg && hasVer && hasIntf && hasInst) {
+ return true;
+ }
+
+ // IFoo/default
+ if (!hasPkg && !hasVer && hasIntf && hasInst) {
+ return true;
+ }
+
+ // Other cases are covered by FQName::setTo, but instance name should be empty.
+ return !hasInst;
+}
+
+bool FqInstance::setTo(const std::string& package, size_t majorVer, size_t minorVer,
+ const std::string& interface, const std::string& instance) {
+ std::stringstream ss;
+ ss << package << "@" << majorVer << "." << minorVer << "::" << interface << INSTANCE_SEP
+ << instance;
+ return setTo(ss.str());
+}
+
+bool FqInstance::setTo(size_t majorVer, size_t minorVer, const std::string& interface,
+ const std::string& instance) {
+ return setTo("", majorVer, minorVer, interface, instance);
+}
+
+bool FqInstance::setTo(const std::string& interface, const std::string& instance) {
+ return setTo(interface + INSTANCE_SEP + instance);
+}
+
+std::string FqInstance::string() const {
+ std::string ret = mFqName.string();
+ if (hasInstance()) ret += INSTANCE_SEP + mInstance;
+ return ret;
+}
+
+bool FqInstance::operator<(const FqInstance& other) const {
+ return string() < other.string();
+}
+
+bool FqInstance::operator==(const FqInstance& other) const {
+ return string() == other.string();
+}
+
+bool FqInstance::operator!=(const FqInstance& other) const {
+ return !(*this == other);
+}
+
+} // namespace android