mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 01:07:15 +03:00
a6bc389217
Summary: Everyone who holds heap-allocated memory gets destructors! Test Plan: valgrind and confirmed no memory leaking from ctreemanifest Reviewers: #fastmanifest, durham Reviewed By: durham Subscribers: mitrandir Differential Revision: https://phabricator.intern.facebook.com/D3763327 Tasks: 12818084 Signature: t1:3763327:1472105103:8ac9d9694be4bf3b09e19e4381737622c94a2dac
89 lines
2.6 KiB
C++
89 lines
2.6 KiB
C++
// treemanifest.cpp - c++ implementation of a tree manifest
|
|
//
|
|
// Copyright 2016 Facebook, Inc.
|
|
//
|
|
// This software may be used and distributed according to the terms of the
|
|
// GNU General Public License version 2 or any later version.
|
|
//
|
|
// no-check-code
|
|
|
|
#include "treemanifest.h"
|
|
|
|
treemanifest::~treemanifest() {
|
|
if (this->rootManifest != NULL) {
|
|
delete this->rootManifest;
|
|
}
|
|
}
|
|
|
|
void _treemanifest_find(
|
|
const std::string &filename,
|
|
const std::string &rootnode,
|
|
Manifest **cachedlookup,
|
|
const ManifestFetcher &fetcher,
|
|
std::string *resultnode, char *resultflag) {
|
|
size_t curpathlen = 0;
|
|
std::string curnode(rootnode);
|
|
|
|
// Loop over the parts of the query filename
|
|
PathIterator pathiter(filename);
|
|
const char *word;
|
|
size_t wordlen;
|
|
while (pathiter.next(&word, &wordlen)) {
|
|
if (*cachedlookup == NULL) {
|
|
// Obtain the raw data for this directory
|
|
*cachedlookup = fetcher.get(filename.c_str(), curpathlen, curnode);
|
|
}
|
|
|
|
Manifest *manifest = *cachedlookup;
|
|
|
|
ManifestIterator mfiterator = manifest->getIterator();
|
|
ManifestEntry *entry;
|
|
bool recurse = false;
|
|
|
|
// Loop over the contents of the current directory looking for the
|
|
// next directory/file.
|
|
while ((entry = mfiterator.next()) != NULL) {
|
|
// If the current entry matches the query file/directory, either recurse,
|
|
// return, or abort.
|
|
if (wordlen == entry->filenamelen &&
|
|
strncmp(word, entry->filename, wordlen) == 0) {
|
|
// If this is the last entry in the query path, either return or abort
|
|
if (pathiter.isfinished()) {
|
|
// If it's a file, it's our result
|
|
if (!entry->isdirectory()) {
|
|
resultnode->assign(binfromhex(entry->node));
|
|
if (entry->flag == NULL) {
|
|
*resultflag = '\0';
|
|
} else {
|
|
*resultflag = *entry->flag;
|
|
}
|
|
return;
|
|
} else {
|
|
// Found a directory when expecting a file - give up
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If there's more in the query, either recurse or give up
|
|
curpathlen = curpathlen + wordlen + 1;
|
|
if (entry->isdirectory() && filename.length() > curpathlen) {
|
|
curnode.erase();
|
|
curnode.append(binfromhex(entry->node));
|
|
cachedlookup = &entry->resolved;
|
|
recurse = true;
|
|
break;
|
|
} else {
|
|
// Found a file when we expected a directory or
|
|
// found a directory when we expected a file.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!recurse) {
|
|
// Failed to find a match
|
|
return;
|
|
}
|
|
}
|
|
}
|