summaryrefslogtreecommitdiff
path: root/src/UriFile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/UriFile.c')
-rw-r--r--src/UriFile.c335
1 files changed, 157 insertions, 178 deletions
diff --git a/src/UriFile.c b/src/UriFile.c
index 232957d..7510e70 100644
--- a/src/UriFile.c
+++ b/src/UriFile.c
@@ -41,202 +41,181 @@
#include <uriparser/UriDefsConfig.h>
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* Include SELF twice */
-# ifdef URI_ENABLE_ANSI
-# define URI_PASS_ANSI 1
-# include "UriFile.c"
-# undef URI_PASS_ANSI
-# endif
-# ifdef URI_ENABLE_UNICODE
-# define URI_PASS_UNICODE 1
-# include "UriFile.c"
-# undef URI_PASS_UNICODE
-# endif
+# ifdef URI_ENABLE_ANSI
+# define URI_PASS_ANSI 1
+# include "UriFile.c"
+# undef URI_PASS_ANSI
+# endif
+# ifdef URI_ENABLE_UNICODE
+# define URI_PASS_UNICODE 1
+# include "UriFile.c"
+# undef URI_PASS_UNICODE
+# endif
#else
-# ifdef URI_PASS_ANSI
-# include <uriparser/UriDefsAnsi.h>
-# else
-# include <uriparser/UriDefsUnicode.h>
-# include <wchar.h>
-# endif
-
-
-
-#ifndef URI_DOXYGEN
-# include <uriparser/Uri.h>
-#endif
-
-
-
-#include <stdlib.h> /* for size_t, avoiding stddef.h for older MSVCs */
+# ifdef URI_PASS_ANSI
+# include <uriparser/UriDefsAnsi.h>
+# else
+# include <uriparser/UriDefsUnicode.h>
+# include <wchar.h>
+# endif
+# ifndef URI_DOXYGEN
+# include <uriparser/Uri.h>
+# endif
+# include <stdlib.h> /* for size_t, avoiding stddef.h for older MSVCs */
static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename,
- URI_CHAR * uriString, UriBool fromUnix) {
- const URI_CHAR * input = filename;
- const URI_CHAR * lastSep = input - 1;
- UriBool firstSegment = URI_TRUE;
- URI_CHAR * output = uriString;
- UriBool absolute;
- UriBool is_windows_network;
-
- if ((filename == NULL) || (uriString == NULL)) {
- return URI_ERROR_NULL;
- }
-
- is_windows_network = (filename[0] == _UT('\\')) && (filename[1] == _UT('\\'));
- absolute = fromUnix
- ? (filename[0] == _UT('/'))
- : (((filename[0] != _UT('\0')) && (filename[1] == _UT(':')))
- || is_windows_network);
-
- if (absolute) {
- const URI_CHAR * const prefix = fromUnix
- ? _UT("file://")
- : is_windows_network
- ? _UT("file:")
- : _UT("file:///");
- const size_t prefixLen = URI_STRLEN(prefix);
-
- /* Copy prefix */
- memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR));
- output += prefixLen;
- }
-
- /* Copy and escape on the fly */
- for (;;) {
- if ((input[0] == _UT('\0'))
- || (fromUnix && input[0] == _UT('/'))
- || (!fromUnix && input[0] == _UT('\\'))) {
- /* Copy text after last separator */
- if (lastSep + 1 < input) {
- if (!fromUnix && absolute && (firstSegment == URI_TRUE)) {
- /* Quick hack to not convert "C:" to "C%3A" */
- const int charsToCopy = (int)(input - (lastSep + 1));
- memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR));
- output += charsToCopy;
- } else {
- output = URI_FUNC(EscapeEx)(lastSep + 1, input, output,
- URI_FALSE, URI_FALSE);
- }
- }
- firstSegment = URI_FALSE;
- }
-
- if (input[0] == _UT('\0')) {
- output[0] = _UT('\0');
- break;
- } else if (fromUnix && (input[0] == _UT('/'))) {
- /* Copy separators unmodified */
- output[0] = _UT('/');
- output++;
- lastSep = input;
- } else if (!fromUnix && (input[0] == _UT('\\'))) {
- /* Convert backslashes to forward slashes */
- output[0] = _UT('/');
- output++;
- lastSep = input;
- }
- input++;
- }
-
- return URI_SUCCESS;
+ URI_CHAR * uriString,
+ UriBool fromUnix) {
+ const URI_CHAR * input = filename;
+ const URI_CHAR * lastSep = input - 1;
+ UriBool firstSegment = URI_TRUE;
+ URI_CHAR * output = uriString;
+ UriBool absolute;
+ UriBool is_windows_network;
+
+ if ((filename == NULL) || (uriString == NULL)) {
+ return URI_ERROR_NULL;
+ }
+
+ is_windows_network = (filename[0] == _UT('\\')) && (filename[1] == _UT('\\'));
+ absolute = fromUnix ? (filename[0] == _UT('/'))
+ : (((filename[0] != _UT('\0')) && (filename[1] == _UT(':')))
+ || is_windows_network);
+
+ if (absolute) {
+ const URI_CHAR * const prefix = fromUnix ? _UT("file://")
+ : is_windows_network ? _UT("file:")
+ : _UT("file:///");
+ const size_t prefixLen = URI_STRLEN(prefix);
+
+ /* Copy prefix */
+ memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR));
+ output += prefixLen;
+ }
+
+ /* Copy and escape on the fly */
+ for (;;) {
+ if ((input[0] == _UT('\0')) || (fromUnix && input[0] == _UT('/'))
+ || (!fromUnix && input[0] == _UT('\\'))) {
+ /* Copy text after last separator */
+ if (lastSep + 1 < input) {
+ if (!fromUnix && absolute && (firstSegment == URI_TRUE)) {
+ /* Quick hack to not convert "C:" to "C%3A" */
+ const int charsToCopy = (int)(input - (lastSep + 1));
+ memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR));
+ output += charsToCopy;
+ } else {
+ output = URI_FUNC(EscapeEx)(lastSep + 1, input, output, URI_FALSE,
+ URI_FALSE);
+ }
+ }
+ firstSegment = URI_FALSE;
+ }
+
+ if (input[0] == _UT('\0')) {
+ output[0] = _UT('\0');
+ break;
+ } else if (fromUnix && (input[0] == _UT('/'))) {
+ /* Copy separators unmodified */
+ output[0] = _UT('/');
+ output++;
+ lastSep = input;
+ } else if (!fromUnix && (input[0] == _UT('\\'))) {
+ /* Convert backslashes to forward slashes */
+ output[0] = _UT('/');
+ output++;
+ lastSep = input;
+ }
+ input++;
+ }
+
+ return URI_SUCCESS;
}
-
-
static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,
- URI_CHAR * filename, UriBool toUnix) {
- if ((uriString == NULL) || (filename == NULL)) {
- return URI_ERROR_NULL;
- }
-
- {
- const UriBool file_unknown_slashes =
- URI_STRNCMP(uriString, _UT("file:"), URI_STRLEN(_UT("file:"))) == 0;
- const UriBool file_one_or_more_slashes = file_unknown_slashes
- && (URI_STRNCMP(uriString, _UT("file:/"), URI_STRLEN(_UT("file:/"))) == 0);
- const UriBool file_two_or_more_slashes = file_one_or_more_slashes
- && (URI_STRNCMP(uriString, _UT("file://"), URI_STRLEN(_UT("file://"))) == 0);
- const UriBool file_three_or_more_slashes = file_two_or_more_slashes
- && (URI_STRNCMP(uriString, _UT("file:///"), URI_STRLEN(_UT("file:///"))) == 0);
-
- const size_t charsToSkip = file_two_or_more_slashes
- ? file_three_or_more_slashes
- ? toUnix
- /* file:///bin/bash */
- ? URI_STRLEN(_UT("file://"))
- /* file:///E:/Documents%20and%20Settings */
- : URI_STRLEN(_UT("file:///"))
- /* file://Server01/Letter.txt */
- : URI_STRLEN(_UT("file://"))
- : ((file_one_or_more_slashes && toUnix)
- /* file:/bin/bash */
- /* https://tools.ietf.org/html/rfc8089#appendix-B */
- ? URI_STRLEN(_UT("file:"))
- : ((! toUnix && file_unknown_slashes && ! file_one_or_more_slashes)
- /* file:c:/path/to/file */
- /* https://tools.ietf.org/html/rfc8089#appendix-E.2 */
- ? URI_STRLEN(_UT("file:"))
- : 0));
- const size_t charsToCopy = URI_STRLEN(uriString + charsToSkip) + 1;
-
- const UriBool is_windows_network_with_authority =
- (toUnix == URI_FALSE)
- && file_two_or_more_slashes
- && ! file_three_or_more_slashes;
-
- URI_CHAR * const unescape_target = is_windows_network_with_authority
- ? (filename + 2)
- : filename;
-
- if (is_windows_network_with_authority) {
- filename[0] = '\\';
- filename[1] = '\\';
- }
-
- memcpy(unescape_target, uriString + charsToSkip, charsToCopy * sizeof(URI_CHAR));
- URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH);
- }
-
- /* Convert forward slashes to backslashes */
- if (!toUnix) {
- URI_CHAR * walker = filename;
- while (walker[0] != _UT('\0')) {
- if (walker[0] == _UT('/')) {
- walker[0] = _UT('\\');
- }
- walker++;
- }
- }
-
- return URI_SUCCESS;
+ URI_CHAR * filename, UriBool toUnix) {
+ if ((uriString == NULL) || (filename == NULL)) {
+ return URI_ERROR_NULL;
+ }
+
+ const UriBool file_unknown_slashes =
+ URI_STRNCMP(uriString, _UT("file:"), URI_STRLEN(_UT("file:"))) == 0;
+ const UriBool file_one_or_more_slashes =
+ file_unknown_slashes
+ && (URI_STRNCMP(uriString, _UT("file:/"), URI_STRLEN(_UT("file:/"))) == 0);
+ const UriBool file_two_or_more_slashes =
+ file_one_or_more_slashes
+ && (URI_STRNCMP(uriString, _UT("file://"), URI_STRLEN(_UT("file://"))) == 0);
+ const UriBool file_three_or_more_slashes =
+ file_two_or_more_slashes
+ && (URI_STRNCMP(uriString, _UT("file:///"), URI_STRLEN(_UT("file:///"))) == 0);
+
+ const size_t charsToSkip =
+ file_two_or_more_slashes
+ ? file_three_or_more_slashes ? toUnix
+ /* file:///bin/bash */
+ ? URI_STRLEN(_UT("file://"))
+ /* file:///E:/Documents%20and%20Settings */
+ : URI_STRLEN(_UT("file:///"))
+ /* file://Server01/Letter.txt */
+ : URI_STRLEN(_UT("file://"))
+ : ((file_one_or_more_slashes && toUnix)
+ /* file:/bin/bash */
+ /* https://tools.ietf.org/html/rfc8089#appendix-B */
+ ? URI_STRLEN(_UT("file:"))
+ : ((!toUnix && file_unknown_slashes && !file_one_or_more_slashes)
+ /* file:c:/path/to/file */
+ /* https://tools.ietf.org/html/rfc8089#appendix-E.2 */
+ ? URI_STRLEN(_UT("file:"))
+ : 0));
+ const size_t charsToCopy = URI_STRLEN(uriString + charsToSkip) + 1;
+
+ const UriBool is_windows_network_with_authority =
+ (toUnix == URI_FALSE) && file_two_or_more_slashes && !file_three_or_more_slashes;
+
+ URI_CHAR * const unescape_target =
+ is_windows_network_with_authority ? (filename + 2) : filename;
+
+ if (is_windows_network_with_authority) {
+ filename[0] = '\\';
+ filename[1] = '\\';
+ }
+
+ memcpy(unescape_target, uriString + charsToSkip, charsToCopy * sizeof(URI_CHAR));
+ URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH);
+
+ /* Convert forward slashes to backslashes */
+ if (!toUnix) {
+ URI_CHAR * walker = filename;
+ while (walker[0] != _UT('\0')) {
+ if (walker[0] == _UT('/')) {
+ walker[0] = _UT('\\');
+ }
+ walker++;
+ }
+ }
+
+ return URI_SUCCESS;
}
-
-
int URI_FUNC(UnixFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {
- return URI_FUNC(FilenameToUriString)(filename, uriString, URI_TRUE);
+ return URI_FUNC(FilenameToUriString)(filename, uriString, URI_TRUE);
}
-
-
-int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {
- return URI_FUNC(FilenameToUriString)(filename, uriString, URI_FALSE);
+int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename,
+ URI_CHAR * uriString) {
+ return URI_FUNC(FilenameToUriString)(filename, uriString, URI_FALSE);
}
-
-
int URI_FUNC(UriStringToUnixFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {
- return URI_FUNC(UriStringToFilename)(uriString, filename, URI_TRUE);
+ return URI_FUNC(UriStringToFilename)(uriString, filename, URI_TRUE);
}
-
-
-int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {
- return URI_FUNC(UriStringToFilename)(uriString, filename, URI_FALSE);
+int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString,
+ URI_CHAR * filename) {
+ return URI_FUNC(UriStringToFilename)(uriString, filename, URI_FALSE);
}
-
-
#endif