1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_UTILITIES_JSON_HPP
  26 #define SHARE_VM_UTILITIES_JSON_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "utilities/globalDefinitions.hpp"
  30 
  31 #if defined(__APPLE__) || defined(_WINDOWS) || defined(SOLARIS)
  32 // strchrnul not available on osx
  33 const char* strchrnul(const char *s, int c);
  34 #endif
  35 
  36 class JSON : public ResourceObj {
  37  protected:
  38   JSON(const char* text, bool silent);
  39   void parse();
  40   bool valid();
  41 
  42   typedef enum {
  43     JSON_NONE,
  44     JSON_OBJECT_BEGIN,
  45     JSON_OBJECT_END,
  46     JSON_ARRAY_BEGIN,
  47     JSON_ARRAY_END,
  48     JSON_KEY,
  49     JSON_STRING,
  50     JSON_NUMBER_INT,
  51     JSON_NUMBER_FLOAT,
  52     JSON_TRUE,
  53     JSON_FALSE,
  54     JSON_NULL
  55   } JSON_TYPE;
  56 
  57   typedef union {
  58     int64_t int_value;
  59     double double_value;
  60 
  61     struct {
  62       const char* start;
  63       size_t length;
  64     } str;
  65   } JSON_VAL;
  66 
  67   typedef enum {
  68     INTERNAL_ERROR,
  69     SYNTAX_ERROR,
  70     KEY_ERROR,
  71     VALUE_ERROR
  72   } JSON_ERROR;
  73 
  74   void error(JSON_ERROR e, const char* format, ...) ATTRIBUTE_PRINTF(3, 4);
  75 
  76  private:
  77   const char* start;
  78   const char* pos;
  79 
  80   // For error printing
  81   const char* mark; // Error marker
  82   uint level; // CMH Remove?
  83   uint line; // TODO: correct type?
  84   uint column;
  85 
  86   bool silent;
  87   bool _valid;
  88 
  89   bool parse_json_value();
  90   bool parse_json_object();
  91   bool parse_json_array();
  92   bool parse_json_string(bool key = false);
  93   bool parse_json_key();
  94   bool parse_json_number();
  95   bool parse_json_symbol(const char* name, JSON_TYPE symbol);
  96 
  97   virtual bool callback(JSON_TYPE t, JSON_VAL* v, uint level) = 0;
  98 
  99   void mark_pos();
 100   u_char next();
 101   u_char peek();
 102   u_char peek(size_t i);
 103   int expect_any(const char* valid_chars, const char* error_msg, JSON_ERROR e = SYNTAX_ERROR);
 104   bool expect_string(const char* expected_string, const char* error_msg = "", JSON_ERROR e = SYNTAX_ERROR);
 105   size_t skip(size_t i);
 106   int skip_to_token();
 107   u_char skip_to(u_char want);
 108   u_char skip_line_comment();
 109   int skip_block_comment();
 110 
 111   const char* strerror(JSON_ERROR e);
 112 };
 113 
 114 #ifndef PRODUCT
 115 class JSONTest : public JSON {
 116  public:
 117   static bool test();
 118 
 119  private:
 120   JSONTest(const char* text);
 121   static void test(const char* json, bool valid);
 122 
 123   void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4);
 124 
 125   bool callback(JSON_TYPE t, JSON_VAL* v, uint level);
 126   JSON_TYPE prev;
 127 };
 128 #endif
 129 
 130 #endif // SHARE_VM_UTILITIES_JSON_HPP