summaryrefslogtreecommitdiffstats
path: root/utils/hwstub/include/hwstub_uri.hpp
blob: d461764cd9c5740e60c3e9ff3cc0cfa1802390b5 (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2016 by Amaury Pouly
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#ifndef __HWSTUB_URI_HPP__
#define __HWSTUB_URI_HPP__

#include "hwstub.hpp"
#include "hwstub_net.hpp"

namespace hwstub {
namespace uri {

/** HWSTUB URIs
 *
 * They are of the form:
 * 
 * scheme:[//domain[:port]][/][path[?query]]
 * 
 * The scheme is mandatory and controls the type of context that is created.
 * The following scheme are recognized:
 *   usb      USB context
 *   tcp      TCP context
 *   unix     Unix domain context
 *   virt     Virtual context (Testing and debugging)
 *   default  Default context (This is the default)
 *
 * When creating a USB context, the domain and port must be empty:
 *   usb:
 *
 * When creating a TCP context, the domain and port are given as argument to
 * the context:
 *   tcp://localhost:6666
 *
 * When creating a Unix context, the domain is given as argument to
 * the context, it is invalid to specify a port. There are two types of
 * unix contexts: the one specified by a filesystem path, or (Linux-only) by
 * an abstract domain. Abstract names are specified as a domain starting with a '#',
 * whereas standard path can be any path:
 *   unix:///path/to/socket
 *   unix://#hwstub
 *
 * When creating a virtual context, the domain will contain a specification of
 * the device to create. The device list is of the type(param);type(param);...
 * where the only supported type at the moment is 'dummy' with a single parameter
 * which is the device name:
 *   virt://dummy(Device A);dummy(Device B);dummy(Super device C)
 *
 *
 * HWSTUB SERVER URIs
 *
 * The same scheme can be used to spawn servers. Server URIs are a subset of
 * context URIs and only support tcp and unix schemes.
 */

/** URI
 * 
 * Represents an URI and allows queries on it */
class uri
{
public:
    uri(const std::string& uri);
    /** Return whether the URI is syntactically correct */
    bool valid() const;
    /** Return error description if URI is invalid */
    std::string error() const;
    /** Return the original URI */
    std::string full_uri() const;
    /** Return the scheme */
    std::string scheme() const;
    /** Return the domain, or empty is none */
    std::string domain() const;
    /** Return the port, or empty is none */
    std::string port() const;
    /** Return the path, or empty is none */
    std::string path() const;

protected:
    void parse();
    bool validate_scheme();
    bool validate_domain();
    bool validate_port();

    std::string m_uri; /* original uri */
    bool m_valid; /* did it parse correctly ? */
    std::string m_scheme; /* scheme (extracted from URI) */
    std::string m_domain; /* domain (extracted from URI) */
    std::string m_port; /* port (extracted from URI) */
    std::string m_path; /* path (extracted from URI) */
    std::string m_error; /* error string (for invalid URIs) */
};

/** Create a context based on a URI. This function only uses the scheme/domain/port
 * parts of the URI. This function may fail and return a empty pointer. An optional
 * string can receive a description of the error */
std::shared_ptr<context> create_context(const uri& uri, std::string *error = nullptr);
/** Return a safe default for a URI */
uri default_uri();
/** Special case function for the default function */
std::shared_ptr<context> create_default_context(std::string *error = nullptr);
/** Create a server based on a URI. This function only uses the scheme/domain/port
 * parts of the URI. This function may fail and return a empty pointer. An optional
 * string can receive a description of the error */
std::shared_ptr<net::server> create_server(std::shared_ptr<context> ctx,
    const uri& uri, std::string *error);
/** Return a safe default for a server URI */
uri default_server_uri();
/** Print help for the format of a URI, typically for a command-line help.
 * The help can be client-only, server-only, or both. */
void print_usage(FILE *f, bool client, bool server);

} // namespace uri
} // namespace hwstub

#endif /* __HWSTUB_URI_HPP__ */