This repository has been archived by the owner on Sep 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
tokenizedstream.cpp
133 lines (107 loc) · 3.67 KB
/
tokenizedstream.cpp
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
// Copyright (C) 2011 Mostphotos AB
//
// Author(s):
// Andreas Andersen <andreas@mostphotos.com>
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or (at
// your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License (COPYING.txt) for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "tokenizedstream.h"
#include <boost/regex.h>
#include <iostream>
#include "exception.h"
#include "serverexception.h"
using namespace std;
typedef boost::asio::buffers_iterator<
boost::asio::streambuf::const_buffers_type> boost_iterator;
std::pair<boost_iterator, bool> match_token_delimiter(boost_iterator begin, boost_iterator end) {
boost_iterator i = begin;
while (i != end) {
switch(*i++) {
case ' ':
case '\r':
case '\n':
return std::make_pair(i, true);
default:
continue;
}
}
return std::make_pair(i, false);
}
Beanstalkpp::TokenizedStream::TokenizedStream(boost::asio::ip::tcp::socket &s):
socket(s) {
}
std::string Beanstalkpp::TokenizedStream::nextString() {
boost::system::error_code error;
string line;
boost::asio::read_until(
this->socket, this->socketBuffer, match_token_delimiter, error
);
if(error && error != boost::asio::error::eof)
throw ServerException(ServerException::BAD_FORMAT, "Unable to read from socket");
istream strResponse(&this->socketBuffer);
strResponse >> line;
return line;
}
void Beanstalkpp::TokenizedStream::expectString(const std::string& expected) {
string s = this->nextString();
if(s.compare(expected) != 0)
throw ServerException(ServerException::BAD_FORMAT, "Expected '" + expected + "' but got: " + s);
}
unsigned int Beanstalkpp::TokenizedStream::expectInt() {
string s = this->nextString();
unsigned int ret;
istringstream stream(s);
if(!(stream >> ret))
throw ServerException(ServerException::BAD_FORMAT, "Expected integer but got: " + s);
return ret;
}
uint64_t Beanstalkpp::TokenizedStream::expectULL() {
string s = this->nextString();
uint64_t ret;
istringstream stream(s);
if(!(stream >> ret))
throw ServerException(ServerException::BAD_FORMAT, "Expected unsigned long long but got: " + s);
return ret;
}
void Beanstalkpp::TokenizedStream::expectEol() {
char *buf = this->readChunk(2);
try {
if(buf[0] != '\r') throw ServerException(ServerException::BAD_FORMAT, "Expected \\r\\n");
if(buf[1] != '\n') throw ServerException(ServerException::BAD_FORMAT, "Expected \\r\\n");
delete[] buf;
} catch(...) {
delete[] buf;
throw;
}
}
char* Beanstalkpp::TokenizedStream::readChunk ( size_t bytes ) {
char *buf = new char[bytes];
char *bufp = buf;
size_t read = 0, totalRead = 0;
while(totalRead < bytes) {
size_t avail = this->socketBuffer.in_avail();
if(avail == 0) {
boost::asio::read(
this->socket, this->socketBuffer, boost::asio::transfer_at_least(bytes - totalRead)
);
}
read = this->socketBuffer.sgetn(bufp, bytes - read);
if(read == 0)
throw ServerException(ServerException::BAD_FORMAT, "Got 0 bytes from the server");
bufp += read;
totalRead += read;
}
return buf;
}