1
0
Fork 0
mirror of git://git.psyc.eu/libpsyc synced 2024-08-15 03:19:02 +00:00

uniform struct

This commit is contained in:
Gabor Adam Toth 2011-10-14 01:16:09 +02:00
parent 4c7b78aecc
commit 4b0705d697
3 changed files with 102 additions and 87 deletions

View file

@ -7,27 +7,47 @@
#include <psyc.h> #include <psyc.h>
typedef enum { typedef enum {
PSYC_SCHEME_PSYC = 0,
PSYC_SCHEME_IRC = 1,
PSYC_SCHEME_XMPP = 2,
PSYC_SCHEME_SIP = 3,
} psycScheme;
typedef struct {
// essential parts // essential parts
PSYC_UNIFORM_SCHEME = 0, psycScheme type;
PSYC_UNIFORM_USER = 1, psycString scheme;
PSYC_UNIFORM_PASS = 2, psycString user;
PSYC_UNIFORM_HOST = 3, psycString pass;
PSYC_UNIFORM_PORT = 4, psycString host;
PSYC_UNIFORM_TRANSPORT = 5, psycString port;
PSYC_UNIFORM_RESOURCE = 6, psycString transport;
PSYC_UNIFORM_QUERY = 7, psycString resource;
PSYC_UNIFORM_CHANNEL = 8, psycString query;
psycString channel;
// convenient snippets of the URL // convenient snippets of the URL
PSYC_UNIFORM_FULL = 9, // the URL as such psycString full; // the URL as such
PSYC_UNIFORM_BODY = 10, // the URL without scheme and '//' psycString body; // the URL without scheme and '//'
PSYC_UNIFORM_USERATHOST = 11, // mailto and xmpp style psycString user_host; // mailto and xmpp style
PSYC_UNIFORM_HOSTPORT = 12, // just host:port (and transport) psycString host_port; // just host:port (and transport)
PSYC_UNIFORM_ROOT = 13, // root UNI of peer/server psycString root; // root UNI of peer/server
PSYC_UNIFORM_SLASHES = 14, // the // if the protocol has them psycString slashes; // the // if the protocol has them
PSYC_UNIFORM_NICK = 15, // whatever works as a nickname psycString nick; // whatever works as a nickname
PSYC_UNIFORM_SIZE = 16, } psycUniform;
} psycUniformField;
typedef enum {
PSYC_UNIFORM_SCHEME = 0,
PSYC_UNIFORM_SLASHES,
PSYC_UNIFORM_USER,
PSYC_UNIFORM_PASS,
PSYC_UNIFORM_HOST,
PSYC_UNIFORM_PORT,
PSYC_UNIFORM_TRANSPORT,
PSYC_UNIFORM_RESOURCE,
PSYC_UNIFORM_QUERY,
PSYC_UNIFORM_CHANNEL,
} psycUniformPart;
typedef enum { typedef enum {
PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7,
@ -39,13 +59,6 @@ typedef enum {
PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1,
} psycParseUniformRC; } psycParseUniformRC;
typedef enum {
PSYC_SCHEME_PSYC = 0,
PSYC_SCHEME_IRC = 1,
PSYC_SCHEME_XMPP = 2,
PSYC_SCHEME_SIP = 3,
} psycScheme;
typedef enum { typedef enum {
PSYC_TRANSPORT_TCP = 'c', PSYC_TRANSPORT_TCP = 'c',
PSYC_TRANSPORT_UDP = 'd', PSYC_TRANSPORT_UDP = 'd',
@ -59,8 +72,6 @@ typedef enum {
PSYC_ENTITY_SERVICE = '$', PSYC_ENTITY_SERVICE = '$',
} psycEntityType; } psycEntityType;
typedef psycString psycUniform[PSYC_UNIFORM_SIZE];
int psyc_parseUniform2(psycUniform *uni, const char *str, size_t length); int psyc_parseUniform2(psycUniform *uni, const char *str, size_t length);
int psyc_parseUniform(psycUniform *uni, psycString *str); int psyc_parseUniform(psycUniform *uni, psycString *str);

View file

@ -7,105 +7,109 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length)
{ {
char c; char c;
psycString *p; psycString *p;
size_t pos = 0, part = PSYC_UNIFORM_SCHEME, scheme; size_t pos = 0, part = PSYC_UNIFORM_SCHEME;
(*uni)[PSYC_UNIFORM_FULL].ptr = str; uni->full.ptr = str;
(*uni)[PSYC_UNIFORM_FULL].length = length; uni->full.length = length;
while (pos < length) { while (pos < length) {
c = str[pos]; c = str[pos];
if (c == ':') { if (c == ':') {
(*uni)[part].ptr = str; uni->scheme.ptr = str;
(*uni)[part].length = pos++; uni->scheme.length = pos++;
break; break;
} else if (!psyc_isHostChar(c)) } else if (!psyc_isHostChar(c))
return PSYC_PARSE_UNIFORM_INVALID_SCHEME; return PSYC_PARSE_UNIFORM_INVALID_SCHEME;
pos++; pos++;
} }
p = &(*uni)[PSYC_UNIFORM_SCHEME]; p = &uni->scheme;
if (p->length == 4 && if (p->length == 4 &&
tolower(p->ptr[0]) == 'p' && tolower(p->ptr[0]) == 'p' &&
tolower(p->ptr[1]) == 's' && tolower(p->ptr[1]) == 's' &&
tolower(p->ptr[2]) == 'y' && tolower(p->ptr[2]) == 'y' &&
tolower(p->ptr[3]) == 'c') { tolower(p->ptr[3]) == 'c') {
scheme = PSYC_SCHEME_PSYC;
uni->type = PSYC_SCHEME_PSYC;
part = PSYC_UNIFORM_SLASHES; part = PSYC_UNIFORM_SLASHES;
(*uni)[part].ptr = str + pos; uni->slashes.ptr = str + pos;
(*uni)[part].length = 0; uni->slashes.length = 0;
while (pos < length) { while (pos < length) {
c = str[pos]; c = str[pos];
switch (part) { switch (part) {
case PSYC_UNIFORM_SLASHES: case PSYC_UNIFORM_SLASHES:
if (c == '/') if (c == '/')
(*uni)[part].length++; uni->slashes.length++;
else return PSYC_PARSE_UNIFORM_INVALID_SLASHES; else return PSYC_PARSE_UNIFORM_INVALID_SLASHES;
if ((*uni)[part].length == 2) { if (uni->slashes.length == 2) {
part = PSYC_UNIFORM_HOST; part = PSYC_UNIFORM_HOST;
(*uni)[part].ptr = str + pos + 1; uni->host.ptr = str + pos + 1;
(*uni)[part].length = 0; uni->host.length = 0;
} }
break; break;
case PSYC_UNIFORM_HOST: case PSYC_UNIFORM_HOST:
if (psyc_isHostChar(c)) { if (psyc_isHostChar(c)) {
(*uni)[part].length++; uni->host.length++;
break; break;
} }
if ((*uni)[part].length == 0) if (uni->host.length == 0)
return PSYC_PARSE_UNIFORM_INVALID_HOST; return PSYC_PARSE_UNIFORM_INVALID_HOST;
if (c == ':') if (c == ':') {
part = PSYC_UNIFORM_PORT; part = PSYC_UNIFORM_PORT;
else if (c == '/') p = &uni->port;
} else if (c == '/') {
part = PSYC_UNIFORM_RESOURCE; part = PSYC_UNIFORM_RESOURCE;
p = &uni->resource;
}
else return PSYC_PARSE_UNIFORM_INVALID_HOST; else return PSYC_PARSE_UNIFORM_INVALID_HOST;
(*uni)[part].ptr = str + pos + 1; p->ptr = str + pos + 1;
(*uni)[part].length = 0; p->length = 0;
break; break;
case PSYC_UNIFORM_PORT: case PSYC_UNIFORM_PORT:
if (psyc_isNumeric(c)) { if (psyc_isNumeric(c)) {
(*uni)[part].length++; uni->port.length++;
break; break;
} }
if ((*uni)[part].length == 0 && c != PSYC_TRANSPORT_GNUNET) if (uni->port.length == 0 && c != PSYC_TRANSPORT_GNUNET)
return PSYC_PARSE_UNIFORM_INVALID_PORT; return PSYC_PARSE_UNIFORM_INVALID_PORT;
if (c == '/') { if (c == '/') {
part = PSYC_UNIFORM_RESOURCE; part = PSYC_UNIFORM_RESOURCE;
(*uni)[part].ptr = str + pos + 1; uni->resource.ptr = str + pos + 1;
(*uni)[part].length = 0; uni->resource.length = 0;
break; break;
} }
else { else {
part = PSYC_UNIFORM_TRANSPORT; part = PSYC_UNIFORM_TRANSPORT;
(*uni)[part].ptr = str + pos; uni->transport.ptr = str + pos;
(*uni)[part].length = 0; uni->transport.length = 0;
} }
// fall thru // fall thru
case PSYC_UNIFORM_TRANSPORT: case PSYC_UNIFORM_TRANSPORT:
switch (c) { switch (c) {
case PSYC_TRANSPORT_GNUNET: case PSYC_TRANSPORT_GNUNET:
if ((*uni)[PSYC_UNIFORM_PORT].length > 0) if (uni->port.length > 0)
return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT;
case PSYC_TRANSPORT_TCP: case PSYC_TRANSPORT_TCP:
case PSYC_TRANSPORT_UDP: case PSYC_TRANSPORT_UDP:
case PSYC_TRANSPORT_TLS: case PSYC_TRANSPORT_TLS:
if ((*uni)[part].length > 0) if (uni->transport.length > 0)
return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT;
(*uni)[part].length++; uni->transport.length++;
break; break;
case '/': case '/':
part = PSYC_UNIFORM_RESOURCE; part = PSYC_UNIFORM_RESOURCE;
(*uni)[part].ptr = str + pos + 1; uni->resource.ptr = str + pos + 1;
(*uni)[part].length = 0; uni->resource.length = 0;
break; break;
default: default:
return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT; return PSYC_PARSE_UNIFORM_INVALID_TRANSPORT;
@ -114,50 +118,50 @@ int psyc_parseUniform2 (psycUniform *uni, const char *str, size_t length)
case PSYC_UNIFORM_RESOURCE: case PSYC_UNIFORM_RESOURCE:
if (psyc_isNameChar(c)) { if (psyc_isNameChar(c)) {
(*uni)[part].length++; uni->resource.length++;
break; break;
} else if (c == '#') { } else if (c == '#') {
part = PSYC_UNIFORM_CHANNEL; part = PSYC_UNIFORM_CHANNEL;
(*uni)[part].ptr = str + pos + 1; uni->channel.ptr = str + pos + 1;
(*uni)[part].length = 0; uni->channel.length = 0;
break; break;
} else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE; } else return PSYC_PARSE_UNIFORM_INVALID_RESOURCE;
case PSYC_UNIFORM_CHANNEL: case PSYC_UNIFORM_CHANNEL:
if (psyc_isNameChar(c)) { if (psyc_isNameChar(c)) {
(*uni)[part].length++; uni->channel.length++;
break; break;
} else return PSYC_PARSE_UNIFORM_INVALID_CHANNEL; } else return PSYC_PARSE_UNIFORM_INVALID_CHANNEL;
} }
pos++; pos++;
} }
if ((*uni)[PSYC_UNIFORM_HOST].length == 0) if (uni->host.length == 0)
return PSYC_PARSE_UNIFORM_INVALID_HOST; return PSYC_PARSE_UNIFORM_INVALID_HOST;
(*uni)[PSYC_UNIFORM_ROOT].ptr = str; uni->host_port.ptr = uni->host.ptr;
(*uni)[PSYC_UNIFORM_ROOT].length = (*uni)[PSYC_UNIFORM_SCHEME].length + 1 + uni->host_port.length = uni->host.length + uni->port.length + uni->transport.length;
(*uni)[PSYC_UNIFORM_SLASHES].length + (*uni)[PSYC_UNIFORM_HOST].length + if (uni->port.length > 0 || uni->transport.length > 0)
(*uni)[PSYC_UNIFORM_PORT].length + (*uni)[PSYC_UNIFORM_TRANSPORT].length; uni->host_port.length++;
if ((*uni)[PSYC_UNIFORM_PORT].length > 0 || uni->root.ptr = str;
(*uni)[PSYC_UNIFORM_TRANSPORT].length > 0) uni->root.length = uni->scheme.length + 1 + uni->slashes.length +
(*uni)[PSYC_UNIFORM_ROOT].length++; // : uni->host_port.length;
(*uni)[PSYC_UNIFORM_BODY].ptr = (*uni)[PSYC_UNIFORM_HOST].ptr; uni->body.ptr = uni->host.ptr;
(*uni)[PSYC_UNIFORM_BODY].length = length - (*uni)[PSYC_UNIFORM_SCHEME].length - 1 - uni->body.length = length - uni->scheme.length - 1 - uni->slashes.length;
(*uni)[PSYC_UNIFORM_SLASHES].length;
if ((*uni)[PSYC_UNIFORM_RESOURCE].length) { if (uni->resource.length) {
(*uni)[PSYC_UNIFORM_NICK].ptr = (*uni)[PSYC_UNIFORM_RESOURCE].ptr + 1; uni->nick.ptr = uni->resource.ptr + 1;
(*uni)[PSYC_UNIFORM_NICK].length = (*uni)[PSYC_UNIFORM_RESOURCE].length; uni->nick.length = uni->resource.length;
} }
} else return PSYC_PARSE_UNIFORM_INVALID_SCHEME; } else return PSYC_PARSE_UNIFORM_INVALID_SCHEME;
if ((*uni)[PSYC_UNIFORM_HOST].length == 0) if (uni->host.length == 0)
return PSYC_PARSE_UNIFORM_INVALID_HOST; return PSYC_PARSE_UNIFORM_INVALID_HOST;
return scheme; return uni->type;
} }
int psyc_parseUniform (psycUniform *uni, psycString *str) int psyc_parseUniform (psycUniform *uni, psycString *str)

View file

@ -11,16 +11,16 @@ testUniform(char *str, int ret) {
int r = psyc_parseUniform2(uni, str, strlen(str)); int r = psyc_parseUniform2(uni, str, strlen(str));
PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n", PP(("[%.*s] : [%.*s] [%.*s] : [%.*s] [%.*s] / [%.*s] # [%.*s]\n[%.*s] [%.*s]\n[%.*s]\n\n",
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_SCHEME]), (int)PSYC_S2ARG2(uni->scheme),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_SLASHES]), (int)PSYC_S2ARG2(uni->slashes),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_HOST]), (int)PSYC_S2ARG2(uni->host),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_PORT]), (int)PSYC_S2ARG2(uni->port),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_TRANSPORT]), (int)PSYC_S2ARG2(uni->transport),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_RESOURCE]), (int)PSYC_S2ARG2(uni->resource),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_CHANNEL]), (int)PSYC_S2ARG2(uni->channel),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_ROOT]), (int)PSYC_S2ARG2(uni->root),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_NICK]), (int)PSYC_S2ARG2(uni->nick),
(int)PSYC_S2ARG2((*uni)[PSYC_UNIFORM_BODY]))); (int)PSYC_S2ARG2(uni->body)));
free(uni); free(uni);
if (r != ret) { if (r != ret) {