📄 gwinhttpfile.c
字号:
/* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * Author: Alexander Larsson <alexl@redhat.com> * Author: Tor Lillqvist <tml@novell.com> */#include "config.h"#include <string.h>#include <wchar.h>#include "gfile.h"#include "gfileattribute.h"#include "gfileinfo.h"#include "gwinhttpfile.h"#include "gwinhttpfileinputstream.h"#include "gwinhttpfileoutputstream.h"#include "gioerror.h"#include "glibintl.h"#include "gioalias.h"static void g_winhttp_file_file_iface_init (GFileIface *iface);#define g_winhttp_file_get_type _g_winhttp_file_get_typeG_DEFINE_TYPE_WITH_CODE (GWinHttpFile, g_winhttp_file, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_FILE, g_winhttp_file_file_iface_init))static voidg_winhttp_file_finalize (GObject *object){ GWinHttpFile *file; file = G_WINHTTP_FILE (object); g_free (file->url.lpszScheme); g_free (file->url.lpszHostName); g_free (file->url.lpszUserName); g_free (file->url.lpszPassword); g_free (file->url.lpszUrlPath); g_free (file->url.lpszExtraInfo); G_OBJECT_CLASS (g_winhttp_file_parent_class)->finalize (object);}static voidg_winhttp_file_class_init (GWinHttpFileClass *klass){ GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = g_winhttp_file_finalize;}static voidg_winhttp_file_init (GWinHttpFile *winhttp){}/** * _g_winhttp_file_new: * @vfs: GWinHttpVfs to use * @uri: URI of the GWinHttpFile to create. * * Returns: new winhttp #GFile. **/GFile *_g_winhttp_file_new (GWinHttpVfs *vfs, const char *uri){ wchar_t *wuri; GWinHttpFile *file; wuri = g_utf8_to_utf16 (uri, -1, NULL, NULL, NULL); if (wuri == NULL) return NULL; file = g_object_new (G_TYPE_WINHTTP_FILE, NULL); file->vfs = vfs; memset (&file->url, 0, sizeof (file->url)); file->url.dwStructSize = sizeof (file->url); file->url.dwSchemeLength = 1; file->url.dwHostNameLength = 1; file->url.dwUserNameLength = 1; file->url.dwPasswordLength = 1; file->url.dwUrlPathLength = 1; file->url.dwExtraInfoLength = 1; if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url)) { g_free (wuri); return NULL; } file->url.lpszScheme = g_new (wchar_t, ++file->url.dwSchemeLength); file->url.lpszHostName = g_new (wchar_t, ++file->url.dwHostNameLength); file->url.lpszUserName = g_new (wchar_t, ++file->url.dwUserNameLength); file->url.lpszPassword = g_new (wchar_t, ++file->url.dwPasswordLength); file->url.lpszUrlPath = g_new (wchar_t, ++file->url.dwUrlPathLength); file->url.lpszExtraInfo = g_new (wchar_t, ++file->url.dwExtraInfoLength); if (!G_WINHTTP_VFS_GET_CLASS (vfs)->funcs->pWinHttpCrackUrl (wuri, 0, 0, &file->url)) { g_free (file->url.lpszScheme); g_free (file->url.lpszHostName); g_free (file->url.lpszUserName); g_free (file->url.lpszPassword); g_free (file->url.lpszUrlPath); g_free (file->url.lpszExtraInfo); g_free (wuri); return NULL; } g_free (wuri); return G_FILE (file);}static gbooleang_winhttp_file_is_native (GFile *file){ return FALSE;}static gbooleang_winhttp_file_has_uri_scheme (GFile *file, const char *uri_scheme){ return (g_ascii_strcasecmp (uri_scheme, "http") == 0 || g_ascii_strcasecmp (uri_scheme, "https") == 0);}static char *g_winhttp_file_get_uri_scheme (GFile *file){ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); return g_utf16_to_utf8 (winhttp_file->url.lpszScheme, -1, NULL, NULL, NULL);}static char *g_winhttp_file_get_basename (GFile *file){ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); char *basename; char *last_slash; char *retval; basename = g_utf16_to_utf8 (winhttp_file->url.lpszUrlPath, -1, NULL, NULL, NULL); last_slash = strrchr (basename, '/'); /* If no slash, or only "/" fallback to full path part of URI */ if (last_slash == NULL || last_slash[1] == '\0') return basename; retval = g_strdup (last_slash + 1); g_free (basename); return retval;}static char *g_winhttp_file_get_path (GFile *file){ return NULL;}static char *g_winhttp_file_get_uri (GFile *file){ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); DWORD len; wchar_t *wuri; char *retval; len = 0; if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, NULL, &len) && GetLastError () != ERROR_INSUFFICIENT_BUFFER) return NULL; wuri = g_new (wchar_t, ++len); if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->funcs->pWinHttpCreateUrl (&winhttp_file->url, ICU_ESCAPE, wuri, &len)) { g_free (wuri); return NULL; } retval = g_utf16_to_utf8 (wuri, -1, NULL, NULL, NULL); g_free (wuri); if (g_str_has_prefix (retval, "http://:@")) { memmove (retval + 7, retval + 9, strlen (retval) - 9); retval[strlen (retval) - 2] = '\0'; } else if (g_str_has_prefix (retval, "https://:@")) { memmove (retval + 8, retval + 10, strlen (retval) - 10); retval[strlen (retval) - 2] = '\0'; } return retval;}static char *g_winhttp_file_get_parse_name (GFile *file){ /* FIXME: More hair surely needed */ return g_winhttp_file_get_uri (file);}static GFile *g_winhttp_file_get_parent (GFile *file){ GWinHttpFile *winhttp_file; char *uri; char *last_slash; GFile *parent; winhttp_file = G_WINHTTP_FILE (file); uri = g_winhttp_file_get_uri (file); if (uri == NULL) return NULL; last_slash = strrchr (uri, '/'); if (last_slash == NULL || *(last_slash+1) == 0) { g_free (uri); return NULL; } while (last_slash > uri && *last_slash == '/') last_slash--; last_slash[1] = '\0'; parent = _g_winhttp_file_new (winhttp_file->vfs, uri); g_free (uri); return parent;}static GFile *g_winhttp_file_dup (GFile *file){ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); char *uri = g_winhttp_file_get_uri (file); GFile *retval = _g_winhttp_file_new (winhttp_file->vfs, uri); g_free (uri); return retval;}static guintg_winhttp_file_hash (GFile *file){ char *uri = g_winhttp_file_get_uri (file); guint retval = g_str_hash (uri); g_free (uri); return retval;}static gbooleang_winhttp_file_equal (GFile *file1, GFile *file2){ char *uri1 = g_winhttp_file_get_uri (file1); char *uri2 = g_winhttp_file_get_uri (file2); gboolean retval = g_str_equal (uri1, uri2); g_free (uri1); g_free (uri2); return retval;}static const char *match_prefix (const char *path, const char *prefix){ int prefix_len; prefix_len = strlen (prefix); if (strncmp (path, prefix, prefix_len) != 0) return NULL; if (prefix_len > 0 && prefix[prefix_len-1] == '/') prefix_len--; return path + prefix_len;}static gbooleang_winhttp_file_prefix_matches (GFile *parent, GFile *descendant){ char *parent_uri = g_winhttp_file_get_uri (parent); char *descendant_uri = g_winhttp_file_get_uri (descendant); const char *remainder; gboolean retval; remainder = match_prefix (descendant_uri, parent_uri); if (remainder != NULL && *remainder == '/') retval = TRUE; else retval = FALSE; g_free (parent_uri); g_free (descendant_uri); return retval;}static char *g_winhttp_file_get_relative_path (GFile *parent, GFile *descendant){ char *parent_uri = g_winhttp_file_get_uri (parent); char *descendant_uri = g_winhttp_file_get_uri (descendant); const char *remainder; char *retval; remainder = match_prefix (descendant_uri, parent_uri); if (remainder != NULL && *remainder == '/') retval = g_strdup (remainder + 1); else retval = NULL; g_free (parent_uri); g_free (descendant_uri); return retval;}static GFile *g_winhttp_file_resolve_relative_path (GFile *file, const char *relative_path){ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file); GWinHttpFile *child; wchar_t *wnew_path = g_utf8_to_utf16 (relative_path, -1, NULL, NULL, NULL); if (wnew_path == NULL) return NULL; if (*wnew_path != '/') { wchar_t *tmp = g_new (wchar_t, wcslen (winhttp_file->url.lpszUrlPath) + 1 + wcslen (wnew_path) + 1); wcscpy (tmp, winhttp_file->url.lpszUrlPath); wcscat (tmp, L"/"); wcscat (tmp, wnew_path); g_free (wnew_path); wnew_path = tmp; } child = g_object_new (G_TYPE_WINHTTP_FILE, NULL); child->vfs = winhttp_file->vfs; child->url = winhttp_file->url; child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, winhttp_file->url.dwSchemeLength*2); child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, winhttp_file->url.dwHostNameLength*2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -