Skip to main content
2 of 2
added 2 characters in body
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. writing 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;
    }
}
```
John
  • 459
  • 2
  • 18