// Write out the given protobuf to the specified file descriptor by // first writing out the length of the protobuf followed by the contents. // NOTE: On error, this may have written partial data to the file. inline Try<Nothing> write(int fd, const google::protobuf::Message& message) { if (!message.IsInitialized()) { return Error("Uninitialized protocol buffer"); } // First write the size of the protobuf. uint32_t size = message.ByteSize(); std::string bytes = std::string((char*) &size, sizeof(size)); Try<Nothing> result = os::write(fd, bytes); if (result.isError()) { return Error("Failed to write size: " + result.error()); } if (!message.SerializeToFileDescriptor(fd)) { return Error("Failed to write/serialize message"); } return Nothing(); }
// Write out the given protobuf to the specified file descriptor by // first writing out the length of the protobuf followed by the // contents. inline Result<bool> write(int fd, const google::protobuf::Message& message) { if (!message.IsInitialized()) { LOG(ERROR) << "Failed to write protocol buffer to file, " << "protocol buffer is not initialized!"; return false; } uint32_t size = message.ByteSize(); ssize_t length = ::write(fd, (void*) &size, sizeof(size)); if (length == -1) { std::string error = strerror(errno); error = error + " (" + __FILE__ + ":" + utils::stringify(__LINE__) + ")"; return Result<bool>::error(error); } CHECK(length != 0); CHECK(length == sizeof(size)); // TODO(benh): Handle a non-blocking fd? return message.SerializeToFileDescriptor(fd); }
void PersistentData::setValueFilepath(const QString& filepath, const google::protobuf::Message& data, Global::DataFolderType dataFolderType, bool humanReadable) try { const QString TEMP_FILEPATH(filepath + TEMP_SUFFIX_TERM); // To avoid ::Print(..) to crash, see defect #153. if (Global::availableDiskSpace(Global::getDataFolder(dataFolderType)) < 20 * 1024 * 1024) return; { QFile file(TEMP_FILEPATH); if (!file.open(QIODevice::WriteOnly)) throw PersistentDataIOException(QString("Unable to open the file in write mode : %1, error : %2").arg(TEMP_FILEPATH).arg(file.errorString())); #if !DEBUG if (humanReadable) { #endif google::protobuf::io::FileOutputStream fileStream(file.handle()); google::protobuf::TextFormat::Printer printer; printer.SetUseShortRepeatedPrimitives(true); printer.Print(data, &fileStream); #if !DEBUG } else { data.SerializeToFileDescriptor(file.handle()); } #endif } Global::rename(TEMP_FILEPATH, filepath); } catch(Global::UnableToGetFolder& e) { throw PersistentDataIOException(e.errorMessage); }