xref: /OK3568_Linux_fs/external/xserver/hw/xwin/winclipboard/textconv.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
3  *
4  *Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  *"Software"), to deal in the Software without restriction, including
7  *without limitation the rights to use, copy, modify, merge, publish,
8  *distribute, sublicense, and/or sell copies of the Software, and to
9  *permit persons to whom the Software is furnished to do so, subject to
10  *the following conditions:
11  *
12  *The above copyright notice and this permission notice shall be
13  *included in all copies or substantial portions of the Software.
14  *
15  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
19  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  *Except as contained in this notice, the name of Harold L Hunt II
24  *shall not be used in advertising or otherwise to promote the sale, use
25  *or other dealings in this Software without prior written authorization
26  *from Harold L Hunt II.
27  *
28  * Authors:	Harold L Hunt II
29  */
30 
31 #ifdef HAVE_XWIN_CONFIG_H
32 #include <xwin-config.h>
33 #endif
34 
35 /*
36  * Including any server header might define the macro _XSERVER64 on 64 bit machines.
37  * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
38  * So let's undef that macro if necessary.
39  */
40 #ifdef _XSERVER64
41 #undef _XSERVER64
42 #endif
43 
44 #include <stdlib.h>
45 #include "internal.h"
46 
47 /*
48  * Convert \r\n to \n
49  *
50  * NOTE: This was heavily inspired by, Cygwin's
51  * winsup/cygwin/fhandler.cc/fhandler_base::read ()
52  */
53 
54 void
winClipboardDOStoUNIX(char * pszSrc,int iLength)55 winClipboardDOStoUNIX(char *pszSrc, int iLength)
56 {
57     char *pszDest = pszSrc;
58     char *pszEnd = pszSrc + iLength;
59 
60     /* Loop until the last character */
61     while (pszSrc < pszEnd) {
62         /* Copy the current source character to current destination character */
63         *pszDest = *pszSrc;
64 
65         /* Advance to the next source character */
66         pszSrc++;
67 
68         /* Don't advance the destination character if we need to drop an \r */
69         if (*pszDest != '\r' || *pszSrc != '\n')
70             pszDest++;
71     }
72 
73     /* Move the terminating null */
74     *pszDest = '\0';
75 }
76 
77 /*
78  * Convert \n to \r\n
79  */
80 
81 void
winClipboardUNIXtoDOS(char ** ppszData,int iLength)82 winClipboardUNIXtoDOS(char **ppszData, int iLength)
83 {
84     int iNewlineCount = 0;
85     char *pszSrc = *ppszData;
86     char *pszEnd = pszSrc + iLength;
87     char *pszDest = NULL, *pszDestBegin = NULL;
88 
89     winDebug("UNIXtoDOS () - Original data:'%s'\n", *ppszData);
90 
91     /* Count \n characters without leading \r */
92     while (pszSrc < pszEnd) {
93         /* Skip ahead two character if found set of \r\n */
94         if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') {
95             pszSrc += 2;
96             continue;
97         }
98 
99         /* Increment the count if found naked \n */
100         if (*pszSrc == '\n') {
101             iNewlineCount++;
102         }
103 
104         pszSrc++;
105     }
106 
107     /* Return if no naked \n's */
108     if (iNewlineCount == 0)
109         return;
110 
111     /* Allocate a new string */
112     pszDestBegin = pszDest = malloc(iLength + iNewlineCount + 1);
113 
114     /* Set source pointer to beginning of data string */
115     pszSrc = *ppszData;
116 
117     /* Loop through all characters in source string */
118     while (pszSrc < pszEnd) {
119         /* Copy line endings that are already valid */
120         if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') {
121             *pszDest = *pszSrc;
122             *(pszDest + 1) = *(pszSrc + 1);
123             pszDest += 2;
124             pszSrc += 2;
125             continue;
126         }
127 
128         /* Add \r to naked \n's */
129         if (*pszSrc == '\n') {
130             *pszDest = '\r';
131             *(pszDest + 1) = *pszSrc;
132             pszDest += 2;
133             pszSrc += 1;
134             continue;
135         }
136 
137         /* Copy normal characters */
138         *pszDest = *pszSrc;
139         pszSrc++;
140         pszDest++;
141     }
142 
143     /* Put terminating null at end of new string */
144     *pszDest = '\0';
145 
146     /* Swap string pointers */
147     free(*ppszData);
148     *ppszData = pszDestBegin;
149 
150     winDebug("UNIXtoDOS () - Final string:'%s'\n", pszDestBegin);
151 }
152