A gopher client for your terminal.
git clone git://git.skec.site/pub/sr71.git
log | files | refs | readme | license

uri.h (2795B)

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
#ifndef URI_H_
#define URI_H_

#include "str.h"

enum uri_protocol
{
    /* The protocol is not one thatwe understand. */
    PROTOCOL_UNSUPPORTED = -1,

    PROTOCOL_NONE = 0,

    /*
     * Protocols that have slashes:
     *   gopher://example.com
     */
    PROTOCOL_GOPHER,
    //PROTOCOL_GEMINI,
    PROTOCOL_FILE,

    /*
     * Protocols that do not have slashes:
     *   internal:history
     *   mailto:info@example.com
     */
#define PROTOCOL_NO_SLASHES_FIRST SUPPORTED_PROTOCOL_COUNT //PROTOCOL_INTERNAL
    //PROTOCOL_INTERNAL,
    //PROTOCOL_MAILTO,
    //PROTOCOL_MAGNET,

    SUPPORTED_PROTOCOL_COUNT
};

static const char *const SUPPORTED_PROTOCOL_NAMES[SUPPORTED_PROTOCOL_COUNT] =
{
    [PROTOCOL_NONE]   = "",
    [PROTOCOL_GOPHER] = "gopher",
    [PROTOCOL_FILE]   = "file",
};

/* Lookup supported protocol by name */
static inline enum uri_protocol
uri_protocol_lookup(const char *s, size_t n)
{
    int i;

    for (i = 0; i < SUPPORTED_PROTOCOL_COUNT; ++i)
    {
        ASSERT(SUPPORTED_PROTOCOL_NAMES[i] && "unnamed protocol");

        if (str_equal(s, SUPPORTED_PROTOCOL_NAMES[i], n))
            return (enum uri_protocol)i;
    }

    return PROTOCOL_UNSUPPORTED;
}

static inline bool
uri_protocol_has_slashes(enum uri_protocol p)
{
    ASSERT(p != PROTOCOL_UNSUPPORTED && "unsupported protocol");
    ASSERT(p > PROTOCOL_NONE &&
           p < SUPPORTED_PROTOCOL_COUNT && "invalid protocol");

    return p < PROTOCOL_NO_SLASHES_FIRST;
}

#define URI_NO_PROTOCOL_SLASHES_BIT 0x01 /* URI protocol has no slashes.
                                          * e.g. mailto: and internal: URIs. */

struct uri
{
    uint32_t          flags;
    int               port;
    enum uri_protocol protocol;
    char              protocol_str[16]; /* protocol (no colon or slashes) */
    char              host[256]; /* includes at-sign (@) for mailto */
    char              path[512];
    char              query[256];
};

/* Parse URI from string */
struct uri uri_parse(const char *uristr, int uristr_len);

/* uristr flags */
#define URISTR_NO_PORT_BIT  0x01 /* exclude port from the string */
#define URISTR_FANCY_BIT    0x02 /* fancy URI styling/colouring */
#define URISTR_NOSCHEME_BIT 0x04 /* omit protocol/scheme */
#define URISTR_NOSLASH_BIT  0x08 /* omit trailing slash from path */
#define URISTR_NOGITEM_BIT  0x10 /* omit gopher item type */
#define URISTR_NOQUERY_BIT  0x20 /* omit query */

/* Convert URI to string */
size_t uri_str(char *b,
               const struct uri *const u,
               size_t b_size,
               uint32_t flags);

/* urieq flags */
#define URIEQ_IGNORE_TRAILING_SLASH_BIT 0x01
#define URIEQ_IGNORE_QUERY_BIT 0x02

/* @return true if URIs are equal */
bool uri_equal(struct uri u1, struct uri u2, uint32_t flags);

#endif