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

📄 sqlite3odbc.c

📁 定时器for timer for ic chip
💻 C
📖 第 1 页 / 共 5 页
字号:
    ret = cp;
    for (i = 0; i < len; i++) {
	unsigned long c = str[i];

	if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
	    c &= 0xffff;
	}
	if (c < 0xc0) {
	    *cp++ = c;
	} else if (c < 0x800) {
	    *cp++ = 0xc0 | ((c >> 6) & 0x1f);
	    *cp++ = 0x80 | (c & 0x3f);
	} else if (c < 0x10000) {
	    if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
		c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
		unsigned long c2 = str[i + 1] & 0xffff;

		if (c2 >= 0xdc00 && c <= 0xdfff) {
		    c = ((c & 0x3ff) | ((c2 & 0x3ff) << 10)) + 0x10000;
		    *cp++ = 0xf0 | ((c >> 18) & 0x07);
		    *cp++ = 0x80 | ((c >> 12) & 0x3f);
		    *cp++ = 0x80 | ((c >> 6) & 0x3f);
		    *cp++ = 0x80 | (c & 0x3f);
		    ++i;
		    continue;
		}
	    }
	    *cp++ = 0xe0 | ((c >> 12) & 0x0f);
	    *cp++ = 0x80 | ((c >> 6) & 0x3f);
	    *cp++ = 0x80 | (c & 0x3f);
	} else if (c < 0x200000) {
	    *cp++ = 0xf0 | ((c >> 18) & 0x07);
	    *cp++ = 0x80 | ((c >> 12) & 0x3f);
	    *cp++ = 0x80 | ((c >> 6) & 0x3f);
	    *cp++ = 0x80 | (c & 0x3f);
	} else if (c < 0x4000000) {
	    *cp++ = 0xf8 | ((c >> 24) & 0x03);
	    *cp++ = 0x80 | ((c >> 18) & 0x3f);
	    *cp++ = 0x80 | ((c >> 12) & 0x3f);
	    *cp++ = 0x80 | ((c >> 6) & 0x3f);
	    *cp++ = 0x80 | (c & 0x3f);
	} else if (c < 0x80000000) {
	    *cp++ = 0xfc | ((c >> 31) & 0x01);
	    *cp++ = 0x80 | ((c >> 24) & 0x3f);
	    *cp++ = 0x80 | ((c >> 18) & 0x3f);
	    *cp++ = 0x80 | ((c >> 12) & 0x3f);
	    *cp++ = 0x80 | ((c >> 6) & 0x3f);
	    *cp++ = 0x80 | (c & 0x3f);
	}
    }
    *cp = '\0';
    return ret;
}

/**
 * Make UTF8 string from UNICODE string.
 * @param str UNICODE string to be converted
 * @param len length of UNICODE string in characters
 * @return alloc'ed UTF8 string to be free'd by uc_free()
 */

static char *
uc_to_utf_c(SQLWCHAR *str, int len)
{
    if (len != SQL_NTS) {
	len = len * sizeof (SQLWCHAR);
    }
    return uc_to_utf(str, len);
}

#endif /* WINTERFACE */

#if defined(WINTERFACE) || defined(_WIN32)

/**
 * Free converted UTF8 or UNICODE string.
 * @param str string to be free'd
 */

static void
uc_free(void *str)
{
    if (str) {
	xfree(str);
    }
}

#endif

#ifdef _WIN32

/**
 * Convert multibyte, current code page string to UTF8 string,
 * @param str multibyte string to be converted
 * @param len length of multibyte string
 * @return alloc'ed UTF8 string to be free'd by uc_free()
 */

static char *
wmb_to_utf(char *str, int len)
{
    WCHAR *wstr;
    OSVERSIONINFO ovi;
    int nchar, is2k, cp = CP_OEMCP;

    ovi.dwOSVersionInfoSize = sizeof (ovi);
    GetVersionEx(&ovi);
    is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
    if (AreFileApisANSI()) {
	cp = is2k ? CP_THREAD_ACP : CP_ACP;
    }
    nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
    wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
    if (!wstr) {
	return NULL;
    }
    wstr[0] = 0;
    nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
    wstr[nchar] = 0;
    str = xmalloc((nchar + 1) * 7);
    if (!str) {
	xfree(wstr);
	return NULL;
    }
    str[0] = '\0';
    nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
    str[nchar] = '\0';
    xfree(wstr);
    return str;
}

