1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS DNS Shared Library 4 * FILE: lib/dnslib/string.c 5 * PURPOSE: functions for string manipulation and conversion. 6 */ 7 8 /* INCLUDES ******************************************************************/ 9 #include "precomp.h" 10 11 /* DATA **********************************************************************/ 12 13 /* FUNCTIONS *****************************************************************/ 14 15 ULONG 16 WINAPI 17 Dns_StringCopy(OUT PVOID Destination, 18 IN OUT PULONG DestinationSize, 19 IN PVOID String, 20 IN ULONG StringSize OPTIONAL, 21 IN DWORD InputType, 22 IN DWORD OutputType) 23 { 24 ULONG DestSize; 25 ULONG OutputSize = 0; 26 27 /* Check if the caller already gave us the string size */ 28 if (!StringSize) 29 { 30 /* He didn't, get the input type */ 31 if (InputType == UnicodeString) 32 { 33 /* Unicode string, calculate the size */ 34 StringSize = (ULONG)wcslen((LPWSTR)String); 35 } 36 else 37 { 38 /* ANSI or UTF-8 sting, get the size */ 39 StringSize = (ULONG)strlen((LPSTR)String); 40 } 41 } 42 43 /* Check if we have a limit on the desination size */ 44 if (DestinationSize) 45 { 46 /* Make sure that we can respect it */ 47 DestSize = Dns_GetBufferLengthForStringCopy(String, 48 StringSize, 49 InputType, 50 OutputType); 51 if (*DestinationSize < DestSize) 52 { 53 /* Fail due to missing buffer space */ 54 SetLastError(ERROR_MORE_DATA); 55 56 /* Return how much data we actually need */ 57 *DestinationSize = DestSize; 58 return 0; 59 } 60 else if (!DestSize) 61 { 62 /* Fail due to invalid data */ 63 SetLastError(ERROR_INVALID_DATA); 64 return 0; 65 } 66 67 /* Return how much data we actually need */ 68 *DestinationSize = DestSize; 69 } 70 71 /* Now check if this is a Unicode String as input */ 72 if (InputType == UnicodeString) 73 { 74 /* Check if the output is ANSI */ 75 if (OutputType == AnsiString) 76 { 77 /* Convert and return the final desination size */ 78 OutputSize = WideCharToMultiByte(CP_ACP, 79 0, 80 String, 81 StringSize, 82 Destination, 83 -1, 84 NULL, 85 NULL) + 1; 86 } 87 else if (OutputType == UnicodeString) 88 { 89 /* Copy the string */ 90 StringSize = StringSize * sizeof(WCHAR); 91 RtlMoveMemory(Destination, String, StringSize); 92 93 /* Return output length */ 94 OutputSize = StringSize + 2; 95 } 96 else if (OutputType == Utf8String) 97 { 98 /* FIXME */ 99 OutputSize = 0; 100 } 101 } 102 else if (InputType == AnsiString) 103 { 104 /* It's ANSI, is the output ansi too? */ 105 if (OutputType == AnsiString) 106 { 107 /* Copy the string */ 108 RtlMoveMemory(Destination, String, StringSize); 109 110 /* Return output length */ 111 OutputSize = StringSize + 1; 112 } 113 else if (OutputType == UnicodeString) 114 { 115 /* Convert to Unicode and return size */ 116 OutputSize = MultiByteToWideChar(CP_ACP, 117 0, 118 String, 119 StringSize, 120 Destination, 121 -1) * sizeof(WCHAR) + 2; 122 } 123 else if (OutputType == Utf8String) 124 { 125 /* FIXME */ 126 OutputSize = 0; 127 } 128 } 129 else if (InputType == Utf8String) 130 { 131 /* FIXME */ 132 OutputSize = 0; 133 } 134 135 /* Return the output size */ 136 return OutputSize; 137 } 138 139 LPWSTR 140 WINAPI 141 Dns_CreateStringCopy_W(IN LPWSTR Name) 142 { 143 SIZE_T StringLength; 144 LPWSTR NameCopy; 145 146 /* Make sure that we have a name */ 147 if (!Name) 148 { 149 /* Fail */ 150 SetLastError(ERROR_INVALID_PARAMETER); 151 return NULL; 152 } 153 154 /* Find out the size of the string */ 155 StringLength = (wcslen(Name) + 1) * sizeof(WCHAR); 156 157 /* Allocate space for the copy */ 158 NameCopy = Dns_AllocZero(StringLength); 159 if (NameCopy) 160 { 161 /* Copy it */ 162 RtlCopyMemory(NameCopy, Name, StringLength); 163 } 164 else 165 { 166 /* Fail */ 167 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 168 } 169 170 /* Return the copy */ 171 return NameCopy; 172 } 173 174 ULONG 175 WINAPI 176 Dns_GetBufferLengthForStringCopy(IN PVOID String, 177 IN ULONG Size OPTIONAL, 178 IN DWORD InputType, 179 IN DWORD OutputType) 180 { 181 ULONG OutputSize = 0; 182 183 /* Check what kind of string this is */ 184 if (InputType == UnicodeString) 185 { 186 /* Check if we have a size */ 187 if (!Size) 188 { 189 /* Get it ourselves */ 190 Size = (ULONG)wcslen(String); 191 } 192 193 /* Check the output type */ 194 if (OutputType == UnicodeString) 195 { 196 /* Convert the size to bytes */ 197 OutputSize = (Size + 1) * sizeof(WCHAR); 198 } 199 else if (OutputType == Utf8String) 200 { 201 /* FIXME */ 202 OutputSize = 0; 203 } 204 else 205 { 206 /* Find out how much it will be in ANSI bytes */ 207 OutputSize = WideCharToMultiByte(CP_ACP, 208 0, 209 String, 210 Size, 211 NULL, 212 0, 213 NULL, 214 NULL) + 1; 215 } 216 } 217 else if (InputType == AnsiString) 218 { 219 /* Check if we have a size */ 220 if (!Size) 221 { 222 /* Get it ourselves */ 223 Size = (ULONG)strlen(String); 224 } 225 226 /* Check the output type */ 227 if (OutputType == AnsiString) 228 { 229 /* Just add a byte for the null char */ 230 OutputSize = Size + 1; 231 } 232 else if (OutputType == UnicodeString) 233 { 234 /* Calculate the bytes for a Unicode string */ 235 OutputSize = (MultiByteToWideChar(CP_ACP, 236 0, 237 String, 238 Size, 239 NULL, 240 0) + 1) * sizeof(WCHAR); 241 } 242 else if (OutputType == Utf8String) 243 { 244 /* FIXME */ 245 OutputSize = 0; 246 } 247 } 248 else if (InputType == Utf8String) 249 { 250 /* FIXME */ 251 OutputSize = 0; 252 } 253 254 /* Return the size required */ 255 return OutputSize; 256 } 257 258