मैं एक कस्टम std :: fstream बनाने की कोशिश कर रहा हूं, जो पढ़ते समय डेटा को एन्कोड/डीकोड करेगा।

template <class T>
class _filebuf : public std::filebuf {
public:
    using transform_type = T;

    int_type underflow() override {
        auto c = std::filebuf::underflow();
        return c < 0 ? c : transform.decode(c);
    }

    int_type overflow(int_type c) override {
        return c < 0 ? c : std::filebuf::overflow(transform.encode(c));
    }

private:
    transform_type transform;
};

template <class T>
class _fstream : public std::iostream {
public:
    using buffer_type = _filebuf<T>;
    
    explicit _fstream(const std::string& path, std::ios::openmode openmode)
        : std::iostream(0)
    {
        this->init(&buffer);
        buffer.open(path, openmode);
    }

private:
    buffer_type buffer;
};

और यहां एक उपयोग उदाहरण है:

class _transform {
public:
    template <class T>
    T encode(T value) const {
        return value - 1;
    }
   
    template <class T>
    T decode(T value) const {
        return value + 1;
    }    
};

int main() {
    _fstream<_transform> ofs("test.txt", std::ios::out | std::ios::trunc);
    ofs << "ABC"; // outputs "@BC" to the file (@ is 64 in ASCII, so only first character encoded properly)

    _fstream<_transform> ifs("test.txt", std::ios::in);
    std::string s;
    ifs >> s; // inputs  "ABC" when "@BC" was in the file so again only first character is decoded

    // ...
};

अपने स्वयं के शोध के बाद, मुझे पता चला कि 'ओवरफ्लो' फ़ंक्शन को प्रक्रिया में दो बार कॉल किया जाता है (65 और -1 के साथ, जहां -1 शायद EOF है), और 'अंडरफ्लो' भी दो बार (64 और -1 के साथ)। चूंकि अन्य पात्र खो नहीं जाते हैं, वे शायद उन कार्यों को कॉल किए बिना किसी तरह संसाधित होते हैं।

ऐसा क्यों हो रहा है और इसे कैसे बदला जाए?

7
Kuba Chrabański 15 जून 2020, 17:59

1 उत्तर

सबसे बढ़िया उत्तर

std::streambuf<CharT,Traits>::underflow सुनिश्चित करता है कि कम से कम एक वर्ण प्राप्त क्षेत्र में उपलब्ध है, std::filebuf का कुशल कार्यान्वयन हमेशा प्राप्त क्षेत्र में वर्णों के पूर्ण बफ़र्स को पढ़ने का प्रयास करेगा। जब तक आप स्ट्रीम की तलाश नहीं करते underflow को फिर से कॉल नहीं किया जाएगा जब तक कि sgetn/xsgetn या sbumpc पर कॉल करके गेट एरिया खाली नहीं हो जाता।

मुझे लगता है कि फ़ाइल बफर को विस्तारित करने के बजाय आपको शायद अधिक सफलता प्राप्त होगी।

बूस्ट iostreams लेखन स्ट्रीम फ़िल्टर को बहुत आसान बना देता है .

2
Alan Birtles 15 जून 2020, 15:17