~ubuntu-branches/debian/squeeze/glib2.0/squeeze

« back to all changes in this revision

Viewing changes to gio/win32/gwinhttpfileoutputstream.c

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo Noronha Silva
  • Date: 2009-02-15 13:00:43 UTC
  • mfrom: (1.3.1 upstream) (69.1.10 intrepid)
  • Revision ID: james.westby@ubuntu.com-20090215130043-q47fbt3owmt42m2f
Tags: 2.18.4-2
* Release to unstable
* debian/rules:
- bump SHVER, since we are already forcing a 2.18.0 dependecy on the
  symbols introduced in the development versions
* debian/control.in:
- added Homepage and Vcs-* control fields

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* GIO - GLib Input, Output and Streaming Library
 
2
 *
 
3
 * Copyright (C) 2006-2007 Red Hat, Inc.
 
4
 * Copyright (C) 2008 Novell, Inc.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General
 
17
 * Public License along with this library; if not, write to the
 
18
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 
19
 * Boston, MA 02111-1307, USA.
 
20
 *
 
21
 * Author: Alexander Larsson <alexl@redhat.com>
 
22
 * Author: Tor Lillqvist <tml@novell.com>
 
23
 */
 
24
 
 
25
#include "config.h"
 
26
 
 
27
#include <glib.h>
 
28
 
 
29
#include "gcancellable.h"
 
30
#include "gioerror.h"
 
31
#include "gwinhttpfileoutputstream.h"
 
32
#include "glibintl.h"
 
33
 
 
34
#include "gioalias.h"
 
35
 
 
36
struct _GWinHttpFileOutputStream
 
37
{
 
38
  GFileOutputStream parent_instance;
 
39
 
 
40
  GWinHttpFile *file;
 
41
  HINTERNET connection;
 
42
  goffset offset;
 
43
};
 
44
 
 
45
struct _GWinHttpFileOutputStreamClass
 
46
{
 
47
  GFileOutputStreamClass parent_class;
 
48
};
 
49
 
 
50
#define g_winhttp_file_output_stream_get_type _g_winhttp_file_output_stream_get_type
 
51
G_DEFINE_TYPE (GWinHttpFileOutputStream, g_winhttp_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM);
 
52
 
 
53
static gssize     g_winhttp_file_output_stream_write      (GOutputStream     *stream,
 
54
                                                           const void        *buffer,
 
55
                                                           gsize              count,
 
56
                                                           GCancellable      *cancellable,
 
57
                                                           GError           **error);
 
58
 
 
59
static void
 
60
g_winhttp_file_output_stream_finalize (GObject *object)
 
61
{
 
62
  GWinHttpFileOutputStream *winhttp_stream;
 
63
 
 
64
  winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (object);
 
65
 
 
66
  if (winhttp_stream->connection != NULL)
 
67
    G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (winhttp_stream->connection);
 
68
 
 
69
  G_OBJECT_CLASS (g_winhttp_file_output_stream_parent_class)->finalize (object);
 
70
}
 
71
 
 
72
static void
 
73
g_winhttp_file_output_stream_class_init (GWinHttpFileOutputStreamClass *klass)
 
74
{
 
75
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
76
  GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
 
77
 
 
78
  gobject_class->finalize = g_winhttp_file_output_stream_finalize;
 
79
 
 
80
  stream_class->write_fn = g_winhttp_file_output_stream_write;
 
81
}
 
82
 
 
83
static void
 
84
g_winhttp_file_output_stream_init (GWinHttpFileOutputStream *info)
 
85
{
 
86
}
 
87
 
 
88
/**
 
89
 * g_winhttp_file_output_stream_new:
 
90
 * @file: the GWinHttpFile being read
 
91
 * @connection: handle to the HTTP connection, as from WinHttpConnect()
 
92
 * @request: handle to the HTTP request, as from WinHttpOpenRequest
 
93
 *
 
94
 * Returns: #GFileOutputStream for the given request
 
95
 **/
 
96
GFileOutputStream *
 
97
_g_winhttp_file_output_stream_new (GWinHttpFile *file,
 
98
                                   HINTERNET     connection)
 
99
{
 
100
  GWinHttpFileOutputStream *stream;
 
101
 
 
102
  stream = g_object_new (G_TYPE_WINHTTP_FILE_OUTPUT_STREAM, NULL);
 
103
 
 
104
  stream->file = file;
 
105
  stream->connection = connection;
 
106
  stream->offset = 0;
 
107
 
 
108
  return G_FILE_OUTPUT_STREAM (stream);
 
109
}
 
110
 
 
111
static gssize
 
112
g_winhttp_file_output_stream_write (GOutputStream  *stream,
 
113
                                    const void     *buffer,
 
114
                                    gsize           count,
 
115
                                    GCancellable   *cancellable,
 
116
                                    GError        **error)
 
117
{
 
118
  GWinHttpFileOutputStream *winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (stream);
 
119
  HINTERNET request;
 
120
  char *headers;
 
121
  wchar_t *wheaders;
 
122
  DWORD bytes_written;
 
123
 
 
124
  request = G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpOpenRequest
 
125
    (winhttp_stream->connection,
 
126
     L"PUT",
 
127
     winhttp_stream->file->url.lpszUrlPath,
 
128
     NULL,
 
129
     WINHTTP_NO_REFERER,
 
130
     NULL,
 
131
     winhttp_stream->file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0);
 
132
 
 
133
  if (request == NULL)
 
134
    {
 
135
      _g_winhttp_set_error (error, GetLastError (), "PUT request");
 
136
 
 
137
      return -1;
 
138
    }
 
139
 
 
140
  headers = g_strdup_printf ("Content-Range: bytes %" G_GINT64_FORMAT "-%" G_GINT64_FORMAT "/*\r\n",
 
141
                             winhttp_stream->offset, winhttp_stream->offset + count);
 
142
  wheaders = g_utf8_to_utf16 (headers, -1, NULL, NULL, NULL);
 
143
  g_free (headers);
 
144
 
 
145
  if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpSendRequest
 
146
      (request,
 
147
       wheaders, -1,
 
148
       NULL, 0,
 
149
       count,
 
150
       0))
 
151
    {
 
152
      _g_winhttp_set_error (error, GetLastError (), "PUT request");
 
153
 
 
154
      G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
 
155
      g_free (wheaders);
 
156
 
 
157
      return -1;
 
158
    }
 
159
 
 
160
  g_free (wheaders);
 
161
 
 
162
  if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpWriteData
 
163
      (request, buffer, count, &bytes_written))
 
164
    {
 
165
      _g_winhttp_set_error (error, GetLastError (), "PUT request");
 
166
 
 
167
      G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
 
168
 
 
169
      return -1;
 
170
    }
 
171
 
 
172
  winhttp_stream->offset += bytes_written;
 
173
 
 
174
  if (!_g_winhttp_response (winhttp_stream->file->vfs,
 
175
                            request,
 
176
                            error,
 
177
                            "PUT request"))
 
178
    {
 
179
      G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
 
180
 
 
181
      return -1;
 
182
    }
 
183
 
 
184
  G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->funcs->pWinHttpCloseHandle (request);
 
185
 
 
186
  return bytes_written;
 
187
}