Skip to main content
Notice removed Canonical answer required by CommunityBot
Bounty Ended with G. Sliepen's answer chosen by CommunityBot
Notice added Canonical answer required by John
Bounty Started worth 50 reputation by John
added 2 characters in body
Source Link
John
  • 459
  • 2
  • 18
  1. storing the data to a std::string

  2. writewriting the data to a given file descriptor

  3. both of the above

  1. storing the data to a std::string

  2. write the data to a given file descriptor

  3. both of the above

  1. storing the data to a std::string

  2. writing the data to a given file descriptor

  3. both of the above

Source Link
John
  • 459
  • 2
  • 18

A uniform interface for storing data by fd or container

I need to store the data in three different ways:

  1. storing the data to a std::string

  2. write the data to a given file descriptor

  3. 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;
    }
}
```