Support/PathV2: Implement has_magic.

llvm-svn: 122587
This commit is contained in:
Michael J. Spencer 2010-12-28 01:49:01 +00:00
parent 5e5cfbe871
commit 848f46bb84
2 changed files with 39 additions and 1 deletions

View File

@ -448,7 +448,7 @@ error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
/// @results errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
error_code has_magic(const Twine &path, const Twine &magic);
error_code has_magic(const Twine &path, const Twine &magic, bool &result);
/// @brief Get \a path's first \a len bytes.
///

View File

@ -15,6 +15,8 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ErrorHandling.h"
#include <cctype>
#include <cstdio>
#include <cstring>
namespace {
using llvm::StringRef;
@ -659,6 +661,42 @@ void directory_entry::replace_filename(const Twine &filename, file_status st,
SymlinkStatus = symlink_st;
}
error_code has_magic(const Twine &path, const Twine &magic, bool &result) {
SmallString<128> PathStorage;
SmallString<32> MagicStorage;
StringRef Path = path.toNullTerminatedStringRef(PathStorage);
StringRef Magic = magic.toNullTerminatedStringRef(MagicStorage);
assert(Magic.size() > 0 && "magic must be non-empty!");
SmallString<32> BufferStorage;
BufferStorage.reserve(Magic.size());
// Open file.
std::FILE *file = std::fopen(Path.data(), "rb");
if (file == 0)
return error_code(errno, posix_category());
int size = ::fread(BufferStorage.data(), 1, Magic.size(), file);
if (size != Magic.size()) {
int error = errno;
bool eof = std::feof(file) != 0;
std::fclose(file);
if (eof) {
// EOF, return false.
result = false;
return success;
}
return error_code(error, posix_category());
}
std::fclose(file);
if (std::memcmp(BufferStorage.data(), Magic.data(), Magic.size()) != 0)
result = false;
else
result = true;
return success;
}
} // end namespace fs
} // end namespace sys
} // end namespace llvm