Rename format.{cc,h} -> util.{cc,h}.
[cumulus.git] / util.cc
1 /* LBS: An LFS-inspired filesystem backup system
2  * Copyright (C) 2007  Michael Vrable
3  *
4  * Utility functions for converting various datatypes to text format (and
5  * later, for parsing them back, perhaps).
6  */
7
8 #include <stdio.h>
9 #include <uuid/uuid.h>
10
11 #include <iostream>
12 #include <map>
13 #include <string>
14 #include <sstream>
15
16 using std::map;
17 using std::ostream;
18 using std::string;
19
20 /* Perform URI-style escaping of a string.  Bytes which cannot be represented
21  * directly are encoded in the form %xx (where "xx" is a string of two
22  * hexadecimal digits). */
23 string uri_encode(const string &in)
24 {
25     string out;
26
27     for (size_t i = 0; i < in.length(); i++) {
28         unsigned char c = in[i];
29
30         if (c >= '+' && c < 0x7f) {
31             out += c;
32         } else {
33             char buf[4];
34             sprintf(buf, "%%%02x", c);
35             out += buf;
36         }
37     }
38
39     return out;
40 }
41
42 /* Decoding of strings produced by uri_encode. */
43 string uri_decode(const string &in)
44 {
45     char *buf = new char[in.size() + 1];
46
47     const char *input = in.c_str();
48     char *output = buf;
49
50     while (*input != '\0') {
51         if (*input == '%') {
52             char hexbuf[4];
53             if (isxdigit(input[1]) && isxdigit(input[2])) {
54                 hexbuf[0] = input[1];
55                 hexbuf[1] = input[2];
56                 hexbuf[2] = '\0';
57                 *output++ = strtol(hexbuf, NULL, 16);
58                 input += 3;
59             } else {
60                 input++;
61             }
62         } else {
63             *output++ = *input++;
64         }
65     }
66
67     *output = '\0';
68
69     string result(buf);
70     delete buf;
71     return result;
72 }
73
74 /* Return the string representation of an integer. */
75 string encode_int(long long n)
76 {
77     char buf[64];
78     sprintf(buf, "%lld", n);
79     return buf;
80 }
81
82 /* Return the string representation of an integer. */
83 long long parse_int(const string &s)
84 {
85     return strtoll(s.c_str(), NULL, 10);
86 }
87
88 /* Output a dictionary of string key/value pairs to the given output stream.
89  * The format is a sequence of lines of the form "key: value". */
90 void dict_output(ostream &o, map<string, string> dict)
91 {
92     for (map<string, string>::const_iterator i = dict.begin();
93          i != dict.end(); ++i) {
94         o << i->first << ": " << i->second << "\n";
95     }
96 }