Improve comments, and track number of bytes written to a stream.
[cumulus.git] / store.h
1 /* LBS: An LFS-inspired filesystem backup system
2  * Copyright (C) 2006  Michael Vrable
3  *
4  * Backup data is stored in a collection of objects, which are grouped together
5  * into segments for storage purposes.  This file provides interfaces for
6  * reading and writing objects and segments. */
7
8 #ifndef _LBS_STORE_H
9 #define _LBS_STORE_H
10
11 #include <stdint.h>
12
13 #include <exception>
14 #include <map>
15 #include <string>
16 #include <sstream>
17
18 /* In memory datatype to represent key/value pairs of information, such as file
19  * metadata.  Currently implemented as map<string, string>. */
20 typedef std::map<std::string, std::string> dictionary;
21
22 /* IOException will be thrown if an error occurs while reading or writing in
23  * one of the I/O wrappers.  Depending upon the context; this may be fatal or
24  * not--typically, errors reading/writing the store will be serious, but errors
25  * reading an individual file are less so. */
26 class IOException : public std::exception {
27 private:
28     std::string error;
29 public:
30     explicit IOException(const std::string &err) { error = err; }
31     virtual ~IOException() throw () { }
32     std::string getError() const { return error; }
33 };
34
35 /* OutputStream is an abstract interface for writing data without seeking.
36  * Output could be to a file, to an object within a segment, or even to a
37  * memory buffer to help serialize data. */
38 class OutputStream {
39 public:
40     OutputStream();
41     virtual ~OutputStream() { }
42
43     // Write the given data buffer
44     void write(const void *data, size_t len);
45
46     // Return the total number of bytes written so far
47     int64_t get_pos() const { return bytes_written; }
48
49     // Convenience functions for writing other data types.  Values are always
50     // written out in little-endian order.
51     void write_u8(uint8_t val);
52     void write_u16(uint16_t val);
53     void write_u32(uint32_t val);
54     void write_u64(uint64_t val);
55
56     void write_s32(int32_t val) { write_u32((uint32_t)val); }
57     void write_s64(int64_t val) { write_u64((uint64_t)val); }
58
59     void write_varint(uint64_t val);
60
61     void write_string(const std::string &s);
62     void write_dictionary(const dictionary &d);
63
64 protected:
65     // Function which actually causes a write: must be overridden by
66     // implementation.
67     virtual void write_internal(const void *data, size_t len) = 0;
68
69 private:
70     int64_t bytes_written;
71 };
72
73 /* An OutputStream implementation which writes data to memory and returns the
74  * result as a string. */
75 class StringOutputStream : public OutputStream {
76 public:
77     StringOutputStream();
78     std::string contents() const { return buf.str(); }
79
80 protected:
81     virtual void write_internal(const void *data, size_t len);
82
83 private:
84     std::stringstream buf;
85 };
86
87 /* An OutputStream implementation which writes data via the C stdio layer. */
88 class FileOutputStream : public OutputStream {
89 public:
90     explicit FileOutputStream(FILE *file);
91     virtual ~FileOutputStream();
92
93 protected:
94     virtual void write_internal(const void *data, size_t len);
95
96 private:
97     FILE *f;
98 };
99
100 /* Simple wrappers that encode integers using a StringOutputStream and return
101  * the encoded result. */
102 std::string encode_u16(uint16_t val);
103 std::string encode_u32(uint32_t val);
104 std::string encode_u64(uint64_t val);
105
106 #endif // _LBS_STORE_H