fdupes  2.1.2
About: FDUPES finds duplicate files in a given set of directories.
  Fossies Dox: fdupes-2.1.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mbstowcs_escape_invalid.c
Go to the documentation of this file.
1 /* Copyright (c) 2019 Adrian Lopez
2 
3  This software is provided 'as-is', without any express or implied
4  warranty. In no event will the authors be held liable for any damages
5  arising from the use of this software.
6 
7  Permission is granted to anyone to use this software for any purpose,
8  including commercial applications, and to alter it and redistribute it
9  freely, subject to the following restrictions:
10 
11  1. The origin of this software must not be misrepresented; you must not
12  claim that you wrote the original software. If you use this software
13  in a product, an acknowledgment in the product documentation would be
14  appreciated but is not required.
15  2. Altered source versions must be plainly marked as such, and must not be
16  misrepresented as being the original software.
17  3. This notice may not be removed or altered from any source distribution. */
18 
19 #include "config.h"
21 #include <wchar.h>
22 #include <string.h>
23 #include <stdio.h>
24 
25 void reset_mbstate(mbstate_t *state)
26 {
27  memset(state, 0, sizeof(mbstate_t));
28 }
29 
30 size_t putoctal(wchar_t *dest, char c)
31 {
32  swprintf(dest, 5, L"\\%03o", (unsigned char) c);
33  return 4;
34 }
35 
36 size_t put_invalid_sequence(wchar_t *dest, const char *src, size_t *destination_index, size_t count, size_t max)
37 {
38  size_t x;
39 
40  for (x = 0; x < count; ++x)
41  {
42  if (dest != 0)
43  {
44  if (*destination_index + 5 > max)
45  return x;
46 
47  putoctal(dest + *destination_index, src[x]);
48  }
49 
50  *destination_index += 4;
51  }
52 
53  return count;
54 }
55 
56 size_t mbstowcs_escape_invalid(wchar_t *dest, const char *src, size_t n)
57 {
58  mbstate_t state;
59  wchar_t wc;
60  size_t x;
61  size_t i;
62  size_t dx;
63  size_t write;
64  size_t written;
65  size_t result;
66 
67  reset_mbstate(&state);
68 
69  x = 0;
70  i = 0;
71  dx = 0;
72 
73  while (src[x] != '\0')
74  {
75  result = mbrtowc(&wc, src + x, 1, &state);
76 
77  if (result == -2)
78  /* sequence is not yet complete */
79  {
80  ++x;
81  ++i;
82  }
83  else if (result == -1)
84  /* invalid sequence */
85  {
86  write = i == 0 ? 1 : i;
87 
88  if (dest != 0)
89  {
90  written = put_invalid_sequence(dest, src + (x - i), &dx, write, n);
91 
92  if (written != write)
93  return -1;
94  }
95  else
96  put_invalid_sequence(0, src + (x - i), &dx, write, 0);
97 
98  if (i == 0)
99  ++x;
100 
101  i = 0;
102 
103  reset_mbstate(&state);
104  }
105  else if (result != 0)
106  /* OK, add character */
107  {
108  if (dest != 0)
109  {
110  if (dx < n)
111  dest[dx++] = wc;
112  else
113  return -1;
114  }
115  else
116  ++dx;
117 
118  ++x;
119 
120  i = 0;
121  }
122 
123  if (src[x] == L'\0' && i > 0)
124  /* output final incomplete sequence */
125  {
126  if (dest != 0)
127  {
128  written = put_invalid_sequence(dest, src + (x - i), &dx, i, n);
129 
130  if (written != i)
131  return -1;
132  }
133  else
134  put_invalid_sequence(0, src + (x - i), &dx, i, 0);
135  }
136  }
137 
138  if (dest != 0)
139  {
140  if (dx < n)
141  dest[dx] = L'\0';
142  else
143  return -1;
144  }
145 
146  return dx + 1;
147 }
mbstowcs_escape_invalid
size_t mbstowcs_escape_invalid(wchar_t *dest, const char *src, size_t n)
Definition: mbstowcs_escape_invalid.c:56
reset_mbstate
void reset_mbstate(mbstate_t *state)
Definition: mbstowcs_escape_invalid.c:25
put_invalid_sequence
size_t put_invalid_sequence(wchar_t *dest, const char *src, size_t *destination_index, size_t count, size_t max)
Definition: mbstowcs_escape_invalid.c:36
mbstowcs_escape_invalid.h
putoctal
size_t putoctal(wchar_t *dest, char c)
Definition: mbstowcs_escape_invalid.c:30