1/* 2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de> 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include <package/PackageVersion.h> 8 9#include <NaturalCompare.h> 10 11#include <package/PackageInfo.h> 12#include <package/hpkg/PackageInfoAttributeValue.h> 13 14 15using BPrivate::NaturalCompare; 16 17 18namespace BPackageKit { 19 20 21BPackageVersion::BPackageVersion() 22 : 23 fRevision(0) 24{ 25} 26 27 28BPackageVersion::BPackageVersion(const BPackageVersionData& data) 29{ 30 SetTo(data.major, data.minor, data.micro, data.preRelease, data.revision); 31} 32 33 34BPackageVersion::BPackageVersion(const BString& versionString, 35 bool revisionIsOptional) 36{ 37 SetTo(versionString, revisionIsOptional); 38} 39 40 41BPackageVersion::BPackageVersion(const BString& major, const BString& minor, 42 const BString& micro, const BString& preRelease, uint32 revision) 43{ 44 SetTo(major, minor, micro, preRelease, revision); 45} 46 47 48status_t 49BPackageVersion::InitCheck() const 50{ 51 return fMajor.Length() > 0 ? B_OK : B_NO_INIT; 52} 53 54 55const BString& 56BPackageVersion::Major() const 57{ 58 return fMajor; 59} 60 61 62const BString& 63BPackageVersion::Minor() const 64{ 65 return fMinor; 66} 67 68 69const BString& 70BPackageVersion::Micro() const 71{ 72 return fMicro; 73} 74 75 76const BString& 77BPackageVersion::PreRelease() const 78{ 79 return fPreRelease; 80} 81 82 83uint32 84BPackageVersion::Revision() const 85{ 86 return fRevision; 87} 88 89 90int 91BPackageVersion::Compare(const BPackageVersion& other) const 92{ 93 int diff = NaturalCompare(fMajor.String(), other.fMajor.String()); 94 if (diff != 0) 95 return diff; 96 97 diff = NaturalCompare(fMinor.String(), other.fMinor.String()); 98 if (diff != 0) 99 return diff; 100 101 diff = NaturalCompare(fMicro.String(), other.fMicro.String()); 102 if (diff != 0) 103 return diff; 104 105 // The pre-version works differently: The empty string is greater than any 106 // non-empty string (e.g. "R1" is newer than "R1-rc2"). So we catch the 107 // empty string cases first. 108 if (fPreRelease.IsEmpty()) { 109 if (!other.fPreRelease.IsEmpty()) 110 return 1; 111 } else if (other.fPreRelease.IsEmpty()) { 112 return -1; 113 } else { 114 // both are non-null -- compare normally 115 diff = NaturalCompare(fPreRelease.String(), other.fPreRelease.String()); 116 if (diff != 0) 117 return diff; 118 } 119 120 return (int)fRevision - (int)other.fRevision; 121} 122 123 124BString 125BPackageVersion::ToString() const 126{ 127 if (InitCheck() != B_OK) 128 return BString(); 129 130 BString string = fMajor; 131 132 if (fMinor.Length() > 0) { 133 string << '.' << fMinor; 134 if (fMicro.Length() > 0) 135 string << '.' << fMicro; 136 } 137 138 if (!fPreRelease.IsEmpty()) 139 string << '~' << fPreRelease; 140 141 if (fRevision > 0) 142 string << '-' << fRevision; 143 144 return string; 145} 146 147 148void 149BPackageVersion::SetTo(const BString& major, const BString& minor, 150 const BString& micro, const BString& preRelease, uint32 revision) 151{ 152 fMajor = major; 153 fMinor = minor; 154 fMicro = micro; 155 fPreRelease = preRelease; 156 fRevision = revision; 157 158 fMajor.ToLower(); 159 fMinor.ToLower(); 160 fMicro.ToLower(); 161 fPreRelease.ToLower(); 162} 163 164 165status_t 166BPackageVersion::SetTo(const BString& versionString, bool revisionIsOptional) 167{ 168 Clear(); 169 return BPackageInfo::ParseVersionString(versionString, revisionIsOptional, 170 *this); 171} 172 173 174void 175BPackageVersion::Clear() 176{ 177 fMajor.Truncate(0); 178 fMinor.Truncate(0); 179 fMicro.Truncate(0); 180 fPreRelease.Truncate(0); 181 fRevision = 0; 182} 183 184 185} // namespace BPackageKit 186