/**
 * Convert UTF8 string to multibyte, current code page string,
 * @param str UTF8 string to be converted
 * @param len length of UTF8 string
 * @return alloc'ed multibyte string to be free'd by uc_free()
 */

static char *
utf_to_wmb(char *str, int len)
{
    WCHAR *wstr;
    OSVERSIONINFO ovi;
    int nchar, is2k, cp = CP_OEMCP;

    ovi.dwOSVersionInfoSize = sizeof (ovi);
    GetVersionEx(&ovi);
    is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
    if (AreFileApisANSI()) {
	cp = is2k ? CP_THREAD_ACP : CP_ACP;
    }
    nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
    wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
    if (!wstr) {
	return NULL;
    }
    wstr[0] = 0;
    nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
    wstr[nchar] = 0;
    str = xmalloc((nchar + 1) * 7);
    if (!str) {
	xfree(wstr);
	return NULL;
    }
    str[0] = '\0';
    nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
    str[nchar] = '\0';
    xfree(wstr);
    return str;
}

#ifdef WINTERFACE

/**
 * Convert multibyte, current code page string to UNICODE string,
 * @param str multibyte string to be converted
 * @param len length of multibyte string
 * @return alloc'ed UNICODE string to be free'd by uc_free()
 */

static WCHAR *
wmb_to_uc(char *str, int len)
{
    WCHAR *wstr;
    OSVERSIONINFO ovi;
    int nchar, is2k, cp = CP_OEMCP;

    ovi.dwOSVersionInfoSize = sizeof (ovi);
    GetVersionEx(&ovi);
    is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
    if (AreFileApisANSI()) {
	cp = is2k ? CP_THREAD_ACP : CP_ACP;
    }
    nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
    wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
    if (!wstr) {
	return NULL;
    }
    wstr[0] = 0;
    nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
    wstr[nchar] = 0;
    return wstr;
}

/**
 * Convert UNICODE string to multibyte, current code page string,
 * @param str UNICODE string to be converted
 * @param len length of UNICODE string
 * @return alloc'ed multibyte string to be free'd by uc_free()
 */

static char *
uc_to_wmb(WCHAR *wstr, int len)
{
    char *str;
    OSVERSIONINFO ovi;
    int nchar, is2k, cp = CP_OEMCP;

    ovi.dwOSVersionInfoSize = sizeof (ovi);
    GetVersionEx(&ovi);
    is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
    if (AreFileApisANSI()) {
	cp = is2k ? CP_THREAD_ACP : CP_ACP;
    }
    nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
    str = xmalloc((nchar + 1) * 2);
    if (!str) {
	return NULL;
    }
    str[0] = '\0';
    nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
    str[nchar] = '\0';
    return str;
}

#endif /* WINTERFACE */

#endif /* _WIN32 */


#ifdef USE_DLOPEN_FOR_GPPS

#include <dlfcn.h>

#define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)

/*
 * EXPERIMENTAL: SQLGetPrivateProfileString infrastructure using
 * dlopen(), in theory this makes the driver independent from the
 * driver manager, i.e. the same driver binary can run with iODBC
 * and unixODBC.
 */

static void
drvgetgpps(DBC *d)
{
    void *lib;
    int (*gpps)();

    lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
    if (!lib) {
	lib = dlopen("libodbcinst.so", RTLD_LAZY);
    }
    if (!lib) {
	lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
    }
    if (!lib) {
	lib = dlopen("libiodbcinst.so", RTLD_LAZY);
    }
    if (lib) {
	gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
	if (!gpps) {
	    dlclose(lib);
	    return;
	}
	d->instlib = lib;
	d->gpps = gpps;
    }
}

static void
drvrelgpps(DBC *d)
{
    if (d->instlib) {
	dlclose(d->instlib);
	d->instlib = 0;
    }
}

