Пример #1
0
void
handle_acl_log(const struct flow *headers, struct ofpbuf *userdata)
{
    if (!VLOG_IS_INFO_ENABLED()) {
        return;
    }

    struct log_pin_header *lph = ofpbuf_try_pull(userdata, sizeof *lph);
    if (!lph) {
        VLOG_WARN("log data missing");
        return;
    }

    size_t name_len = userdata->size;
    char *name = name_len ? xmemdup0(userdata->data, name_len) : NULL;

    struct ds ds = DS_EMPTY_INITIALIZER;
    ds_put_cstr(&ds, "name=");
    json_string_escape(name_len ? name : "<unnamed>", &ds);
    ds_put_format(&ds, ", verdict=%s, severity=%s: ",
                  log_verdict_to_string(lph->verdict),
                  log_severity_to_string(lph->severity));
    flow_format(&ds, headers, NULL);

    VLOG_INFO("%s", ds_cstr(&ds));
    ds_destroy(&ds);
    free(name);
}
Пример #2
0
static char*
string_value_from_array(DBusMessageIter *array_iter,
                        int              value_type)
{
    GString *json_array;

    /* We store arrays as JSON lists */
    
    json_array = g_string_new("[");

    while (dbus_message_iter_get_arg_type(array_iter) != DBUS_TYPE_INVALID) {
        switch (value_type) {
        case DBUS_TYPE_STRING:
            {
                const char *v_STRING;                        
                char *s;
                dbus_message_iter_get_basic(array_iter, &v_STRING);
                s = json_string_escape(v_STRING);
                g_string_append(json_array, s);
                g_free(s);
            }
            break;
        case DBUS_TYPE_INT32:
            {
                dbus_int32_t v_INT32;
                dbus_message_iter_get_basic(array_iter, &v_INT32);
                g_string_append_printf(json_array, "%d", v_INT32);
            }
            break;
        case DBUS_TYPE_BOOLEAN:
            {
                dbus_bool_t v_BOOLEAN;
                dbus_message_iter_get_basic(array_iter, &v_BOOLEAN);
                g_string_append(json_array, v_BOOLEAN ? "true" : "false");
            }
            break;
        case DBUS_TYPE_DOUBLE:
            {
                double v_DOUBLE;
                char buf[G_ASCII_DTOSTR_BUF_SIZE];
                dbus_message_iter_get_basic(array_iter, &v_DOUBLE);
                g_ascii_dtostr(buf, G_ASCII_DTOSTR_BUF_SIZE, v_DOUBLE);
                g_string_append(json_array, buf);
            }
            break;
        default:
            /* since we already validated signature, should not happen */
            g_assert_not_reached();
            break;
        }

        if (dbus_message_iter_has_next(array_iter)) {
            g_string_append(json_array, ",");
        }
                
        dbus_message_iter_next(array_iter);
    }
    
    g_string_append(json_array, "]");

    return g_string_free(json_array, FALSE);
}
Пример #3
0
/**
   @brief Parses JSON strings, in a very generic manner.
   @param text Input text.
   @param idx Starting index of the string.
   @param setter Function to call with each character.
   @param setarg Argument to give to the setter function.
 */
static struct parser_arg json_string(const wchar_t *text, size_t idx,
                                     output_setter setter, void *setarg)
{
  wchar_t wc;
  struct parser_arg a = {
    .state = START,
    .text = text,
    .textidx = idx,
    .outidx = 0,
    .setter = setter,
    .setter_arg = setarg,
    .prev = 0,
    .curr = 0,
    .error = JSONERR_NO_ERROR
  };

  while (a.state != END) {
    wc = a.text[a.textidx];
    switch (a.state) {
    case START:
      json_string_start(&a, wc);
      break;
    case INSTRING:
      json_string_instring(&a, wc);
      break;
    case ESCAPE:
      json_string_escape(&a, wc);
      break;
    case UESC0:
    case UESC1:
    case UESC2:
    case UESC3:
      json_string_uesc(&a, wc);
      break;
    case END:
      // never happens
      assert(false);
      break;
    }
    a.textidx++;
  }
  if (a.prev != 0) {
    a.error = JSONERR_INVALID_SURROGATE;
  }
  return a;
}

/*******************************************************************************

                          Application-Specific Parsers

*******************************************************************************/

/**
   @brief Parse a string literal.
   @param text The text we're parsing.
   @param arr The token buffer.
   @param maxtoken The length of the token buffer.
   @param p The parser state.
   @returns Parser state after parsing the string.
 */
struct json_parser json_parse_string(wchar_t *text, struct json_token *arr,
                                     size_t maxtoken, struct json_parser p)
{
  struct json_token tok;
  struct parser_arg a;

  tok.type = JSON_STRING;
  tok.start = p.textidx;

  a = json_string(text, p.textidx, NULL, NULL);

  tok.end = a.textidx - 1;
  tok.child = 0;
  tok.next = 0;
  tok.length = a.outidx;
  json_settoken(arr, tok, p, maxtoken);

  p.error = a.error;
  p.tokenidx++;
  p.textidx = a.textidx;
  return p;
}

