You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hey there,
It's me again !
I found a bug in the position() method. It does not give the good position of the cursor when we have an other type than a string (int for instance).
(I put my whole example that retrieves position from JSON path)
Example :
#pragma once
#include<iostream>
#include<jsoncons/json.hpp>usingnamespacejsoncons;classstring_locator : publicjsoncons::default_json_visitor
{
char* data_;
std::size_t length_;
std::string path_;
std::string from_;
std::vector<std::string> current_;
std::vector<std::size_t>& positions_;
std::vector < std::pair<int,int>> arrayIndexes; //Position in current_, value
std::vector<int> arrayObjects_;
bool check = false;
bool alreadyUpdated = false;
public:using jsoncons::default_json_visitor::string_view_type;
string_locator(char* data, std::size_t length,
const std::string& path,
const std::string& from, std::vector<std::size_t>& positions)
: data_(data), length_(length),
path_(path),
from_(from),
positions_(positions)
{
}
std::string buildNormalizedPath(const std::vector<std::string>& iKeyList)
{
//Init
std::string aNormalizedPath = "$";
//For each key in the current stackfor (auto& key : iKeyList)
{
aNormalizedPath += "[" + key + "]";
}
return aNormalizedPath;
}
boolcustom_visit(const ser_context& context)
{
if (check)
{
arrayObjects_.push_back(current_.size());
}
check = false;
std::string aNormPath;
if (arrayObjects_.size() > 0 && arrayObjects_.back() == current_.size() && arrayIndexes.size() > 0)
{
auto& [pos, val] = arrayIndexes.back();
current_.at(pos) = std::to_string(val);
aNormPath = buildNormalizedPath(current_);
val += 1;
}
else
{
aNormPath = buildNormalizedPath(current_);
}
std::cout << aNormPath << std::endl;
if (path_ == aNormPath)
{
positions_.push_back(context.position());
}
alreadyUpdated = false;
returntrue;
}
boolvisit_begin_object(semantic_tag, const ser_context&, std::error_code&) override
{
//If we are in an array of objects and we are at the same depth (current_.size()) of the object if (arrayObjects_.size() > 0 && arrayObjects_.back() == current_.size())
{
auto& [pos, val] = arrayIndexes.back();
val += 1;
current_.at(pos) = std::to_string(val);
}elseif (check)
{
//we have an array of objects//we save the size of the current stack in a vector//so when we are again at this size it means we need to update the index
arrayObjects_.push_back(current_.size());
}
current_.emplace_back();
returntrue;
}
boolvisit_end_object(const ser_context&, std::error_code&) override
{
current_.pop_back();
check = false;
returntrue;
}
boolvisit_key(const string_view_type& key, const ser_context&, std::error_code&) override
{
current_.back() = "'"+std::string(key)+"'";
check = false;
returntrue;
}
boolvisit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override
{
current_.emplace_back(std::to_string(0));
arrayIndexes.emplace_back(std::make_pair(current_.size()-1,0));
check = true;
returntrue;
}
boolvisit_end_array(const ser_context&, std::error_code& ec) override
{
current_.pop_back();
arrayIndexes.pop_back();
check = false;
arrayObjects_.pop_back();
returntrue;
}
boolvisit_string(const string_view_type& value, jsoncons::semantic_tag, const jsoncons::ser_context& context, std::error_code&) override
{
returncustom_visit(context);
}
boolvisit_null(semantic_tag, const ser_context&, std::error_code& ec) override
{
returntrue;
}
boolvisit_uint64(uint64_t, semantic_tag, const ser_context& context, std::error_code& ec) override
{
returncustom_visit(context);
}
boolvisit_int64(int64_t, semantic_tag, const ser_context& context, std::error_code& ec) override
{
returncustom_visit(context);
}
boolvisit_double(double, semantic_tag, const ser_context& context, std::error_code& ec) override
{
returncustom_visit(context);
}
boolvisit_bool(bool, semantic_tag, const ser_context& context, std::error_code& ec) override
{
returncustom_visit(context);
}
};
voidupdate_in_place(std::string& input,
const std::string& path)
{
std::vector<std::size_t> positions;
string_locator updater(input.data(), input.size(), path, "", positions);
jsoncons::json_reader reader(jsoncons::string_view(input), updater);
reader.read();
for (auto it = positions.rbegin(); it != positions.rend(); ++it)
{
std::cout << "Position : " << *it << std::endl;
}
}
intmain()
{
std::string input1 = R"( { "Parent": { "Child": { "Test": 4444333322221111 } } })";
std::string input2 = R"( { "Parent": { "Child": { "Test": "4444333322221111" } } })";
try
{
update_in_place(input1, "$['Parent']['Child']['Test']");
update_in_place(input2, "$['Parent']['Child']['Test']");
}
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
}
Output :
Position : 92
Position : 77
So it seems we are missing a position() - value.size() when value is not a string.
Thanks a lot for your work.
Regards,
The text was updated successfully, but these errors were encountered:
Fixed on master, but note a change in behavior for string. For all events now, including name, object, array, string, bool, and null, position points to the beginning of the value, which for name and string is at the double quote character (rather than the first character of the string.)
Hey there,
It's me again !
I found a bug in the position() method. It does not give the good position of the cursor when we have an other type than a string (int for instance).
(I put my whole example that retrieves position from JSON path)
Example :
Output :
So it seems we are missing a position() - value.size() when value is not a string.
Thanks a lot for your work.
Regards,
The text was updated successfully, but these errors were encountered: