source: box/trunk/lib/common/Archive.h @ 2584

Revision 2584, 3.7 KB checked in by chris, 3 years ago (diff)

Add methods to read and write exact 32-bit and 64-bit types.

Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    Archive.h
5//              Purpose: Backup daemon state archive
6//              Created: 2005/04/11
7//
8// --------------------------------------------------------------------------
9
10#ifndef ARCHIVE__H
11#define ARCHIVE__H
12
13#include <vector>
14#include <string>
15#include <memory>
16
17#include "IOStream.h"
18#include "Guards.h"
19
20#define ARCHIVE_GET_SIZE(hdr)           (( ((uint8_t)((hdr)[0])) | ( ((uint8_t)((hdr)[1])) << 8)) >> 2)
21
22#define ARCHIVE_MAGIC_VALUE_RECURSE 0x4449525F
23#define ARCHIVE_MAGIC_VALUE_NOOP 0x5449525F
24
25class Archive
26{
27public:
28        Archive(IOStream &Stream, int Timeout)
29                : mrStream(Stream)
30        {
31                mTimeout = Timeout;
32        }
33private:
34        // no copying
35        Archive(const Archive &);
36        Archive & operator=(const Archive &);
37public:
38        ~Archive()
39        {
40        }
41        //
42        //
43        //
44        void Write(bool Item)
45        {
46                Write((int) Item);
47        }
48        void WriteExact(uint32_t Item) { Write((int)Item); }
49        void Write(int Item)
50        {
51                int32_t privItem = htonl(Item);
52                mrStream.Write(&privItem, sizeof(privItem));
53        }
54        void Write(int64_t Item)
55        {
56                int64_t privItem = box_hton64(Item);
57                mrStream.Write(&privItem, sizeof(privItem));
58        }
59        void WriteExact(uint64_t Item) { Write(Item); }
60        void Write(uint64_t Item)
61        {
62                uint64_t privItem = box_hton64(Item);
63                mrStream.Write(&privItem, sizeof(privItem));
64        }
65        void Write(uint8_t Item)
66        {
67                int privItem = Item;
68                Write(privItem);
69        }
70        void Write(const std::string &Item)
71        {
72                int size = Item.size();
73                Write(size);
74                mrStream.Write(Item.c_str(), size);
75        }
76        //
77        //
78        //
79        void Read(bool &rItemOut)
80        {
81                int privItem;
82                Read(privItem);
83
84                if (privItem)
85                {
86                        rItemOut = true;
87                }
88                else
89                {
90                        rItemOut = false;
91                }
92        }
93        void ReadExact(uint32_t &rItemOut) { Read((int&)rItemOut); }
94        void Read(int &rItemOut)
95        {
96                int32_t privItem;
97                if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), 0 /* not interested in bytes read if this fails */))
98                {
99                        THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead)
100                }
101                rItemOut = ntohl(privItem);
102        }
103        void Read(int64_t &rItemOut)
104        {
105                int64_t privItem;
106                if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), 0 /* not interested in bytes read if this fails */))
107                {
108                        THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead)
109                }
110                rItemOut = box_ntoh64(privItem);
111        }
112        void ReadExact(uint64_t &rItemOut) { Read(rItemOut); }
113        void Read(uint64_t &rItemOut)
114        {
115                uint64_t privItem;
116                if(!mrStream.ReadFullBuffer(&privItem, sizeof(privItem), 0 /* not interested in bytes read if this fails */))
117                {
118                        THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead)
119                }
120                rItemOut = box_ntoh64(privItem);
121        }
122        void Read(uint8_t &rItemOut)
123        {
124                int privItem;
125                Read(privItem);
126                rItemOut = privItem;
127        }
128        void Read(std::string &rItemOut)
129        {
130                int size;
131                Read(size);
132
133                // Assume most strings are relatively small
134                char buf[256];
135                if(size < (int) sizeof(buf))
136                {
137                        // Fetch rest of pPayload, relying on the Protocol to error on stupidly large sizes for us
138                        if(!mrStream.ReadFullBuffer(buf, size, 0 /* not interested in bytes read if this fails */, mTimeout))
139                        {
140                                THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead)
141                        }
142                        // assign to this string, storing the header and the extra payload
143                        rItemOut.assign(buf, size);
144                }
145                else
146                {
147                        // Block of memory to hold it
148                        MemoryBlockGuard<char*> dataB(size);
149                        char *ppayload = dataB;
150
151                        // Fetch rest of pPayload, relying on the Protocol to error on stupidly large sizes for us
152                        if(!mrStream.ReadFullBuffer(ppayload, size, 0 /* not interested in bytes read if this fails */, mTimeout))
153                        {
154                                THROW_EXCEPTION(CommonException, ArchiveBlockIncompleteRead)
155                        }
156                        // assign to this string, storing the header and the extra pPayload
157                        rItemOut.assign(ppayload, size);
158                }
159        }
160private:
161        IOStream &mrStream;
162        int mTimeout;
163};
164
165#endif // ARCHIVE__H
Note: See TracBrowser for help on using the repository browser.