Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR: Provide API for emit+append #345

Open
huangqinjin opened this issue Dec 18, 2022 · 5 comments
Open

FR: Provide API for emit+append #345

huangqinjin opened this issue Dec 18, 2022 · 5 comments

Comments

@huangqinjin
Copy link

Currently emitrs_json(ConstNodeRef const& n, CharOwningContainer * cont) will overwrite the original content of cont.

May I request an API to keep the content of cont but append emitted string to cont.

@biojppm
Copy link
Owner

biojppm commented Dec 18, 2022

It does make sense, but I'm not inclined to add that, as the emit overload set is already too large.

Also, you can already achieve this by using the lower level emit_json() function. Let's start from the current emitrs_json() implementation:

template<class CharOwningContainer>
substr emitrs_json(Tree const& t, size_t id, CharOwningContainer * cont)
{
    substr buf = to_substr(*cont);
    substr ret = emit_json(t, id, buf, /*error_on_excess*/false);
    if(ret.str == nullptr && ret.len > 0)
    {
        cont->resize(ret.len);
        buf = to_substr(*cont);
        ret = emit_json(t, id, buf, /*error_on_excess*/true);
    }
    return ret;
}

Using this as a starting point, and assuming we will append after cont->size(), it is easy to append by doing something like this (not tested):

template<class CharOwningContainer>
substr emitrs_json_append(Tree const& t, size_t id, CharOwningContainer * cont)
{
    size_t sz = cont->size(); // save the original container size
    cont->resize(cont->capacity()); // expand the container to its current capacity
                                    // to give us a chance to not allocate
    substr buf = to_substr(*cont); // get the full view as above
    buf = buf.sub(sz);             // but skip the original container size
                                   // (retain only at the end)
    substr ret = emit_json(t, id, buf, /*error_on_excess*/false);
    if(ret.str == nullptr && ret.len > 0)
    {
        cont->resize(sz + ret.len); // original + needed size
        buf = to_substr(*cont);
        buf = buf.sub(sz); // skip the original size
        ret = emit_json(t, id, buf, /*error_on_excess*/true);
    }
    return ret;
}
template<class CharOwningContainer>
substr emitrs_json_append(ConstNodeRef const &n, CharOwningContainer * cont)
{
    return emitrs_json_append(n.tree(), n.id(), cont);
}

HTH.

@huangqinjin
Copy link
Author

I think the emitrs_json should be implemented as emit+append, so if you need emit+resize, you just need clear the container before calling emit+append.

@biojppm
Copy link
Owner

biojppm commented May 16, 2024

That's just not going to happen. But while working on an unrelated issue, I've had to create an EmitOptions that can be elegantly used to implement emit and append. Stay tuned.

@biojppm
Copy link
Owner

biojppm commented May 16, 2024

See the commit/PR linked above. It will land in master in a few weeks.

@huangqinjin
Copy link
Author

See the commit/PR linked above. It will land in master in a few weeks.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants