BlobStorage::Blob BlobStorage::add(const String& path, const Data& data)
{
    ASSERT(!RunLoop::isMain());

    auto hash = computeSHA1(data);
    if (data.isEmpty())
        return { data, hash };

    auto blobPath = WebCore::fileSystemRepresentation(blobPathForHash(hash));
    auto linkPath = WebCore::fileSystemRepresentation(path);
    unlink(linkPath.data());

    bool blobExists = access(blobPath.data(), F_OK) != -1;
    if (blobExists) {
        auto existingData = mapFile(blobPath.data());
        if (bytesEqual(existingData, data)) {
            link(blobPath.data(), linkPath.data());
            return { existingData, hash };
        }
        unlink(blobPath.data());
    }

    auto mappedData = data.mapToFile(blobPath.data());
    if (mappedData.isNull())
        return { };

    link(blobPath.data(), linkPath.data());

    m_approximateSize += mappedData.size();

    return { mappedData, hash };
}
BlobStorage::Blob BlobStorage::get(const String& path)
{
    ASSERT(!RunLoop::isMain());

    auto linkPath = WebCore::fileSystemRepresentation(path);
    auto data = mapFile(linkPath.data());

    return { data, computeSHA1(data) };
}
BlobStorage::Blob BlobStorage::add(const String& path, const Data& data)
{
    ASSERT(!RunLoop::isMain());

    auto hash = computeSHA1(data);
    if (data.isEmpty())
        return { data, hash };

    auto blobPath = WebCore::fileSystemRepresentation(blobPathForHash(hash));
    auto linkPath = WebCore::fileSystemRepresentation(path);
    unlink(linkPath.data());

    bool blobExists = access(blobPath.data(), F_OK) != -1;
    if (blobExists) {
        auto existingData = mapFile(blobPath.data());
        if (bytesEqual(existingData, data)) {
            link(blobPath.data(), linkPath.data());
            return { existingData, hash };
        }
        unlink(blobPath.data());
    }

    int fd = open(blobPath.data(), O_CREAT | O_EXCL | O_RDWR , S_IRUSR | S_IWUSR);
    if (fd < 0)
        return { };

    size_t size = data.size();
    if (ftruncate(fd, size) < 0) {
        close(fd);
        return { };
    }

    void* map = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);

    if (map == MAP_FAILED)
        return { };

    uint8_t* mapData = static_cast<uint8_t*>(map);
    data.apply([&mapData](const uint8_t* bytes, size_t bytesSize) {
        memcpy(mapData, bytes, bytesSize);
        mapData += bytesSize;
        return true;
    });

    // Drop the write permission.
    mprotect(map, size, PROT_READ);

    auto mappedData = Data::adoptMap(map, size);

    link(blobPath.data(), linkPath.data());

    m_approximateSize += size;

    return { mappedData, hash };
}
Example #4
0
File: main.cpp Project: Fafou/D-LAN
/**
  * Entry point.
  * @param argc Must be equal to 3.
  * @param argv Must contain :
  *  1) the executable name.
  *  2) "all" to compute the sha1 of the whole file or "chunk" for compute sha1 of each chunk.
  *  3) The filename.
  * @return 0 if all done fine else > 0
  */
int main(int argc, char* argv[])
{
   QTextStream out(stdout);

   if (argc != 3)
   {
      out << "Usage : " << argv[0] << " (all|chunk) <file>" << endl;
      return 1;
   }

   QString mode = QString(argv[1]);
   if (mode == "all")
   {
      out << computeSHA1(argv[2], BUFFER_SIZE).toHex() << "\n";
   }
   else if (mode == "chunk")
   {
      QList<QByteArray> shas = computeMultiSHA1(argv[2], CHUNK_SIZE, BUFFER_SIZE);
      foreach (QByteArray sha, shas)
         out << sha.toHex() << "\n";
   }

   return 0;
}