Libraries: A powerful and feature-rich JSON library for MQL5, designed to bring a modern development experience similar to Python/JS

 

A powerful and feature-rich JSON library for MQL5, designed to bring a modern development experience similar to Python/JS:

A powerful and feature-rich JSON library for MQL5, designed to bring a modern development experience similar to Python/JS

A powerful and feature-rich JSON library for MQL5, designed to bring a modern development experience similar to Python/JS

Author: Dao Liang Ding

 

Thank you for sharing your work. I'm curious—how does your library compare to Sergeev’s Json Lib in terms of performance or capabilities?

JSON Serialization and Deserialization (native MQL)
JSON Serialization and Deserialization (native MQL)
  • 2015.10.12
  • www.mql5.com
Serialization and deserialization of JSON protocol. The code is ported from a high-speed С++ library.
 
Thank you very much for sharing the code!
 
Advanced Query 4 Verification failed, is this normal?
 

To resolve the issue of validation failure in Advanced Query 4, replace this function in JsonPath.mqh.

   void EvaluatePath(const MQL5_Json::JsonNode &root, const string &path, MQL5_Json::JsonNode &out_nodes[], MQL5_Json::JsonError &error)
   {
      MQL5_Json::JsonNode current_nodes[];
      if(root.IsValid())
      {
         ArrayResize(current_nodes,1);
         current_nodes[0] = root;
      }
      Tokenizer tokenizer(path);
      while(true)
      {
         Tokenizer::Token token = tokenizer.NextToken();
         if(token.type == Tokenizer::Eof) break;
         if(token.type == Tokenizer::Error)
         {
            error.message = "Invalid JSONPath token";
            error.context = token.str_val;
            return;
         }
         if(token.type == Tokenizer::Root || token.type == Tokenizer::Dot) continue;
         MQL5_Json::JsonNode next_gen_nodes[];
         for(int i=0; i < ArraySize(current_nodes); i++)
         {
            MQL5_Json::JsonNode current_node = current_nodes[i];
            if(!current_node.IsValid()) continue;
            if(token.type == Tokenizer::Ddot)  // Deep scan from current node
            {
               // Add current node if it has children that will be processed next
               if(current_node.IsObject() || current_node.IsArray())
               {
                  int s=ArraySize(next_gen_nodes);
                  ArrayResize(next_gen_nodes,s+1);
                  next_gen_nodes[s]=current_node;
               }
            }
            else if(token.type == Tokenizer::Id || token.type == Tokenizer::Str)
            {
               if(current_node.IsObject())
               {
                  MQL5_Json::JsonNode child=current_node.Get(token.str_val);
                  if(child.IsValid())
                  {
                     int s=ArraySize(next_gen_nodes);
                     ArrayResize(next_gen_nodes,s+1);
                     next_gen_nodes[s]=child;
                  }
               }
               else if(current_node.IsArray())
               {
                  for(int j=0; j<current_node.Size();j++)
                  {
                     MQL5_Json::JsonNode item=current_node.At(j);
                     if(item.IsObject())
                     {
                        MQL5_Json::JsonNode child=item.Get(token.str_val);
                        if(child.IsValid())
                        {
                           int s=ArraySize(next_gen_nodes);
                           ArrayResize(next_gen_nodes,s+1);
                           next_gen_nodes[s]=child;
                        }
                     }
                  }
               }
            }
            else if(token.type == Tokenizer::Lbr)  // [index] or [*]
            {
               Tokenizer::Token next_token = tokenizer.NextToken();
               if(next_token.type == Tokenizer::Wild) // [*] 
               {
                  Tokenizer::Token rbr_token = tokenizer.NextToken();
                  if(rbr_token.type == Tokenizer::Rbr)
                  {
                     if(current_node.IsArray())
                     {
                        for(int j=0; j<current_node.Size(); j++)
                        {
                           MQL5_Json::JsonNode child=current_node.At(j);
                           if(child.IsValid())
                           {
                              int s=ArraySize(next_gen_nodes);
                              ArrayResize(next_gen_nodes,s+1);
                              next_gen_nodes[s]=child;
                           }
                        }
                     }
                  }
               }
               else if(next_token.type == Tokenizer::Num) // [index] 
               {
                  Tokenizer::Token rbr_token = tokenizer.NextToken();
                  if(rbr_token.type == Tokenizer::Rbr)
                  {
                     if(current_node.IsArray())
                     {
                        int index = (int)next_token.num_val;
                        if(index >= 0 && index < current_node.Size())
                        {
                           MQL5_Json::JsonNode child=current_node.At(index);
                           if(child.IsValid())
                           {
                              int s=ArraySize(next_gen_nodes);
                              ArrayResize(next_gen_nodes,s+1);
                              next_gen_nodes[s]=child;
                           }
                        }
                     }
                  }
               }
               else
               {
                  error.message = "Invalid array access syntax";
                  error.context = "Expected [*] or [index]";
                  return;
               }
            }
            else if(token.type == Tokenizer::Wild)
            {
               if(current_node.IsObject())
               {
                  string k[];
                  current_node.GetKeys(k);
                  for(int j=0;j<ArraySize(k);j++)
                  {
                     MQL5_Json::JsonNode child=current_node.Get(k[j]);
                     if(child.IsValid())
                     {
                        int s=ArraySize(next_gen_nodes);
                        ArrayResize(next_gen_nodes,s+1);
                        next_gen_nodes[s]=child;
                     }
                  }
               }
               else if(current_node.IsArray())
               {
                  for(int j=0; j<current_node.Size(); j++)
                  {
                     MQL5_Json::JsonNode child=current_node.At(j);
                     if(child.IsValid())
                     {
                        int s=ArraySize(next_gen_nodes);
                        ArrayResize(next_gen_nodes,s+1);
                        next_gen_nodes[s]=child;
                     }
                  }
               }
            }
         }
         // [THE FIX] Replace illegal ArrayCopy with a compliant `for` loop
         int size = ArraySize(next_gen_nodes);
         ArrayResize(current_nodes, size);
         for(int i=0; i<size; i++) current_nodes[i] = next_gen_nodes[i];
      }
      // [THE FIX] Replace illegal ArrayCopy with a compliant `for` loop
      int size_out = ArraySize(current_nodes);
      ArrayResize(out_nodes, size_out);
      for(int i=0; i<size_out; i++) out_nodes[i] = current_nodes[i];
   }