mirror of https://github.com/grpc/grpc.git
commit
ee4b311605
33 changed files with 339 additions and 2135 deletions
@ -1,34 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_JSON_JSON_COMMON_H |
||||
#define GRPC_CORE_LIB_JSON_JSON_COMMON_H |
||||
|
||||
/* The various json types. */ |
||||
typedef enum { |
||||
GRPC_JSON_OBJECT, |
||||
GRPC_JSON_ARRAY, |
||||
GRPC_JSON_STRING, |
||||
GRPC_JSON_NUMBER, |
||||
GRPC_JSON_TRUE, |
||||
GRPC_JSON_FALSE, |
||||
GRPC_JSON_NULL, |
||||
GRPC_JSON_TOP_LEVEL |
||||
} grpc_json_type; |
||||
|
||||
#endif /* GRPC_CORE_LIB_JSON_JSON_COMMON_H */ |
@ -1,146 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_JSON_JSON_READER_H |
||||
#define GRPC_CORE_LIB_JSON_JSON_READER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/json/json_common.h" |
||||
|
||||
typedef enum { |
||||
GRPC_JSON_STATE_OBJECT_KEY_BEGIN, |
||||
GRPC_JSON_STATE_OBJECT_KEY_STRING, |
||||
GRPC_JSON_STATE_OBJECT_KEY_END, |
||||
GRPC_JSON_STATE_VALUE_BEGIN, |
||||
GRPC_JSON_STATE_VALUE_STRING, |
||||
GRPC_JSON_STATE_STRING_ESCAPE, |
||||
GRPC_JSON_STATE_STRING_ESCAPE_U1, |
||||
GRPC_JSON_STATE_STRING_ESCAPE_U2, |
||||
GRPC_JSON_STATE_STRING_ESCAPE_U3, |
||||
GRPC_JSON_STATE_STRING_ESCAPE_U4, |
||||
GRPC_JSON_STATE_VALUE_NUMBER, |
||||
GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL, |
||||
GRPC_JSON_STATE_VALUE_NUMBER_ZERO, |
||||
GRPC_JSON_STATE_VALUE_NUMBER_DOT, |
||||
GRPC_JSON_STATE_VALUE_NUMBER_E, |
||||
GRPC_JSON_STATE_VALUE_NUMBER_EPM, |
||||
GRPC_JSON_STATE_VALUE_TRUE_R, |
||||
GRPC_JSON_STATE_VALUE_TRUE_U, |
||||
GRPC_JSON_STATE_VALUE_TRUE_E, |
||||
GRPC_JSON_STATE_VALUE_FALSE_A, |
||||
GRPC_JSON_STATE_VALUE_FALSE_L, |
||||
GRPC_JSON_STATE_VALUE_FALSE_S, |
||||
GRPC_JSON_STATE_VALUE_FALSE_E, |
||||
GRPC_JSON_STATE_VALUE_NULL_U, |
||||
GRPC_JSON_STATE_VALUE_NULL_L1, |
||||
GRPC_JSON_STATE_VALUE_NULL_L2, |
||||
GRPC_JSON_STATE_VALUE_END, |
||||
GRPC_JSON_STATE_END |
||||
} grpc_json_reader_state; |
||||
|
||||
enum { |
||||
/* The first non-unicode value is 0x110000. But let's pick
|
||||
* a value high enough to start our error codes from. These |
||||
* values are safe to return from the read_char function. |
||||
*/ |
||||
GRPC_JSON_READ_CHAR_EOF = 0x7ffffff0, |
||||
GRPC_JSON_READ_CHAR_EAGAIN, |
||||
GRPC_JSON_READ_CHAR_ERROR |
||||
}; |
||||
|
||||
struct grpc_json_reader; |
||||
|
||||
typedef struct grpc_json_reader_vtable { |
||||
/* Clears your internal string scratchpad. */ |
||||
void (*string_clear)(void* userdata); |
||||
/* Adds a char to the string scratchpad. */ |
||||
void (*string_add_char)(void* userdata, uint32_t c); |
||||
/* Adds a utf32 char to the string scratchpad. */ |
||||
void (*string_add_utf32)(void* userdata, uint32_t c); |
||||
/* Reads a character from your input. May be utf-8, 16 or 32. */ |
||||
uint32_t (*read_char)(void* userdata); |
||||
/* Starts a container of type GRPC_JSON_ARRAY or GRPC_JSON_OBJECT. */ |
||||
void (*container_begins)(void* userdata, grpc_json_type type); |
||||
/* Ends the current container. Must return the type of its parent. */ |
||||
grpc_json_type (*container_ends)(void* userdata); |
||||
/* Your internal string scratchpad is an object's key. */ |
||||
void (*set_key)(void* userdata); |
||||
/* Your internal string scratchpad is a string value. */ |
||||
void (*set_string)(void* userdata); |
||||
/* Your internal string scratchpad is a numerical value. Return 1 if valid. */ |
||||
int (*set_number)(void* userdata); |
||||
/* Sets the values true, false or null. */ |
||||
void (*set_true)(void* userdata); |
||||
void (*set_false)(void* userdata); |
||||
void (*set_null)(void* userdata); |
||||
} grpc_json_reader_vtable; |
||||
|
||||
typedef struct grpc_json_reader { |
||||
/* That structure is fully private, and initialized by grpc_json_reader_init.
|
||||
* The definition is public so you can put it on your stack. |
||||
*/ |
||||
|
||||
void* userdata; |
||||
grpc_json_reader_vtable* vtable; |
||||
int depth; |
||||
int in_object; |
||||
int in_array; |
||||
int escaped_string_was_key; |
||||
int container_just_begun; |
||||
uint16_t unicode_char, unicode_high_surrogate; |
||||
grpc_json_reader_state state; |
||||
} grpc_json_reader; |
||||
|
||||
/* The return type of the parser. */ |
||||
typedef enum { |
||||
GRPC_JSON_DONE, /* The parser finished successfully. */ |
||||
GRPC_JSON_EAGAIN, /* The parser yields to get more data. */ |
||||
GRPC_JSON_READ_ERROR, /* The parser passes through a read error. */ |
||||
GRPC_JSON_PARSE_ERROR, /* The parser found an error in the json stream. */ |
||||
GRPC_JSON_INTERNAL_ERROR /* The parser got an internal error. */ |
||||
} grpc_json_reader_status; |
||||
|
||||
/* Call this function to start parsing the input. It will return the following:
|
||||
* . GRPC_JSON_DONE if the input got eof, and the parsing finished |
||||
* successfully. |
||||
* . GRPC_JSON_EAGAIN if the read_char function returned again. Call the |
||||
* parser again as needed. It is okay to call the parser in polling mode, |
||||
* although a bit dull. |
||||
* . GRPC_JSON_READ_ERROR if the read_char function returned an error. The |
||||
* state isn't broken however, and the function can be called again if the |
||||
* error has been corrected. But please use the EAGAIN feature instead for |
||||
* consistency. |
||||
* . GRPC_JSON_PARSE_ERROR if the input was somehow invalid. |
||||
* . GRPC_JSON_INTERNAL_ERROR if the parser somehow ended into an invalid |
||||
* internal state. |
||||
*/ |
||||
grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader); |
||||
|
||||
/* Call this function to initialize the reader structure. */ |
||||
void grpc_json_reader_init(grpc_json_reader* reader, |
||||
grpc_json_reader_vtable* vtable, void* userdata); |
||||
|
||||
/* You may call this from the read_char callback if you don't know where is the
|
||||
* end of your input stream, and you'd like the json reader to hint you that it |
||||
* has completed reading its input, so you can return an EOF to it. Note that |
||||
* there might still be trailing whitespaces after that point. |
||||
*/ |
||||
int grpc_json_reader_is_complete(grpc_json_reader* reader); |
||||
|
||||
#endif /* GRPC_CORE_LIB_JSON_JSON_READER_H */ |
@ -1,367 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/lib/json/json.h" |
||||
#include "src/core/lib/json/json_reader.h" |
||||
#include "src/core/lib/json/json_writer.h" |
||||
|
||||
/* The json reader will construct a bunch of grpc_json objects and
|
||||
* link them all up together in a tree-like structure that will represent |
||||
* the json data in memory. |
||||
* |
||||
* It also uses its own input as a scratchpad to store all of the decoded, |
||||
* unescaped strings. So we need to keep track of all these pointers in |
||||
* that opaque structure the reader will carry for us. |
||||
* |
||||
* Note that this works because the act of parsing json always reduces its |
||||
* input size, and never expands it. |
||||
*/ |
||||
typedef struct { |
||||
grpc_json* top; |
||||
grpc_json* current_container; |
||||
grpc_json* current_value; |
||||
uint8_t* input; |
||||
uint8_t* key; |
||||
uint8_t* string; |
||||
uint8_t* string_ptr; |
||||
size_t remaining_input; |
||||
} json_reader_userdata; |
||||
|
||||
/* This json writer will put everything in a big string.
|
||||
* The point is that we allocate that string in chunks of 256 bytes. |
||||
*/ |
||||
typedef struct { |
||||
char* output; |
||||
size_t free_space; |
||||
size_t string_len; |
||||
size_t allocated; |
||||
} json_writer_userdata; |
||||
|
||||
/* This function checks if there's enough space left in the output buffer,
|
||||
* and will enlarge it if necessary. We're only allocating chunks of 256 |
||||
* bytes at a time (or multiples thereof). |
||||
*/ |
||||
static void json_writer_output_check(void* userdata, size_t needed) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
if (state->free_space >= needed) return; |
||||
needed -= state->free_space; |
||||
/* Round up by 256 bytes. */ |
||||
needed = (needed + 0xff) & ~0xffU; |
||||
state->output = |
||||
static_cast<char*>(gpr_realloc(state->output, state->allocated + needed)); |
||||
state->free_space += needed; |
||||
state->allocated += needed; |
||||
} |
||||
|
||||
/* These are needed by the writer's implementation. */ |
||||
static void json_writer_output_char(void* userdata, char c) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
json_writer_output_check(userdata, 1); |
||||
state->output[state->string_len++] = c; |
||||
state->free_space--; |
||||
} |
||||
|
||||
static void json_writer_output_string_with_len(void* userdata, const char* str, |
||||
size_t len) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
json_writer_output_check(userdata, len); |
||||
memcpy(state->output + state->string_len, str, len); |
||||
state->string_len += len; |
||||
state->free_space -= len; |
||||
} |
||||
|
||||
static void json_writer_output_string(void* userdata, const char* str) { |
||||
size_t len = strlen(str); |
||||
json_writer_output_string_with_len(userdata, str, len); |
||||
} |
||||
|
||||
/* The reader asks us to clear our scratchpad. In our case, we'll simply mark
|
||||
* the end of the current string, and advance our output pointer. |
||||
*/ |
||||
static void json_reader_string_clear(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
if (state->string) { |
||||
GPR_ASSERT(state->string_ptr < state->input); |
||||
*state->string_ptr++ = 0; |
||||
} |
||||
state->string = state->string_ptr; |
||||
} |
||||
|
||||
static void json_reader_string_add_char(void* userdata, uint32_t c) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
GPR_ASSERT(state->string_ptr < state->input); |
||||
GPR_ASSERT(c <= 0xff); |
||||
*state->string_ptr++ = static_cast<uint8_t>(c); |
||||
} |
||||
|
||||
/* We are converting a UTF-32 character into UTF-8 here,
|
||||
* as described by RFC3629. |
||||
*/ |
||||
static void json_reader_string_add_utf32(void* userdata, uint32_t c) { |
||||
if (c <= 0x7f) { |
||||
json_reader_string_add_char(userdata, c); |
||||
} else if (c <= 0x7ff) { |
||||
uint32_t b1 = 0xc0 | ((c >> 6) & 0x1f); |
||||
uint32_t b2 = 0x80 | (c & 0x3f); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
} else if (c <= 0xffff) { |
||||
uint32_t b1 = 0xe0 | ((c >> 12) & 0x0f); |
||||
uint32_t b2 = 0x80 | ((c >> 6) & 0x3f); |
||||
uint32_t b3 = 0x80 | (c & 0x3f); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
json_reader_string_add_char(userdata, b3); |
||||
} else if (c <= 0x1fffff) { |
||||
uint32_t b1 = 0xf0 | ((c >> 18) & 0x07); |
||||
uint32_t b2 = 0x80 | ((c >> 12) & 0x3f); |
||||
uint32_t b3 = 0x80 | ((c >> 6) & 0x3f); |
||||
uint32_t b4 = 0x80 | (c & 0x3f); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
json_reader_string_add_char(userdata, b3); |
||||
json_reader_string_add_char(userdata, b4); |
||||
} |
||||
} |
||||
|
||||
/* We consider that the input may be a zero-terminated string. So we
|
||||
* can end up hitting eof before the end of the alleged string length. |
||||
*/ |
||||
static uint32_t json_reader_read_char(void* userdata) { |
||||
uint32_t r; |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
if (state->remaining_input == 0) return GRPC_JSON_READ_CHAR_EOF; |
||||
|
||||
r = *state->input++; |
||||
state->remaining_input--; |
||||
|
||||
if (r == 0) { |
||||
state->remaining_input = 0; |
||||
return GRPC_JSON_READ_CHAR_EOF; |
||||
} |
||||
|
||||
return r; |
||||
} |
||||
|
||||
/* Helper function to create a new grpc_json object and link it into
|
||||
* our tree-in-progress inside our opaque structure. |
||||
*/ |
||||
static grpc_json* json_create_and_link(void* userdata, grpc_json_type type) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
grpc_json* json = grpc_json_create(type); |
||||
|
||||
json->parent = state->current_container; |
||||
json->prev = state->current_value; |
||||
state->current_value = json; |
||||
|
||||
if (json->prev) { |
||||
json->prev->next = json; |
||||
} |
||||
if (json->parent) { |
||||
if (!json->parent->child) { |
||||
json->parent->child = json; |
||||
} |
||||
if (json->parent->type == GRPC_JSON_OBJECT) { |
||||
json->key = reinterpret_cast<char*>(state->key); |
||||
} |
||||
} |
||||
if (!state->top) { |
||||
state->top = json; |
||||
} |
||||
|
||||
return json; |
||||
} |
||||
|
||||
static void json_reader_container_begins(void* userdata, grpc_json_type type) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
grpc_json* container; |
||||
|
||||
GPR_ASSERT(type == GRPC_JSON_ARRAY || type == GRPC_JSON_OBJECT); |
||||
|
||||
container = json_create_and_link(userdata, type); |
||||
state->current_container = container; |
||||
state->current_value = nullptr; |
||||
} |
||||
|
||||
/* It's important to remember that the reader is mostly stateless, so it
|
||||
* isn't trying to remember what the container was prior the one that just |
||||
* ends. Since we're keeping track of these for our own purpose, we are |
||||
* able to return that information back, which is useful for it to validate |
||||
* the input json stream. |
||||
* |
||||
* Also note that if we're at the top of the tree, and the last container |
||||
* ends, we have to return GRPC_JSON_TOP_LEVEL. |
||||
*/ |
||||
static grpc_json_type json_reader_container_ends(void* userdata) { |
||||
grpc_json_type container_type = GRPC_JSON_TOP_LEVEL; |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
GPR_ASSERT(state->current_container); |
||||
|
||||
state->current_value = state->current_container; |
||||
state->current_container = state->current_container->parent; |
||||
|
||||
if (state->current_container) { |
||||
container_type = state->current_container->type; |
||||
} |
||||
|
||||
return container_type; |
||||
} |
||||
|
||||
/* The next 3 functions basically are the reader asking us to use our string
|
||||
* scratchpad for one of these 3 purposes. |
||||
* |
||||
* Note that in the set_number case, we're not going to try interpreting it. |
||||
* We'll keep it as a string, and leave it to the caller to evaluate it. |
||||
*/ |
||||
static void json_reader_set_key(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
state->key = state->string; |
||||
} |
||||
|
||||
static void json_reader_set_string(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
grpc_json* json = json_create_and_link(userdata, GRPC_JSON_STRING); |
||||
json->value = reinterpret_cast<char*>(state->string); |
||||
} |
||||
|
||||
static int json_reader_set_number(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
grpc_json* json = json_create_and_link(userdata, GRPC_JSON_NUMBER); |
||||
json->value = reinterpret_cast<char*>(state->string); |
||||
return 1; |
||||
} |
||||
|
||||
/* The object types true, false and null are self-sufficient, and don't need
|
||||
* any more information beside their type. |
||||
*/ |
||||
static void json_reader_set_true(void* userdata) { |
||||
json_create_and_link(userdata, GRPC_JSON_TRUE); |
||||
} |
||||
|
||||
static void json_reader_set_false(void* userdata) { |
||||
json_create_and_link(userdata, GRPC_JSON_FALSE); |
||||
} |
||||
|
||||
static void json_reader_set_null(void* userdata) { |
||||
json_create_and_link(userdata, GRPC_JSON_NULL); |
||||
} |
||||
|
||||
static grpc_json_reader_vtable reader_vtable = { |
||||
json_reader_string_clear, json_reader_string_add_char, |
||||
json_reader_string_add_utf32, json_reader_read_char, |
||||
json_reader_container_begins, json_reader_container_ends, |
||||
json_reader_set_key, json_reader_set_string, |
||||
json_reader_set_number, json_reader_set_true, |
||||
json_reader_set_false, json_reader_set_null}; |
||||
|
||||
/* And finally, let's define our public API. */ |
||||
grpc_json* grpc_json_parse_string_with_len(char* input, size_t size) { |
||||
grpc_json_reader reader; |
||||
json_reader_userdata state; |
||||
grpc_json* json = nullptr; |
||||
grpc_json_reader_status status; |
||||
|
||||
if (!input) return nullptr; |
||||
|
||||
state.top = state.current_container = state.current_value = nullptr; |
||||
state.string = state.key = nullptr; |
||||
state.string_ptr = state.input = reinterpret_cast<uint8_t*>(input); |
||||
state.remaining_input = size; |
||||
grpc_json_reader_init(&reader, &reader_vtable, &state); |
||||
|
||||
status = grpc_json_reader_run(&reader); |
||||
json = state.top; |
||||
|
||||
if ((status != GRPC_JSON_DONE) && json) { |
||||
grpc_json_destroy(json); |
||||
json = nullptr; |
||||
} |
||||
|
||||
return json; |
||||
} |
||||
|
||||
#define UNBOUND_JSON_STRING_LENGTH 0x7fffffff |
||||
|
||||
grpc_json* grpc_json_parse_string(char* input) { |
||||
return grpc_json_parse_string_with_len(input, UNBOUND_JSON_STRING_LENGTH); |
||||
} |
||||
|
||||
static void json_dump_recursive(grpc_json_writer* writer, const grpc_json* json, |
||||
int in_object) { |
||||
while (json) { |
||||
if (in_object) grpc_json_writer_object_key(writer, json->key); |
||||
|
||||
switch (json->type) { |
||||
case GRPC_JSON_OBJECT: |
||||
case GRPC_JSON_ARRAY: |
||||
grpc_json_writer_container_begins(writer, json->type); |
||||
if (json->child) |
||||
json_dump_recursive(writer, json->child, |
||||
json->type == GRPC_JSON_OBJECT); |
||||
grpc_json_writer_container_ends(writer, json->type); |
||||
break; |
||||
case GRPC_JSON_STRING: |
||||
grpc_json_writer_value_string(writer, json->value); |
||||
break; |
||||
case GRPC_JSON_NUMBER: |
||||
grpc_json_writer_value_raw(writer, json->value); |
||||
break; |
||||
case GRPC_JSON_TRUE: |
||||
grpc_json_writer_value_raw_with_len(writer, "true", 4); |
||||
break; |
||||
case GRPC_JSON_FALSE: |
||||
grpc_json_writer_value_raw_with_len(writer, "false", 5); |
||||
break; |
||||
case GRPC_JSON_NULL: |
||||
grpc_json_writer_value_raw_with_len(writer, "null", 4); |
||||
break; |
||||
default: |
||||
GPR_UNREACHABLE_CODE(abort()); |
||||
} |
||||
json = json->next; |
||||
} |
||||
} |
||||
|
||||
static grpc_json_writer_vtable writer_vtable = { |
||||
json_writer_output_char, json_writer_output_string, |
||||
json_writer_output_string_with_len}; |
||||
|
||||
char* grpc_json_dump_to_string(const grpc_json* json, int indent) { |
||||
grpc_json_writer writer; |
||||
json_writer_userdata state; |
||||
|
||||
state.output = nullptr; |
||||
state.free_space = state.string_len = state.allocated = 0; |
||||
grpc_json_writer_init(&writer, indent, &writer_vtable, &state); |
||||
|
||||
json_dump_recursive(&writer, json, 0); |
||||
|
||||
json_writer_output_char(&state, 0); |
||||
|
||||
return state.output; |
||||
} |
@ -1,84 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
/* The idea of the writer is basically symmetrical of the reader. While the
|
||||
* reader emits various calls to your code, the writer takes basically the |
||||
* same calls and emit json out of it. It doesn't try to make any check on |
||||
* the order of the calls you do on it. Meaning you can theorically force |
||||
* it to generate invalid json. |
||||
* |
||||
* Also, unlike the reader, the writer expects UTF-8 encoded input strings. |
||||
* These strings will be UTF-8 validated, and any invalid character will |
||||
* cut the conversion short, before any invalid UTF-8 sequence, thus forming |
||||
* a valid UTF-8 string overall. |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_JSON_JSON_WRITER_H |
||||
#define GRPC_CORE_LIB_JSON_JSON_WRITER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <stdlib.h> |
||||
|
||||
#include "src/core/lib/json/json_common.h" |
||||
|
||||
typedef struct grpc_json_writer_vtable { |
||||
/* Adds a character to the output stream. */ |
||||
void (*output_char)(void* userdata, char); |
||||
/* Adds a zero-terminated string to the output stream. */ |
||||
void (*output_string)(void* userdata, const char* str); |
||||
/* Adds a fixed-length string to the output stream. */ |
||||
void (*output_string_with_len)(void* userdata, const char* str, size_t len); |
||||
|
||||
} grpc_json_writer_vtable; |
||||
|
||||
typedef struct grpc_json_writer { |
||||
void* userdata; |
||||
grpc_json_writer_vtable* vtable; |
||||
int indent; |
||||
int depth; |
||||
int container_empty; |
||||
int got_key; |
||||
} grpc_json_writer; |
||||
|
||||
/* Call this to initialize your writer structure. The indent parameter is
|
||||
* specifying the number of spaces to use for indenting the output. If you |
||||
* use indent=0, then the output will not have any newlines either, thus |
||||
* emitting a condensed json output. |
||||
*/ |
||||
void grpc_json_writer_init(grpc_json_writer* writer, int indent, |
||||
grpc_json_writer_vtable* vtable, void* userdata); |
||||
|
||||
/* Signals the beginning of a container. */ |
||||
void grpc_json_writer_container_begins(grpc_json_writer* writer, |
||||
grpc_json_type type); |
||||
/* Signals the end of a container. */ |
||||
void grpc_json_writer_container_ends(grpc_json_writer* writer, |
||||
grpc_json_type type); |
||||
/* Writes down an object key for the next value. */ |
||||
void grpc_json_writer_object_key(grpc_json_writer* writer, const char* string); |
||||
/* Sets a raw value. Useful for numbers. */ |
||||
void grpc_json_writer_value_raw(grpc_json_writer* writer, const char* string); |
||||
/* Sets a raw value with its length. Useful for values like true or false. */ |
||||
void grpc_json_writer_value_raw_with_len(grpc_json_writer* writer, |
||||
const char* string, size_t len); |
||||
/* Sets a string value. It'll be escaped, and utf-8 validated. */ |
||||
void grpc_json_writer_value_string(grpc_json_writer* writer, |
||||
const char* string); |
||||
|
||||
#endif /* GRPC_CORE_LIB_JSON_JSON_WRITER_H */ |
@ -1,4 +1,5 @@ |
||||
include grpc_version.py |
||||
include grpc_status/google/rpc/status.proto |
||||
recursive-include grpc_status *.py |
||||
global-exclude *.pyc |
||||
include LICENSE |
||||
|
@ -1,241 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/lib/json/json_reader.h" |
||||
#include "src/core/lib/json/json_writer.h" |
||||
#include "test/core/util/cmdline.h" |
||||
|
||||
typedef struct json_writer_userdata { |
||||
FILE* out; |
||||
} json_writer_userdata; |
||||
|
||||
typedef struct stacked_container { |
||||
grpc_json_type type; |
||||
struct stacked_container* next; |
||||
} stacked_container; |
||||
|
||||
typedef struct json_reader_userdata { |
||||
FILE* in; |
||||
grpc_json_writer* writer; |
||||
char* scratchpad; |
||||
char* ptr; |
||||
size_t free_space; |
||||
size_t allocated; |
||||
size_t string_len; |
||||
stacked_container* top; |
||||
} json_reader_userdata; |
||||
|
||||
static void json_writer_output_char(void* userdata, char c) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
fputc(c, state->out); |
||||
} |
||||
|
||||
static void json_writer_output_string(void* userdata, const char* str) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
fputs(str, state->out); |
||||
} |
||||
|
||||
static void json_writer_output_string_with_len(void* userdata, const char* str, |
||||
size_t len) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
fwrite(str, len, 1, state->out); |
||||
} |
||||
|
||||
grpc_json_writer_vtable writer_vtable = {json_writer_output_char, |
||||
json_writer_output_string, |
||||
json_writer_output_string_with_len}; |
||||
|
||||
static void check_string(json_reader_userdata* state, size_t needed) { |
||||
if (state->free_space >= needed) return; |
||||
needed -= state->free_space; |
||||
needed = (needed + 0xffu) & ~0xffu; |
||||
state->scratchpad = static_cast<char*>( |
||||
gpr_realloc(state->scratchpad, state->allocated + needed)); |
||||
state->free_space += needed; |
||||
state->allocated += needed; |
||||
} |
||||
|
||||
static void json_reader_string_clear(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
state->free_space = state->allocated; |
||||
state->string_len = 0; |
||||
} |
||||
|
||||
static void json_reader_string_add_char(void* userdata, uint32_t c) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
check_string(state, 1); |
||||
GPR_ASSERT(c < 256); |
||||
state->scratchpad[state->string_len++] = static_cast<char>(c); |
||||
} |
||||
|
||||
static void json_reader_string_add_utf32(void* userdata, uint32_t c) { |
||||
if (c <= 0x7f) { |
||||
json_reader_string_add_char(userdata, c); |
||||
} else if (c <= 0x7ff) { |
||||
uint32_t b1 = 0xc0u | ((c >> 6u) & 0x1fu); |
||||
uint32_t b2 = 0x80u | (c & 0x3fu); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
} else if (c <= 0xffffu) { |
||||
uint32_t b1 = 0xe0u | ((c >> 12u) & 0x0fu); |
||||
uint32_t b2 = 0x80u | ((c >> 6u) & 0x3fu); |
||||
uint32_t b3 = 0x80u | (c & 0x3fu); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
json_reader_string_add_char(userdata, b3); |
||||
} else if (c <= 0x1fffffu) { |
||||
uint32_t b1 = 0xf0u | ((c >> 18u) & 0x07u); |
||||
uint32_t b2 = 0x80u | ((c >> 12u) & 0x3fu); |
||||
uint32_t b3 = 0x80u | ((c >> 6u) & 0x3fu); |
||||
uint32_t b4 = 0x80u | (c & 0x3fu); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
json_reader_string_add_char(userdata, b3); |
||||
json_reader_string_add_char(userdata, b4); |
||||
} |
||||
} |
||||
|
||||
static uint32_t json_reader_read_char(void* userdata) { |
||||
int r; |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
r = fgetc(state->in); |
||||
if (r == EOF) r = GRPC_JSON_READ_CHAR_EOF; |
||||
return static_cast<uint32_t>(r); |
||||
} |
||||
|
||||
static void json_reader_container_begins(void* userdata, grpc_json_type type) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
stacked_container* container = |
||||
static_cast<stacked_container*>(gpr_malloc(sizeof(stacked_container))); |
||||
|
||||
container->type = type; |
||||
container->next = state->top; |
||||
state->top = container; |
||||
|
||||
grpc_json_writer_container_begins(state->writer, type); |
||||
} |
||||
|
||||
static grpc_json_type json_reader_container_ends(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
stacked_container* container = state->top; |
||||
|
||||
grpc_json_writer_container_ends(state->writer, container->type); |
||||
state->top = container->next; |
||||
gpr_free(container); |
||||
return state->top ? state->top->type : GRPC_JSON_TOP_LEVEL; |
||||
} |
||||
|
||||
static void json_reader_set_key(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
json_reader_string_add_char(userdata, 0); |
||||
|
||||
grpc_json_writer_object_key(state->writer, state->scratchpad); |
||||
} |
||||
|
||||
static void json_reader_set_string(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
json_reader_string_add_char(userdata, 0); |
||||
|
||||
grpc_json_writer_value_string(state->writer, state->scratchpad); |
||||
} |
||||
|
||||
static int json_reader_set_number(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, state->scratchpad, |
||||
state->string_len); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
static void json_reader_set_true(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, "true", 4); |
||||
} |
||||
|
||||
static void json_reader_set_false(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, "false", 5); |
||||
} |
||||
|
||||
static void json_reader_set_null(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, "null", 4); |
||||
} |
||||
|
||||
static grpc_json_reader_vtable reader_vtable = { |
||||
json_reader_string_clear, json_reader_string_add_char, |
||||
json_reader_string_add_utf32, json_reader_read_char, |
||||
json_reader_container_begins, json_reader_container_ends, |
||||
json_reader_set_key, json_reader_set_string, |
||||
json_reader_set_number, json_reader_set_true, |
||||
json_reader_set_false, json_reader_set_null}; |
||||
|
||||
int rewrite(FILE* in, FILE* out, int indent) { |
||||
grpc_json_writer writer; |
||||
grpc_json_reader reader; |
||||
grpc_json_reader_status status; |
||||
json_writer_userdata writer_user; |
||||
json_reader_userdata reader_user; |
||||
|
||||
reader_user.writer = &writer; |
||||
reader_user.in = in; |
||||
reader_user.top = nullptr; |
||||
reader_user.scratchpad = nullptr; |
||||
reader_user.string_len = 0; |
||||
reader_user.free_space = 0; |
||||
reader_user.allocated = 0; |
||||
|
||||
writer_user.out = out; |
||||
|
||||
grpc_json_writer_init(&writer, indent, &writer_vtable, &writer_user); |
||||
grpc_json_reader_init(&reader, &reader_vtable, &reader_user); |
||||
|
||||
status = grpc_json_reader_run(&reader); |
||||
|
||||
free(reader_user.scratchpad); |
||||
while (reader_user.top) { |
||||
stacked_container* container = reader_user.top; |
||||
reader_user.top = container->next; |
||||
free(container); |
||||
} |
||||
|
||||
return status == GRPC_JSON_DONE; |
||||
} |
||||
|
||||
int main(int argc, char** argv) { |
||||
int indent = 2; |
||||
gpr_cmdline* cl; |
||||
|
||||
cl = gpr_cmdline_create(nullptr); |
||||
gpr_cmdline_add_int(cl, "indent", nullptr, &indent); |
||||
gpr_cmdline_parse(cl, argc, argv); |
||||
gpr_cmdline_destroy(cl); |
||||
|
||||
return rewrite(stdin, stdout, indent) ? 0 : 1; |
||||
} |
@ -1,294 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
#include "src/core/lib/gpr/useful.h" |
||||
#include "src/core/lib/json/json_reader.h" |
||||
#include "src/core/lib/json/json_writer.h" |
||||
|
||||
typedef struct json_writer_userdata { |
||||
FILE* cmp; |
||||
} json_writer_userdata; |
||||
|
||||
typedef struct stacked_container { |
||||
grpc_json_type type; |
||||
struct stacked_container* next; |
||||
} stacked_container; |
||||
|
||||
typedef struct json_reader_userdata { |
||||
FILE* in; |
||||
grpc_json_writer* writer; |
||||
char* scratchpad; |
||||
char* ptr; |
||||
size_t free_space; |
||||
size_t allocated; |
||||
size_t string_len; |
||||
stacked_container* top; |
||||
int did_eagain; |
||||
} json_reader_userdata; |
||||
|
||||
static void json_writer_output_char(void* userdata, char c) { |
||||
json_writer_userdata* state = static_cast<json_writer_userdata*>(userdata); |
||||
int cmp = fgetc(state->cmp); |
||||
|
||||
/* treat CRLF as LF */ |
||||
if (cmp == '\r' && c == '\n') { |
||||
cmp = fgetc(state->cmp); |
||||
} |
||||
GPR_ASSERT(cmp == c); |
||||
} |
||||
|
||||
static void json_writer_output_string(void* userdata, const char* str) { |
||||
while (*str) { |
||||
json_writer_output_char(userdata, *str++); |
||||
} |
||||
} |
||||
|
||||
static void json_writer_output_string_with_len(void* userdata, const char* str, |
||||
size_t len) { |
||||
size_t i; |
||||
for (i = 0; i < len; i++) { |
||||
json_writer_output_char(userdata, str[i]); |
||||
} |
||||
} |
||||
|
||||
grpc_json_writer_vtable writer_vtable = {json_writer_output_char, |
||||
json_writer_output_string, |
||||
json_writer_output_string_with_len}; |
||||
|
||||
static void check_string(json_reader_userdata* state, size_t needed) { |
||||
if (state->free_space >= needed) return; |
||||
needed -= state->free_space; |
||||
needed = (needed + 0xffu) & ~0xffu; |
||||
state->scratchpad = static_cast<char*>( |
||||
gpr_realloc(state->scratchpad, state->allocated + needed)); |
||||
state->free_space += needed; |
||||
state->allocated += needed; |
||||
} |
||||
|
||||
static void json_reader_string_clear(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
state->free_space = state->allocated; |
||||
state->string_len = 0; |
||||
} |
||||
|
||||
static void json_reader_string_add_char(void* userdata, uint32_t c) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
check_string(state, 1); |
||||
GPR_ASSERT(c <= 256); |
||||
state->scratchpad[state->string_len++] = static_cast<char>(c); |
||||
} |
||||
|
||||
static void json_reader_string_add_utf32(void* userdata, uint32_t c) { |
||||
if (c <= 0x7f) { |
||||
json_reader_string_add_char(userdata, c); |
||||
} else if (c <= 0x7ffu) { |
||||
uint32_t b1 = 0xc0u | ((c >> 6u) & 0x1fu); |
||||
uint32_t b2 = 0x80u | (c & 0x3fu); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
} else if (c <= 0xffffu) { |
||||
uint32_t b1 = 0xe0u | ((c >> 12u) & 0x0fu); |
||||
uint32_t b2 = 0x80u | ((c >> 6u) & 0x3fu); |
||||
uint32_t b3 = 0x80u | (c & 0x3fu); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
json_reader_string_add_char(userdata, b3); |
||||
} else if (c <= 0x1fffffu) { |
||||
uint32_t b1 = 0xf0u | ((c >> 18u) & 0x07u); |
||||
uint32_t b2 = 0x80u | ((c >> 12u) & 0x3fu); |
||||
uint32_t b3 = 0x80u | ((c >> 6u) & 0x3fu); |
||||
uint32_t b4 = 0x80u | (c & 0x3fu); |
||||
json_reader_string_add_char(userdata, b1); |
||||
json_reader_string_add_char(userdata, b2); |
||||
json_reader_string_add_char(userdata, b3); |
||||
json_reader_string_add_char(userdata, b4); |
||||
} |
||||
} |
||||
|
||||
static uint32_t json_reader_read_char(void* userdata) { |
||||
int r; |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
if (!state->did_eagain) { |
||||
state->did_eagain = 1; |
||||
return GRPC_JSON_READ_CHAR_EAGAIN; |
||||
} |
||||
|
||||
state->did_eagain = 0; |
||||
|
||||
r = fgetc(state->in); |
||||
if (r == EOF) r = GRPC_JSON_READ_CHAR_EOF; |
||||
return static_cast<uint32_t>(r); |
||||
} |
||||
|
||||
static void json_reader_container_begins(void* userdata, grpc_json_type type) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
stacked_container* container = |
||||
static_cast<stacked_container*>(gpr_malloc(sizeof(stacked_container))); |
||||
|
||||
container->type = type; |
||||
container->next = state->top; |
||||
state->top = container; |
||||
|
||||
grpc_json_writer_container_begins(state->writer, type); |
||||
} |
||||
|
||||
static grpc_json_type json_reader_container_ends(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
stacked_container* container = state->top; |
||||
|
||||
grpc_json_writer_container_ends(state->writer, container->type); |
||||
state->top = container->next; |
||||
gpr_free(container); |
||||
return state->top ? state->top->type : GRPC_JSON_TOP_LEVEL; |
||||
} |
||||
|
||||
static void json_reader_set_key(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
json_reader_string_add_char(userdata, 0); |
||||
|
||||
grpc_json_writer_object_key(state->writer, state->scratchpad); |
||||
} |
||||
|
||||
static void json_reader_set_string(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
json_reader_string_add_char(userdata, 0); |
||||
|
||||
grpc_json_writer_value_string(state->writer, state->scratchpad); |
||||
} |
||||
|
||||
static int json_reader_set_number(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, state->scratchpad, |
||||
state->string_len); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
static void json_reader_set_true(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, "true", 4); |
||||
} |
||||
|
||||
static void json_reader_set_false(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, "false", 5); |
||||
} |
||||
|
||||
static void json_reader_set_null(void* userdata) { |
||||
json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); |
||||
|
||||
grpc_json_writer_value_raw_with_len(state->writer, "null", 4); |
||||
} |
||||
|
||||
static grpc_json_reader_vtable reader_vtable = { |
||||
json_reader_string_clear, json_reader_string_add_char, |
||||
json_reader_string_add_utf32, json_reader_read_char, |
||||
json_reader_container_begins, json_reader_container_ends, |
||||
json_reader_set_key, json_reader_set_string, |
||||
json_reader_set_number, json_reader_set_true, |
||||
json_reader_set_false, json_reader_set_null}; |
||||
|
||||
int rewrite_and_compare(FILE* in, FILE* cmp, int indent) { |
||||
grpc_json_writer writer; |
||||
grpc_json_reader reader; |
||||
grpc_json_reader_status status; |
||||
json_writer_userdata writer_user; |
||||
json_reader_userdata reader_user; |
||||
|
||||
GPR_ASSERT(in); |
||||
GPR_ASSERT(cmp); |
||||
|
||||
reader_user.writer = &writer; |
||||
reader_user.in = in; |
||||
reader_user.top = nullptr; |
||||
reader_user.scratchpad = nullptr; |
||||
reader_user.string_len = 0; |
||||
reader_user.free_space = 0; |
||||
reader_user.allocated = 0; |
||||
reader_user.did_eagain = 0; |
||||
|
||||
writer_user.cmp = cmp; |
||||
|
||||
grpc_json_writer_init(&writer, indent, &writer_vtable, &writer_user); |
||||
grpc_json_reader_init(&reader, &reader_vtable, &reader_user); |
||||
|
||||
do { |
||||
status = grpc_json_reader_run(&reader); |
||||
} while (status == GRPC_JSON_EAGAIN); |
||||
|
||||
free(reader_user.scratchpad); |
||||
while (reader_user.top) { |
||||
stacked_container* container = reader_user.top; |
||||
reader_user.top = container->next; |
||||
free(container); |
||||
} |
||||
|
||||
return status == GRPC_JSON_DONE; |
||||
} |
||||
|
||||
typedef struct test_file { |
||||
const char* input; |
||||
const char* cmp; |
||||
int indent; |
||||
} test_file; |
||||
|
||||
static test_file test_files[] = { |
||||
{"test/core/json/rewrite_test_input.json", |
||||
"test/core/json/rewrite_test_output_condensed.json", 0}, |
||||
{"test/core/json/rewrite_test_input.json", |
||||
"test/core/json/rewrite_test_output_indented.json", 2}, |
||||
{"test/core/json/rewrite_test_output_indented.json", |
||||
"test/core/json/rewrite_test_output_condensed.json", 0}, |
||||
{"test/core/json/rewrite_test_output_condensed.json", |
||||
"test/core/json/rewrite_test_output_indented.json", 2}, |
||||
}; |
||||
|
||||
void test_rewrites() { |
||||
unsigned i; |
||||
|
||||
for (i = 0; i < GPR_ARRAY_SIZE(test_files); i++) { |
||||
test_file* test = test_files + i; |
||||
FILE* input = fopen(test->input, "rb"); |
||||
FILE* cmp = fopen(test->cmp, "rb"); |
||||
int status; |
||||
gpr_log(GPR_INFO, "Testing file %s against %s using indent=%i", test->input, |
||||
test->cmp, test->indent); |
||||
status = rewrite_and_compare(input, cmp, test->indent); |
||||
GPR_ASSERT(status); |
||||
fclose(input); |
||||
fclose(cmp); |
||||
} |
||||
} |
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc::testing::TestEnvironment env(argc, argv); |
||||
test_rewrites(); |
||||
gpr_log(GPR_INFO, "json_rewrite_test success"); |
||||
return 0; |
||||
} |
@ -1,58 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
#include "src/core/lib/json/json_reader.h" |
||||
#include "src/core/lib/json/json_writer.h" |
||||
|
||||
static int g_string_clear_once = 0; |
||||
|
||||
static void string_clear(void* /*userdata*/) { |
||||
GPR_ASSERT(!g_string_clear_once); |
||||
g_string_clear_once = 1; |
||||
} |
||||
|
||||
static uint32_t read_char(void* /*userdata*/) { |
||||
return GRPC_JSON_READ_CHAR_ERROR; |
||||
} |
||||
|
||||
static grpc_json_reader_vtable reader_vtable = { |
||||
string_clear, nullptr, nullptr, read_char, nullptr, nullptr, |
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; |
||||
|
||||
static void read_error() { |
||||
grpc_json_reader reader; |
||||
grpc_json_reader_status status; |
||||
grpc_json_reader_init(&reader, &reader_vtable, nullptr); |
||||
|
||||
status = grpc_json_reader_run(&reader); |
||||
GPR_ASSERT(status == GRPC_JSON_READ_ERROR); |
||||
} |
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc::testing::TestEnvironment env(argc, argv); |
||||
read_error(); |
||||
gpr_log(GPR_INFO, "json_stream_error success"); |
||||
return 0; |
||||
} |
@ -1,203 +0,0 @@ |
||||
{ |
||||
"unicode, escape and empty test": { "a\tb": "\u00eb", "empty": [{},[],{}] }, |
||||
"some more unicode tests": { |
||||
"typical utf-8 input (plane 0)": "ßâñć⇒", |
||||
"atypical utf-8 input (plane 1)": "𝄞" |
||||
}, |
||||
|
||||
"whitespace test": { "trying" : |
||||
"to" |
||||
, |
||||
|
||||
"break" |
||||
: |
||||
"the" , |
||||
"parser": "a bit" } , |
||||
|
||||
"#": "All these examples are from http://json.org/example", |
||||
"test1": |
||||
{ |
||||
"glossary": { |
||||
"title": "example glossary", |
||||
"GlossDiv": { |
||||
"title": "S", |
||||
"GlossList": { |
||||
"GlossEntry": { |
||||
"ID": "SGML", |
||||
"SortAs": "SGML", |
||||
"GlossTerm": "Standard Generalized Markup Language", |
||||
"Acronym": "SGML", |
||||
"Abbrev": "ISO 8879:1986", |
||||
"GlossDef": { |
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.", |
||||
"GlossSeeAlso": ["GML", "XML"] |
||||
}, |
||||
"GlossSee": "markup" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
|
||||
"test2": |
||||
{"menu": { |
||||
"id": "file", |
||||
"value": "File", |
||||
"popup": { |
||||
"menuitem": [ |
||||
{"value": "New", "onclick": "CreateNewDoc()"}, |
||||
{"value": "Open", "onclick": "OpenDoc()"}, |
||||
{"value": "Close", "onclick": "CloseDoc()"} |
||||
] |
||||
} |
||||
}}, |
||||
|
||||
"test3": |
||||
{"widget": { |
||||
"debug": "on", |
||||
"window": { |
||||
"title": "Sample Konfabulator Widget", |
||||
"name": "main_window", |
||||
"width": 500, |
||||
"height": 500 |
||||
}, |
||||
"image": { |
||||
"src": "Images/Sun.png", |
||||
"name": "sun1", |
||||
"hOffset": 250, |
||||
"vOffset": 250, |
||||
"alignment": "center" |
||||
}, |
||||
"text": { |
||||
"data": "Click Here", |
||||
"size": 36, |
||||
"style": "bold", |
||||
"name": "text1", |
||||
"hOffset": 250, |
||||
"vOffset": 100, |
||||
"alignment": "center", |
||||
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" |
||||
} |
||||
}}, |
||||
|
||||
"test4": |
||||
{"web-app": { |
||||
"servlet": [ |
||||
{ |
||||
"servlet-name": "cofaxCDS", |
||||
"servlet-class": "org.cofax.cds.CDSServlet", |
||||
"init-param": { |
||||
"configGlossary:installationAt": "Philadelphia, PA", |
||||
"configGlossary:adminEmail": "ksm@pobox.com", |
||||
"configGlossary:poweredBy": "Cofax", |
||||
"configGlossary:poweredByIcon": "/images/cofax.gif", |
||||
"configGlossary:staticPath": "/content/static", |
||||
"templateProcessorClass": "org.cofax.WysiwygTemplate", |
||||
"templateLoaderClass": "org.cofax.FilesTemplateLoader", |
||||
"templatePath": "templates", |
||||
"templateOverridePath": "", |
||||
"defaultListTemplate": "listTemplate.htm", |
||||
"defaultFileTemplate": "articleTemplate.htm", |
||||
"useJSP": false, |
||||
"jspListTemplate": "listTemplate.jsp", |
||||
"jspFileTemplate": "articleTemplate.jsp", |
||||
"cachePackageTagsTrack": 200, |
||||
"cachePackageTagsStore": 200, |
||||
"cachePackageTagsRefresh": 60, |
||||
"cacheTemplatesTrack": 100, |
||||
"cacheTemplatesStore": 50, |
||||
"cacheTemplatesRefresh": 15, |
||||
"cachePagesTrack": 200, |
||||
"cachePagesStore": 100, |
||||
"cachePagesRefresh": 10, |
||||
"cachePagesDirtyRead": 10, |
||||
"searchEngineListTemplate": "forSearchEnginesList.htm", |
||||
"searchEngineFileTemplate": "forSearchEngines.htm", |
||||
"searchEngineRobotsDb": "WEB-INF/robots.db", |
||||
"useDataStore": true, |
||||
"dataStoreClass": "org.cofax.SqlDataStore", |
||||
"redirectionClass": "org.cofax.SqlRedirection", |
||||
"dataStoreName": "cofax", |
||||
"dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", |
||||
"dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", |
||||
"dataStoreUser": "sa", |
||||
"dataStorePassword": "dataStoreTestQuery", |
||||
"dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", |
||||
"dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", |
||||
"dataStoreInitConns": 10, |
||||
"dataStoreMaxConns": 100, |
||||
"dataStoreConnUsageLimit": 100, |
||||
"dataStoreLogLevel": "debug", |
||||
"maxUrlLength": 500}}, |
||||
{ |
||||
"servlet-name": "cofaxEmail", |
||||
"servlet-class": "org.cofax.cds.EmailServlet", |
||||
"init-param": { |
||||
"mailHost": "mail1", |
||||
"mailHostOverride": "mail2"}}, |
||||
{ |
||||
"servlet-name": "cofaxAdmin", |
||||
"servlet-class": "org.cofax.cds.AdminServlet"}, |
||||
|
||||
{ |
||||
"servlet-name": "fileServlet", |
||||
"servlet-class": "org.cofax.cds.FileServlet"}, |
||||
{ |
||||
"servlet-name": "cofaxTools", |
||||
"servlet-class": "org.cofax.cms.CofaxToolsServlet", |
||||
"init-param": { |
||||
"templatePath": "toolstemplates/", |
||||
"log": 1, |
||||
"logLocation": "/usr/local/tomcat/logs/CofaxTools.log", |
||||
"logMaxSize": "", |
||||
"dataLog": 1, |
||||
"dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", |
||||
"dataLogMaxSize": "", |
||||
"removePageCache": "/content/admin/remove?cache=pages&id=", |
||||
"removeTemplateCache": "/content/admin/remove?cache=templates&id=", |
||||
"fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", |
||||
"lookInContext": 1, |
||||
"adminGroupID": 4, |
||||
"betaServer": true}}], |
||||
"servlet-mapping": { |
||||
"cofaxCDS": "/", |
||||
"cofaxEmail": "/cofaxutil/aemail/*", |
||||
"cofaxAdmin": "/admin/*", |
||||
"fileServlet": "/static/*", |
||||
"cofaxTools": "/tools/*"}, |
||||
|
||||
"taglib": { |
||||
"taglib-uri": "cofax.tld", |
||||
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}, |
||||
|
||||
"test5": |
||||
{"menu": { |
||||
"header": "SVG Viewer", |
||||
"items": [ |
||||
{"id": "Open"}, |
||||
{"id": "OpenNew", "label": "Open New"}, |
||||
null, |
||||
{"id": "ZoomIn", "label": "Zoom In"}, |
||||
{"id": "ZoomOut", "label": "Zoom Out"}, |
||||
{"id": "OriginalView", "label": "Original View"}, |
||||
null, |
||||
{"id": "Quality"}, |
||||
{"id": "Pause"}, |
||||
{"id": "Mute"}, |
||||
null, |
||||
{"id": "Find", "label": "Find..."}, |
||||
{"id": "FindAgain", "label": "Find Again"}, |
||||
{"id": "Copy"}, |
||||
{"id": "CopyAgain", "label": "Copy Again"}, |
||||
{"id": "CopySVG", "label": "Copy SVG"}, |
||||
{"id": "ViewSVG", "label": "View SVG"}, |
||||
{"id": "ViewSource", "label": "View Source"}, |
||||
{"id": "SaveAs", "label": "Save As"}, |
||||
null, |
||||
{"id": "Help"}, |
||||
{"id": "About", "label": "About Adobe CVG Viewer..."} |
||||
] |
||||
}} |
||||
|
||||
|
||||
} |
@ -1 +0,0 @@ |
||||
{"unicode, escape and empty test":{"a\tb":"\u00eb","empty":[{},[],{}]},"some more unicode tests":{"typical utf-8 input (plane 0)":"\u00df\u00e2\u00f1\u0107\u21d2","atypical utf-8 input (plane 1)":"\ud834\udd1e"},"whitespace test":{"trying":"to","break":"the","parser":"a bit"},"#":"All these examples are from http://json.org/example","test1":{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}},"test2":{"menu":{"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]}}},"test3":{"widget":{"debug":"on","window":{"title":"Sample Konfabulator Widget","name":"main_window","width":500,"height":500},"image":{"src":"Images/Sun.png","name":"sun1","hOffset":250,"vOffset":250,"alignment":"center"},"text":{"data":"Click Here","size":36,"style":"bold","name":"text1","hOffset":250,"vOffset":100,"alignment":"center","onMouseUp":"sun1.opacity = (sun1.opacity / 100) * 90;"}}},"test4":{"web-app":{"servlet":[{"servlet-name":"cofaxCDS","servlet-class":"org.cofax.cds.CDSServlet","init-param":{"configGlossary:installationAt":"Philadelphia, PA","configGlossary:adminEmail":"ksm@pobox.com","configGlossary:poweredBy":"Cofax","configGlossary:poweredByIcon":"/images/cofax.gif","configGlossary:staticPath":"/content/static","templateProcessorClass":"org.cofax.WysiwygTemplate","templateLoaderClass":"org.cofax.FilesTemplateLoader","templatePath":"templates","templateOverridePath":"","defaultListTemplate":"listTemplate.htm","defaultFileTemplate":"articleTemplate.htm","useJSP":false,"jspListTemplate":"listTemplate.jsp","jspFileTemplate":"articleTemplate.jsp","cachePackageTagsTrack":200,"cachePackageTagsStore":200,"cachePackageTagsRefresh":60,"cacheTemplatesTrack":100,"cacheTemplatesStore":50,"cacheTemplatesRefresh":15,"cachePagesTrack":200,"cachePagesStore":100,"cachePagesRefresh":10,"cachePagesDirtyRead":10,"searchEngineListTemplate":"forSearchEnginesList.htm","searchEngineFileTemplate":"forSearchEngines.htm","searchEngineRobotsDb":"WEB-INF/robots.db","useDataStore":true,"dataStoreClass":"org.cofax.SqlDataStore","redirectionClass":"org.cofax.SqlRedirection","dataStoreName":"cofax","dataStoreDriver":"com.microsoft.jdbc.sqlserver.SQLServerDriver","dataStoreUrl":"jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon","dataStoreUser":"sa","dataStorePassword":"dataStoreTestQuery","dataStoreTestQuery":"SET NOCOUNT ON;select test='test';","dataStoreLogFile":"/usr/local/tomcat/logs/datastore.log","dataStoreInitConns":10,"dataStoreMaxConns":100,"dataStoreConnUsageLimit":100,"dataStoreLogLevel":"debug","maxUrlLength":500}},{"servlet-name":"cofaxEmail","servlet-class":"org.cofax.cds.EmailServlet","init-param":{"mailHost":"mail1","mailHostOverride":"mail2"}},{"servlet-name":"cofaxAdmin","servlet-class":"org.cofax.cds.AdminServlet"},{"servlet-name":"fileServlet","servlet-class":"org.cofax.cds.FileServlet"},{"servlet-name":"cofaxTools","servlet-class":"org.cofax.cms.CofaxToolsServlet","init-param":{"templatePath":"toolstemplates/","log":1,"logLocation":"/usr/local/tomcat/logs/CofaxTools.log","logMaxSize":"","dataLog":1,"dataLogLocation":"/usr/local/tomcat/logs/dataLog.log","dataLogMaxSize":"","removePageCache":"/content/admin/remove?cache=pages&id=","removeTemplateCache":"/content/admin/remove?cache=templates&id=","fileTransferFolder":"/usr/local/tomcat/webapps/content/fileTransferFolder","lookInContext":1,"adminGroupID":4,"betaServer":true}}],"servlet-mapping":{"cofaxCDS":"/","cofaxEmail":"/cofaxutil/aemail/*","cofaxAdmin":"/admin/*","fileServlet":"/static/*","cofaxTools":"/tools/*"},"taglib":{"taglib-uri":"cofax.tld","taglib-location":"/WEB-INF/tlds/cofax.tld"}}},"test5":{"menu":{"header":"SVG Viewer","items":[{"id":"Open"},{"id":"OpenNew","label":"Open New"},null,{"id":"ZoomIn","label":"Zoom In"},{"id":"ZoomOut","label":"Zoom Out"},{"id":"OriginalView","label":"Original View"},null,{"id":"Quality"},{"id":"Pause"},{"id":"Mute"},null,{"id":"Find","label":"Find..."},{"id":"FindAgain","label":"Find Again"},{"id":"Copy"},{"id":"CopyAgain","label":"Copy Again"},{"id":"CopySVG","label":"Copy SVG"},{"id":"ViewSVG","label":"View SVG"},{"id":"ViewSource","label":"View Source"},{"id":"SaveAs","label":"Save As"},null,{"id":"Help"},{"id":"About","label":"About Adobe CVG Viewer..."}]}}} |
@ -1,272 +0,0 @@ |
||||
{ |
||||
"unicode, escape and empty test": { |
||||
"a\tb": "\u00eb", |
||||
"empty": [ |
||||
{}, |
||||
[], |
||||
{} |
||||
] |
||||
}, |
||||
"some more unicode tests": { |
||||
"typical utf-8 input (plane 0)": "\u00df\u00e2\u00f1\u0107\u21d2", |
||||
"atypical utf-8 input (plane 1)": "\ud834\udd1e" |
||||
}, |
||||
"whitespace test": { |
||||
"trying": "to", |
||||
"break": "the", |
||||
"parser": "a bit" |
||||
}, |
||||
"#": "All these examples are from http://json.org/example", |
||||
"test1": { |
||||
"glossary": { |
||||
"title": "example glossary", |
||||
"GlossDiv": { |
||||
"title": "S", |
||||
"GlossList": { |
||||
"GlossEntry": { |
||||
"ID": "SGML", |
||||
"SortAs": "SGML", |
||||
"GlossTerm": "Standard Generalized Markup Language", |
||||
"Acronym": "SGML", |
||||
"Abbrev": "ISO 8879:1986", |
||||
"GlossDef": { |
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.", |
||||
"GlossSeeAlso": [ |
||||
"GML", |
||||
"XML" |
||||
] |
||||
}, |
||||
"GlossSee": "markup" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"test2": { |
||||
"menu": { |
||||
"id": "file", |
||||
"value": "File", |
||||
"popup": { |
||||
"menuitem": [ |
||||
{ |
||||
"value": "New", |
||||
"onclick": "CreateNewDoc()" |
||||
}, |
||||
{ |
||||
"value": "Open", |
||||
"onclick": "OpenDoc()" |
||||
}, |
||||
{ |
||||
"value": "Close", |
||||
"onclick": "CloseDoc()" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
}, |
||||
"test3": { |
||||
"widget": { |
||||
"debug": "on", |
||||
"window": { |
||||
"title": "Sample Konfabulator Widget", |
||||
"name": "main_window", |
||||
"width": 500, |
||||
"height": 500 |
||||
}, |
||||
"image": { |
||||
"src": "Images/Sun.png", |
||||
"name": "sun1", |
||||
"hOffset": 250, |
||||
"vOffset": 250, |
||||
"alignment": "center" |
||||
}, |
||||
"text": { |
||||
"data": "Click Here", |
||||
"size": 36, |
||||
"style": "bold", |
||||
"name": "text1", |
||||
"hOffset": 250, |
||||
"vOffset": 100, |
||||
"alignment": "center", |
||||
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" |
||||
} |
||||
} |
||||
}, |
||||
"test4": { |
||||
"web-app": { |
||||
"servlet": [ |
||||
{ |
||||
"servlet-name": "cofaxCDS", |
||||
"servlet-class": "org.cofax.cds.CDSServlet", |
||||
"init-param": { |
||||
"configGlossary:installationAt": "Philadelphia, PA", |
||||
"configGlossary:adminEmail": "ksm@pobox.com", |
||||
"configGlossary:poweredBy": "Cofax", |
||||
"configGlossary:poweredByIcon": "/images/cofax.gif", |
||||
"configGlossary:staticPath": "/content/static", |
||||
"templateProcessorClass": "org.cofax.WysiwygTemplate", |
||||
"templateLoaderClass": "org.cofax.FilesTemplateLoader", |
||||
"templatePath": "templates", |
||||
"templateOverridePath": "", |
||||
"defaultListTemplate": "listTemplate.htm", |
||||
"defaultFileTemplate": "articleTemplate.htm", |
||||
"useJSP": false, |
||||
"jspListTemplate": "listTemplate.jsp", |
||||
"jspFileTemplate": "articleTemplate.jsp", |
||||
"cachePackageTagsTrack": 200, |
||||
"cachePackageTagsStore": 200, |
||||
"cachePackageTagsRefresh": 60, |
||||
"cacheTemplatesTrack": 100, |
||||
"cacheTemplatesStore": 50, |
||||
"cacheTemplatesRefresh": 15, |
||||
"cachePagesTrack": 200, |
||||
"cachePagesStore": 100, |
||||
"cachePagesRefresh": 10, |
||||
"cachePagesDirtyRead": 10, |
||||
"searchEngineListTemplate": "forSearchEnginesList.htm", |
||||
"searchEngineFileTemplate": "forSearchEngines.htm", |
||||
"searchEngineRobotsDb": "WEB-INF/robots.db", |
||||
"useDataStore": true, |
||||
"dataStoreClass": "org.cofax.SqlDataStore", |
||||
"redirectionClass": "org.cofax.SqlRedirection", |
||||
"dataStoreName": "cofax", |
||||
"dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", |
||||
"dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", |
||||
"dataStoreUser": "sa", |
||||
"dataStorePassword": "dataStoreTestQuery", |
||||
"dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", |
||||
"dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", |
||||
"dataStoreInitConns": 10, |
||||
"dataStoreMaxConns": 100, |
||||
"dataStoreConnUsageLimit": 100, |
||||
"dataStoreLogLevel": "debug", |
||||
"maxUrlLength": 500 |
||||
} |
||||
}, |
||||
{ |
||||
"servlet-name": "cofaxEmail", |
||||
"servlet-class": "org.cofax.cds.EmailServlet", |
||||
"init-param": { |
||||
"mailHost": "mail1", |
||||
"mailHostOverride": "mail2" |
||||
} |
||||
}, |
||||
{ |
||||
"servlet-name": "cofaxAdmin", |
||||
"servlet-class": "org.cofax.cds.AdminServlet" |
||||
}, |
||||
{ |
||||
"servlet-name": "fileServlet", |
||||
"servlet-class": "org.cofax.cds.FileServlet" |
||||
}, |
||||
{ |
||||
"servlet-name": "cofaxTools", |
||||
"servlet-class": "org.cofax.cms.CofaxToolsServlet", |
||||
"init-param": { |
||||
"templatePath": "toolstemplates/", |
||||
"log": 1, |
||||
"logLocation": "/usr/local/tomcat/logs/CofaxTools.log", |
||||
"logMaxSize": "", |
||||
"dataLog": 1, |
||||
"dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", |
||||
"dataLogMaxSize": "", |
||||
"removePageCache": "/content/admin/remove?cache=pages&id=", |
||||
"removeTemplateCache": "/content/admin/remove?cache=templates&id=", |
||||
"fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", |
||||
"lookInContext": 1, |
||||
"adminGroupID": 4, |
||||
"betaServer": true |
||||
} |
||||
} |
||||
], |
||||
"servlet-mapping": { |
||||
"cofaxCDS": "/", |
||||
"cofaxEmail": "/cofaxutil/aemail/*", |
||||
"cofaxAdmin": "/admin/*", |
||||
"fileServlet": "/static/*", |
||||
"cofaxTools": "/tools/*" |
||||
}, |
||||
"taglib": { |
||||
"taglib-uri": "cofax.tld", |
||||
"taglib-location": "/WEB-INF/tlds/cofax.tld" |
||||
} |
||||
} |
||||
}, |
||||
"test5": { |
||||
"menu": { |
||||
"header": "SVG Viewer", |
||||
"items": [ |
||||
{ |
||||
"id": "Open" |
||||
}, |
||||
{ |
||||
"id": "OpenNew", |
||||
"label": "Open New" |
||||
}, |
||||
null, |
||||
{ |
||||
"id": "ZoomIn", |
||||
"label": "Zoom In" |
||||
}, |
||||
{ |
||||
"id": "ZoomOut", |
||||
"label": "Zoom Out" |
||||
}, |
||||
{ |
||||
"id": "OriginalView", |
||||
"label": "Original View" |
||||
}, |
||||
null, |
||||
{ |
||||
"id": "Quality" |
||||
}, |
||||
{ |
||||
"id": "Pause" |
||||
}, |
||||
{ |
||||
"id": "Mute" |
||||
}, |
||||
null, |
||||
{ |
||||
"id": "Find", |
||||
"label": "Find..." |
||||
}, |
||||
{ |
||||
"id": "FindAgain", |
||||
"label": "Find Again" |
||||
}, |
||||
{ |
||||
"id": "Copy" |
||||
}, |
||||
{ |
||||
"id": "CopyAgain", |
||||
"label": "Copy Again" |
||||
}, |
||||
{ |
||||
"id": "CopySVG", |
||||
"label": "Copy SVG" |
||||
}, |
||||
{ |
||||
"id": "ViewSVG", |
||||
"label": "View SVG" |
||||
}, |
||||
{ |
||||
"id": "ViewSource", |
||||
"label": "View Source" |
||||
}, |
||||
{ |
||||
"id": "SaveAs", |
||||
"label": "Save As" |
||||
}, |
||||
null, |
||||
{ |
||||
"id": "Help" |
||||
}, |
||||
{ |
||||
"id": "About", |
||||
"label": "About Adobe CVG Viewer..." |
||||
} |
||||
] |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue