⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccsidcurl.c

📁 THIS IS HTTP CURL Example
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *                                  _   _ ____  _ *  Project                     ___| | | |  _ \| | *                             / __| | | | |_) | | *                            | (__| |_| |  _ <| |___ *                             \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id: ccsidcurl.c,v 1.5 2008-01-16 16:04:47 patrickm Exp $ * ***************************************************************************//* CCSID API wrappers for OS/400. */#include <iconv.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <stdarg.h>#pragma enum(int)#include <curl/curl.h>#include "urldata.h"#include "url.h"#include "getinfo.h"#include "ccsidcurl.h"#include "os400sys.h"#ifndef SIZE_MAX#define SIZE_MAX        ((size_t) ~0)   /* Is unsigned on OS/400. */#endif#define ASCII_CCSID     819     /* Use ISO-8859-1 as ASCII. */#define NOCONV_CCSID    65535   /* No conversion. */#define ICONV_ID_SIZE   32      /* Size of iconv_open() code identifier. */#define ICONV_OPEN_ERROR(t)     ((t).return_value == -1)#define ALLOC_GRANULE   8       /* Alloc. granule for curl_formadd_ccsid(). */static voidmakeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid){  /**  *** Convert a CCSID to the corresponding IBM iconv_open() character  ***  code identifier.  ***  This code is specific to the OS400 implementation of the iconv library.  ***  CCSID 65535 (no conversion) is replaced by the ASCII CCSID.  ***  CCSID 0 is interpreted by the OS400 as the job's CCSID.  **/  ccsid &= 0xFFFF;  if (ccsid == NOCONV_CCSID)    ccsid = ASCII_CCSID;  memset(buf, 0, ICONV_ID_SIZE);  curl_msprintf(buf, "IBMCCSID%05u0000000", ccsid);}static iconv_ticonv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin, unsigned int cstr){  char fromcode[ICONV_ID_SIZE];  char tocode[ICONV_ID_SIZE];  /**  ***  Like iconv_open(), but character codes are given as CCSIDs.  ***  If `cstr' is non-zero, conversion is set up to stop whenever a  ***   null character is encountered.  ***  See iconv_open() IBM description in "National Language Support API".  **/  makeOS400IconvCode(fromcode, ccsidin);  makeOS400IconvCode(tocode, ccsidout);  memset(tocode + 13, 0, sizeof tocode - 13);   /* Dest. code id format. */  if (cstr)    fromcode[18] = '1';                         /* Set null-terminator flag. */  return iconv_open(tocode, fromcode);}static intconvert(char * d, size_t dlen, int dccsid,        const char * s, int slen, int sccsid){  int i;  iconv_t cd;  size_t lslen;  /**  ***  Convert `sccsid'-coded `slen'-data bytes at `s' into `dccsid'-coded  ***   data stored in the `dlen'-byte buffer at `d'.  ***  If `slen' < 0, source string is null-terminated.  ***  CCSID 65535 (no conversion) is replaced by the ASCII CCSID.  ***  Return the converted destination byte count, or -1 if error.  **/  if (sccsid == 65535)    sccsid = ASCII_CCSID;  if (dccsid == 65535)    dccsid = ASCII_CCSID;  if (sccsid == dccsid) {    lslen = slen >= 0? slen: strlen(s) + 1;    i = lslen < dlen? lslen: dlen;    if (s != d && i > 0)      memcpy(d, s, i);    return i;    }  if (slen < 0) {    lslen = 0;    cd = iconv_open_CCSID(dccsid, sccsid, 1);    }  else {    lslen = (size_t) slen;    cd = iconv_open_CCSID(dccsid, sccsid, 0);    }  if (ICONV_OPEN_ERROR(cd))    return -1;  i = dlen;  if ((int) iconv(cd, (char * *) &s, &lslen, &d, &dlen) < 0)    i = -1;  else    i -= dlen;  iconv_close(cd);  return i;}static char *dynconvert(int dccsid, const char * s, int slen, int sccsid){  char * d;  char * cp;  size_t dlen;  int l;  int l2;  static const char nullbyte = 0;  /* Like convert, but the destination is allocated and returned. */  dlen = (size_t) (slen < 0? strlen(s): slen) + 1;  dlen *= MAX_CONV_EXPANSION;           /* Allow some expansion. */  d = malloc(dlen);  if (!d)    return (char *) NULL;  l = convert(d, dlen, dccsid, s, slen, sccsid);  if (l < 0) {    free(d);    return (char *) NULL;    }  if (slen < 0) {    /* Need to null-terminate even when source length is given.       Since destination code size is unknown, use a conversion to generate       terminator. */    l2 = convert(d + l, dlen - l, dccsid, &nullbyte, -1, ASCII_CCSID);    if (l2 < 0) {      free(d);      return (char *) NULL;      }    l += l2;    }  if ((size_t) l < dlen) {    cp = realloc(d, l);         /* Shorten to minimum needed. */    if (cp)      d = cp;    }  return d;}char *curl_version_ccsid(unsigned int ccsid){  int i;  char * aversion;  char * eversion;  aversion = curl_version();  if (!aversion)    return aversion;  i = strlen(aversion) + 1;  i *= MAX_CONV_EXPANSION;  if (!(eversion = Curl_thread_buffer(LK_CURL_VERSION, i)))    return (char *) NULL;  if (convert(eversion, i, ccsid, aversion, -1, ASCII_CCSID) < 0)    return (char *) NULL;  return eversion;}char *curl_easy_escape_ccsid(CURL * handle, const char * string, int length,                       unsigned int sccsid, unsigned int dccsid){  char * s;  char * d;  if (!string) {    errno = EINVAL;    return (char *) NULL;    }  s = dynconvert(ASCII_CCSID, s, length? length: -1, sccsid);  if (!s)    return (char *) NULL;  d = curl_easy_escape(handle, s, 0);  free(s);  if (!d)    return (char *) NULL;  s = dynconvert(dccsid, d, -1, ASCII_CCSID);  free(d);  return s;}char *curl_easy_unescape_ccsid(CURL * handle, const char * string, int length,                         int * outlength,                         unsigned int sccsid, unsigned int dccsid){  char * s;  char * d;  if (!string) {    errno = EINVAL;    return (char *) NULL;    }  s = dynconvert(ASCII_CCSID, s, length? length: -1, sccsid);  if (!s)    return (char *) NULL;  d = curl_easy_unescape(handle, s, 0, outlength);  free(s);  if (!d)    return (char *) NULL;  s = dynconvert(dccsid, d, -1, ASCII_CCSID);  free(d);  if (s && outlength)    *outlength = strlen(s);  return s;}struct curl_slist *curl_slist_append_ccsid(struct curl_slist * list,                        const char * data, unsigned int ccsid){  char * s;  s = (char *) NULL;  if (!data)    return curl_slist_append(list, data);  s = dynconvert(ASCII_CCSID, data, -1, ccsid);  if (!s)    return (struct curl_slist *) NULL;  list = curl_slist_append(list, s);  free(s);  return list;}time_tcurl_getdate_ccsid(const char * p, const time_t * unused, unsigned int ccsid){  char * s;  time_t t;  if (!p)    return curl_getdate(p, unused);  s = dynconvert(ASCII_CCSID, p, -1, ccsid);  if (!s)    return (time_t) -1;  t = curl_getdate(s, unused);  free(s);  return t;}static intconvert_version_info_string(const char * * stringp,                            char * * bufp, int * left, unsigned int ccsid){  int l;  /* Helper for curl_version_info_ccsid(): convert a string if defined.     Result is stored in the `*left'-byte buffer at `*bufp'.     `*bufp' and `*left' are updated accordingly.     Return 0 if ok, else -1. */  if (*stringp) {    l = convert(*bufp, *left, ccsid, *stringp, -1, ASCII_CCSID);    if (l <= 0)      return -1;    *stringp = *bufp;    *bufp += l;    *left -= l;    }  return 0;}curl_version_info_data *curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid){  curl_version_info_data * p;  char * cp;  int n;  int nproto;  int i;  curl_version_info_data * id;  /* The assertion below is possible, because although the second operand     is an enum member, the first is a #define. In that case, the OS/400 C     compiler seems to compare string values after substitution. */#if CURLVERSION_NOW != CURLVERSION_FOURTH#error curl_version_info_data structure has changed: upgrade this procedure too.#endif  /* If caller has been compiled with a new version, error. */  if (stamp > CURLVERSION_NOW)    return (curl_version_info_data *) NULL;  p = curl_version_info(stamp);  if (!p)    return p;  /* Measure thread space needed. */  n = 0;  nproto = 0;  if (p->protocols) {    while (p->protocols[nproto])      n += strlen(p->protocols[nproto++]);    n += nproto++;    }  if (p->version)    n += strlen(p->version) + 1;  if (p->host)    n += strlen(p->host) + 1;  if (p->ssl_version)    n += strlen(p->ssl_version) + 1;  if (p->libz_version)    n += strlen(p->libz_version) + 1;  if (p->ares)    n += strlen(p->ares) + 1;  if (p->libidn)    n += strlen(p->libidn) + 1;  if (p->libssh_version)    n += strlen(p->libssh_version) + 1;  /* Allocate thread space. */  n *= MAX_CONV_EXPANSION;  if (nproto)    n += nproto * sizeof(const char *);  cp = Curl_thread_buffer(LK_VERSION_INFO_DATA, n);  id = (curl_version_info_data *) Curl_thread_buffer(LK_VERSION_INFO,                                                     sizeof *id);  if (!id || !cp)    return (curl_version_info_data *) NULL;  /* Copy data and convert strings. */  memcpy((char *) id, (char *) p, sizeof *p);  if (id->protocols) {    id->protocols = (const char * const *) cp;    i = nproto * sizeof id->protocols[0];    memcpy(cp, (char *) p->protocols, i);    cp += i;    n -= i;    for (i = 0; id->protocols[i]; i++)      if (convert_version_info_string(((const char * *) id->protocols) + i,                                      &cp, &n, ccsid))        return (curl_version_info_data *) NULL;    }  if (convert_version_info_string(&id->version, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  if (convert_version_info_string(&id->host, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  if (convert_version_info_string(&id->ssl_version, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  if (convert_version_info_string(&id->libz_version, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  if (convert_version_info_string(&id->ares, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  if (convert_version_info_string(&id->libidn, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  if (convert_version_info_string(&id->libssh_version, &cp, &n, ccsid))    return (curl_version_info_data *) NULL;  return id;}const char *curl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid){  int i;  const char * s;  char * buf;  s = curl_easy_strerror(error);  if (!s)    return s;  i = MAX_CONV_EXPANSION * (strlen(s) + 1);  if (!(buf = Curl_thread_buffer(LK_EASY_STRERROR, i)))    return (const char *) NULL;  if (convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)    return (const char *) NULL;  return (const char *) buf;}const char *curl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid){  int i;  const char * s;  char * buf;  s = curl_share_strerror(error);  if (!s)    return s;  i = MAX_CONV_EXPANSION * (strlen(s) + 1);  if (!(buf = Curl_thread_buffer(LK_SHARE_STRERROR, i)))    return (const char *) NULL;  if (convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)    return (const char *) NULL;  return (const char *) buf;}const char *curl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid){  int i;  const char * s;  char * buf;  s = curl_multi_strerror(error);  if (!s)    return s;  i = MAX_CONV_EXPANSION * (strlen(s) + 1);  if (!(buf = Curl_thread_buffer(LK_MULTI_STRERROR, i)))    return (const char *) NULL;  if (convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)    return (const char *) NULL;  return (const char *) buf;}CURLcodecurl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...){  va_list arg;  void * paramp;  CURLcode ret;  unsigned int ccsid;  char * * cpp;  char * s;  char * d;  struct SessionHandle * data;  /* WARNING: unlike curl_easy_get_info(), the strings returned by this     procedure have to be free'ed. */  data = (struct SessionHandle *) curl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -