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; }
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; }