I need to store the data in three different ways:
storing the data to a std::string
write the data to a given file descriptor
both of the above
And I hope to use a uniform interface for these three different methods.
How to make it better?
Here is the code snippet:
#include <memory>
#include <string>
#include <iostream>
#include <unistd.h>
class DataStorage {
public:
DataStorage()=default;
DataStorage(const DataStorage&) = default;
DataStorage(DataStorage&&) = default;
DataStorage& operator(const DataStorage&) = default;
DataStorage& operator(DataStorage&&) = default;
virtual int Store(const char *buffer, int count) = 0;
virtual ~DataStorage(){};
};
class DataStorageByStr : virtual public DataStorage {
public:
DataStorageByStr(std::string &str) : str_(str), total_count_{0}{};
DataStorageByStr()=delete;
DataStorageByStr(const DataStorageByStr&) = default;
DataStorageByStr(DataStorageByStr&&) = default;
DataStorageByStr& operator(const DataStorageByStr&) = default;
DataStorageByStr& operator(DataStorageByStr&&) = default;
int Store(const char *buffer, int count)
{
str_ += std::string(buffer, count);
total_count_ += count;
return 0;
};
int GetTotalWritten() const {return total_count_;};
private:
std::string &str_;
int total_count_;
};
class DataStorageByFd : virtual public DataStorage {
public:
DataStorageByFd(int &fd):fd_(fd), total_count_{0}{};
int Store(const char *buffer, int count)
{
int ret = write(fd_, buffer, count);
if(ret > 0)
{
total_count_ += ret;
}
return ret;
};
int GetTotalWritten() const {return total_count_;};
private:
int &fd_;
int total_count_;
};
class DataStorageByStrAndFd : public DataStorageByStr, public DataStorageByFd {
public:
DataStorageByStrAndFd(std::string &str, int &fd):DataStorageByStr(str), DataStorageByFd(fd){}
DataStorageByStrAndFd()=default;
DataStorageByStrAndFd(const DataStorageByStrAndFd&) = default;
DataStorageByStrAndFd(DataStorageByStrAndFd&&) = default;
DataStorageByStrAndFd& operator(const DataStorageByStrAndFd&) = default;
DataStorageByStrAndFd& operator(DataStorageByStrAndFd&&) = default;
int Store(const char *buffer, int count)
{
int ret1 = DataStorageByStr::Store(buffer, count);
int ret2 = DataStorageByFd::Store(buffer, count);
return ((0==ret1) && (0==ret2))?0:-1;
}
int GetWrittenByStr() const {return DataStorageByStr::GetTotalWritten();}
int GetWrittenByFd() const {return DataStorageByFd::GetTotalWritten();}
};
int StoreSomeData(DataStorage &storage, const std::string data_to_store)
{
return storage.Store(data_to_store.data(), data_to_store.length());
}
int main()
{
{
std::cout << "==============1=============" <<std::endl;
std::string str{"storing the string to std::string works !"};
std::string data;
DataStorageByStr storage_by_str = DataStorageByStr(data);
DataStorage &storage = storage_by_str;
StoreSomeData(storage, str);
std::cout << data << std::endl;
std::cout << "total written by str:" << storage_by_str.GetTotalWritten() << std::endl;
}
{
std::cout << "==============2=============" <<std::endl;
std::string str{"storing the string to fd works !"};
int fd = 1;
DataStorageByFd storage_by_fd = DataStorageByFd(fd);
DataStorage &storage = storage_by_fd;
StoreSomeData(storage, str);
std::cout << std::endl << "total written by fd:" << storage_by_fd.GetTotalWritten() << std::endl;
}
{
std::cout << "==============3=============" <<std::endl;
std::string str{"thanks for your attention for this matter!"};
std::string data;
int fd = 1;
DataStorageByStrAndFd storage_by_str_and_fd = DataStorageByStrAndFd(data, fd);
StoreSomeData(storage_by_str_and_fd, str);
std::cout << std::endl;
std::cout << "string length:" << str.length() << std::endl;
std::cout << "total written by string:" << storage_by_str_and_fd.GetWrittenByStr() << std::endl;
std::cout << "total written by fd:" << storage_by_str_and_fd.GetWrittenByFd() << std::endl;
}
}
```