1 /* 2 * Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>. 3 * Copyright 2013, Rene Gollent <rene@gollent.com>. 4 * Copyright 2016-2023, Andrew Lindesay <apl@lindesay.co.nz>. 5 * All rights reserved. Distributed under the terms of the MIT License. 6 */ 7 8 9 #include "DepotInfo.h" 10 11 #include <algorithm> 12 13 #include "Logger.h" 14 15 16 // #pragma mark - Sorting Functions 17 18 19 static bool 20 _IsPackageBeforeByName(const PackageInfoRef& p1, const BString& packageName) 21 { 22 return p1->Name().Compare(packageName) < 0; 23 } 24 25 26 /*! This function is used in order to provide an ordering on the packages 27 that are stored on a Depot. 28 */ 29 30 static bool 31 _IsPackageBefore(const PackageInfoRef& p1, const PackageInfoRef& p2) 32 { 33 return _IsPackageBeforeByName(p1, p2->Name()); 34 } 35 36 37 // #pragma mark - Class implementation 38 39 40 DepotInfo::DepotInfo() 41 : 42 fName(), 43 fIdentifier(), 44 fWebAppRepositoryCode() 45 { 46 } 47 48 49 DepotInfo::DepotInfo(const BString& name) 50 : 51 fName(name), 52 fIdentifier(), 53 fWebAppRepositoryCode(), 54 fWebAppRepositorySourceCode() 55 { 56 } 57 58 59 DepotInfo::DepotInfo(const DepotInfo& other) 60 : 61 fName(other.fName), 62 fIdentifier(other.fIdentifier), 63 fPackages(other.fPackages), 64 fWebAppRepositoryCode(other.fWebAppRepositoryCode), 65 fWebAppRepositorySourceCode(other.fWebAppRepositorySourceCode) 66 { 67 } 68 69 70 DepotInfo& 71 DepotInfo::operator=(const DepotInfo& other) 72 { 73 fName = other.fName; 74 fIdentifier = other.fIdentifier; 75 fPackages = other.fPackages; 76 fWebAppRepositoryCode = other.fWebAppRepositoryCode; 77 fWebAppRepositorySourceCode = other.fWebAppRepositorySourceCode; 78 return *this; 79 } 80 81 82 bool 83 DepotInfo::operator==(const DepotInfo& other) const 84 { 85 return fName == other.fName 86 && fIdentifier == fIdentifier 87 && fPackages == other.fPackages; 88 } 89 90 91 bool 92 DepotInfo::operator!=(const DepotInfo& other) const 93 { 94 return !(*this == other); 95 } 96 97 98 int32 99 DepotInfo::CountPackages() const 100 { 101 return fPackages.size(); 102 } 103 104 105 PackageInfoRef 106 DepotInfo::PackageAtIndex(int32 index) 107 { 108 return fPackages[index]; 109 } 110 111 112 /*! This method will insert the package into the list of packages 113 in order so that the list of packages remains in order. 114 */ 115 116 void 117 DepotInfo::AddPackage(PackageInfoRef& package) 118 { 119 std::vector<PackageInfoRef>::iterator itInsertionPt 120 = std::lower_bound( 121 fPackages.begin(), 122 fPackages.end(), 123 package, 124 &_IsPackageBefore); 125 fPackages.insert(itInsertionPt, package); 126 } 127 128 129 bool 130 DepotInfo::HasPackage(const BString& packageName) 131 { 132 std::vector<PackageInfoRef>::const_iterator it 133 = std::lower_bound( 134 fPackages.begin(), 135 fPackages.end(), 136 packageName, 137 &_IsPackageBeforeByName); 138 if (it != fPackages.end()) { 139 PackageInfoRef candidate = *it; 140 return (candidate.Get() != NULL 141 && candidate.Get()->Name() == packageName); 142 } 143 return false; 144 } 145 146 147 PackageInfoRef 148 DepotInfo::PackageByName(const BString& packageName) 149 { 150 std::vector<PackageInfoRef>::const_iterator it 151 = std::lower_bound( 152 fPackages.begin(), 153 fPackages.end(), 154 packageName, 155 &_IsPackageBeforeByName); 156 157 if (it != fPackages.end()) { 158 PackageInfoRef candidate = *it; 159 if (candidate.Get() != NULL && candidate.Get()->Name() == packageName) 160 return candidate; 161 } 162 return PackageInfoRef(); 163 } 164 165 166 void 167 DepotInfo::SyncPackagesFromDepot(const DepotInfoRef& other) 168 { 169 for (int32 i = other->CountPackages() - 1; i >= 0; i--) { 170 PackageInfoRef otherPackage = other->PackageAtIndex(i); 171 PackageInfoRef myPackage = PackageByName(otherPackage->Name()); 172 173 if (myPackage.Get() != NULL) { 174 myPackage->SetState(otherPackage->State()); 175 myPackage->SetLocalFilePath(otherPackage->LocalFilePath()); 176 myPackage->SetSystemDependency(otherPackage->IsSystemDependency()); 177 } 178 else { 179 HDINFO("%s: new package: '%s'", fName.String(), 180 otherPackage->Name().String()); 181 AddPackage(otherPackage); 182 } 183 } 184 185 for (int32 i = CountPackages() - 1; i >= 0; i--) { 186 PackageInfoRef myPackage = PackageAtIndex(i); 187 if (!other->HasPackage(myPackage->Name())) { 188 HDINFO("%s: removing package: '%s'", fName.String(), 189 myPackage->Name().String()); 190 fPackages.erase(fPackages.begin() + i); 191 } 192 } 193 } 194 195 196 bool 197 DepotInfo::HasAnyProminentPackages() const 198 { 199 std::vector<PackageInfoRef>::const_iterator it; 200 for (it = fPackages.begin(); it != fPackages.end(); it++) { 201 const PackageInfoRef& package = *it; 202 if (package->IsProminent()) 203 return true; 204 } 205 return false; 206 } 207 208 209 void 210 DepotInfo::SetIdentifier(const BString& value) 211 { 212 fIdentifier = value; 213 } 214 215 216 void 217 DepotInfo::SetWebAppRepositoryCode(const BString& code) 218 { 219 fWebAppRepositoryCode = code; 220 } 221 222 223 void 224 DepotInfo::SetWebAppRepositorySourceCode(const BString& code) 225 { 226 fWebAppRepositorySourceCode = code; 227 } 228