static int
drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
	int bufsiz, char *fname)
{
    if (d->gpps) {
	return d->gpps(sect, ent, def, buf, bufsiz, fname);
    }
    strncpy(buf, def, bufsiz);
    buf[bufsiz - 1] = '\0';
    return 1;
}
#else
#include <odbcinst.h>
#define drvgetgpps(d)
#define drvrelgpps(d)
#endif

/*
 * Internal function to bind SQLite3 parameters.
 */

static void
s3bind(sqlite3_stmt *stmt, int nparams, BINDPARM *p)
{
    int i;

    if (stmt && p && nparams > 0) {
	for (i = 0; i < nparams; i++, p++) {
	    switch (p->s3type) {
	    default:
	    case SQLITE_NULL:
		sqlite3_bind_null(stmt, i + 1);
		break;
	    case SQLITE_TEXT:
		sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
				  SQLITE_STATIC);
		break;
	    case SQLITE_BLOB:
		sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
				  SQLITE_STATIC);
		break;
	    case SQLITE_FLOAT:
		sqlite3_bind_double(stmt, i + 1, p->s3dval);
		break;
	    case SQLITE_INTEGER:
		if (p->s3size > sizeof (int)) {
		    sqlite3_bind_int64(stmt, i + 1, p->s3lival);
		} else {
		    sqlite3_bind_int(stmt, i + 1, p->s3ival);
		}
		break;
	    }
	}
    }
}

/*
 * Internal structure for managing driver's
 * sqlite3_get_table() implementation.
 */

typedef struct tblres {
    char **resarr;
    char *errmsg;
    sqlite3_stmt *stmt;
    STMT *s;
    int nres;
    int nalloc;
    int nrow;
    int ncol;
    PTRDIFF_T ndata;
    int rc;
} TBLRES;

/*
 * Driver's version of sqlite3_get_table() and friends which are
 * capable of dealing with blobs.
 */

static int
drvgettable_row(TBLRES *t, int ncol, int rc)
{
    int need;
    int i;
    char *p;

    if (t->nrow == 0 && rc == SQLITE_ROW) {
	need = ncol * 2;
    } else {
	need = ncol;
    }
    if (t->ndata + need >= t->nalloc) {
	char **resnew;
	int nalloc = t->nalloc * 2 + need + 1;

	resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
	if (!resnew) {
nomem:
	    t->rc = SQLITE_NOMEM;
	    return 1;
	}
	t->nalloc = nalloc;
	t->resarr = resnew;
    }
    /* column names when first row */
    if (t->nrow == 0) {
	t->ncol = ncol;
	for (i = 0; i < ncol; i++) {
	    p = (char *) sqlite3_column_name(t->stmt, i);
	    if (p) {
		char *q = xmalloc(strlen(p) + 1);

		if (!q) {
		    goto nomem;
		}
		strcpy(q, p);
		p = q;
	    }
	    t->resarr[t->ndata++] = p;
	}
	if (t->s && t->s->guessed_types) {
	    int ncol2 = ncol;

	    setupdyncols(t->s, t->stmt, &ncol2);
	    t->s->guessed_types = 0;
	    t->s->ncols = ncol;
	}
    } else if (t->ncol != ncol) {
	t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
				    " more incompatible queries");
	t->rc = SQLITE_ERROR;
	return 1;
    }
    /* copy row data */
    if (rc == SQLITE_ROW) {
	for (i = 0; i < ncol; i++) {
	    int coltype = sqlite3_column_type(t->stmt, i);

	    p = NULL;
	    if (coltype == SQLITE_BLOB) {
		int k, nbytes = sqlite3_column_bytes(t->stmt, i);
		char *qp;
		unsigned const char *bp;

		bp = sqlite3_column_blob(t->stmt, i);
		qp = xmalloc(nbytes * 2 + 4);
		if (!qp) {
		    goto nomem;
		}
		p = qp;
		*qp++ = 'X';
		*qp++ = '\'';
		for (k = 0; k < nbytes; k++) {
		    *qp++ = xdigits[(bp[k] >> 4)];
		    *qp++ = xdigits[(bp[k] & 0xF)];
		}
		*qp++ = '\'';
		*qp = '\0';
	    } else if (coltype != SQLITE_NULL) {
		p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
		if (!p) {
		    goto nomem;
		}
	    }
	    t->resarr[t->ndata++] = p;
	}
	t->nrow++;
    }
    return 0;
}

