/* * Add a new value to the announcement list or refresh an announcement. */ int kad_announce( const char _query[], int port, time_t lifetime ) { char query[QUERY_MAX_SIZE]; /* Remove .p2p suffix and convert to lowercase */ if( query_sanitize( query, sizeof(query), _query ) != 0 ) { return -1; } /* Store query to call kad_announce_once() later/multiple times */ return values_add( query, port, lifetime ) ? 0 : -2; }
static void json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_len) { const char *const beg = str; char c; int len; const char *se = str + str_len; while (str < se) { c = *str; switch (loader->stat) { case GRN_LOADER_BEGIN : if ((len = grn_isspace(str, ctx->encoding))) { str += len; continue; } switch (c) { case '[' : JSON_READ_OPEN_BRACKET(); break; case '{' : JSON_READ_OPEN_BRACE(); break; default : ERR(GRN_INVALID_ARGUMENT, "JSON must start with '[' or '{': <%.*s>", str_len, beg); loader->stat = GRN_LOADER_END; break; } break; case GRN_LOADER_TOKEN : if ((len = grn_isspace(str, ctx->encoding))) { str += len; continue; } switch (c) { case '"' : loader->stat = GRN_LOADER_STRING; values_add(ctx, loader); str++; break; case '[' : JSON_READ_OPEN_BRACKET(); break; case '{' : JSON_READ_OPEN_BRACE(); break; case ':' : str++; break; case ',' : str++; break; case ']' : bracket_close(ctx, loader); loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; if (ctx->rc == GRN_CANCEL) { loader->stat = GRN_LOADER_END; } str++; break; case '}' : brace_close(ctx, loader); loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; if (ctx->rc == GRN_CANCEL) { loader->stat = GRN_LOADER_END; } str++; break; case '+' : case '-' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->stat = GRN_LOADER_NUMBER; values_add(ctx, loader); break; default : if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('_' == c)) { loader->stat = GRN_LOADER_SYMBOL; values_add(ctx, loader); } else { if ((len = grn_charlen(ctx, str, se))) { GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char('%c') at", c); GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg) + len, beg); GRN_LOG(ctx, GRN_LOG_ERROR, "%*s", (int)(str - beg) + 1, "^"); str += len; } else { GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c); GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg); str = se; } } break; } break; case GRN_LOADER_SYMBOL : if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || ('_' == c)) { GRN_TEXT_PUTC(ctx, loader->last, c); str++; } else { char *v = GRN_TEXT_VALUE(loader->last); switch (*v) { case 'n' : if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "null", 4)) { loader->last->header.domain = GRN_DB_VOID; GRN_BULK_REWIND(loader->last); } break; case 't' : if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "true", 4)) { loader->last->header.domain = GRN_DB_BOOL; GRN_BOOL_SET(ctx, loader->last, GRN_TRUE); } break; case 'f' : if (GRN_TEXT_LEN(loader->last) == 5 && !memcmp(v, "false", 5)) { loader->last->header.domain = GRN_DB_BOOL; GRN_BOOL_SET(ctx, loader->last, GRN_FALSE); } break; default : break; } loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; } break; case GRN_LOADER_NUMBER : switch (c) { case '+' : case '-' : case '.' : case 'e' : case 'E' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : GRN_TEXT_PUTC(ctx, loader->last, c); str++; break; default : { const char *cur, *str = GRN_BULK_HEAD(loader->last); const char *str_end = GRN_BULK_CURR(loader->last); int64_t i = grn_atoll(str, str_end, &cur); if (cur == str_end) { loader->last->header.domain = GRN_DB_INT64; GRN_INT64_SET(ctx, loader->last, i); } else if (cur != str) { uint64_t i = grn_atoull(str, str_end, &cur); if (cur == str_end) { loader->last->header.domain = GRN_DB_UINT64; GRN_UINT64_SET(ctx, loader->last, i); } else if (cur != str) { double d; char *end; grn_obj buf; GRN_TEXT_INIT(&buf, 0); GRN_TEXT_PUT(ctx, &buf, str, GRN_BULK_VSIZE(loader->last)); GRN_TEXT_PUTC(ctx, &buf, '\0'); errno = 0; d = strtod(GRN_TEXT_VALUE(&buf), &end); if (!errno && end + 1 == GRN_BULK_CURR(&buf)) { loader->last->header.domain = GRN_DB_FLOAT; GRN_FLOAT_SET(ctx, loader->last, d); } GRN_OBJ_FIN(ctx, &buf); } } } loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; break; } break; case GRN_LOADER_STRING : switch (c) { case '\\' : loader->stat = GRN_LOADER_STRING_ESC; str++; break; case '"' : str++; loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; /* *(GRN_BULK_CURR(loader->last)) = '\0'; GRN_LOG(ctx, GRN_LOG_ALERT, "read str(%s)", GRN_TEXT_VALUE(loader->last)); */ break; default : if ((len = grn_charlen(ctx, str, se))) { GRN_TEXT_PUT(ctx, loader->last, str, len); str += len; } else { GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c); GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg); str = se; } break; } break; case GRN_LOADER_STRING_ESC : switch (c) { case 'b' : GRN_TEXT_PUTC(ctx, loader->last, '\b'); loader->stat = GRN_LOADER_STRING; break; case 'f' : GRN_TEXT_PUTC(ctx, loader->last, '\f'); loader->stat = GRN_LOADER_STRING; break; case 'n' : GRN_TEXT_PUTC(ctx, loader->last, '\n'); loader->stat = GRN_LOADER_STRING; break; case 'r' : GRN_TEXT_PUTC(ctx, loader->last, '\r'); loader->stat = GRN_LOADER_STRING; break; case 't' : GRN_TEXT_PUTC(ctx, loader->last, '\t'); loader->stat = GRN_LOADER_STRING; break; case 'u' : loader->stat = GRN_LOADER_UNICODE0; break; default : GRN_TEXT_PUTC(ctx, loader->last, c); loader->stat = GRN_LOADER_STRING; break; } str++; break; case GRN_LOADER_UNICODE0 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar = (c - '0') * 0x1000; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar = (c - 'a' + 10) * 0x1000; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar = (c - 'A' + 10) * 0x1000; break; default : ;// todo : error } loader->stat = GRN_LOADER_UNICODE1; str++; break; case GRN_LOADER_UNICODE1 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar += (c - '0') * 0x100; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar += (c - 'a' + 10) * 0x100; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar += (c - 'A' + 10) * 0x100; break; default : ;// todo : error } loader->stat = GRN_LOADER_UNICODE2; str++; break; case GRN_LOADER_UNICODE2 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar += (c - '0') * 0x10; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar += (c - 'a' + 10) * 0x10; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar += (c - 'A' + 10) * 0x10; break; default : ;// todo : error } loader->stat = GRN_LOADER_UNICODE3; str++; break; case GRN_LOADER_UNICODE3 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar += (c - '0'); break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar += (c - 'a' + 10); break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar += (c - 'A' + 10); break; default : ;// todo : error } { uint32_t u = loader->unichar; if (u >= 0xd800 && u <= 0xdbff) { /* High-surrogate code points */ loader->unichar_hi = u; loader->stat = GRN_LOADER_STRING; str++; break; } if (u >= 0xdc00 && u <= 0xdfff) { /* Low-surrogate code points */ u = 0x10000 + (loader->unichar_hi - 0xd800) * 0x400 + u - 0xdc00; } if (u < 0x80) { GRN_TEXT_PUTC(ctx, loader->last, u); } else { if (u < 0x800) { GRN_TEXT_PUTC(ctx, loader->last, (u >> 6) | 0xc0); } else { if (u < 0x10000) { GRN_TEXT_PUTC(ctx, loader->last, (u >> 12) | 0xe0); } else { GRN_TEXT_PUTC(ctx, loader->last, (u >> 18) | 0xf0); GRN_TEXT_PUTC(ctx, loader->last, ((u >> 12) & 0x3f) | 0x80); } GRN_TEXT_PUTC(ctx, loader->last, ((u >> 6) & 0x3f) | 0x80); } GRN_TEXT_PUTC(ctx, loader->last, (u & 0x3f) | 0x80); }