wClipboard/posix: parse text/uri-list format
Now we start handling the actual format data. As the first step we need to convert the text/uri-list data into the list of file names. Each file or directory the user selects to copy is represented with a URI, and the whole list looks like this: file:///home/bob/text-file file:///home/bob/a-directory file:///home/bob/white%20space The MIME format is actually specified by RFC 2483. As said in the comments, we allow some slack for other applications: they can use singular LF and CR as line terminators, and we also will handle missing terminator for the last line (some applications actually do this, but I can't recall which ones at the moment). We will handle only the file:// URI scheme because these refer to local filesystem paths. It is possible for text/uri-list to contain URIs with other schemes when the user selects files from remote filesystems (like an FTP server or an SMB share connect to from a file manager). We cannot pass such paths to open() and for some reason the file managers use the remote URIs even when the remote filesystems are actually mapped to the local filesystem via FUSE. Therefore we restrict ourselves to handling only file://.
This commit is contained in:
parent
09e73a00cb
commit
64e1073044
@ -98,10 +98,98 @@ static void free_posix_file(void* the_file)
|
||||
free(file);
|
||||
}
|
||||
|
||||
static char* decode_percent_encoded_string(const char* str, size_t len)
|
||||
{
|
||||
/* TBD: decode percent-encoded URI into a fresh null-terminated string */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL process_file_name(const char* local_name, wArrayList* files)
|
||||
{
|
||||
/* TBD: add file with `local_name` to `files` */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL process_uri(const char* uri, size_t uri_len, wArrayList* files)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
char* name = NULL;
|
||||
|
||||
#ifdef WITH_DEBUG_WCLIPBOARD
|
||||
WLog_DBG(TAG, "processing URI: %.*s", uri_len, uri);
|
||||
#endif
|
||||
|
||||
if ((uri_len < strlen("file://")) || strncmp(uri, "file://", strlen("file://")))
|
||||
{
|
||||
WLog_ERR(TAG, "non-'file://' URI schemes are not supported");
|
||||
goto out;
|
||||
}
|
||||
|
||||
name = decode_percent_encoded_string(uri + strlen("file://"), uri_len - strlen("file://"));
|
||||
if (!name)
|
||||
goto out;
|
||||
|
||||
result = process_file_name(name, files);
|
||||
out:
|
||||
free(name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL process_uri_list(const char* data, size_t length, wArrayList* files)
|
||||
{
|
||||
const char* cur = data;
|
||||
const char* lim = data + length;
|
||||
const char* start = NULL;
|
||||
const char* stop = NULL;
|
||||
|
||||
#ifdef WITH_DEBUG_WCLIPBOARD
|
||||
WLog_DBG(TAG, "processing URI list:\n%.*s", length, data);
|
||||
#endif
|
||||
|
||||
ArrayList_Clear(files);
|
||||
/* TBD: parse text/uri-list `data` and store it into `files` */
|
||||
|
||||
/*
|
||||
* The "text/uri-list" Internet Media Type is specified by RFC 2483.
|
||||
*
|
||||
* While the RFCs 2046 and 2483 require the lines of text/... formats
|
||||
* to be terminated by CRLF sequence, be prepared for those who don't
|
||||
* read the spec, use plain LFs, and don't leave the trailing CRLF.
|
||||
*/
|
||||
|
||||
while (cur < lim)
|
||||
{
|
||||
BOOL comment = (*cur == '#');
|
||||
|
||||
start = cur;
|
||||
stop = cur;
|
||||
|
||||
for (stop = cur; stop < lim; stop++)
|
||||
{
|
||||
if (*stop == '\r')
|
||||
{
|
||||
if ((stop + 1 < lim) && (*(stop + 1) == '\n'))
|
||||
cur = stop + 2;
|
||||
else
|
||||
cur = stop + 1;
|
||||
break;
|
||||
}
|
||||
if (*stop == '\n')
|
||||
{
|
||||
cur = stop + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stop == lim)
|
||||
cur = lim;
|
||||
|
||||
if (comment)
|
||||
continue;
|
||||
|
||||
if (!process_uri(start, stop - start, files))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user