source: nscp/include/arrayBuffer.cpp @ 1ecd26f

0.4.00.4.10.4.2
Last change on this file since 1ecd26f was 1ecd26f, checked in by Michael Medin <michael@…>, 2 years ago

syncronized streams between 0.4.x and 0.3.x as well as improed the CMAke build *alot*

  • Property mode set to 100644
File size: 12.1 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 <types.hpp>
22#include <arrayBuffer.h>
23#include <msvc_wrappers.h>
24
25/**
26 * Make a list out of a array of char arrays (arguments type)
27 * @param argLen Length of argument array
28 * @param *argument[] Argument array
29 * @return Argument wrapped as a list
30 */
31arrayBuffer::arrayList arrayBuffer::arrayBuffer2list(const unsigned int argLen, wchar_t *argument[]) {
32        arrayList ret;
33        int i=0;
34        for (unsigned int i=0;i<argLen;i++) {
35                std::wstring s = argument[i];
36                ret.push_back(s);
37        }
38        return ret;
39}
40/**
41 * Make a list out of a array of char arrays (arguments type)
42 * @param argLen Length of argument array
43 * @param *argument[] Argument array
44 * @return Argument wrapped as a list
45 */
46arrayBuffer::arrayVector arrayBuffer::arrayBuffer2vector(const unsigned int argLen, wchar_t *argument[]) {
47        arrayVector ret;
48        int i=0;
49        for (unsigned int i=0;i<argLen;i++) {
50                std::wstring s = argument[i];
51                ret.push_back(s);
52        }
53        return ret;
54}
55/**
56* Create an arrayBuffer from a list.
57* This is the reverse of arrayBuffer2list.
58* <b>Notice</b> it is up to the caller to free the memory allocated in the returned buffer.
59*
60* @param lst A list to convert.
61* @param &argLen Write the length to this argument.
62* @return A pointer that is managed by the caller.
63*/
64arrayBuffer::arrayBuffer arrayBuffer::list2arrayBuffer(const arrayList lst, unsigned int &argLen) {
65        argLen = static_cast<unsigned int>(lst.size());
66        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[argLen];
67        arrayList::const_iterator it = lst.begin();
68        int i;
69        for (i=0;it!=lst.end();++it,i++) {
70                std::wstring::size_type alen = (*it).size();
71                arrayBuffer[i] = new wchar_t[alen+2];
72                wcsncpy_s(arrayBuffer[i], alen+2, (*it).c_str(), alen+1);
73        }
74        if (i != argLen)
75                throw ArrayBufferException(_T("Invalid length!"));
76        return arrayBuffer;
77}
78/**
79* Creates an empty arrayBuffer (only used to allow consistency)
80* @param &argLen [OUT] The length (items) of the arrayBuffer
81* @return The arrayBuffer
82*/
83arrayBuffer::arrayBuffer arrayBuffer::createEmptyArrayBuffer(unsigned int &argLen) {
84        argLen = 0;
85        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[0];
86        return arrayBuffer;
87}
88/**
89* Creates an arrayBuffer with N-elements
90* @param &argLen [IN OUT] The length (items) of the arrayBuffer
91* @return The arrayBuffer
92*/
93arrayBuffer::arrayBuffer arrayBuffer::createArrayBuffer(unsigned int &argLen) {
94        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[argLen];
95        for (unsigned int i=0;i<argLen;i++) {
96                arrayBuffer[i] = NULL;
97        }
98        return arrayBuffer;
99}
100/**
101* Joins an arrayBuffer back into a string
102* @param **argument The ArrayBuffer
103* @param argLen The length of the ArrayBuffer
104* @param join The char to use as separators when joining
105* @return The joined arrayBuffer
106*/
107std::wstring arrayBuffer::arrayBuffer2string(arrayBuffer::arrayBuffer argument, const unsigned int argLen, std::wstring join) {
108        std::wstring ret;
109        for (unsigned int i=0;i<argLen;i++) {
110                if (argument[i] != NULL) {
111                        ret += argument[i];
112                        if (i != argLen-1)
113                                ret += join;
114                }
115        }
116        return ret;
117}
118/**
119* Split a string into elements as a newly created arrayBuffer
120* @param buffer The CharArray to split along
121* @param splitChar The char to use as splitter
122* @param &argLen [OUT] The length of the Array
123* @return The arrayBuffer
124*/
125arrayBuffer::arrayBuffer arrayBuffer::split2arrayBuffer(const wchar_t* buffer, wchar_t splitChar, unsigned int &argLen) {
126        if (!buffer)
127                throw ArrayBufferException(_T("Invalid buffer specified!"));
128        argLen = 0;
129        const wchar_t *p = buffer;
130        if (!p[0]) {
131                return createEmptyArrayBuffer(argLen);
132        }
133        while (*p) {
134                if (*p == splitChar)
135                        argLen++;
136                p++;
137        }
138        argLen++;
139        wchar_t **arrayBuffer = new wchar_t*[argLen];
140        p = buffer;
141        for (unsigned int i=0;i<argLen;i++) {
142                const wchar_t *q = wcschr(p, (i<argLen-1)?splitChar:0);
143                unsigned int len = static_cast<int>(q-p);
144                arrayBuffer[i] = new wchar_t[len+1];
145                wcsncpy_s(arrayBuffer[i], len+1, p, len);
146                arrayBuffer[i][len] = 0;
147                p = ++q;
148        }
149        return arrayBuffer;
150}
151
152
153void arrayBuffer::set(arrayBuffer arrayBuffer, const unsigned int argLen, const unsigned int position, std::wstring argument) {
154        if (position >= argLen)
155                throw ArrayBufferException(_T("position is outside the buffer"));
156        delete [] arrayBuffer[position];
157        size_t len = argument.length();
158        arrayBuffer[position] = new wchar_t[len+2];
159        wcsncpy_s(arrayBuffer[position], len+1, argument.c_str(), len);
160        arrayBuffer[position][len] = 0;
161}
162
163/**
164 * Split a string into elements as a newly created arrayBuffer
165 * @param inBuf The CharArray to split along
166 * @param splitChar The char to use as splitter
167 * @param &argLen [OUT] The length of the Array
168 * @param escape [IN] Set to true to try to escape ":s ie. //token1 "token2 with space" token3//
169 * @return The arrayBuffer
170 */
171arrayBuffer::arrayBuffer arrayBuffer::split2arrayBuffer(const std::wstring inBuf, wchar_t splitChar, unsigned int &argLen, bool escape) {
172        if (inBuf.empty())
173                return createEmptyArrayBuffer(argLen);
174
175        std::wstring::size_type p1 = 0;
176        std::wstring::size_type p2 = 0;
177        std::list<std::wstring> token_list;
178        while (p1 != std::wstring::npos && p2 != std::wstring::npos) {
179                if (escape && inBuf[p1] == '\"') {
180                        p2 = inBuf.find('\"', p1+1);
181                        if (p2 != std::wstring::npos)
182                                p2 = inBuf.find(splitChar, p2);
183                } else {
184                        p2 = inBuf.find(splitChar, p1);
185                }
186                if (p2 == std::wstring::npos)
187                        p2 = inBuf.size();
188                if (p1 == p2 && p1 != inBuf.size()) {
189                        p1++;
190                        continue;
191                }
192                // p1 = start of "this token"
193                // p2 = end of "this token" (next split char)
194
195                if (p2<=p1)
196                        throw ArrayBufferException(_T("Invalid position"));
197                std::wstring token = inBuf.substr(p1,p2-p1);
198                if (escape && token[0] == '\"')
199                        token = token.substr(1);
200                if (escape && token[token.size()-1] == '\"')
201                        token = token.substr(0, token.size()-1);
202
203
204                token_list.push_back(token);
205                if (p2 < inBuf.size())
206                        p2++;
207                if (p2 == inBuf.size())
208                        p2 = std::wstring::npos;
209                p1 = p2;
210        }
211        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[token_list.size()];
212        argLen=0;
213        for (std::list<std::wstring>::const_iterator cit=token_list.begin();cit!=token_list.end();++cit) {
214                size_t len = (*cit).size();
215                wchar_t* token = new wchar_t[len+1];
216                wcsncpy_s(token, len+1, (*cit).c_str(), len);
217                arrayBuffer[argLen++] = token;
218        }
219        token_list.clear();
220        return arrayBuffer;
221/*
222
223                unsigned int len = static_cast<unsigned int>(p-l);
224                arrayBuffer[i] = new TCHAR[len+1];
225                wcsncpy_s(arrayBuffer[i], len+1, inBuf.substr(l,p).c_str(), len);
226                arrayBuffer[i][len] = 0;
227                if (p == std::wstring::npos)
228                        break;
229                l = ++p;
230                if (escape && l < inBuf.size() && inBuf[l] == '\"') {
231                        p = inBuf.find('\"', l+1);
232                        if (p != std::wstring::npos)
233                                p = inBuf.find(splitChar, p);
234                } else if (p < inBuf.size()) {
235                        p = inBuf.find(splitChar, p);
236                } else {
237                        p = std::wstring::npos;
238                }
239                */
240//      }
241
242/*
243
244        argLen = 1;
245        std::wstring::size_type p = inBuf.find(splitChar);
246        while (p != std::wstring::npos) {
247                argLen++;
248                p = inBuf.find(splitChar, p+1);
249        }
250        arrayBuffer::arrayBuffer arrayBuffer = new arrayBuffer::arrayBufferItem[argLen];
251        if (escape && inBuf[0] == '\"') {
252                p = inBuf.find('\"');
253                if (p != std::wstring::npos)
254                        p = inBuf.find(splitChar, p);
255        } else {
256                p = inBuf.find(splitChar);
257        }
258        std::wstring::size_type l = 0;
259        for (unsigned int i=0;i<argLen;i++) {
260                if (p == std::wstring::npos)
261                        p = inBuf.size();
262                //              TCHAR *q = strchr(p, (i<argLen-1)?splitChar:0);
263                unsigned int len = static_cast<unsigned int>(p-l);
264                arrayBuffer[i] = new TCHAR[len+1];
265                wcsncpy_s(arrayBuffer[i], len+1, inBuf.substr(l,p).c_str(), len);
266                arrayBuffer[i][len] = 0;
267                if (p == std::wstring::npos)
268                        break;
269                l = ++p;
270                if (escape && l < inBuf.size() && inBuf[l] == '\"') {
271                        p = inBuf.find('\"', l+1);
272                        if (p != std::wstring::npos)
273                                p = inBuf.find(splitChar, p);
274                } else if (p < inBuf.size()) {
275                        p = inBuf.find(splitChar, p);
276                } else {
277                        p = std::wstring::npos;
278                }
279        }
280        */
281        //return arrayBuffer;
282}
283
284/**
285* Destroy an arrayBuffer.
286* The buffer should have been created with list2arrayBuffer.
287*
288* @param **argument
289* @param argLen
290*/
291void arrayBuffer::destroyArrayBuffer(arrayBuffer::arrayBuffer argument, const unsigned int argLen) {
292        for (unsigned int i=0;i<argLen;i++) {
293                delete [] argument[i];
294        }
295        delete [] argument;
296}
297
298
299
300#ifdef _DEBUG
301/**
302 * Test function for createEmptyArrayBuffer
303 */
304void arrayBuffer::test_createEmptyArrayBuffer() {
305        std::wcout << "arrayBuffer::test_createEmptyArrayBuffer() : ";
306        unsigned int argLen;
307        wchar_t ** c = createEmptyArrayBuffer(argLen);
308        if ((c) && (argLen == 0))
309                std::wcout << "Succeeded" << std::endl;
310        else
311                std::wcout << "Failed" << 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_str(std::wstring 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 * Test function for split2arrayBuffer
332 * @param buffer
333 * @param splitter
334 * @param OUT_argLen
335 */
336void arrayBuffer::test_split2arrayBuffer_char(wchar_t* buffer, wchar_t splitter, int OUT_argLen) {
337        std::wcout << _T("arrayBuffer::test_split2arrayBuffer(") << buffer << _T(", ...) : ");
338        unsigned int argLen = 0;
339        wchar_t ** c = split2arrayBuffer(buffer, splitter, argLen);
340        if ((c) && (argLen == OUT_argLen))
341                std::wcout << _T("Succeeded") << std::endl;
342        else
343                std::wcout << _T("Failed |") << argLen << _T("=") << OUT_argLen << _T("]") << std::endl;
344        destroyArrayBuffer(c, argLen);
345}
346
347/**
348 * Test function for ArrayBuffer
349 */
350void arrayBuffer::run_testArrayBuffer() {
351        test_createEmptyArrayBuffer();
352        test_split2arrayBuffer_str(_T(""), '&', 0);
353        test_split2arrayBuffer_str(_T("foo"), '&', 1);
354        test_split2arrayBuffer_str(_T("&"), '&', 2);
355        test_split2arrayBuffer_str(_T("foo&"), '&', 2);
356        test_split2arrayBuffer_str(_T("&foo&"), '&', 3);
357        test_split2arrayBuffer_str(_T("foo&bar"), '&', 2);
358        test_split2arrayBuffer_str(_T("foo&bar&test"), '&', 3);
359        test_split2arrayBuffer_str(_T("foo&&&"), '&', 4);
360
361        test_split2arrayBuffer_char(_T(""), '&', 0);
362        test_split2arrayBuffer_char(_T("foo"), '&', 1);
363        test_split2arrayBuffer_char(_T("&"), '&', 2);
364        test_split2arrayBuffer_char(_T("foo&"), '&', 2);
365        test_split2arrayBuffer_char(_T("&foo&"), '&', 3);
366        test_split2arrayBuffer_char(_T("foo&bar"), '&', 2);
367        test_split2arrayBuffer_char(_T("foo&bar&test"), '&', 3);
368        test_split2arrayBuffer_char(_T("foo&&&"), '&', 4);
369}
370#endif
Note: See TracBrowser for help on using the repository browser.