1 /* LBS: An LFS-inspired filesystem backup system
2 * Copyright (C) 2007 Michael Vrable
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. */
14 /* ======================== Object Reference Syntax ========================
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]).
21 * Each object within a segment is assigned a sequence number, which is given
22 * as a hexadecimal value:
23 * <object-seq> ::= xxxxxxxx
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"
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.
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.
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
48 * The full syntax for an object reference is:
50 * ::= <object-name> [ "(" <checksum> ")" ] [ "[" <range> "]" ]
51 * Example: "cf47429e-a503-43ac-9c31-bb3175fbb820/0000002b(sha1=b9f5d0a21b8d07356723f041f5463dec892654af)[1024+512]"
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>
60 /* Generate a fresh UUID, suitable for use as a segment name. */
61 std::string generate_uuid();
63 /* Class representing an object reference, which allows it to be manipulated
64 * and converted to and from the text representation. */
65 class ObjectReference {
68 ObjectReference(const std::string& segment, int sequence);
69 ObjectReference(const std::string& segment, const std::string& sequence);
71 bool is_null() const { return segment.size() == 0; }
72 std::string to_string() const;
73 static ObjectReference parse(const std::string& s);
75 std::string get_segment() const { return segment; }
76 std::string get_sequence() const { return object; }
77 std::string get_basename() const { return segment + "/" + object; }
79 bool has_checksum() const { return checksum_valid; }
80 std::string get_checksum() const { return checksum; }
81 void clear_checksum() { checksum = ""; checksum_valid = false; }
82 void set_checksum(const std::string& checksum)
83 { this->checksum = checksum; checksum_valid = true; }
85 bool has_range() const { return range_valid; }
86 size_t get_range_start() const { return range_start; }
87 size_t get_range_length() const { return range_length; }
88 void clear_range() { range_start = range_length = 0; range_valid = false; }
89 void set_range(size_t start, size_t length)
90 { range_start = start; range_length = length; range_valid = true; }
92 bool merge(ObjectReference ref);
95 std::string segment, object, checksum;
96 size_t range_start, range_length;
97 bool checksum_valid, range_valid;