forked from artyom-beilis/cppcms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharchive.cpp
More file actions
144 lines (118 loc) · 2.61 KB
/
archive.cpp
File metadata and controls
144 lines (118 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// See accompanying file COPYING.TXT file for licensing details.
//
///////////////////////////////////////////////////////////////////////////////
#define CPPCMS_SOURCE
#include <cppcms/serialization_classes.h>
#include <cppcms/cstdint.h>
#include <string.h>
namespace cppcms {
struct archive::_data {};
archive::archive() :
ptr_(0),
mode_(save_to_archive)
{
}
archive::archive(archive const &other) :
buffer_(other.buffer_),
ptr_(other.ptr_),
mode_(other.mode_)
{
}
archive::archive(archive &&other) :
buffer_(std::move(other.buffer_)),
ptr_(std::move(other.ptr_)),
mode_(std::move(other.mode_))
{
}
archive &archive::operator=(archive &&other)
{
if(this!=&other) {
buffer_=std::move(other.buffer_);
ptr_ = other.ptr_;
mode_=other.mode_;
}
return *this;
}
archive const &archive::operator=(archive const &other)
{
if(this!=&other) {
buffer_=other.buffer_;
ptr_ = other.ptr_;
mode_=other.mode_;
}
return *this;
}
archive::~archive()
{
}
void archive::reserve(size_t n)
{
buffer_.reserve(n);
}
void archive::write_chunk(void const *begin,size_t len)
{
uint32_t size = len;
buffer_.append(reinterpret_cast<char *>(&size),4);
buffer_.append(reinterpret_cast<char const *>(begin),len);
}
void archive::read_chunk(void *begin,size_t len)
{
size_t next = next_chunk_size();
if(next!=len)
throw archive_error("Invalid block length");
ptr_+=4;
memcpy(begin,buffer_.c_str()+ptr_,len);
ptr_+=len;
}
size_t archive::next_chunk_size()
{
uint32_t size=0;
if(eof())
throw archive_error("At end of archive");
if(buffer_.size() - ptr_ < 4) {
throw archive_error("Invalid archive format");
}
memcpy(&size,buffer_.c_str() + ptr_,4);
if(ptr_ + size < ptr_ || ptr_ + size >=buffer_.size())
throw archive_error("Invalid archive_format");
return size;
}
bool archive::eof()
{
return ptr_ >= buffer_.size();
}
std::string archive::read_chunk_as_string()
{
size_t size = next_chunk_size();
std::string result(buffer_.c_str() + ptr_ + 4,size);
ptr_ +=4+size;
return result;
}
archive::mode_type archive::mode()
{
return mode_;
}
void archive::mode(archive::mode_type m)
{
mode_ = m;
ptr_ = 0;
}
void archive::reset()
{
ptr_ = 0;
}
std::string archive::str()
{
return buffer_;
}
void archive::str(std::string const &str)
{
buffer_ = str;
mode_ = load_from_archive;
ptr_ = 0;
}
} // cppcms