/**
   @brief Argument passed to setter when we are doing json_string_match().
 */
struct string_compare_arg {
  /**
     @brief String we're comparing to.
   */
  const wchar_t *other;
  /**
     @brief Whether or not the string has evaluated to equal so far.
   */
  bool equal;
};

/**
   @brief This is the "setter" function for json_string_match().
   @param a Parser arguments.
   @param wc Character to set.
   @param arg The struct string_compare_arg.

   This function just compares each output character to the corresponding
   character in the other string.  It stores the result in the arg, which will
   be examined after the fact.
 */
static void json_string_comparator(struct parser_arg *a, wchar_t wc, void *arg)
{
  struct string_compare_arg *ca = arg;
  // we are depending on short-circuit evaluation here :)
  ca->equal = ca->equal && (wc == ca->other[a->outidx]);
}

bool json_string_match(const wchar_t *json, const struct json_token *tokens,
                       size_t index, const wchar_t *other)
{
  struct string_compare_arg ca = {
    .other = other,
    .equal = true,
  };
  struct parser_arg pa = json_string(json, tokens[index].start,
                                     &json_string_comparator, &ca);

  // They are equal if every previous character matches, and the next character
  // in the other string is the null character, signifying the end.
  return ca.equal && (other[pa.outidx] == L'\0');
}

/**
   @brief This is the "setter" function for json_string_match().
   @param a Parser arguments.
   @param wc Character to set.
   @param arg The struct string_compare_arg.

   This function just compares each output character to the corresponding
   character in the other string.  It stores the result in the arg, which will
   be examined after the fact.
 */
static void json_string_loader(struct parser_arg *a, wchar_t wc, void *arg)
{
  wchar_t *str = arg;
  // we are depending on short-circuit evaluation here :)
  str[a->outidx] = wc;
}

void json_string_load(const wchar_t *json, const struct json_token *tokens,
                      size_t index, wchar_t *buffer)
{
  struct parser_arg pa = json_string(json, tokens[index].start,
                                     &json_string_loader, buffer);

  buffer[pa.outidx] = L'\0';
}
Пример #4
0
Файл: lex.c Проект: l8huang/ovs
/* Appends a string representation of 'token' to 's', in a format that can be
 * losslessly parsed back by the lexer.  (LEX_T_END and LEX_T_ERROR can't be
 * parsed back.) */
void
lex_token_format(const struct lex_token *token, struct ds *s)
{
    switch (token->type) {
    case LEX_T_END:
        ds_put_cstr(s, "$");
        break;

    case LEX_T_ID:
        ds_put_cstr(s, token->s);
        break;

    case LEX_T_ERROR:
        ds_put_cstr(s, "error(");
        json_string_escape(token->s, s);
        ds_put_char(s, ')');
        break;

    case LEX_T_STRING:
        json_string_escape(token->s, s);
        break;

    case LEX_T_INTEGER:
        lex_token_format_value(&token->value, lex_token_get_format(token), s);
        break;

    case LEX_T_MASKED_INTEGER:
        lex_token_format_masked_integer(token, s);
        break;

    case LEX_T_LPAREN:
        ds_put_cstr(s, "(");
        break;
    case LEX_T_RPAREN:
        ds_put_cstr(s, ")");
        break;
    case LEX_T_LCURLY:
        ds_put_cstr(s, "{");
        break;
    case LEX_T_RCURLY:
        ds_put_cstr(s, "}");
        break;
    case LEX_T_LSQUARE:
        ds_put_cstr(s, "[");
        break;
    case LEX_T_RSQUARE:
        ds_put_cstr(s, "]");
        break;
    case LEX_T_EQ:
        ds_put_cstr(s, "==");
        break;
    case LEX_T_NE:
        ds_put_cstr(s, "!=");
        break;
    case LEX_T_LT:
        ds_put_cstr(s, "<");
        break;
    case LEX_T_LE:
        ds_put_cstr(s, "<=");
        break;
    case LEX_T_GT:
        ds_put_cstr(s, ">");
        break;
    case LEX_T_GE:
        ds_put_cstr(s, ">=");
        break;
    case LEX_T_LOG_NOT:
        ds_put_cstr(s, "!");
        break;
    case LEX_T_LOG_AND:
        ds_put_cstr(s, "&&");
        break;
    case LEX_T_LOG_OR:
        ds_put_cstr(s, "||");
        break;
    case LEX_T_ELLIPSIS:
        ds_put_cstr(s, "..");
        break;
    case LEX_T_COMMA:
        ds_put_cstr(s, ",");
        break;
    case LEX_T_SEMICOLON:
        ds_put_cstr(s, ";");
        break;
    case LEX_T_EQUALS:
        ds_put_cstr(s, "=");
        break;
    case LEX_T_EXCHANGE:
        ds_put_cstr(s, "<->");
        break;
    case LEX_T_DECREMENT:
        ds_put_cstr(s, "--");
        break;
    default:
        OVS_NOT_REACHED();
    }

}