* Implemented a class that can handle Tracker's query files. Only read support
for now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38767 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
14bf35a2ef
commit
24b218c5a7
66
headers/private/shared/QueryFile.h
Normal file
66
headers/private/shared/QueryFile.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _QUERY_FILE_H
|
||||
#define _QUERY_FILE_H
|
||||
|
||||
|
||||
#include <EntryList.h>
|
||||
#include <Query.h>
|
||||
#include <List.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BQueryFile : public BEntryList {
|
||||
public:
|
||||
BQueryFile(const entry_ref& ref);
|
||||
BQueryFile(const BEntry& entry);
|
||||
BQueryFile(const char* path);
|
||||
BQueryFile(BQuery& query);
|
||||
virtual ~BQueryFile();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
status_t SetTo(const entry_ref& ref);
|
||||
status_t SetTo(const BEntry& entry);
|
||||
status_t SetTo(const char* path);
|
||||
status_t SetTo(BQuery& query);
|
||||
void Unset();
|
||||
|
||||
status_t SetPredicate(const char* predicate);
|
||||
status_t AddVolume(const BVolume& volume);
|
||||
status_t AddVolume(dev_t device);
|
||||
|
||||
const char* Predicate() const;
|
||||
int32 CountVolumes() const;
|
||||
dev_t VolumeAt(int32 index) const;
|
||||
|
||||
status_t WriteTo(const entry_ref& ref);
|
||||
status_t WriteTo(const char* path);
|
||||
|
||||
// BEntryList implementation
|
||||
|
||||
virtual status_t GetNextEntry(BEntry* entry,
|
||||
bool traverse = false);
|
||||
virtual status_t GetNextRef(entry_ref* ref);
|
||||
virtual int32 GetNextDirents(struct dirent* buffer,
|
||||
size_t length, int32 count = INT_MAX);
|
||||
virtual status_t Rewind();
|
||||
virtual int32 CountEntries();
|
||||
|
||||
static const char* MimeType();
|
||||
|
||||
private:
|
||||
status_t _SetQuery(int32 index);
|
||||
|
||||
private:
|
||||
status_t fStatus;
|
||||
BString fPredicate;
|
||||
BQuery fQuery;
|
||||
BList fVolumes;
|
||||
int32 fCurrentVolumeIndex;
|
||||
};
|
||||
|
||||
|
||||
#endif // _QUERY_FILE_H
|
@ -6,6 +6,7 @@ AddSubDirSupportedPlatforms libbe_test ;
|
||||
UseLibraryHeaders agg ;
|
||||
UsePrivateHeaders shared libbe ;
|
||||
UseHeaders [ FDirName $(HAIKU_COMMON_DEBUG_OBJECT_DIR) servers input ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src kits ] ;
|
||||
|
||||
# for RWLockManager only
|
||||
UsePrivateSystemHeaders ;
|
||||
@ -19,6 +20,7 @@ StaticLibrary libshared.a :
|
||||
DragTrackingFilter.cpp
|
||||
HashString.cpp
|
||||
Keymap.cpp
|
||||
QueryFile.cpp
|
||||
RWLockManager.cpp
|
||||
SHA256.cpp
|
||||
ShakeTrackingFilter.cpp
|
||||
|
357
src/kits/shared/QueryFile.cpp
Normal file
357
src/kits/shared/QueryFile.cpp
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <QueryFile.h>
|
||||
|
||||
#include <fs_attr.h>
|
||||
#include <Volume.h>
|
||||
#include <VolumeRoster.h>
|
||||
|
||||
#include "tracker/MimeTypes.h"
|
||||
#include "tracker/Utilities.h"
|
||||
|
||||
|
||||
// TODO: add write support
|
||||
// TODO: let Tracker use it?
|
||||
// TODO: live query support?
|
||||
|
||||
|
||||
const char* kAttrQueryString = "_trk/qrystr";
|
||||
const char* kAttrQueryVolume = "_trk/qryvol1";
|
||||
|
||||
|
||||
BQueryFile::BQueryFile(const entry_ref& ref)
|
||||
{
|
||||
SetTo(ref);
|
||||
}
|
||||
|
||||
|
||||
BQueryFile::BQueryFile(const BEntry& entry)
|
||||
{
|
||||
SetTo(entry);
|
||||
}
|
||||
|
||||
|
||||
BQueryFile::BQueryFile(const char* path)
|
||||
{
|
||||
SetTo(path);
|
||||
}
|
||||
|
||||
|
||||
BQueryFile::BQueryFile(BQuery& query)
|
||||
{
|
||||
SetTo(query);
|
||||
}
|
||||
|
||||
|
||||
BQueryFile::~BQueryFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::InitCheck() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::SetTo(const entry_ref& ref)
|
||||
{
|
||||
Unset();
|
||||
|
||||
BNode node(&ref);
|
||||
fStatus = node.InitCheck();
|
||||
if (fStatus != B_OK)
|
||||
return fStatus;
|
||||
|
||||
ssize_t bytesRead = node.ReadAttrString(kAttrQueryString, &fPredicate);
|
||||
if (bytesRead < 0)
|
||||
return fStatus = bytesRead;
|
||||
|
||||
bool searchAllVolumes = true;
|
||||
attr_info info;
|
||||
if (node.GetAttrInfo(kAttrQueryVolume, &info) == B_OK) {
|
||||
void* buffer = malloc(info.size);
|
||||
if (buffer == NULL)
|
||||
return fStatus = B_NO_MEMORY;
|
||||
|
||||
BMessage message;
|
||||
fStatus = message.Unflatten((const char*)buffer);
|
||||
if (fStatus == B_OK) {
|
||||
for (int32 index = 0; index < 100; index++) {
|
||||
BVolume volume;
|
||||
status_t status = BPrivate::MatchArchivedVolume(&volume,
|
||||
&message, index);
|
||||
if (status == B_OK) {
|
||||
fStatus = AddVolume(volume);
|
||||
if (fStatus != B_OK)
|
||||
break;
|
||||
|
||||
searchAllVolumes = false;
|
||||
} else if (status != B_DEV_BAD_DRIVE_NUM) {
|
||||
// Volume doesn't seem to be mounted
|
||||
fStatus = status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
if (searchAllVolumes) {
|
||||
// add all volumes to query
|
||||
BVolumeRoster roster;
|
||||
BVolume volume;
|
||||
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||
if (volume.IsPersistent() && volume.KnowsQuery())
|
||||
AddVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::SetTo(const BEntry& entry)
|
||||
{
|
||||
entry_ref ref;
|
||||
fStatus = entry.GetRef(&ref);
|
||||
if (fStatus != B_OK)
|
||||
return fStatus;
|
||||
|
||||
return SetTo(ref);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::SetTo(const char* path)
|
||||
{
|
||||
entry_ref ref;
|
||||
fStatus = get_ref_for_path(path, &ref);
|
||||
if (fStatus != B_OK)
|
||||
return fStatus;
|
||||
|
||||
return SetTo(ref);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::SetTo(BQuery& query)
|
||||
{
|
||||
Unset();
|
||||
|
||||
BString predicate;
|
||||
query.GetPredicate(&predicate);
|
||||
|
||||
fStatus = SetPredicate(predicate.String());
|
||||
if (fStatus != B_OK)
|
||||
return fStatus;
|
||||
|
||||
return fStatus = AddVolume(query.TargetDevice());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BQueryFile::Unset()
|
||||
{
|
||||
fStatus = B_NO_INIT;
|
||||
fCurrentVolumeIndex = -1;
|
||||
fVolumes.MakeEmpty();
|
||||
fQuery.Clear();
|
||||
fPredicate = "";
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::SetPredicate(const char* predicate)
|
||||
{
|
||||
fPredicate = predicate;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::AddVolume(const BVolume& volume)
|
||||
{
|
||||
return fVolumes.AddItem((void*)volume.Device()) ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::AddVolume(dev_t device)
|
||||
{
|
||||
return fVolumes.AddItem((void*)device) ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BQueryFile::Predicate() const
|
||||
{
|
||||
return fPredicate.String();
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BQueryFile::CountVolumes() const
|
||||
{
|
||||
return fVolumes.CountItems();
|
||||
}
|
||||
|
||||
|
||||
dev_t
|
||||
BQueryFile::VolumeAt(int32 index) const
|
||||
{
|
||||
if (index < 0 || index >= fVolumes.CountItems())
|
||||
return -1;
|
||||
|
||||
return (dev_t)fVolumes.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::WriteTo(const entry_ref& ref)
|
||||
{
|
||||
// TODO: implement
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::WriteTo(const char* path)
|
||||
{
|
||||
entry_ref ref;
|
||||
status_t status = get_ref_for_path(path, &ref);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return WriteTo(ref);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BEntryList implementation
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::GetNextEntry(BEntry* entry, bool traverse)
|
||||
{
|
||||
if (fCurrentVolumeIndex == -1) {
|
||||
// Start with first volume
|
||||
fCurrentVolumeIndex = 0;
|
||||
|
||||
status_t status = _SetQuery(0);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t status = B_ENTRY_NOT_FOUND;
|
||||
|
||||
while (fCurrentVolumeIndex < CountVolumes()) {
|
||||
status = fQuery.GetNextEntry(entry, traverse);
|
||||
if (status != B_ENTRY_NOT_FOUND)
|
||||
break;
|
||||
|
||||
// Continue with next volume, if any
|
||||
status = _SetQuery(++fCurrentVolumeIndex);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::GetNextRef(entry_ref* ref)
|
||||
{
|
||||
if (fCurrentVolumeIndex == -1) {
|
||||
// Start with first volume
|
||||
fCurrentVolumeIndex = 0;
|
||||
|
||||
status_t status = _SetQuery(0);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t status = B_ENTRY_NOT_FOUND;
|
||||
|
||||
while (fCurrentVolumeIndex < CountVolumes()) {
|
||||
status = fQuery.GetNextRef(ref);
|
||||
if (status != B_ENTRY_NOT_FOUND)
|
||||
break;
|
||||
|
||||
// Continue with next volume, if any
|
||||
status = _SetQuery(++fCurrentVolumeIndex);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BQueryFile::GetNextDirents(struct dirent* buffer, size_t length, int32 count)
|
||||
{
|
||||
if (fCurrentVolumeIndex == -1) {
|
||||
// Start with first volume
|
||||
fCurrentVolumeIndex = 0;
|
||||
|
||||
status_t status = _SetQuery(0);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t status = B_ENTRY_NOT_FOUND;
|
||||
|
||||
while (fCurrentVolumeIndex < CountVolumes()) {
|
||||
status = fQuery.GetNextDirents(buffer, length, count);
|
||||
if (status != B_ENTRY_NOT_FOUND)
|
||||
break;
|
||||
|
||||
// Continue with next volume, if any
|
||||
status = _SetQuery(++fCurrentVolumeIndex);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::Rewind()
|
||||
{
|
||||
fCurrentVolumeIndex = -1;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BQueryFile::CountEntries()
|
||||
{
|
||||
// not supported
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ const char*
|
||||
BQueryFile::MimeType()
|
||||
{
|
||||
return B_QUERY_MIMETYPE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BQueryFile::_SetQuery(int32 index)
|
||||
{
|
||||
if (fCurrentVolumeIndex >= CountVolumes())
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
BVolume volume(VolumeAt(fCurrentVolumeIndex));
|
||||
fQuery.Clear();
|
||||
fQuery.SetPredicate(fPredicate.String());
|
||||
fQuery.SetVolume(&volume);
|
||||
|
||||
return fQuery.Fetch();
|
||||
}
|
Loading…
Reference in New Issue
Block a user