Welcome to mirror list, hosted at ThFree Co, Russian Federation.

strfuncs.cc « cygwin « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 130be76f1f775d9312a07c31fa8c28112979344c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* strfuncs.cc: misc funcs that don't belong anywhere else

   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
   2005, 2006, 2007 Red Hat, Inc.

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include "winsup.h"
#include <stdlib.h>
#include <winbase.h>
#include <winnls.h>
#include <ntdll.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"

codepage_type current_codepage = ansi_cp;
UINT active_codepage = 0;

#ifdef __OUTSIDE_CYGWIN__
#define codepage_init(cp)	(active_codepage = GetACP ())
#endif

UINT
get_cp ()
{
  if (!active_codepage)
    codepage_init ("ansi");
  return active_codepage;
}

bool
is_cp_multibyte (UINT cp)
{
  CPINFO cpi; 
  GetCPInfo (cp, &cpi);
  return cpi.MaxCharSize > 1;
}

/* tlen is always treated as the maximum buffer size, including the '\0'
   character.  sys_wcstombs will always return a 0-terminated result, no
   matter what. */
int __stdcall
sys_wcstombs (char *tgt, int tlen, const PWCHAR src, int slen)
{
  int ret;

  ret = WideCharToMultiByte (get_cp (), 0, src, slen, tgt, tlen, NULL, NULL);
  if (ret && tgt)
    {
      ret = (ret < tlen) ? ret : tlen - 1;
      tgt[ret] = '\0';
    }
  return ret;
}

/* Allocate a buffer big enough for the string, always including the
   terminating '\0'.  The buffer pointer is returned in *tgt_p, the return
   value is the number of bytes written to the buffer, as usual.
   The "type" argument determines where the resulting buffer is stored.
   It's either one of the cygheap_types values, or it's "HEAP_NOTHEAP".
   In the latter case the allocation uses simple calloc.
   
   Note that this code is shared by cygserver (which requires it via
   __small_vsprintf) and so when built there plain calloc is the 
   only choice.  */
int __stdcall
sys_wcstombs_alloc (char **tgt_p, int type, const PWCHAR src, int slen)
{
  int ret;

  ret = WideCharToMultiByte (get_cp (), 0, src, slen, NULL, 0,NULL, NULL);
  if (ret)
    {
      size_t tlen = (slen == -1 ? ret : ret + 1);

#ifndef __OUTSIDE_CYGWIN__
      if (type == HEAP_NOTHEAP)
#endif
        *tgt_p = (char *) calloc (tlen, sizeof (char));
#ifndef __OUTSIDE_CYGWIN__
      else
      	*tgt_p = (char *) ccalloc ((cygheap_types) type, tlen, sizeof (char));
#endif
      if (!*tgt_p)
        return 0;
      ret = sys_wcstombs (*tgt_p, tlen, src, slen);
    }
  return ret;
}

int __stdcall
sys_mbstowcs (PWCHAR tgt, const char *src, int len)
{
  int res = MultiByteToWideChar (get_cp (), 0, src, -1, tgt, len);
  return res;
}

/* Same as sys_wcstombs_alloc, just backwards. */
int __stdcall
sys_mbstowcs_alloc (PWCHAR *tgt_p, int type, const char *src)
{
  int ret;

  ret = MultiByteToWideChar (get_cp (), 0, src, -1, NULL, 0);
  if (ret)
    {
#ifndef __OUTSIDE_CYGWIN__
      if (type == HEAP_NOTHEAP)
#endif
        *tgt_p = (PWCHAR) calloc (ret, sizeof (WCHAR));
#ifndef __OUTSIDE_CYGWIN__
      else
      	*tgt_p = (PWCHAR) ccalloc ((cygheap_types) type, ret, sizeof (WCHAR));
#endif
      if (!*tgt_p)
        return 0;
      ret = sys_mbstowcs (*tgt_p, src, ret);
    }
  return ret;
}

static WCHAR hex_wchars[] = L"0123456789abcdef";

NTSTATUS NTAPI
RtlInt64ToHexUnicodeString (ULONGLONG value, PUNICODE_STRING dest,
			    BOOLEAN append)
{
  USHORT len = append ? dest->Length : 0;
  if (dest->MaximumLength - len < 16 * (int) sizeof (WCHAR))
    return STATUS_BUFFER_OVERFLOW;
  PWCHAR end = (PWCHAR) ((PBYTE) dest->Buffer + len);
  register PWCHAR p = end + 16;
  while (p-- > end)
    {
      *p = hex_wchars[value & 0xf];
      value >>= 4;
    }
  dest->Length += 16 * sizeof (WCHAR);
  return STATUS_SUCCESS;
}