Giter Club home page Giter Club logo

Comments (8)

clabnet avatar clabnet commented on June 19, 2024 1

closed

from json_struct.

jorgen avatar jorgen commented on June 19, 2024

Hi, thank you for the query!

There are multiple ways of finding the size of vec, but I think the easiest and most versatile is to use a std::vector. Please see the following example:

#include <string>
#include <json_struct.h>

const char json[] = R"json(
{
  "vec" : [
    { "key" : 4, "value": 1.0 },
    { "key" : 5, "value": 2.0 },
    { "key" : 6, "value": 3.0 }
  ]
}
)json";

struct VecMember
{
  std::string key;
  double value;

  JS_OBJ(key, value);
};

struct JsonObject
{
  std::vector<VecMember> vec;
  JS_OBJ(vec);
};


int main()
{
    JsonObject obj;
    JS::ParseContext parseContext(json);
    if (parseContext.parseTo(obj) != JS::Error::NoError)
    {
        std::string errorStr = parseContext.makeErrorString();
        fprintf(stderr, "Error parsing struct %s\n", errorStr.c_str());
        return -1;
    }

    fprintf(stdout, "Vec has size %zu\n", obj.vec.size());

    return 0;
}

Hope this answers the question. If it does please close the issue.

from json_struct.

clabnet avatar clabnet commented on June 19, 2024

Hi @jorgen , thank you for your fast response.
Your reply is very valuable, but my problem is a little too complicated.
I try to be more precise. My json_data is contained into config.json file:

{
    "webInterface": "localhost",
    "......"; "......",
    "moduleList": [
        { "id": 0, "name": "MAINTENANCE" },
        { "id": 1, "name": "CORE" },
        { "id": 2, "name": "BLA BLA" }
    ]
}

and my struct is here : https://pastebin.com/embed_js/fp7WYs6c
Please note on this code the struct TypeHandler<ModuleList<T>> part and the MODULELIST_COUNT define.

When I read the config.json file,

   std::ifstream ifs(config_file.c_str());
   if (!ifs) {
                throw std::invalid_argument("Can't open app config file " + config_file);
   }
   std::string json_data((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
   spdlog::trace(json_data);

I can't parse securely the entire json into Config struct because I can't know how much elements of array the user can be defined. The user can be define one, two, "n" element on moduleList array.

The final goal:
I would remove from the source code the MODULELIST_COUNT define constant, but I don't know.

Sorry for the long post and thank you for your time.

Regards,

from json_struct.

jorgen avatar jorgen commented on June 19, 2024

right! ok. so you want to have a static sized buffer, but want to populate it with dynamic data? so I assume you will have som size variable keeping count of how much of the buffer is filled up? Since you have already a type handler we can modify it "by copying the array type handler spesialisation" and make it fit your needs. I have adjusted the example, does this fit the bill? We have some more options if it doesn't do what you want it to :D

#include <string>
#include <json_struct.h>

const char json[] = R"json(
{
  "vec" : [
    { "key" : 4, "value": 1.0 },
    { "key" : 5, "value": 2.0 },
    { "key" : 6, "value": 3.0 }
  ]
}
)json";

struct VecMember
{
  std::string key;
  double value;

  JS_OBJ(key, value);
};


struct ModuleList
{
  enum
  {
    ReservedSize = 16
  };
  VecMember modules[ReservedSize];
  int size = 0;
};

namespace JS
{
template <>
struct TypeHandler<ModuleList>
{
  static inline Error to(ModuleList &to_type, ParseContext &context)
  {
    if (context.token.value_type != Type::ArrayStart)
      return JS::Error::ExpectedArrayStart;

    context.nextToken();
    for (size_t i = 0; i < ModuleList::ReservedSize; i++)
    {
      if (context.error != JS::Error::NoError)
        return context.error;
      if (context.token.value_type == Type::ArrayEnd)
      {
        to_type.size = i;
        break;
      }
      context.error = TypeHandler<VecMember>::to(to_type.modules[i], context);
      if (context.error != JS::Error::NoError)
        return context.error;

      context.nextToken();
    }

    if (context.token.value_type != Type::ArrayEnd)
      return JS::Error::ExpectedArrayEnd;
    return context.error;
  }

  static inline void from(const ModuleList &from_type, Token &token, Serializer &serializer)
  {
    token.value_type = Type::ArrayStart;
    token.value = DataRef("[");
    serializer.write(token);

    token.name = DataRef("");
    for (size_t i = 0; i < from_type.size; i++)
      TypeHandler<VecMember>::from(from_type.modules[i], token, serializer);

    token.name = DataRef("");
    token.value_type = Type::ArrayEnd;
    token.value = DataRef("]");
    serializer.write(token);
  }
};
} // namespace JS

struct JsonObject
{
  ModuleList vec;
  JS_OBJ(vec);
};


int main()
{
    JsonObject obj;
    JS::ParseContext parseContext(json);
    if (parseContext.parseTo(obj) != JS::Error::NoError)
    {
        std::string errorStr = parseContext.makeErrorString();
        fprintf(stderr, "Error parsing struct %s\n", errorStr.c_str());
        return -1;
    }

    fprintf(stdout, "Vec has size %zu\n", obj.vec.size);

    return 0;
}

from json_struct.

jorgen avatar jorgen commented on June 19, 2024

Hi! I just added a new type to json_struct called JS::ArrayVariableContent. It is basically the code above but removes the need for a more advanced type handler.

https://github.com/jorgen/json_struct/blob/master/tests/json-struct-array-varlength.cpp

from json_struct.

jorgen avatar jorgen commented on June 19, 2024

Can I close this issue now?

from json_struct.

clabnet avatar clabnet commented on June 19, 2024

Sorry for delay, tomorrow I send you my solution.

from json_struct.

clabnet avatar clabnet commented on June 19, 2024

Many thanks for your proposal, but I have found a short road.
I have set MODULELIST_COUNT to 32 (fortunately I know how the max number of elements the user can create)
and defined

        std::vector<Module> moduleList;

It work as is.

Good to hear you, and many thanks @jorgen.

Best regards.

from json_struct.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.