1 | // **************************************************************************
|
---|
2 | /** @struct Description
|
---|
3 |
|
---|
4 | @brief A struct which stores a name, a unit and a comment
|
---|
5 |
|
---|
6 | To have proper descriptions of commands and services in the network
|
---|
7 | (and later proper informations in the FITS files) this struct provides
|
---|
8 | a simple storage for a name, a unit and a comment.
|
---|
9 |
|
---|
10 | Assume you want to write a descriptive string for a command with three arguments.
|
---|
11 | It could look like this:
|
---|
12 |
|
---|
13 | COMMAND=Description|int[addr]:Address range (from - to)|val[byte]:Value to be set
|
---|
14 |
|
---|
15 | Description is a general description of the command or service itself,
|
---|
16 | int and val are the names of the arguments (e.g. names of FITS columns),
|
---|
17 | addr and byte have the meaning of a unit (e.g. unit of FITS column)
|
---|
18 | and the text after the colon is a description of the arguments
|
---|
19 | (e.g. comment of a FITS column). The description must not contain a
|
---|
20 | line-break character \n.
|
---|
21 |
|
---|
22 | Such a string can then be converted with SplitDescription into a vector
|
---|
23 | of Description objects, each containing the name, the unit and a
|
---|
24 | comment indivdually. The first object will contain COMMAND as name and
|
---|
25 | Description as comment. The unit will remain empty.
|
---|
26 |
|
---|
27 | You can omit either the name, the unit or the comment or any combination of them.
|
---|
28 | The descriptions of the individual format strings are separated by a vertical line.
|
---|
29 |
|
---|
30 | */
|
---|
31 | // **************************************************************************
|
---|
32 | #include "Description.h"
|
---|
33 |
|
---|
34 | #include <sstream>
|
---|
35 |
|
---|
36 | using namespace std;
|
---|
37 |
|
---|
38 | // --------------------------------------------------------------------------
|
---|
39 | //
|
---|
40 | //! This function removed whitshapces on both sides of a string.
|
---|
41 | //!
|
---|
42 | //! @param s
|
---|
43 | //! string to be cleaned
|
---|
44 | //!
|
---|
45 | //! @returns
|
---|
46 | //! string cleaned from whitespaces
|
---|
47 | //
|
---|
48 | string Description::Trim(string s)
|
---|
49 | {
|
---|
50 | // Trim Both leading and trailing spaces
|
---|
51 | const size_t start = s.find_first_not_of(' '); // Find the first character position after excluding leading blank spaces
|
---|
52 | const size_t end = s.find_last_not_of(' '); // Find the first character position from reverse af
|
---|
53 |
|
---|
54 | // if all spaces or empty return an empty string
|
---|
55 | if (string::npos==start || string::npos==end)
|
---|
56 | return string();
|
---|
57 |
|
---|
58 | return s.substr(start, end-start+1);
|
---|
59 | }
|
---|
60 |
|
---|
61 | // --------------------------------------------------------------------------
|
---|
62 | //
|
---|
63 | //! This functio0n breaks down a descriptive string into its components.
|
---|
64 | //! For details see class reference.
|
---|
65 | //!
|
---|
66 | //! @param buffer
|
---|
67 | //! string which should be broekn into pieces
|
---|
68 | //!
|
---|
69 | //! @returns
|
---|
70 | //! A vector<Description> containing all the descriptions found.
|
---|
71 | //! The first entry contains the discription name and comment.
|
---|
72 | //
|
---|
73 | vector<Description> Description::SplitDescription(const string &buffer)
|
---|
74 | {
|
---|
75 | const size_t p0 = buffer.find_first_of('=');
|
---|
76 |
|
---|
77 | const string svc = buffer.substr(0, p0);
|
---|
78 | const string desc = buffer.substr(p0+1);
|
---|
79 |
|
---|
80 | const size_t p = desc.find_first_of('|');
|
---|
81 |
|
---|
82 | // Extract a general description
|
---|
83 | const string d = Description::Trim(desc.substr(0, p));
|
---|
84 |
|
---|
85 | vector<Description> vec;
|
---|
86 | vec.push_back(Description(svc, "", d));
|
---|
87 |
|
---|
88 | if (p==string::npos)
|
---|
89 | return vec;
|
---|
90 |
|
---|
91 | string buf;
|
---|
92 | stringstream stream(desc.substr(p+1));
|
---|
93 | while (getline(stream, buf, '|'))
|
---|
94 | {
|
---|
95 | if (buf.empty())
|
---|
96 | continue;
|
---|
97 |
|
---|
98 | const size_t p1 = buf.find_first_of(':');
|
---|
99 |
|
---|
100 | const string comment = p1==string::npos ? "" : buf.substr(p1+1);
|
---|
101 | if (p1!=string::npos)
|
---|
102 | buf.erase(p1);
|
---|
103 |
|
---|
104 | const size_t p2 = buf.find_last_of('[');
|
---|
105 | const size_t p3 = buf.find_last_of(']');
|
---|
106 |
|
---|
107 | const bool hasunit = p2<p3 && p2!=string::npos;
|
---|
108 |
|
---|
109 | const string unit = hasunit ? buf.substr(p2+1, p3-p2-1) : "";
|
---|
110 | const string name = hasunit ? buf.substr(0, p2) : buf;
|
---|
111 |
|
---|
112 | vec.push_back(Description(name, unit, comment));
|
---|
113 | }
|
---|
114 |
|
---|
115 | return vec;
|
---|
116 | }
|
---|