VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/clipboard-helper.cpp@ 7073

Last change on this file since 7073 was 7073, checked in by vboxsync, 17 years ago

Added support for the clipboard on Mac OS X hosts. Currently unicode text can be
transfered from and to the host/guest. I'm also separated some functions of linux.cpp
in a separate clipboard-helper.cpp for reuse in the mac parts.

  • Property svn:keywords set to Date Revision Author Id
File size: 7.8 KB
Line 
1/** @file
2 *
3 * Shared Clipboard:
4 * Some helper function for converting between the various eol.
5 */
6
7/*
8 * Copyright (C) 2006-2008 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "clipboard-helper.h"
20#include "VBox/log.h"
21#include <iprt/assert.h>
22
23int vboxClipboardUtf16GetWinSize(PRTUTF16 pu16Src, size_t cwSrc, size_t *pcwDest)
24{
25 size_t cwDest, i;
26
27 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc));
28 if (pu16Src == 0)
29 {
30 LogRel(("vboxClipboardUtf16GetWinSize: received a null Utf16 string, returning VERR_INVALID_PARAMETER\n"));
31 AssertReturn(pu16Src != 0, VERR_INVALID_PARAMETER);
32 }
33 /* We only take little endian Utf16 */
34 if (pu16Src[0] == UTF16BEMARKER)
35 {
36 LogRel(("vboxClipboardUtf16GetWinSize: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
37 AssertReturn(pu16Src[0] != UTF16BEMARKER, VERR_INVALID_PARAMETER);
38 }
39 if (cwSrc == 0)
40 {
41 *pcwDest = 0;
42 LogFlowFunc(("empty source string, returning\n"));
43 return VINF_SUCCESS;
44 }
45 cwDest = 0;
46 /* Calculate the size of the destination text string. */
47 /* Is this Utf16 or Utf16-LE? */
48 for (i = (pu16Src[0] == UTF16LEMARKER ? 1 : 0); i < cwSrc; ++i, ++cwDest)
49 {
50 if (pu16Src[i] == LINEFEED)
51 ++cwDest;
52 if (pu16Src[i] == 0)
53 {
54 /* Don't count this, as we do so below. */
55 break;
56 }
57 }
58 /* Count the terminating null byte. */
59 ++cwDest;
60 LogFlowFunc(("returning VINF_SUCCESS, %d 16bit words\n", cwDest));
61 *pcwDest = cwDest;
62 return VINF_SUCCESS;
63}
64
65int vboxClipboardUtf16LinToWin(PRTUTF16 pu16Src, size_t cwSrc, PRTUTF16 pu16Dest,
66 size_t cwDest)
67{
68 size_t i, j;
69 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc));
70 if (!VALID_PTR(pu16Src) || !VALID_PTR(pu16Dest))
71 {
72 LogRel(("vboxClipboardUtf16LinToWin: received an invalid pointer, pu16Src=%p, pu16Dest=%p, returning VERR_INVALID_PARAMETER\n", pu16Src, pu16Dest));
73 AssertReturn(VALID_PTR(pu16Src) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER);
74 }
75 /* We only take little endian Utf16 */
76 if (pu16Src[0] == UTF16BEMARKER)
77 {
78 LogRel(("vboxClipboardUtf16LinToWin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
79 AssertReturn(pu16Src[0] != UTF16BEMARKER, VERR_INVALID_PARAMETER);
80 }
81 if (cwSrc == 0)
82 {
83 if (cwDest == 0)
84 {
85 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
86 return VERR_BUFFER_OVERFLOW;
87 }
88 pu16Dest[0] = 0;
89 LogFlowFunc(("empty source string, returning\n"));
90 return VINF_SUCCESS;
91 }
92 /* Don't copy the endian marker. */
93 for (i = (pu16Src[0] == UTF16LEMARKER ? 1 : 0), j = 0; i < cwSrc; ++i, ++j)
94 {
95 /* Don't copy the null byte, as we add it below. */
96 if (pu16Src[i] == 0)
97 break;
98 if (j == cwDest)
99 {
100 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
101 return VERR_BUFFER_OVERFLOW;
102 }
103 if (pu16Src[i] == LINEFEED)
104 {
105 pu16Dest[j] = CARRIAGERETURN;
106 ++j;
107 if (j == cwDest)
108 {
109 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
110 return VERR_BUFFER_OVERFLOW;
111 }
112 }
113 pu16Dest[j] = pu16Src[i];
114 }
115 /* Add the trailing null. */
116 if (j == cwDest)
117 {
118 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
119 return VERR_BUFFER_OVERFLOW;
120 }
121 pu16Dest[j] = 0;
122 LogFlowFunc(("rc=VINF_SUCCESS, pu16Dest=%ls\n", pu16Dest));
123 return VINF_SUCCESS;
124}
125
126int vboxClipboardUtf16GetLinSize(PRTUTF16 pu16Src, size_t cwSrc, size_t *pcwDest)
127{
128 size_t cwDest;
129
130 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u\n", cwSrc, pu16Src, cwSrc));
131 if (!VALID_PTR(pu16Src))
132 {
133 LogRel(("vboxClipboardUtf16GetLinSize: received an invalid Utf16 string %p. Returning VERR_INVALID_PARAMETER.\n", pu16Src));
134 AssertReturn(VALID_PTR(pu16Src), VERR_INVALID_PARAMETER);
135 }
136 /* We only take little endian Utf16 */
137 if (pu16Src[0] == UTF16BEMARKER)
138 {
139 LogRel(("vboxClipboardUtf16GetLinSize: received a big endian Utf16 string. Returning VERR_INVALID_PARAMETER.\n"));
140 AssertReturn(pu16Src[0] != UTF16BEMARKER, VERR_INVALID_PARAMETER);
141 }
142 if (cwSrc == 0)
143 {
144 LogFlowFunc(("empty source string, returning VINF_SUCCESS\n"));
145 *pcwDest = 0;
146 return VINF_SUCCESS;
147 }
148 /* Calculate the size of the destination text string. */
149 /* Is this Utf16 or Utf16-LE? */
150 if (pu16Src[0] == UTF16LEMARKER)
151 cwDest = 0;
152 else
153 cwDest = 1;
154 for (size_t i = 0; i < cwSrc; ++i, ++cwDest)
155 {
156 if ( (i + 1 < cwSrc)
157 && (pu16Src[i] == CARRIAGERETURN)
158 && (pu16Src[i + 1] == LINEFEED))
159 {
160 ++i;
161 }
162 if (pu16Src[i] == 0)
163 {
164 break;
165 }
166 }
167 /* Terminating zero */
168 ++cwDest;
169 LogFlowFunc(("returning %d\n", cwDest));
170 *pcwDest = cwDest;
171 return VINF_SUCCESS;
172}
173
174int vboxClipboardUtf16WinToLin(PRTUTF16 pu16Src, size_t cwSrc, PRTUTF16 pu16Dest,
175 size_t cwDest)
176{
177 size_t cwDestPos;
178
179 LogFlowFunc(("pu16Src=%.*ls, cwSrc=%u, pu16Dest=%p, cwDest=%u\n",
180 cwSrc, pu16Src, cwSrc, pu16Dest, cwDest));
181 /* A buffer of size 0 may not be an error, but it is not a good idea either. */
182 Assert(cwDest > 0);
183 if (!VALID_PTR(pu16Src) || !VALID_PTR(pu16Dest))
184 {
185 LogRel(("vboxClipboardUtf16WinToLin: received an invalid ptr, pu16Src=%p, pu16Dest=%p, returning VERR_INVALID_PARAMETER\n", pu16Src, pu16Dest));
186 AssertReturn(VALID_PTR(pu16Src) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER);
187 }
188 /* We only take little endian Utf16 */
189 if (pu16Src[0] == UTF16BEMARKER)
190 {
191 LogRel(("vboxClipboardUtf16WinToLin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
192 AssertMsgFailedReturn(("received a big endian string\n"), VERR_INVALID_PARAMETER);
193 }
194 if (cwDest == 0)
195 {
196 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
197 return VERR_BUFFER_OVERFLOW;
198 }
199 if (cwSrc == 0)
200 {
201 pu16Dest[0] = 0;
202 LogFlowFunc(("received empty string. Returning VINF_SUCCESS\n"));
203 return VINF_SUCCESS;
204 }
205 /* Prepend the Utf16 byte order marker if it is missing. */
206 if (pu16Src[0] == UTF16LEMARKER)
207 {
208 cwDestPos = 0;
209 }
210 else
211 {
212 pu16Dest[0] = UTF16LEMARKER;
213 cwDestPos = 1;
214 }
215 for (size_t i = 0; i < cwSrc; ++i, ++cwDestPos)
216 {
217 if (pu16Src[i] == 0)
218 {
219 break;
220 }
221 if (cwDestPos == cwDest)
222 {
223 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
224 return VERR_BUFFER_OVERFLOW;
225 }
226 if ( (i + 1 < cwSrc)
227 && (pu16Src[i] == CARRIAGERETURN)
228 && (pu16Src[i + 1] == LINEFEED))
229 {
230 ++i;
231 }
232 pu16Dest[cwDestPos] = pu16Src[i];
233 }
234 /* Terminating zero */
235 if (cwDestPos == cwDest)
236 {
237 LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
238 return VERR_BUFFER_OVERFLOW;
239 }
240 pu16Dest[cwDestPos] = 0;
241 LogFlowFunc(("set string %ls. Returning\n", pu16Dest + 1));
242 return VINF_SUCCESS;
243}
244
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette