~ubuntu-branches/ubuntu/raring/curl/raring-proposed

« back to all changes in this revision

Viewing changes to docs/examples/htmltitle.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-02-12 08:54:32 UTC
  • mfrom: (3.4.34 sid)
  • Revision ID: package-import@ubuntu.com-20130212085432-r1fyi0b37enr93pp
Tags: 7.29.0-1ubuntu1
* Resynchronise with Debian. Remaining changes:
  - Drop dependencies not in main:
    + Build-Depends: Drop stunnel4 and libssh2-1-dev.
    + Drop libssh2-1-dev from binary package Depends.
  - Add new libcurl3-udeb package.
  - Add new curl-udeb package.
* Add warning to debian/patches/series.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *                                  _   _ ____  _
3
 
 *  Project                     ___| | | |  _ \| |
4
 
 *                             / __| | | | |_) | |
5
 
 *                            | (__| |_| |  _ <| |___
6
 
 *                             \___|\___/|_| \_\_____|
7
 
 *
8
 
 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
9
 
 *
10
 
 * This software is licensed as described in the file COPYING, which
11
 
 * you should have received as part of this distribution. The terms
12
 
 * are also available at http://curl.haxx.se/docs/copyright.html.
13
 
 *
14
 
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 
 * copies of the Software, and permit persons to whom the Software is
16
 
 * furnished to do so, under the terms of the COPYING file.
17
 
 *
18
 
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 
 * KIND, either express or implied.
20
 
 *
21
 
 ***************************************************************************/
22
 
// Get a web page, parse it with libxml.
23
 
//
24
 
// Written by Lars Nilsson
25
 
//
26
 
// GNU C++ compile command line suggestion (edit paths accordingly):
27
 
//
28
 
// g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cc \
29
 
// -o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
30
 
 
31
 
#include <stdio.h>
32
 
#include <string.h>
33
 
#include <stdlib.h>
34
 
#include <string>
35
 
#include <curl/curl.h>
36
 
#include <libxml/HTMLparser.h>
37
 
 
38
 
//
39
 
//  Case-insensitive string comparison
40
 
//
41
 
 
42
 
#ifdef _MSC_VER
43
 
#define COMPARE(a, b) (!stricmp((a), (b)))
44
 
#else
45
 
#define COMPARE(a, b) (!strcasecmp((a), (b)))
46
 
#endif
47
 
 
48
 
//
49
 
//  libxml callback context structure
50
 
//
51
 
 
52
 
struct Context
53
 
{
54
 
  Context(): addTitle(false) { }
55
 
 
56
 
  bool addTitle;
57
 
  std::string title;
58
 
};
59
 
 
60
 
//
61
 
//  libcurl variables for error strings and returned data
62
 
 
63
 
static char errorBuffer[CURL_ERROR_SIZE];
64
 
static std::string buffer;
65
 
 
66
 
//
67
 
//  libcurl write callback function
68
 
//
69
 
 
70
 
static int writer(char *data, size_t size, size_t nmemb,
71
 
                  std::string *writerData)
72
 
{
73
 
  if (writerData == NULL)
74
 
    return 0;
75
 
 
76
 
  writerData->append(data, size*nmemb);
77
 
 
78
 
  return size * nmemb;
79
 
}
80
 
 
81
 
//
82
 
//  libcurl connection initialization
83
 
//
84
 
 
85
 
static bool init(CURL *&conn, char *url)
86
 
{
87
 
  CURLcode code;
88
 
 
89
 
  conn = curl_easy_init();
90
 
 
91
 
  if (conn == NULL)
92
 
  {
93
 
    fprintf(stderr, "Failed to create CURL connection\n");
94
 
 
95
 
    exit(EXIT_FAILURE);
96
 
  }
97
 
 
98
 
  code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
99
 
  if (code != CURLE_OK)
100
 
  {
101
 
    fprintf(stderr, "Failed to set error buffer [%d]\n", code);
102
 
 
103
 
    return false;
104
 
  }
105
 
 
106
 
  code = curl_easy_setopt(conn, CURLOPT_URL, url);
107
 
  if (code != CURLE_OK)
108
 
  {
109
 
    fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
110
 
 
111
 
    return false;
112
 
  }
113
 
 
114
 
  code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
115
 
  if (code != CURLE_OK)
116
 
  {
117
 
    fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
118
 
 
119
 
    return false;
120
 
  }
121
 
 
122
 
  code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
123
 
  if (code != CURLE_OK)
124
 
  {
125
 
    fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
126
 
 
127
 
    return false;
128
 
  }
129
 
 
130
 
  code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
131
 
  if (code != CURLE_OK)
132
 
  {
133
 
    fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
134
 
 
135
 
    return false;
136
 
  }
137
 
 
138
 
  return true;
139
 
}
140
 
 
141
 
//
142
 
//  libxml start element callback function
143
 
//
144
 
 
145
 
static void StartElement(void *voidContext,
146
 
                         const xmlChar *name,
147
 
                         const xmlChar **attributes)
148
 
{
149
 
  Context *context = (Context *)voidContext;
150
 
 
151
 
  if (COMPARE((char *)name, "TITLE"))
152
 
  {
153
 
    context->title = "";
154
 
    context->addTitle = true;
155
 
  }
156
 
  (void) attributes;
157
 
}
158
 
 
159
 
//
160
 
//  libxml end element callback function
161
 
//
162
 
 
163
 
static void EndElement(void *voidContext,
164
 
                       const xmlChar *name)
165
 
{
166
 
  Context *context = (Context *)voidContext;
167
 
 
168
 
  if (COMPARE((char *)name, "TITLE"))
169
 
    context->addTitle = false;
170
 
}
171
 
 
172
 
//
173
 
//  Text handling helper function
174
 
//
175
 
 
176
 
static void handleCharacters(Context *context,
177
 
                             const xmlChar *chars,
178
 
                             int length)
179
 
{
180
 
  if (context->addTitle)
181
 
    context->title.append((char *)chars, length);
182
 
}
183
 
 
184
 
//
185
 
//  libxml PCDATA callback function
186
 
//
187
 
 
188
 
static void Characters(void *voidContext,
189
 
                       const xmlChar *chars,
190
 
                       int length)
191
 
{
192
 
  Context *context = (Context *)voidContext;
193
 
 
194
 
  handleCharacters(context, chars, length);
195
 
}
196
 
 
197
 
//
198
 
//  libxml CDATA callback function
199
 
//
200
 
 
201
 
static void cdata(void *voidContext,
202
 
                  const xmlChar *chars,
203
 
                  int length)
204
 
{
205
 
  Context *context = (Context *)voidContext;
206
 
 
207
 
  handleCharacters(context, chars, length);
208
 
}
209
 
 
210
 
//
211
 
//  libxml SAX callback structure
212
 
//
213
 
 
214
 
static htmlSAXHandler saxHandler =
215
 
{
216
 
  NULL,
217
 
  NULL,
218
 
  NULL,
219
 
  NULL,
220
 
  NULL,
221
 
  NULL,
222
 
  NULL,
223
 
  NULL,
224
 
  NULL,
225
 
  NULL,
226
 
  NULL,
227
 
  NULL,
228
 
  NULL,
229
 
  NULL,
230
 
  StartElement,
231
 
  EndElement,
232
 
  NULL,
233
 
  Characters,
234
 
  NULL,
235
 
  NULL,
236
 
  NULL,
237
 
  NULL,
238
 
  NULL,
239
 
  NULL,
240
 
  NULL,
241
 
  cdata,
242
 
  NULL
243
 
};
244
 
 
245
 
//
246
 
//  Parse given (assumed to be) HTML text and return the title
247
 
//
248
 
 
249
 
static void parseHtml(const std::string &html,
250
 
                      std::string &title)
251
 
{
252
 
  htmlParserCtxtPtr ctxt;
253
 
  Context context;
254
 
 
255
 
  ctxt = htmlCreatePushParserCtxt(&saxHandler, &context, "", 0, "",
256
 
                                  XML_CHAR_ENCODING_NONE);
257
 
 
258
 
  htmlParseChunk(ctxt, html.c_str(), html.size(), 0);
259
 
  htmlParseChunk(ctxt, "", 0, 1);
260
 
 
261
 
  htmlFreeParserCtxt(ctxt);
262
 
 
263
 
  title = context.title;
264
 
}
265
 
 
266
 
int main(int argc, char *argv[])
267
 
{
268
 
  CURL *conn = NULL;
269
 
  CURLcode code;
270
 
  std::string title;
271
 
 
272
 
  // Ensure one argument is given
273
 
 
274
 
  if (argc != 2)
275
 
  {
276
 
    fprintf(stderr, "Usage: %s <url>\n", argv[0]);
277
 
 
278
 
    exit(EXIT_FAILURE);
279
 
  }
280
 
 
281
 
  curl_global_init(CURL_GLOBAL_DEFAULT);
282
 
 
283
 
  // Initialize CURL connection
284
 
 
285
 
  if (!init(conn, argv[1]))
286
 
  {
287
 
    fprintf(stderr, "Connection initializion failed\n");
288
 
 
289
 
    exit(EXIT_FAILURE);
290
 
  }
291
 
 
292
 
  // Retrieve content for the URL
293
 
 
294
 
  code = curl_easy_perform(conn);
295
 
  curl_easy_cleanup(conn);
296
 
 
297
 
  if (code != CURLE_OK)
298
 
  {
299
 
    fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
300
 
 
301
 
    exit(EXIT_FAILURE);
302
 
  }
303
 
 
304
 
  // Parse the (assumed) HTML code
305
 
 
306
 
  parseHtml(buffer, title);
307
 
 
308
 
  // Display the extracted title
309
 
 
310
 
  printf("Title: %s\n", title.c_str());
311
 
 
312
 
  return EXIT_SUCCESS;
313
 
}