From a3dd6caf55b8862747542069f3bf116e92723eab Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 3 Apr 2013 02:06:26 +0000 Subject: [PATCH] Add public package version parsing API * BPackageVersion: Add respective constructor and SetTo(). * BPackageInfo: Add static ParseVersionString() utility method. It's only there because the parser lives in the BPackageInfo implementation. --- headers/os/package/PackageInfo.h | 6 ++++ headers/os/package/PackageVersion.h | 4 +++ src/kits/package/PackageInfo.cpp | 49 +++++++++++++++++++++++++++++ src/kits/package/PackageVersion.cpp | 17 ++++++++++ 4 files changed, 76 insertions(+) diff --git a/headers/os/package/PackageInfo.h b/headers/os/package/PackageInfo.h index aad8b13ac8..25383886fe 100644 --- a/headers/os/package/PackageInfo.h +++ b/headers/os/package/PackageInfo.h @@ -141,6 +141,12 @@ public: static status_t GetArchitectureByName(const BString& name, BPackageArchitecture& _architecture); + static status_t ParseVersionString(const BString& string, + bool releaseIsOptional, + BPackageVersion& _version, + ParseErrorListener* listener = NULL); + +public: static const char* kElementNames[]; static const char* kArchitectureNames[]; diff --git a/headers/os/package/PackageVersion.h b/headers/os/package/PackageVersion.h index e571b64757..12a80d198b 100644 --- a/headers/os/package/PackageVersion.h +++ b/headers/os/package/PackageVersion.h @@ -23,6 +23,8 @@ public: BPackageVersion(); BPackageVersion( const BPackageVersionData& data); + BPackageVersion(const BString& versionString, + bool releaseIsOptional = true); BPackageVersion(const BString& major, const BString& minor, const BString& micro, const BString& preRelease, uint8 release); @@ -41,6 +43,8 @@ public: void SetTo(const BString& major, const BString& minor, const BString& micro, const BString& preRelease, uint8 release); + status_t SetTo(const BString& versionString, + bool releaseIsOptional = true); void Clear(); int Compare(const BPackageVersion& other) const; diff --git a/src/kits/package/PackageInfo.cpp b/src/kits/package/PackageInfo.cpp index 42da18ec90..41f39b4e94 100644 --- a/src/kits/package/PackageInfo.cpp +++ b/src/kits/package/PackageInfo.cpp @@ -68,6 +68,10 @@ public: status_t Parse(const BString& packageInfoString, BPackageInfo* packageInfo); + status_t ParseVersion(const BString& versionString, + bool releaseIsOptional, + BPackageVersion& _version); + private: struct Token; struct ListElementParser; @@ -82,6 +86,9 @@ private: BPackageArchitecture* value); void _ParseVersionValue(BPackageVersion* value, bool releaseIsOptional); + static void _ParseVersionValue(Token& word, + BPackageVersion* value, + bool releaseIsOptional); void _ParseList(ListElementParser& elementParser, bool allowSingleNonListElement); void _ParseStringList(BStringList* value, @@ -206,6 +213,31 @@ BPackageInfo::Parser::Parse(const BString& packageInfoString, } +status_t +BPackageInfo::Parser::ParseVersion(const BString& versionString, + bool releaseIsOptional, BPackageVersion& _version) +{ + fPos = versionString.String(); + + try { + Token token(TOKEN_WORD, fPos, versionString.Length()); + _ParseVersionValue(token, &_version, releaseIsOptional); + } catch (const ParseError& error) { + if (fListener != NULL) { + int32 offset = error.pos - versionString.String(); + fListener->OnError(error.message, 1, offset); + } + return B_BAD_DATA; + } catch (const std::bad_alloc& e) { + if (fListener != NULL) + fListener->OnError("out of memory", 0, 0); + return B_NO_MEMORY; + } + + return B_OK; +} + + BPackageInfo::Parser::Token BPackageInfo::Parser::_NextToken() { @@ -360,6 +392,14 @@ BPackageInfo::Parser::_ParseVersionValue(BPackageVersion* value, bool releaseIsOptional) { Token word = _NextToken(); + _ParseVersionValue(word, value, releaseIsOptional); +} + + +/*static*/ void +BPackageInfo::Parser::_ParseVersionValue(Token& word, BPackageVersion* value, + bool releaseIsOptional) +{ if (word.type != TOKEN_WORD) throw ParseError("expected word (a version)", word.pos); @@ -1365,4 +1405,13 @@ BPackageInfo::GetArchitectureByName(const BString& name, return B_NAME_NOT_FOUND; } + +/*static*/ status_t +BPackageInfo::ParseVersionString(const BString& string, bool releaseIsOptional, + BPackageVersion& _version, ParseErrorListener* listener) +{ + return Parser(listener).ParseVersion(string, releaseIsOptional, _version); +} + + } // namespace BPackageKit diff --git a/src/kits/package/PackageVersion.cpp b/src/kits/package/PackageVersion.cpp index a4d1dd23dd..6b0de38a41 100644 --- a/src/kits/package/PackageVersion.cpp +++ b/src/kits/package/PackageVersion.cpp @@ -8,6 +8,7 @@ #include +#include #include @@ -30,6 +31,13 @@ BPackageVersion::BPackageVersion(const BPackageVersionData& data) } +BPackageVersion::BPackageVersion(const BString& versionString, + bool releaseIsOptional) +{ + SetTo(versionString, releaseIsOptional); +} + + BPackageVersion::BPackageVersion(const BString& major, const BString& minor, const BString& micro, const BString& preRelease, uint8 release) { @@ -151,6 +159,15 @@ BPackageVersion::SetTo(const BString& major, const BString& minor, } +status_t +BPackageVersion::SetTo(const BString& versionString, bool releaseIsOptional) +{ + Clear(); + return BPackageInfo::ParseVersionString(versionString, releaseIsOptional, + *this); +} + + void BPackageVersion::Clear() {