Search code examples
c++poco

Cleanup / Reset before or after operation


So this is the situation:

I want to use a class of 3rd party library (namely Poco) to parse a JSON string. This Parser class is designed in such a way that after each parsing (operation) it has to be reseted (by calling reset(), who would have thought it?). I reuse one Parser multiple times on different places inside the class I'm implementing, therefor this is important for me. Calling reset() even if the class is reseted already is harmless.

Therefor my question: Should I rather make sure that I reset the parser before each operation or should I ensure that I reset it after an operation.

The first case is handy because it is guaranteed that my parser is in a correct state before operation, but at the same time I feel dirty because I leave the parser in an invalid state and others might expect that I reset the parser.

The second case I dislike because I fear that I could miss a case where my method might exit (e.g a uncaught exception) leaving the parser in an invalid state while other expect it for sure to be valid this time. Of course this could be solved by using RAII (like a scoped lock) but this sounds kind of over engineered for me.

Another solution could be to combine both cases, so: reset, parse, and reset again; but this is kind of redundant IMO.


I'm really unsure here and can't decide for any of these cases and I hope that your opinion (based on design-related considerations, don't you close my question! ;) ) will help me to choose.


Solution

  • Well I would advise not using Poco at all but rather looking at JsonCpp. The design choice Poco made by making you call reset on it is rather odd. That aside, the RAII approach is fairly simple:

    template <typename T>
    struct ScopedParser {
        T& parser; // parser object
    
        ScopedParser(T& p) : parser(p) {} // set parser in constuctor
        ScopedParser(ScopedParser&&) = delete; // no moving
        ScopedParser(const ScopedParser&) = delete; // no copying
    
        ~ScopedParser() {
            parser.reset(); // reset it
        }
    }
    

    Example on how to use it:

    void myFunc() {
        Poco::JSONParser p;
        ScopedParser<Poco::JSONParser> pScoped(p);
    }