Exemplo n.º 1
0
bool TransferInfo::Save(const string &doc_root) {
  if (saved_) {
    VLOG(1) << "Saved";
    return true;
  }
  if (!Finished()) {
    VLOG(1) << "Unfinished";
    return false;
  }
  boost::mutex::scoped_lock locker(save_mutex_);
  if (saved_) {
    VLOG(1) << "Saved";
    return true;
  }
  boost::filesystem::path checkbook_dest_filename(doc_root);
  checkbook_dest_filename /= this->checkbook_dest_filename();
  VLOG(2) << this->checkbook_dest_filename() << " transfer finished";
  const int slice_size = checkbook_->slice_size();
  const FileTransfer::Slice &last_slice = checkbook_->slice(slice_size - 1);
  int file_size = last_slice.offset() + last_slice.length();
  boost::filesystem::path dest_filename(doc_root);
  dest_filename /= checkbook_->meta().dest_filename();
  boost::iostreams::mapped_file_params p(dest_filename.string());
  p.mode = std::ios_base::out | std::ios_base::trunc;
  p.new_file_size = file_size;
  boost::iostreams::mapped_file out;
  out.open(p);
  if (!out.is_open()) {
    LOG(WARNING) << "Fail to open file " << dest_filename << " error: " << strerror(errno);
    return false;
  }
  VLOG(1) << "Save file to: " << dest_filename;
  for (int i = 0; i < slice_size; ++i) {
    const FileTransfer::Slice &slice = checkbook_->slice(i);
    boost::filesystem::path slice_name(doc_root);
    slice_name /= GetSliceName(&slice);
    FileTransfer::SliceRequest slice_request;
    if (!boost::filesystem::exists(slice_name)) {
      LOG(WARNING) << "Slice file: " << slice_name << " don't existing";
      return false;
    }
    ifstream in(slice_name.string().c_str(), ios::in | ios::binary);
    if (!slice_request.ParseFromIstream(&in)) {
      LOG(WARNING) << "Fail to parse slice file: " << slice_name;
      return false;
    }
    const string &content = slice_request.content();
    uint32 adler;
    adler = adler32(slice.previous_adler(),
                    reinterpret_cast<const Bytef*>(content.c_str()),
                    content.size());
    if (adler != slice.adler()) {
      LOG(WARNING) << "slice: " << slice.index() << " checksum error";
      return false;
    }
    memmove(out.data() + slice.offset(),
            content.c_str(),
            slice.length());
  }
  out.close();
  for (int i = 0; i < slice_size; ++i) {
    const FileTransfer::Slice &slice = checkbook_->slice(i);
    boost::filesystem::path slice_name(doc_root);
    slice_name /= GetSliceName(&slice);
    boost::filesystem::remove(slice_name);
  }
  boost::filesystem::remove(checkbook_dest_filename);
  saved_ = true;
  return true;
}
Exemplo n.º 2
0
bool WmdmDevice::CopyToStorage(const CopyJob& job) {
  if (!storage_control_ || !storage_)
    return false;

  // Create the song metadata
  IWMDMMetaData* metadata_iface = NULL;
  storage_->CreateEmptyMetadataObject(&metadata_iface);
  job.metadata_.ToWmdm(metadata_iface);

  // Convert the filenames to wchars
  ScopedWCharArray source_filename(QDir::toNativeSeparators(job.source_));
  ScopedWCharArray dest_filename(job.metadata_.basefilename());

  // Create the progress object
  WmdmProgress progress(job.progress_);

  // Copy the file
  IWMDMStorage* new_storage = NULL;
  if (storage_control_->Insert3(
      WMDM_MODE_BLOCK | WMDM_STORAGECONTROL_INSERTINTO |
      WMDM_FILE_CREATE_OVERWRITE | WMDM_CONTENT_FILE,
      WMDM_FILE_ATTR_FOLDER,
      source_filename,
      dest_filename,
      NULL, // operation
      &progress, // progress
      metadata_iface,
      NULL, // data
      &new_storage)) {
    qLog(Warning) << "Couldn't copy file to WMDM device";
    metadata_iface->Release();
    return false;
  }
  metadata_iface->Release();

  if (!new_storage)
    return false;

  // Get the metadata from the newly copied file
  IWMDMStorage3* new_storage3 = NULL;
  IWMDMMetaData* new_metadata = NULL;

  new_storage->QueryInterface(IID_IWMDMStorage3, (void**)&new_storage3);
  new_storage3->GetMetadata(&new_metadata);

  new_storage->Release();
  new_storage3->Release();

  if (!new_metadata)
    return false;

  // Add it to our LibraryModel
  Song new_song;
  new_song.InitFromWmdm(new_metadata);
  new_song.set_directory_id(1);
  songs_to_add_ << new_song;

  new_metadata->Release();

  // Remove the original if requested
  if (job.remove_original_) {
    if (!QFile::remove(job.source_))
      return false;
  }

  return true;
}