"Fossies" - the Fresh Open Source Software Archive

Member "fdupes-2.1.2/mbstowcs_escape_invalid.c" (12 Aug 2020, 3500 Bytes) of package /linux/privat/fdupes-2.1.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mbstowcs_escape_invalid.c" see the Fossies "Dox" file reference documentation.

    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"
   20 #include "mbstowcs_escape_invalid.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 }