-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathcmnDataFunctionsString.cpp
140 lines (126 loc) · 4.91 KB
/
cmnDataFunctionsString.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
134
135
136
137
138
139
140
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
/*
Author(s): Anton Deguet
Created on: 2011-06-27
(C) Copyright 2011-2018 Johns Hopkins University (JHU), All Rights Reserved.
--- begin cisst license - do not edit ---
This software is provided "as is" under an open source license, with
no warranty. The complete license can be found in license.txt and
http://www.cisst.org/cisst/license.txt.
--- end cisst license ---
*/
#include <cisstCommon/cmnDataFunctionsString.h>
size_t cmnDataSerializeBinary(const std::string & data, char * buffer, size_t bufferSize)
{
// check that buffer is large enough to serialize
const size_t dataSize = cmnData<std::string>::SerializeBinaryByteSize(data);
if (bufferSize < dataSize) {
return 0;
}
// serialize length as a size_T object
const size_t length = data.size();
buffer += cmnData<size_t>::SerializeBinary(length, buffer, cmnData<size_t>::SerializeBinaryByteSize(0));
// serialize string itself
const size_t numberOfBytes = length * sizeof(std::string::value_type);
memcpy(buffer, data.data(), length * numberOfBytes);
bufferSize -= numberOfBytes;
return dataSize;
}
size_t cmnDataDeSerializeBinary(std::string & data, const char * buffer, size_t bufferSize,
const cmnDataFormat & localFormat,
const cmnDataFormat & remoteFormat)
{
size_t stringSize;
size_t byteRead = cmnData<size_t>::DeSerializeBinary(stringSize, buffer, bufferSize,
localFormat, remoteFormat);
// make sure we can at least get a string size
if (byteRead == 0) {
return 0;
}
// if the string itself was empty, return
if (stringSize == 0) {
data.clear();
return byteRead;
}
// make sure the buffer has the whole string
const size_t sizeOfData = stringSize * sizeof(std::string::value_type);
if (bufferSize < sizeOfData) {
return 0;
}
// get the string characters
data.resize(stringSize);
data.assign(buffer + byteRead, stringSize);
bufferSize -= sizeOfData;
return byteRead + sizeOfData;
}
void cmnDataSerializeBinary(const std::string & data,
std::ostream & outputStream)
CISST_THROW(std::runtime_error)
{
cmnData<size_t>::SerializeBinary(data.size(), outputStream);
outputStream.write(data.data(), data.size());
if (outputStream.fail()) {
cmnThrow("cmnDataSerializeBinary(std::string): error occured with std::ostream::write");
}
}
void cmnDataDeSerializeBinary(std::string & data,
std::istream & inputStream,
const cmnDataFormat & localFormat,
const cmnDataFormat & remoteFormat)
CISST_THROW(std::runtime_error)
{
size_t size;
// retrieve size of string
cmnData<size_t>::DeSerializeBinary(size, inputStream, localFormat, remoteFormat);
data.resize(size);
inputStream.read(const_cast<char *>(data.data()), size);
if (inputStream.fail()) {
cmnThrow("cmnDataDeSerializeBinary(std::string): error occured with std::istream::read");
}
}
void cmnDataSerializeText(const std::string & data,
std::ostream & outputStream,
const char delimiter)
CISST_THROW(std::runtime_error)
{
const std::string::const_iterator end = data.end();
std::string::const_iterator iter = data.begin();
for (; iter != end; ++iter) {
if ((*iter == delimiter)
|| (*iter == '\\')) {
outputStream << '\\';
}
outputStream << *iter;
}
}
void cmnDataDeSerializeText(std::string & data,
std::istream & inputStream,
const char delimiter)
CISST_THROW(std::runtime_error)
{
// reset string content
data = "";
bool lastCharWasEscape = false;
char newChar;
// seek around to figure how many characters are left in input stream
std::streampos currentPosition = inputStream.tellg();
inputStream.seekg(0, inputStream.end);
std::streamoff charactersLeft = inputStream.tellg() - currentPosition;
inputStream.seekg(currentPosition);
// keep reading as long as we don't run into comma
while (charactersLeft > 0 // there is still something to read
&& ((inputStream.peek() != delimiter) // we are not finding the delimiter
|| lastCharWasEscape) // unless the delimiter has been "escaped"
) {
inputStream.get(newChar);
--charactersLeft;
if ((newChar == '\\')
&& !lastCharWasEscape) {
lastCharWasEscape = true;
} else {
lastCharWasEscape = false;
data.append(1, newChar);
}
}
}