source: nscp/include/arrayBuffer.cpp @ 7f9c823

0.4.00.4.10.4.2
Last change on this file since 7f9c823 was 7f9c823, checked in by Michael Medin <michael@…>, 4 years ago

First attempt at serious boostification.
NOTICE! This is NOT a complete edition, it build and runs but many features are disabled and/or broken.
But we have working, sockets and mutexes and conversion functions from boost inside now and more to come...
Also started to build with CMake since it works better then boost.build

  • Property mode set to 100644
File size: 11.6 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#include <arrayBuffer.h>
22#include <msvc_wrappers.h>
23
24/**
25 * Make a list out of a array of char arrays (arguments type)
26 * @param argLen Length of argument array
27 * @param *argument[] Argument array
28 * @return Argument wrapped as a list
29 */
30arrayBuffer::arrayList arrayBuffer::arrayBuffer2list(const unsigned int argLen, wchar_t *argument[]) {
31        arrayList ret;
32        int i=0;
33        for (unsigned int i=0;i<argLen;i++) {
34                std::wstring s = argument[i];
35                ret.push_back(s);
36        }
37        return ret;
38}
39/**
40* Create an arrayBuffer from a list.
41* This is the reverse of arrayBuffer2list.
42* <b>Notice</b> it is up to the caller to free the memory allocated in the returned buffer.
43*
44* @param lst A list to convert.
45* @param &argLen Write the length to this argument.
46* @return A pointer that is managed by the caller.
47*/
48arrayBuffer::arrayBuffer arrayBuffer::list2arrayBuffer(const arrayList lst, unsigned int &argLen) {
49        argLen = static_cast<unsigned int>(lst.size());
50        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[argLen];
51        arrayList::const_iterator it = lst.begin();
52        int i;
53        for (i=0;it!=lst.end();++it,i++) {
54                std::wstring::size_type alen = (*it).size();
55                arrayBuffer[i] = new wchar_t[alen+2];
56                wcsncpy_s(arrayBuffer[i], alen+2, (*it).c_str(), alen+1);
57        }
58        if (i != argLen)
59                throw ArrayBufferException(_T("Invalid length!"));
60        return arrayBuffer;
61}
62/**
63* Creates an empty arrayBuffer (only used to allow consistency)
64* @param &argLen [OUT] The length (items) of the arrayBuffer
65* @return The arrayBuffer
66*/
67arrayBuffer::arrayBuffer arrayBuffer::createEmptyArrayBuffer(unsigned int &argLen) {
68        argLen = 0;
69        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[0];
70        return arrayBuffer;
71}
72/**
73* Creates an arrayBuffer with N-elements
74* @param &argLen [IN OUT] The length (items) of the arrayBuffer
75* @return The arrayBuffer
76*/
77arrayBuffer::arrayBuffer arrayBuffer::createArrayBuffer(unsigned int &argLen) {
78        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[argLen];
79        for (unsigned int i=0;i<argLen;i++) {
80                arrayBuffer[i] = NULL;
81        }
82        return arrayBuffer;
83}
84/**
85* Joins an arrayBuffer back into a string
86* @param **argument The ArrayBuffer
87* @param argLen The length of the ArrayBuffer
88* @param join The char to use as separators when joining
89* @return The joined arrayBuffer
90*/
91std::wstring arrayBuffer::arrayBuffer2string(arrayBuffer::arrayBuffer argument, const unsigned int argLen, std::wstring join) {
92        std::wstring ret;
93        for (unsigned int i=0;i<argLen;i++) {
94                if (argument[i] != NULL) {
95                        ret += argument[i];
96                        if (i != argLen-1)
97                                ret += join;
98                }
99        }
100        return ret;
101}
102/**
103* Split a string into elements as a newly created arrayBuffer
104* @param buffer The CharArray to split along
105* @param splitChar The char to use as splitter
106* @param &argLen [OUT] The length of the Array
107* @return The arrayBuffer
108*/
109arrayBuffer::arrayBuffer arrayBuffer::split2arrayBuffer(const wchar_t* buffer, wchar_t splitChar, unsigned int &argLen) {
110        if (!buffer)
111                throw ArrayBufferException(_T("Invalid buffer specified!"));
112        argLen = 0;
113        const wchar_t *p = buffer;
114        if (!p[0]) {
115                return createEmptyArrayBuffer(argLen);
116        }
117        while (*p) {
118                if (*p == splitChar)
119                        argLen++;
120                p++;
121        }
122        argLen++;
123        wchar_t **arrayBuffer = new wchar_t*[argLen];
124        p = buffer;
125        for (unsigned int i=0;i<argLen;i++) {
126                const wchar_t *q = wcschr(p, (i<argLen-1)?splitChar:0);
127                unsigned int len = static_cast<int>(q-p);
128                arrayBuffer[i] = new wchar_t[len+1];
129                wcsncpy_s(arrayBuffer[i], len+1, p, len);
130                arrayBuffer[i][len] = 0;
131                p = ++q;
132        }
133        return arrayBuffer;
134}
135
136
137void arrayBuffer::set(arrayBuffer arrayBuffer, const unsigned int argLen, const unsigned int position, std::wstring argument) {
138        if (position >= argLen)
139                throw ArrayBufferException(_T("position is outside the buffer"));
140        delete [] arrayBuffer[position];
141        size_t len = argument.length();
142        arrayBuffer[position] = new wchar_t[len+2];
143        wcsncpy_s(arrayBuffer[position], len+1, argument.c_str(), len);
144        arrayBuffer[position][len] = 0;
145}
146
147/**
148 * Split a string into elements as a newly created arrayBuffer
149 * @param inBuf The CharArray to split along
150 * @param splitChar The char to use as splitter
151 * @param &argLen [OUT] The length of the Array
152 * @param escape [IN] Set to true to try to escape ":s ie. //token1 "token2 with space" token3//
153 * @return The arrayBuffer
154 */
155arrayBuffer::arrayBuffer arrayBuffer::split2arrayBuffer(const std::wstring inBuf, wchar_t splitChar, unsigned int &argLen, bool escape) {
156        if (inBuf.empty())
157                return createEmptyArrayBuffer(argLen);
158
159        std::wstring::size_type p1 = 0;
160        std::wstring::size_type p2 = 0;
161        std::list<std::wstring> token_list;
162        while (p1 != std::wstring::npos && p2 != std::wstring::npos) {
163                if (escape && inBuf[p1] == '\"') {
164                        p2 = inBuf.find('\"', p1+1);
165                        if (p2 != std::wstring::npos)
166                                p2 = inBuf.find(splitChar, p2);
167                } else {
168                        p2 = inBuf.find(splitChar, p1);
169                }
170                if (p2 == std::wstring::npos)
171                        p2 = inBuf.size();
172                if (p1 == p2 && p1 != inBuf.size()) {
173                        p1++;
174                        continue;
175                }
176                // p1 = start of "this token"
177                // p2 = end of "this token" (next split char)
178
179                if (p2<=p1)
180                        throw ArrayBufferException(_T("Invalid position"));
181                std::wstring token = inBuf.substr(p1,p2-p1);
182                if (escape && token[0] == '\"')
183                        token = token.substr(1);
184                if (escape && token[token.size()-1] == '\"')
185                        token = token.substr(0, token.size()-1);
186
187
188                token_list.push_back(token);
189                if (p2 < inBuf.size())
190                        p2++;
191                if (p2 == inBuf.size())
192                        p2 = std::wstring::npos;
193                p1 = p2;
194        }
195        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[token_list.size()];
196        argLen=0;
197        for (std::list<std::wstring>::const_iterator cit=token_list.begin();cit!=token_list.end();++cit) {
198                size_t len = (*cit).size();
199                wchar_t* token = new wchar_t[len+1];
200                wcsncpy_s(token, len+1, (*cit).c_str(), len);
201                arrayBuffer[argLen++] = token;
202        }
203        token_list.clear();
204        return arrayBuffer;
205/*
206
207                unsigned int len = static_cast<unsigned int>(p-l);
208                arrayBuffer[i] = new TCHAR[len+1];
209                wcsncpy_s(arrayBuffer[i], len+1, inBuf.substr(l,p).c_str(), len);
210                arrayBuffer[i][len] = 0;
211                if (p == std::wstring::npos)
212                        break;
213                l = ++p;
214                if (escape && l < inBuf.size() && inBuf[l] == '\"') {
215                        p = inBuf.find('\"', l+1);
216                        if (p != std::wstring::npos)
217                                p = inBuf.find(splitChar, p);
218                } else if (p < inBuf.size()) {
219                        p = inBuf.find(splitChar, p);
220                } else {
221                        p = std::wstring::npos;
222                }
223                */
224//      }
225
226/*
227
228        argLen = 1;
229        std::wstring::size_type p = inBuf.find(splitChar);
230        while (p != std::wstring::npos) {
231                argLen++;
232                p = inBuf.find(splitChar, p+1);
233        }
234        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[argLen];
235        if (escape && inBuf[0] == '\"') {
236                p = inBuf.find('\"');
237                if (p != std::wstring::npos)
238                        p = inBuf.find(splitChar, p);
239        } else {
240                p = inBuf.find(splitChar);
241        }
242        std::wstring::size_type l = 0;
243        for (unsigned int i=0;i<argLen;i++) {
244                if (p == std::wstring::npos)
245                        p = inBuf.size();
246                //              TCHAR *q = strchr(p, (i<argLen-1)?splitChar:0);
247                unsigned int len = static_cast<unsigned int>(p-l);
248                arrayBuffer[i] = new TCHAR[len+1];
249                wcsncpy_s(arrayBuffer[i], len+1, inBuf.substr(l,p).c_str(), len);
250                arrayBuffer[i][len] = 0;
251                if (p == std::wstring::npos)
252                        break;
253                l = ++p;
254                if (escape && l < inBuf.size() && inBuf[l] == '\"') {
255                        p = inBuf.find('\"', l+1);
256                        if (p != std::wstring::npos)
257                                p = inBuf.find(splitChar, p);
258                } else if (p < inBuf.size()) {
259                        p = inBuf.find(splitChar, p);
260                } else {
261                        p = std::wstring::npos;
262                }
263        }
264        */
265        //return arrayBuffer;
266}
267
268/**
269* Destroy an arrayBuffer.
270* The buffer should have been created with list2arrayBuffer.
271*
272* @param **argument
273* @param argLen
274*/
275void arrayBuffer::destroyArrayBuffer(arrayBuffer::arrayBuffer argument, const unsigned int argLen) {
276        for (unsigned int i=0;i<argLen;i++) {
277                delete [] argument[i];
278        }
279        delete [] argument;
280}
281
282
283
284#ifdef _DEBUG
285/**
286 * Test function for createEmptyArrayBuffer
287 */
288void arrayBuffer::test_createEmptyArrayBuffer() {
289        std::wcout << "arrayBuffer::test_createEmptyArrayBuffer() : ";
290        unsigned int argLen;
291        wchar_t ** c = createEmptyArrayBuffer(argLen);
292        if ((c) && (argLen == 0))
293                std::wcout << "Succeeded" << std::endl;
294        else
295                std::wcout << "Failed" << std::endl;
296        destroyArrayBuffer(c, argLen);
297}
298/**
299 * Test function for split2arrayBuffer
300 * @param buffer
301 * @param splitter
302 * @param OUT_argLen
303 */
304void arrayBuffer::test_split2arrayBuffer_str(std::wstring buffer, wchar_t splitter, int OUT_argLen) {
305        std::wcout << _T("arrayBuffer::test_split2arrayBuffer(") << buffer << _T(", ...) : ");
306        unsigned int argLen = 0;
307        wchar_t ** c = split2arrayBuffer(buffer, splitter, argLen);
308        if ((c) && (argLen == OUT_argLen))
309                std::wcout << _T("Succeeded") << std::endl;
310        else
311                std::wcout << _T("Failed |") << argLen << _T("=") << OUT_argLen << _T("]") << std::endl;
312        destroyArrayBuffer(c, argLen);
313}
314/**
315 * Test function for split2arrayBuffer
316 * @param buffer
317 * @param splitter
318 * @param OUT_argLen
319 */
320void arrayBuffer::test_split2arrayBuffer_char(wchar_t* buffer, wchar_t splitter, int OUT_argLen) {
321        std::wcout << _T("arrayBuffer::test_split2arrayBuffer(") << buffer << _T(", ...) : ");
322        unsigned int argLen = 0;
323        wchar_t ** c = split2arrayBuffer(buffer, splitter, argLen);
324        if ((c) && (argLen == OUT_argLen))
325                std::wcout << _T("Succeeded") << std::endl;
326        else
327                std::wcout << _T("Failed |") << argLen << _T("=") << OUT_argLen << _T("]") << std::endl;
328        destroyArrayBuffer(c, argLen);
329}
330
331/**
332 * Test function for ArrayBuffer
333 */
334void arrayBuffer::run_testArrayBuffer() {
335        test_createEmptyArrayBuffer();
336        test_split2arrayBuffer_str(_T(""), '&', 0);
337        test_split2arrayBuffer_str(_T("foo"), '&', 1);
338        test_split2arrayBuffer_str(_T("&"), '&', 2);
339        test_split2arrayBuffer_str(_T("foo&"), '&', 2);
340        test_split2arrayBuffer_str(_T("&foo&"), '&', 3);
341        test_split2arrayBuffer_str(_T("foo&bar"), '&', 2);
342        test_split2arrayBuffer_str(_T("foo&bar&test"), '&', 3);
343        test_split2arrayBuffer_str(_T("foo&&&"), '&', 4);
344
345        test_split2arrayBuffer_char(_T(""), '&', 0);
346        test_split2arrayBuffer_char(_T("foo"), '&', 1);
347        test_split2arrayBuffer_char(_T("&"), '&', 2);
348        test_split2arrayBuffer_char(_T("foo&"), '&', 2);
349        test_split2arrayBuffer_char(_T("&foo&"), '&', 3);
350        test_split2arrayBuffer_char(_T("foo&bar"), '&', 2);
351        test_split2arrayBuffer_char(_T("foo&bar&test"), '&', 3);
352        test_split2arrayBuffer_char(_T("foo&&&"), '&', 4);
353}
354#endif
Note: See TracBrowser for help on using the repository browser.