static int
drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
	    int *ncolp, char **errp, int nparam, BINDPARM *p)
{
    DBC *d = (DBC *) s->dbc;
    int rc = SQLITE_OK;
    TBLRES tres;
    const char *sqlleft;
    int nretry = 0, haveerr = 0;

    if (!resp) {
	return SQLITE_ERROR;
    }
    *resp = NULL;
    if (nrowp) {
	*nrowp = 0;
    }
    if (ncolp) {
	*ncolp = 0;
    }
    if (!sql) {
	return SQLITE_OK;
    }
    tres.errmsg = NULL;
    tres.nres = 0;
    tres.nrow = 0;
    tres.ncol = 0;
    tres.ndata = 1;
    tres.nalloc = 20;
    tres.rc = SQLITE_OK;
    tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
    tres.stmt = NULL;
    tres.s = s;
    if (!tres.resarr) {
	return SQLITE_NOMEM;
    }
    tres.resarr[0] = 0;
    while (*sql && (rc == SQLITE_OK ||
		      (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
	int ncol;

	tres.stmt = NULL;
#if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
	dbtraceapi(d, "sqlite3_prepare_v2", sql);
	rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
#else
	dbtraceapi(d, "sqlite3_prepare", sql);
	rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
#endif
	if (rc != SQLITE_OK) {
	    if (tres.stmt) {
		dbtraceapi(d, "sqlite3_finalize", 0);
		sqlite3_finalize(tres.stmt);
		tres.stmt = NULL;
	    }
	    continue;
	}
	if (!tres.stmt) {
	    /* this happens for a comment or white-space */
	    sql = sqlleft;
	    continue;
	}
	if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
	    if (errp) {
		*errp =
		    sqlite3_mprintf("%s", "parameter marker count incorrect");
	    }
	    haveerr = 1;
	    rc = SQLITE_ERROR;
	    goto tbldone;
	}
	s3bind(tres.stmt, nparam, p);
	ncol = sqlite3_column_count(tres.stmt);
	while (1) {
	    rc = sqlite3_step(tres.stmt);
	    if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
		if (drvgettable_row(&tres, ncol, rc)) {
		    rc = SQLITE_ABORT;
		    goto tbldone;
		}
	    }
	    if (rc != SQLITE_ROW) {
		dbtraceapi(d, "sqlite3_finalize", 0);
		rc = sqlite3_finalize(tres.stmt);
		tres.stmt = 0;
		if (rc != SQLITE_SCHEMA) {
		    nretry = 0;
		    sql = sqlleft;
		    while (ISSPACE(*sql)) {
			sql++;
		    }
		}
		if (rc == SQLITE_DONE) {
		    rc = SQLITE_OK;
		}
		break;
	    }
	}
    }
tbldone:
    if (tres.stmt) {
	dbtraceapi(d, "sqlite3_finalize", 0);
	sqlite3_finalize(tres.stmt);
    }
    if (haveerr) {
	/* message already in *errp if any */
    } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
	*errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
    } else if (errp) {
	*errp = NULL;
    }
    if (tres.resarr) {
	tres.resarr[0] = (char *) (tres.ndata - 1);
    }
    if (rc == SQLITE_ABORT) {
	freerows(&tres.resarr[1]);
	if (tres.errmsg) {
	    if (errp) {
		if (*errp) {
		    sqlite3_free(*errp);
		}
		*errp = tres.errmsg;
	    } else {
		sqlite3_free(tres.errmsg);
	    }
	}
	return tres.rc;
    }
    sqlite3_free(tres.errmsg);
    if (rc != SQLITE_OK) {
	freerows(&tres.resarr[1]);
	return rc;
    }

⌨️ 快捷键说明

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