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 15 using BPrivate::NaturalCompare; 16 17 18 namespace BPackageKit { 19 20 21 BPackageVersion::BPackageVersion() 22 : 23 fRevision(0) 24 { 25 } 26 27 28 BPackageVersion::BPackageVersion(const BPackageVersionData& data) 29 { 30 SetTo(data.major, data.minor, data.micro, data.preRelease, data.revision); 31 } 32 33 34 BPackageVersion::BPackageVersion(const BString& versionString, 35 bool revisionIsOptional) 36 { 37 SetTo(versionString, revisionIsOptional); 38 } 39 40 41 BPackageVersion::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 48 status_t 49 BPackageVersion::InitCheck() const 50 { 51 return fMajor.Length() > 0 ? B_OK : B_NO_INIT; 52 } 53 54 55 const BString& 56 BPackageVersion::Major() const 57 { 58 return fMajor; 59 } 60 61 62 const BString& 63 BPackageVersion::Minor() const 64 { 65 return fMinor; 66 } 67 68 69 const BString& 70 BPackageVersion::Micro() const 71 { 72 return fMicro; 73 } 74 75 76 const BString& 77 BPackageVersion::PreRelease() const 78 { 79 return fPreRelease; 80 } 81 82 83 uint32 84 BPackageVersion::Revision() const 85 { 86 return fRevision; 87 } 88 89 90 int 91 BPackageVersion::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 124 BString 125 BPackageVersion::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 148 void 149 BPackageVersion::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 165 status_t 166 BPackageVersion::SetTo(const BString& versionString, bool revisionIsOptional) 167 { 168 Clear(); 169 return BPackageInfo::ParseVersionString(versionString, revisionIsOptional, 170 *this); 171 } 172 173 174 void 175 BPackageVersion::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