#include "config.h"
#include "FileSystem.h"
#include <wtf/HexNumber.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#if !PLATFORM(WIN)
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
namespace WebCore {
static const bool needsEscaping[128] = {
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, false, true, false, false, true, false, false,
false, false, true, false, false, false, false, true,
false, false, false, false, false, false, false, false,
false, false, true, false, true, false, true, true,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, true, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, true, false, false, true,
};
static inline bool shouldEscapeUChar(UChar c)
{
return c > 127 ? false : needsEscaping[c];
}
String encodeForFileName(const String& inputString)
{
StringBuilder result;
StringImpl* stringImpl = inputString.impl();
unsigned length = inputString.length();
for (unsigned i = 0; i < length; ++i) {
UChar character = (*stringImpl)[i];
if (shouldEscapeUChar(character)) {
result.append('%');
appendByteAsHex(character, result);
} else
result.append(character);
}
return result.toString();
}
#if !PLATFORM(MAC)
void setMetadataURL(String&, const String&, const String&)
{
}
bool canExcludeFromBackup()
{
return false;
}
bool excludeFromBackup(const String&)
{
return false;
}
#endif
MappedFileData::~MappedFileData()
{
#if !PLATFORM(WIN)
if (!m_fileData)
return;
munmap(m_fileData, m_fileSize);
#endif
}
MappedFileData::MappedFileData(const String& filePath, bool& success)
{
#if PLATFORM(WIN)
success = false;
#else
CString fsRep = fileSystemRepresentation(filePath);
int fd = !fsRep.isNull() ? open(fsRep.data(), O_RDONLY) : -1;
if (fd < 0) {
success = false;
return;
}
struct stat fileStat;
if (fstat(fd, &fileStat)) {
close(fd);
success = false;
return;
}
if (fileStat.st_size < 0 || fileStat.st_size > std::numeric_limits<unsigned>::max()) {
close(fd);
success = false;
return;
}
unsigned size = static_cast<unsigned>(fileStat.st_size);
if (!size) {
close(fd);
success = true;
return;
}
void* data = mmap(0, size, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
close(fd);
if (data == MAP_FAILED) {
success = false;
return;
}
success = true;
m_fileData = data;
m_fileSize = size;
#endif
}
}