Add a new object-oriented wrapper for building object references.
[cumulus.git] / ref.h
1 /* LBS: An LFS-inspired filesystem backup system
2  * Copyright (C) 2007  Michael Vrable
3  *
4  * Backups are structured as a collection of objects, which may refer to other
5  * objects.  Object references are used to name other objects or parts of them.
6  * This file defines the class for representing object references and the
7  * textual representation of these references. */
8
9 #ifndef _LBS_REF_H
10 #define _LBS_REF_H
11
12 #include <string>
13
14 /* ======================== Object Reference Syntax ========================
15  *
16  * Segments are groups of objects.  Segments are named by UUID, which is a
17  * 128-bit value.  The text representation is
18  *    <segment> ::= xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx
19  * where each <x> is a lowercase hexadecimal digit ([0-9a-f]).
20  *
21  * Each object within a segment is assigned a sequence number, which is given
22  * as a hexadecimal value:
23  *    <object-seq> ::= xxxxxxxx
24  *
25  * An object can be uniquely named by the combination of segment name and
26  * object sequence number:
27  *    <object-name> ::= <segment> "/" <object-seq>
28  * Example: "cf47429e-a503-43ac-9c31-bb3175fbb820/0000002b"
29  *
30  * An object name may optionally be suffixed with a checksum, which allows
31  * checking the integrity of the referenced object.
32  *    <checksum> ::= <checksum-alg> "=" <checksum-value>
33  * Currently the only checksum-alg is "sha1", but others may be defined later.
34  * <checksum-value> is a hexadecimal string.  If included, the checksum is
35  * enclosed in parentheses.
36  *
37  * Each object is stored as a string of bytes, and object reference may specify
38  * a substring rather than the entire string using a range specifier.  If no
39  * range specifier is given, then by default the entire object is used.
40  *    <range> ::= <start> "+" <length>
41  * Both <start> and <length> are decimal values.  If included, the range is
42  * enclosed in brackets.
43  *
44  * When both a checksum and a range are included, note that the checksum is
45  * taken over the entire original object, before the range is taken into
46  * account.
47  *
48  * The full syntax for an object reference is:
49  *    <object-reference>
50  *      ::= <object-name> [ "(" <checksum> ")" ] [ "[" <range> "]" ]
51  * Example: "cf47429e-a503-43ac-9c31-bb3175fbb820/0000002b(sha1=b9f5d0a21b8d07356723f041f5463dec892654af)[1024+512]"
52  *
53  * Finally, in specific circumstances, and indirect reference may be used.  In
54  * cases where data could be listed directly, instead an object reference can
55  * be given, prefixed with "@", which indicates that the data stored at the
56  * referenced object should be treated as being included.
57  *    <indirect-reference> ::= "@" <object-reference>
58  */
59
60 /* Generate a fresh UUID, suitable for use as a segment name. */
61 std::string generate_uuid();
62
63 /* Class representing an object reference, which allows it to be manipulated
64  * and converted to and from the text representation. */
65 class ObjectReference {
66 public:
67     ObjectReference(const std::string& segment, int sequence);
68
69     std::string to_string() const;
70
71     std::string get_segment() const { return segment; }
72     void set_segment(const std::string& segment) { this->segment = segment; }
73
74     bool has_checksum() const { return checksum_valid; }
75     std::string get_checksum() const { return checksum; }
76     void clear_checksum() { checksum = ""; checksum_valid = false; }
77     void set_checksum(const std::string& checksum)
78         { this->checksum = checksum; checksum_valid = true; }
79
80     bool has_range() const { return range_valid; }
81     size_t get_range_start() const { return range_start; }
82     size_t get_range_length() const { return range_length; }
83     void clear_range() { range_start = range_length = 0; range_valid = false; }
84     void set_range(size_t start, size_t length)
85         { range_start = start; range_length = length; range_valid = true; }
86
87 private:
88     std::string segment, object, checksum;
89     size_t range_start, range_length;
90     bool checksum_valid, range_valid;
91 };
92
93 #endif // _LBS_REF_H