1/* 2 * Copyright 2011-2013, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Oliver Tappe <zooey@hirschkaefer.de> 7 * Ingo Weinhold <ingo_weinhold@gmx.de> 8 */ 9 10 11#include <package/RepositoryCache.h> 12 13#include <stdio.h> 14 15#include <new> 16 17#include <Directory.h> 18#include <File.h> 19#include <FindDirectory.h> 20#include <Path.h> 21 22#include <package/hpkg/ErrorOutput.h> 23#include <package/hpkg/PackageInfoAttributeValue.h> 24#include <package/hpkg/RepositoryContentHandler.h> 25#include <package/hpkg/RepositoryReader.h> 26#include <package/hpkg/StandardErrorOutput.h> 27#include <package/PackageInfo.h> 28#include <package/RepositoryInfo.h> 29 30#include <package/PackageInfoContentHandler.h> 31 32 33namespace BPackageKit { 34 35 36using namespace BHPKG; 37 38 39// #pragma mark - RepositoryContentHandler 40 41 42struct BRepositoryCache::RepositoryContentHandler : BRepositoryContentHandler { 43 RepositoryContentHandler(BRepositoryInfo& repositoryInfo, 44 BPackageInfoSet& packages, BErrorOutput* errorOutput) 45 : 46 fRepositoryInfo(repositoryInfo), 47 fPackageInfo(), 48 fPackages(packages), 49 fPackageInfoContentHandler(fPackageInfo, errorOutput) 50 { 51 } 52 53 virtual status_t HandlePackage(const char* packageName) 54 { 55 fPackageInfo.Clear(); 56 return B_OK; 57 } 58 59 60 virtual status_t HandlePackageAttribute( 61 const BPackageInfoAttributeValue& value) 62 { 63 return fPackageInfoContentHandler.HandlePackageAttribute(value); 64 } 65 66 virtual status_t HandlePackageDone(const char* packageName) 67 { 68 status_t result = fPackageInfo.InitCheck(); 69 if (result != B_OK) 70 return result; 71 72 result = fPackages.AddInfo(fPackageInfo); 73 if (result != B_OK) 74 return result; 75 76 return B_OK; 77 } 78 79 virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo) 80 { 81 fRepositoryInfo = repositoryInfo; 82 83 return B_OK; 84 } 85 86 virtual void HandleErrorOccurred() 87 { 88 } 89 90private: 91 BRepositoryInfo& fRepositoryInfo; 92 BPackageInfo fPackageInfo; 93 BPackageInfoSet& fPackages; 94 BPackageInfoContentHandler fPackageInfoContentHandler; 95}; 96 97 98// #pragma mark - BRepositoryCache 99 100 101BRepositoryCache::BRepositoryCache() 102 : 103 fIsUserSpecific(false), 104 fPackages() 105{ 106} 107 108 109BRepositoryCache::~BRepositoryCache() 110{ 111} 112 113 114const BEntry& 115BRepositoryCache::Entry() const 116{ 117 return fEntry; 118} 119 120 121const BRepositoryInfo& 122BRepositoryCache::Info() const 123{ 124 return fInfo; 125} 126 127 128bool 129BRepositoryCache::IsUserSpecific() const 130{ 131 return fIsUserSpecific; 132} 133 134 135void 136BRepositoryCache::SetIsUserSpecific(bool isUserSpecific) 137{ 138 fIsUserSpecific = isUserSpecific; 139} 140 141 142status_t 143BRepositoryCache::SetTo(const BEntry& entry) 144{ 145 // unset 146 fPackages.MakeEmpty(); 147 fEntry.Unset(); 148 149 // get cache file path 150 fEntry = entry; 151 152 BPath repositoryCachePath; 153 status_t result; 154 if ((result = entry.GetPath(&repositoryCachePath)) != B_OK) 155 return result; 156 157 // read repository cache 158 BStandardErrorOutput errorOutput; 159 BRepositoryReader repositoryReader(&errorOutput); 160 if ((result = repositoryReader.Init(repositoryCachePath.Path())) != B_OK) 161 return result; 162 163 RepositoryContentHandler handler(fInfo, fPackages, &errorOutput); 164 if ((result = repositoryReader.ParseContent(&handler)) != B_OK) 165 return result; 166 167 BPath userSettingsPath; 168 if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) { 169 BDirectory userSettingsDir(userSettingsPath.Path()); 170 fIsUserSpecific = userSettingsDir.Contains(&entry); 171 } else 172 fIsUserSpecific = false; 173 174 return B_OK; 175} 176 177 178uint32 179BRepositoryCache::CountPackages() const 180{ 181 return fPackages.CountInfos(); 182} 183 184 185BRepositoryCache::Iterator 186BRepositoryCache::GetIterator() const 187{ 188 return fPackages.GetIterator(); 189} 190 191 192} // namespace BPackageKit 193