Blame winpr/libwinpr/crt/string.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * String Manipulation (CRT)
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <errno.h>
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
#include <wctype.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/endian.h>
Packit 1fb8d4
Packit 1fb8d4
/* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */
Packit 1fb8d4
Packit 1fb8d4
#include "../log.h"
Packit 1fb8d4
#define TAG WINPR_TAG("crt")
Packit 1fb8d4
Packit 1fb8d4
#ifndef _WIN32
Packit 1fb8d4
Packit 1fb8d4
char* _strdup(const char* strSource)
Packit 1fb8d4
{
Packit 1fb8d4
	char* strDestination;
Packit 1fb8d4
Packit 1fb8d4
	if (strSource == NULL)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	strDestination = strdup(strSource);
Packit 1fb8d4
Packit 1fb8d4
	if (strDestination == NULL)
Packit Service 5a9772
		WLog_ERR(TAG, "strdup");
Packit 1fb8d4
Packit 1fb8d4
	return strDestination;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
WCHAR* _wcsdup(const WCHAR* strSource)
Packit 1fb8d4
{
Packit 1fb8d4
	WCHAR* strDestination;
Packit 1fb8d4
Packit 1fb8d4
	if (strSource == NULL)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
#if defined(__APPLE__) && defined(__MACH__) || defined(ANDROID) || defined(sun)
Packit 1fb8d4
	strDestination = malloc(wcslen((wchar_t*)strSource));
Packit 1fb8d4
Packit 1fb8d4
	if (strDestination != NULL)
Packit 1fb8d4
		wcscpy((wchar_t*)strDestination, (const wchar_t*)strSource);
Packit 1fb8d4
Packit 1fb8d4
#else
Packit Service 5a9772
	strDestination = (WCHAR*)wcsdup((wchar_t*)strSource);
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
	if (strDestination == NULL)
Packit Service 5a9772
		WLog_ERR(TAG, "wcsdup");
Packit 1fb8d4
Packit 1fb8d4
	return strDestination;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int _stricmp(const char* string1, const char* string2)
Packit 1fb8d4
{
Packit 1fb8d4
	return strcasecmp(string1, string2);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int _strnicmp(const char* string1, const char* string2, size_t count)
Packit 1fb8d4
{
Packit 1fb8d4
	return strncasecmp(string1, string2, count);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* _wcscmp -> wcscmp */
Packit 1fb8d4
Packit 1fb8d4
int _wcscmp(const WCHAR* string1, const WCHAR* string2)
Packit 1fb8d4
{
Packit 1fb8d4
	WCHAR value1, value2;
Packit 1fb8d4
Packit 1fb8d4
	while (*string1 && (*string1 == *string2))
Packit 1fb8d4
	{
Packit 1fb8d4
		string1++;
Packit 1fb8d4
		string2++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Data_Read_UINT16(string1, value1);
Packit 1fb8d4
	Data_Read_UINT16(string2, value2);
Packit 1fb8d4
	return value1 - value2;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* _wcslen -> wcslen */
Packit 1fb8d4
Packit 1fb8d4
size_t _wcslen(const WCHAR* str)
Packit 1fb8d4
{
Packit Service 5a9772
	const WCHAR* p = (const WCHAR*)str;
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	while (*p)
Packit 1fb8d4
		p++;
Packit 1fb8d4
Packit Service 5a9772
	return (size_t)(p - str);
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
/* _wcsnlen -> wcsnlen */
Packit Service 5a9772
Packit Service 5a9772
size_t _wcsnlen(const WCHAR* str, size_t max)
Packit Service 5a9772
{
Packit Service 5a9772
	size_t x;
Packit Service 5a9772
Packit Service 5a9772
	if (!str)
Packit Service 5a9772
		return 0;
Packit Service 5a9772
Packit Service 5a9772
	for (x = 0; x < max; x++)
Packit Service 5a9772
	{
Packit Service 5a9772
		if (str[x] == 0)
Packit Service 5a9772
			return x;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return x;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* _wcschr -> wcschr */
Packit 1fb8d4
Packit 1fb8d4
WCHAR* _wcschr(const WCHAR* str, WCHAR c)
Packit 1fb8d4
{
Packit Service 5a9772
	WCHAR* p = (WCHAR*)str;
Packit 1fb8d4
	WCHAR value;
Packit 1fb8d4
	Data_Write_UINT16(&value, c);
Packit Service 5a9772
Packit 1fb8d4
	while (*p && (*p != value))
Packit 1fb8d4
		p++;
Packit 1fb8d4
Packit 1fb8d4
	return ((*p == value) ? p : NULL);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* _wcsrchr -> wcsrchr */
Packit 1fb8d4
Packit 1fb8d4
WCHAR* _wcsrchr(const WCHAR* str, WCHAR c)
Packit 1fb8d4
{
Packit Service 5a9772
	WCHAR* p;
Packit 1fb8d4
	WCHAR ch;
Packit 1fb8d4
Packit 1fb8d4
	if (!str)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit Service 5a9772
	for (p = (WCHAR*)0; (ch = *str); str++)
Packit 1fb8d4
		if (ch == c)
Packit Service 5a9772
			p = (WCHAR*)str;
Packit 1fb8d4
Packit 1fb8d4
	return p;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
char* strtok_s(char* strToken, const char* strDelimit, char** context)
Packit 1fb8d4
{
Packit 1fb8d4
	return strtok_r(strToken, strDelimit, context);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context)
Packit 1fb8d4
{
Packit 1fb8d4
	WCHAR* nextToken;
Packit 1fb8d4
	WCHAR value;
Packit 1fb8d4
Packit 1fb8d4
	if (!strToken)
Packit 1fb8d4
		strToken = *context;
Packit 1fb8d4
Packit 1fb8d4
	Data_Read_UINT16(strToken, value);
Packit Service 5a9772
Packit 1fb8d4
	while (*strToken && _wcschr(strDelimit, value))
Packit 1fb8d4
	{
Packit 1fb8d4
		strToken++;
Packit 1fb8d4
		Data_Read_UINT16(strToken, value);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!*strToken)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	nextToken = strToken++;
Packit 1fb8d4
	Data_Read_UINT16(strToken, value);
Packit Service 5a9772
Packit 1fb8d4
	while (*strToken && !(_wcschr(strDelimit, value)))
Packit 1fb8d4
	{
Packit 1fb8d4
		strToken++;
Packit 1fb8d4
		Data_Read_UINT16(strToken, value);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (*strToken)
Packit 1fb8d4
		*strToken++ = 0;
Packit 1fb8d4
Packit 1fb8d4
	*context = strToken;
Packit 1fb8d4
	return nextToken;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if !defined(_WIN32) || defined(_UWP)
Packit 1fb8d4
Packit 1fb8d4
/* Windows API Sets - api-ms-win-core-string-l2-1-0.dll
Packit 1fb8d4
 * http://msdn.microsoft.com/en-us/library/hh802935/
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#include "casing.c"
Packit 1fb8d4
Packit 1fb8d4
LPSTR CharUpperA(LPSTR lpsz)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t i;
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
Packit 1fb8d4
	if (!lpsz)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit Service 5a9772
	length = strlen(lpsz);
Packit 1fb8d4
Packit 1fb8d4
	if (length < 1)
Packit Service 5a9772
		return (LPSTR)NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (length == 1)
Packit 1fb8d4
	{
Packit 1fb8d4
		char c = *lpsz;
Packit 1fb8d4
Packit 1fb8d4
		if ((c >= 'a') && (c <= 'z'))
Packit 1fb8d4
			c = c - 32;
Packit 1fb8d4
Packit 1fb8d4
		*lpsz = c;
Packit 1fb8d4
		return lpsz;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < length; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((lpsz[i] >= 'a') && (lpsz[i] <= 'z'))
Packit 1fb8d4
			lpsz[i] = lpsz[i] - 32;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return lpsz;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
LPWSTR CharUpperW(LPWSTR lpsz)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "CharUpperW unimplemented!");
Packit Service 5a9772
	return (LPWSTR)NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
DWORD CharUpperBuffA(LPSTR lpsz, DWORD cchLength)
Packit 1fb8d4
{
Packit 1fb8d4
	DWORD i;
Packit 1fb8d4
Packit 1fb8d4
	if (cchLength < 1)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < cchLength; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((lpsz[i] >= 'a') && (lpsz[i] <= 'z'))
Packit 1fb8d4
			lpsz[i] = lpsz[i] - 32;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return cchLength;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
DWORD CharUpperBuffW(LPWSTR lpsz, DWORD cchLength)
Packit 1fb8d4
{
Packit 1fb8d4
	DWORD i;
Packit 1fb8d4
	WCHAR value;
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < cchLength; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		Data_Read_UINT16(&lpsz[i], value);
Packit 1fb8d4
		value = WINPR_TOUPPERW(value);
Packit 1fb8d4
		Data_Write_UINT16(&lpsz[i], value);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return cchLength;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
LPSTR CharLowerA(LPSTR lpsz)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t i;
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
Packit 1fb8d4
	if (!lpsz)
Packit Service 5a9772
		return (LPSTR)NULL;
Packit 1fb8d4
Packit Service 5a9772
	length = strlen(lpsz);
Packit 1fb8d4
Packit 1fb8d4
	if (length < 1)
Packit Service 5a9772
		return (LPSTR)NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (length == 1)
Packit 1fb8d4
	{
Packit 1fb8d4
		char c = *lpsz;
Packit 1fb8d4
Packit 1fb8d4
		if ((c >= 'A') && (c <= 'Z'))
Packit 1fb8d4
			c = c + 32;
Packit 1fb8d4
Packit 1fb8d4
		*lpsz = c;
Packit 1fb8d4
		return lpsz;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < length; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((lpsz[i] >= 'A') && (lpsz[i] <= 'Z'))
Packit 1fb8d4
			lpsz[i] = lpsz[i] + 32;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return lpsz;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
LPWSTR CharLowerW(LPWSTR lpsz)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "CharLowerW unimplemented!");
Packit Service 5a9772
	return (LPWSTR)NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
DWORD CharLowerBuffA(LPSTR lpsz, DWORD cchLength)
Packit 1fb8d4
{
Packit 1fb8d4
	DWORD i;
Packit 1fb8d4
Packit 1fb8d4
	if (cchLength < 1)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < cchLength; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((lpsz[i] >= 'A') && (lpsz[i] <= 'Z'))
Packit 1fb8d4
			lpsz[i] = lpsz[i] + 32;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return cchLength;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
DWORD CharLowerBuffW(LPWSTR lpsz, DWORD cchLength)
Packit 1fb8d4
{
Packit 1fb8d4
	DWORD i;
Packit 1fb8d4
	WCHAR value;
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < cchLength; i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		Data_Read_UINT16(&lpsz[i], value);
Packit 1fb8d4
		value = WINPR_TOLOWERW(value);
Packit 1fb8d4
		Data_Write_UINT16(&lpsz[i], value);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return cchLength;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharAlphaA(CHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')))
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	else
Packit 1fb8d4
		return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharAlphaW(WCHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "IsCharAlphaW unimplemented!");
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharAlphaNumericA(CHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
Packit Service 5a9772
	    ((ch >= '0') && (ch <= '9')))
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	else
Packit 1fb8d4
		return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharAlphaNumericW(WCHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "IsCharAlphaNumericW unimplemented!");
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharUpperA(CHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	if ((ch >= 'A') && (ch <= 'Z'))
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	else
Packit 1fb8d4
		return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharUpperW(WCHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "IsCharUpperW unimplemented!");
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharLowerA(CHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	if ((ch >= 'a') && (ch <= 'z'))
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	else
Packit 1fb8d4
		return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL IsCharLowerW(WCHAR ch)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "IsCharLowerW unimplemented!");
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int lstrlenA(LPCSTR lpString)
Packit 1fb8d4
{
Packit Service 5a9772
	return (int)strlen(lpString);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int lstrlenW(LPCWSTR lpString)
Packit 1fb8d4
{
Packit 1fb8d4
	LPWSTR p;
Packit 1fb8d4
Packit 1fb8d4
	if (!lpString)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit Service 5a9772
	p = (LPWSTR)lpString;
Packit 1fb8d4
Packit 1fb8d4
	while (*p)
Packit 1fb8d4
		p++;
Packit 1fb8d4
Packit Service 5a9772
	return (int)(p - lpString);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Packit 1fb8d4
{
Packit 1fb8d4
	return strcmp(lpString1, lpString2);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Packit 1fb8d4
{
Packit 1fb8d4
	WCHAR value1, value2;
Packit 1fb8d4
Packit 1fb8d4
	while (*lpString1 && (*lpString1 == *lpString2))
Packit 1fb8d4
	{
Packit 1fb8d4
		lpString1++;
Packit 1fb8d4
		lpString2++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Data_Read_UINT16(lpString1, value1);
Packit 1fb8d4
	Data_Read_UINT16(lpString2, value2);
Packit 1fb8d4
	return value1 - value2;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
int ConvertLineEndingToLF(char* str, int size)
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit 1fb8d4
	char* end;
Packit 1fb8d4
	char* pInput;
Packit 1fb8d4
	char* pOutput;
Packit 1fb8d4
	end = &str[size];
Packit 1fb8d4
	pInput = pOutput = str;
Packit 1fb8d4
Packit 1fb8d4
	while (pInput < end)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((pInput[0] == '\r') && (pInput[1] == '\n'))
Packit 1fb8d4
		{
Packit 1fb8d4
			*pOutput++ = '\n';
Packit 1fb8d4
			pInput += 2;
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			*pOutput++ = *pInput++;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	status = (int)(pOutput - str);
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
char* ConvertLineEndingToCRLF(const char* str, int* size)
Packit 1fb8d4
{
Packit 1fb8d4
	int count;
Packit 1fb8d4
	char* newStr;
Packit 1fb8d4
	char* pOutput;
Packit 1fb8d4
	const char* end;
Packit 1fb8d4
	const char* pInput;
Packit 1fb8d4
	end = &str[*size];
Packit 1fb8d4
	count = 0;
Packit 1fb8d4
	pInput = str;
Packit 1fb8d4
Packit 1fb8d4
	while (pInput < end)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (*pInput == '\n')
Packit 1fb8d4
			count++;
Packit 1fb8d4
Packit 1fb8d4
		pInput++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	newStr = (char*)malloc(*size + (count * 2) + 1);
Packit 1fb8d4
Packit 1fb8d4
	if (!newStr)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	pInput = str;
Packit 1fb8d4
	pOutput = newStr;
Packit 1fb8d4
Packit 1fb8d4
	while (pInput < end)
Packit 1fb8d4
	{
Packit 1fb8d4
		if ((*pInput == '\n') && ((pInput > str) && (pInput[-1] != '\r')))
Packit 1fb8d4
		{
Packit 1fb8d4
			*pOutput++ = '\r';
Packit 1fb8d4
			*pOutput++ = '\n';
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			*pOutput++ = *pInput;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		pInput++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	*size = (int)(pOutput - newStr);
Packit 1fb8d4
	return newStr;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
char* StrSep(char** stringp, const char* delim)
Packit 1fb8d4
{
Packit 1fb8d4
	char* start = *stringp;
Packit 1fb8d4
	char* p;
Packit 1fb8d4
	p = (start != NULL) ? strpbrk(start, delim) : NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (!p)
Packit 1fb8d4
		*stringp = NULL;
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		*p = '\0';
Packit 1fb8d4
		*stringp = p + 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return start;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
INT64 GetLine(char** lineptr, size_t* size, FILE* stream)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(_WIN32)
Packit 1fb8d4
	char c;
Packit Service 5a9772
	char* n;
Packit 1fb8d4
	size_t step = 32;
Packit 1fb8d4
	size_t used = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (!lineptr || !size)
Packit 1fb8d4
	{
Packit 1fb8d4
		errno = EINVAL;
Packit 1fb8d4
		return -1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	do
Packit 1fb8d4
	{
Packit 1fb8d4
		if (used + 2 >= *size)
Packit 1fb8d4
		{
Packit 1fb8d4
			*size += step;
Packit 1fb8d4
			n = realloc(*lineptr, *size);
Packit Service 5a9772
Packit 1fb8d4
			if (!n)
Packit 1fb8d4
			{
Packit 1fb8d4
				return -1;
Packit 1fb8d4
			}
Packit Service 5a9772
Packit 1fb8d4
			*lineptr = n;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit Service 5a9772
		c = fgetc(stream);
Packit Service 5a9772
Packit Service 5a9772
		if (c != EOF)
Packit Service 5a9772
			(*lineptr)[used++] = c;
Packit Service 5a9772
	} while ((c != '\n') && (c != '\r') && (c != EOF));
Packit Service 5a9772
Packit Service 5a9772
	(*lineptr)[used] = '\0';
Packit 1fb8d4
	return used;
Packit 1fb8d4
#elif !defined(ANDROID) && !defined(IOS)
Packit 1fb8d4
	return getline(lineptr, size, stream);
Packit 1fb8d4
#else
Packit 1fb8d4
	return -1;
Packit 1fb8d4
#endif
Packit 1fb8d4
}