00001
00186 #ifdef STANDALONE
00187 #include <sqlite3.h>
00188 #else
00189 #include <sqlite3ext.h>
00190 static SQLITE_EXTENSION_INIT1
00191 #endif
00192
00193 #include <stdlib.h>
00194 #include <string.h>
00195 #include <stdarg.h>
00196 #include <stdio.h>
00197
00198 #ifdef _WIN32
00199 #define strcasecmp _stricmp
00200 #define strncasecmp _strnicmp
00201 #define vsnprintf _vsnprintf
00202 #endif
00203
00204 #define TYPE_CODE(num, type) (((num) << 8) | (sizeof (type)))
00205 #define TYPE_SIZE(code) ((code) & 0xFF)
00206
00207 #define TYPE_CHAR TYPE_CODE( 0, char)
00208 #define TYPE_UCHAR TYPE_CODE( 1, char)
00209 #define TYPE_SHORT_LE TYPE_CODE( 2, short)
00210 #define TYPE_USHORT_LE TYPE_CODE( 3, short)
00211 #define TYPE_SHORT_BE TYPE_CODE( 4, short)
00212 #define TYPE_USHORT_BE TYPE_CODE( 5, short)
00213 #define TYPE_INT_LE TYPE_CODE( 6, int)
00214 #define TYPE_UINT_LE TYPE_CODE( 7, int)
00215 #define TYPE_INT_BE TYPE_CODE( 8, int)
00216 #define TYPE_UINT_BE TYPE_CODE( 9, int)
00217 #define TYPE_BIGINT_LE TYPE_CODE(10, sqlite_int64)
00218 #define TYPE_BIGINT_BE TYPE_CODE(11, sqlite_int64)
00219 #define TYPE_FLOAT TYPE_CODE(12, float)
00220 #define TYPE_DOUBLE TYPE_CODE(13, double)
00221
00228 typedef struct b2xy_table {
00229 sqlite3_vtab base;
00230 sqlite3 *db;
00231 char *master_table;
00232 char *fq_master_table;
00233 char *key_column;
00234 char *blob_column;
00235 char *x_scale_column;
00236 char *x_offset_column;
00237 char *y_scale_column;
00238 char *y_offset_column;
00239 char *other_columns;
00240 int type;
00241 int do_x_sl;
00242 int x_start, x_length;
00243 int argc;
00244 char **argv;
00245 } b2xy_table;
00246
00253 typedef struct b2xy_cursor {
00254 sqlite3_vtab_cursor base;
00255 b2xy_table *table;
00256 sqlite3_stmt *select;
00257 sqlite3_value *key;
00258 int fix_cols;
00259 int num_cols;
00260 char *val;
00261 int val_len;
00262 int x_scale_col;
00263 int x_offset_col;
00264 double x_scale, x_offset;
00265 int y_scale_col;
00266 int y_offset_col;
00267 double y_scale, y_offset;
00268 int do_x_scale;
00269 int do_y_scale;
00270 int do_x_sl;
00271 int x_start, x_length;
00272 int type;
00273 int index;
00274 int rowid_from_key;
00275 sqlite_int64 rowid;
00276 } b2xy_cursor;
00277
00284 static int
00285 string_to_type(const char *str)
00286 {
00287 if (strcasecmp(str, "char") == 0) {
00288 return TYPE_CHAR;
00289 }
00290 if (strcasecmp(str, "uchar") == 0) {
00291 return TYPE_UCHAR;
00292 }
00293 if (strcasecmp(str, "short_le") == 0) {
00294 return TYPE_SHORT_LE;
00295 }
00296 if (strcasecmp(str, "ushort_le") == 0) {
00297 return TYPE_USHORT_LE;
00298 }
00299 if (strcasecmp(str, "short_be") == 0) {
00300 return TYPE_SHORT_BE;
00301 }
00302 if (strcasecmp(str, "ushort_be") == 0) {
00303 return TYPE_USHORT_BE;
00304 }
00305 if (strcasecmp(str, "int_le") == 0) {
00306 return TYPE_INT_LE;
00307 }
00308 if (strcasecmp(str, "uint_le") == 0) {
00309 return TYPE_UINT_LE;
00310 }
00311 if (strcasecmp(str, "int_be") == 0) {
00312 return TYPE_INT_BE;
00313 }
00314 if (strcasecmp(str, "uint_be") == 0) {
00315 return TYPE_UINT_BE;
00316 }
00317 if (strcasecmp(str, "bigint_le") == 0) {
00318 return TYPE_BIGINT_LE;
00319 }
00320 if (strcasecmp(str, "bigint_be") == 0) {
00321 return TYPE_BIGINT_BE;
00322 }
00323 if (strcasecmp(str, "float") == 0) {
00324 return TYPE_FLOAT;
00325 }
00326 if (strcasecmp(str, "double") == 0) {
00327 return TYPE_DOUBLE;
00328 }
00329 return 0;
00330 }
00331
00338 static int
00339 b2xy_destroy(sqlite3_vtab *vtab)
00340 {
00341 b2xy_table *bt = (b2xy_table *) vtab;
00342
00343 sqlite3_free(bt);
00344 return SQLITE_OK;
00345 }
00346
00375 static int
00376 b2xy_create(sqlite3 *db, void *userdata, int argc,
00377 const char * const *argv, sqlite3_vtab **vtabret, char **errp)
00378 {
00379 int rc = SQLITE_NOMEM;
00380 b2xy_table *bt;
00381 int i, size, type = TYPE_CHAR;
00382 int x_start = -1, x_length = 0;
00383
00384 if (argc < 6) {
00385 *errp = sqlite3_mprintf("need at least 3 arguments");
00386 return SQLITE_ERROR;
00387 }
00388 if (argc > 6) {
00389 type = string_to_type(argv[6]);
00390 if (!type) {
00391 *errp = sqlite3_mprintf("unsupported type %Q", argv[6]);
00392 return SQLITE_ERROR;
00393 }
00394 }
00395 if (argc > 11) {
00396 if ((argv[11][0] != '"') && (argv[11][0] != '\'')) {
00397 *errp = sqlite3_mprintf("other columns must be quoted");
00398 return SQLITE_ERROR;
00399 }
00400 }
00401 if (argc > 12) {
00402 char *endp = 0;
00403
00404 x_start = strtol(argv[12], &endp, 10);
00405 if ((endp == argv[12]) || (endp && (endp[0] != '\0'))) {
00406 *errp = sqlite3_mprintf("X start index must be integer");
00407 return SQLITE_ERROR;
00408 }
00409 if (x_start < 0) {
00410 *errp = sqlite3_mprintf("X start index must be >= 0");
00411 return SQLITE_ERROR;
00412 }
00413 }
00414 if (argc > 13) {
00415 char *endp = 0;
00416
00417 x_length = strtol(argv[13], &endp, 10);
00418 if ((endp == argv[13]) || (endp && (endp[0] != '\0'))) {
00419 *errp = sqlite3_mprintf("X length must be integer");
00420 return SQLITE_ERROR;
00421 }
00422 if (x_length <= 0) {
00423 *errp = sqlite3_mprintf("X length must be > 0");
00424 return SQLITE_ERROR;
00425 }
00426 }
00427 size = sizeof (char *) * argc;
00428 for (i = 0; i < argc; i++) {
00429 size += argv[i] ? (strlen(argv[i]) + 1) : 0;
00430 }
00431
00432 size += argv[1] ? (strlen(argv[1]) + 3) : 3;
00433 size += argv[3] ? (strlen(argv[3]) + 3) : 0;
00434 bt = sqlite3_malloc(sizeof (b2xy_table) + size);
00435 if (bt) {
00436 char *p, *key_type = 0, *x_type, *y_type, *other_types = 0;
00437
00438 memset(bt, 0, sizeof (b2xy_table) + size);
00439 bt->db = db;
00440 bt->type = type;
00441 bt->x_start = x_start;
00442 bt->x_length = x_length;
00443 bt->do_x_sl = (x_start >= 0) || (x_length > 0);
00444 if (bt->x_start < 0) {
00445 bt->x_start = 0;
00446 }
00447 bt->argc = argc;
00448 bt->argv = (char **) (bt + 1);
00449 p = (char *) (bt->argv + argc);
00450 for (i = 0; i < argc; i++) {
00451 if (argv[i]) {
00452 bt->argv[i] = p;
00453 strcpy(p, argv[i]);
00454 p += strlen(p) + 1;
00455 }
00456 }
00457 bt->master_table = bt->argv[3];
00458 bt->fq_master_table = p;
00459 p[0] = '\0';
00460 if (bt->argv[1]) {
00461 strcat(p, "\"");
00462 strcat(p, bt->argv[1]);
00463 strcat(p, "\".");
00464 }
00465 if (bt->argv[3]) {
00466 strcat(p, "\"");
00467 strcat(p, bt->argv[3]);
00468 strcat(p, "\"");
00469 }
00470 bt->key_column = bt->argv[4];
00471 bt->blob_column = bt->argv[5];
00472 if ((bt->argc > 7) && bt->argv[7][0]) {
00473 bt->x_scale_column = bt->argv[7];
00474 if (strcasecmp(bt->x_scale_column, "null") == 0) {
00475 bt->x_scale_column = 0;
00476 }
00477 }
00478 if ((bt->argc > 8) && bt->argv[8][0]) {
00479 bt->x_offset_column = bt->argv[8];
00480 if (strcasecmp(bt->x_offset_column, "null") == 0) {
00481 bt->x_offset_column = 0;
00482 }
00483 }
00484 if ((bt->argc > 9) && bt->argv[9][0]) {
00485 bt->y_scale_column = bt->argv[9];
00486 if (strcasecmp(bt->y_scale_column, "null") == 0) {
00487 bt->y_scale_column = 0;
00488 }
00489 }
00490 if ((bt->argc > 10) && bt->argv[10][0]) {
00491 bt->y_offset_column = bt->argv[10];
00492 if (strcasecmp(bt->y_offset_column, "null") == 0) {
00493 bt->y_offset_column = 0;
00494 }
00495 }
00496 if (bt->argc > 11) {
00497 p = bt->argv[11];
00498 p[0] = ',';
00499 bt->other_columns = p;
00500 p += strlen(p) - 1;
00501 if ((*p == '"') || (*p == '\'')) {
00502 *p = '\0';
00503 }
00504 } else {
00505 bt->other_columns = "";
00506 }
00507
00508 if (bt->x_scale_column || bt->x_offset_column ||
00509 (bt->type == TYPE_FLOAT) || (bt->type == TYPE_DOUBLE)) {
00510 x_type = " DOUBLE";
00511 } else {
00512 x_type = " INTEGER";
00513 }
00514 if (bt->y_scale_column || bt->y_offset_column ||
00515 (bt->type == TYPE_FLOAT) || (bt->type == TYPE_DOUBLE)) {
00516 y_type = " DOUBLE";
00517 } else {
00518 y_type = " INTEGER";
00519 }
00520 p = sqlite3_mprintf("PRAGMA %Q.table_info(%Q)",
00521 bt->argv[1] ? bt->argv[1] : "MAIN",
00522 bt->master_table);
00523 if (p) {
00524 int nrows = 0, ncols = 0;
00525 char **rows = 0;
00526
00527 rc = sqlite3_get_table(db, p, &rows, &nrows, &ncols, 0);
00528 sqlite3_free(p);
00529 if (rc == SQLITE_OK) {
00530 for (i = 1; (ncols >= 3) && (i <= nrows); i++) {
00531 p = rows[i * ncols + 1];
00532 if (p && (strcasecmp(bt->key_column, p) == 0)) {
00533 key_type = sqlite3_mprintf(" %s", rows[i * ncols + 2]);
00534 break;
00535 }
00536 }
00537 }
00538 if (rows) {
00539 sqlite3_free_table(rows);
00540 }
00541 }
00542
00543 p = 0;
00544 if (bt->other_columns[0]) {
00545 p = sqlite3_mprintf("SELECT %s FROM %s WHERE 0",
00546 bt->other_columns + 1, bt->fq_master_table);
00547 }
00548 if (p) {
00549 sqlite3_stmt *stmt = 0;
00550
00551 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
00552 rc = sqlite3_prepare_v2(db, p, -1, &stmt, 0);
00553 #else
00554 rc = sqlite3_prepare(db, p, -1, &stmt, 0);
00555 #endif
00556 sqlite3_free(p);
00557 if ((rc == SQLITE_OK) && stmt) {
00558 sqlite3_step(stmt);
00559 for (i = 0; i < sqlite3_column_count(stmt); i++) {
00560 p = sqlite3_mprintf("%s%s\"%s\" %s",
00561 other_types ? other_types : "",
00562 other_types ? "," : "",
00563 sqlite3_column_name(stmt, i),
00564 sqlite3_column_decltype(stmt, i));
00565 sqlite3_free(other_types);
00566 other_types = 0;
00567 if (p) {
00568 other_types = p;
00569 } else {
00570 break;
00571 }
00572 }
00573 sqlite3_finalize(stmt);
00574 if (other_types) {
00575 p = sqlite3_mprintf(",%s", other_types);
00576 sqlite3_free(other_types);
00577 other_types = p;
00578 }
00579 }
00580 }
00581 p = sqlite3_mprintf("CREATE TABLE \"%s\"(key%s CONSTRAINT fk "
00582 "REFERENCES \"%s\"(\"%s\"),x%s,y%s%s)",
00583 argv[2], key_type ? key_type : "",
00584 bt->master_table, bt->key_column,
00585 x_type, y_type,
00586 other_types ? other_types : bt->other_columns);
00587 if (key_type) {
00588 sqlite3_free(key_type);
00589 }
00590 if (other_types) {
00591 sqlite3_free(other_types);
00592 }
00593 if (p) {
00594 rc = sqlite3_declare_vtab(db, p);
00595 sqlite3_free(p);
00596 }
00597 if (rc != SQLITE_OK) {
00598 b2xy_destroy((sqlite3_vtab *) bt);
00599 bt = 0;
00600 }
00601 }
00602 *vtabret = (sqlite3_vtab *) bt;
00603 return rc;
00604 }
00605
00613 static int
00614 b2xy_open(sqlite3_vtab *vtab, sqlite3_vtab_cursor **curret)
00615 {
00616 int rc = SQLITE_NOMEM;
00617 b2xy_table *bt = (b2xy_table *) vtab;
00618 b2xy_cursor *bc;
00619
00620 bc = sqlite3_malloc(sizeof (b2xy_cursor));
00621 if (bc) {
00622 memset(bc, 0, sizeof(b2xy_cursor));
00623 bc->table = bt;
00624 bc->type = bt->type;
00625 bc->do_x_sl = bt->do_x_sl;
00626 bc->x_start = bt->x_start;
00627 bc->x_length = bt->x_length;
00628 *curret = (sqlite3_vtab_cursor *) bc;
00629 rc = SQLITE_OK;
00630 }
00631 return rc;
00632 }
00633
00640 static int
00641 b2xy_close(sqlite3_vtab_cursor *cur)
00642 {
00643 b2xy_cursor *bc = (b2xy_cursor *) cur;
00644
00645 sqlite3_finalize(bc->select);
00646 sqlite3_free(bc);
00647 return SQLITE_OK;
00648 }
00649
00658 static int
00659 b2xy_column(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i)
00660 {
00661 b2xy_cursor *bc = (b2xy_cursor *) cur;
00662 char *p;
00663 double v;
00664
00665 switch (i) {
00666 case 0:
00667 sqlite3_result_value(ctx, bc->key);
00668 break;
00669 case 1:
00670 if (bc->do_x_scale) {
00671 v = bc->index * bc->x_scale + bc->x_offset;
00672 sqlite3_result_double(ctx, v);
00673 } else {
00674 sqlite3_result_int(ctx, bc->index);
00675 }
00676 break;
00677 case 2:
00678 if (!bc->val ||
00679 ((bc->index + 1) * TYPE_SIZE(bc->type) > bc->val_len)) {
00680 goto put_null;
00681 }
00682 p = bc->val + bc->index * TYPE_SIZE(bc->type);
00683 switch (bc->type) {
00684 case TYPE_CHAR:
00685 if (bc->do_y_scale) {
00686 v = p[0];
00687 goto scale_it;
00688 }
00689 sqlite3_result_int(ctx, p[0]);
00690 break;
00691 case TYPE_UCHAR:
00692 if (bc->do_y_scale) {
00693 v = p[0] & 0xFF;
00694 goto scale_it;
00695 }
00696 sqlite3_result_int(ctx, p[0] & 0xFF);
00697 break;
00698 case TYPE_SHORT_LE:
00699 if (bc->do_y_scale) {
00700 v = (p[0] & 0xFF) | (p[1] << 8);
00701 goto scale_it;
00702 }
00703 sqlite3_result_int(ctx, (p[0] & 0xFF) | (p[1] << 8));
00704 break;
00705 case TYPE_USHORT_LE:
00706 if (bc->do_y_scale) {
00707 v = (p[0] & 0xFF) | ((p[1] & 0xFF) << 8);
00708 goto scale_it;
00709 }
00710 sqlite3_result_int(ctx, (p[0] & 0xFF) | ((p[1] & 0xFF) << 8));
00711 break;
00712 case TYPE_SHORT_BE:
00713 if (bc->do_y_scale) {
00714 v = (p[1] & 0xFF) | (p[0] << 8);
00715 goto scale_it;
00716 }
00717 sqlite3_result_int(ctx, (p[1] & 0xFF) | (p[0] << 8));
00718 break;
00719 case TYPE_USHORT_BE:
00720 if (bc->do_y_scale) {
00721 v = (p[1] & 0xFF) | ((p[0] & 0xFF) << 8);
00722 goto scale_it;
00723 }
00724 sqlite3_result_int(ctx, (p[1] & 0xFF) | ((p[0] & 0xFF) << 8));
00725 break;
00726 case TYPE_INT_LE:
00727 if (bc->do_y_scale) {
00728 v = (p[0] & 0xFF) | ((p[1] & 0xFF) << 8) |
00729 ((p[2] & 0xFF) << 16) | (p[3] << 24);
00730 goto scale_it;
00731 }
00732 sqlite3_result_int64(ctx, (p[0] & 0xFF) |
00733 ((p[1] & 0xFF) << 8) |
00734 ((p[2] & 0xFF) << 16) |
00735 (p[3] << 24));
00736 break;
00737 case TYPE_UINT_LE:
00738 if (bc->do_y_scale) {
00739 v = (p[0] & 0xFF) | ((p[1] & 0xFF) << 8) |
00740 ((p[2] & 0xFF) << 16) | ((p[3] & 0xFF) << 24);
00741 goto scale_it;
00742 }
00743 sqlite3_result_int64(ctx, (p[0] & 0xFF) |
00744 ((p[1] & 0xFF) << 8) |
00745 ((p[2] & 0xFF) << 16) |
00746 ((p[3] & 0xFF) << 24));
00747 break;
00748 case TYPE_INT_BE:
00749 if (bc->do_y_scale) {
00750 v = (p[3] & 0xFF) | ((p[2] & 0xFF) << 8) |
00751 ((p[1] & 0xFF) << 16) | (p[0] << 24);
00752 goto scale_it;
00753 }
00754 sqlite3_result_int64(ctx, (p[3] & 0xFF) |
00755 ((p[2] & 0xFF) << 8) |
00756 ((p[1] & 0xFF) << 16) |
00757 (p[0] << 24));
00758 break;
00759 case TYPE_UINT_BE:
00760 if (bc->do_y_scale) {
00761 v = (p[3] & 0xFF) | ((p[2] & 0xFF) << 8) |
00762 ((p[1] & 0xFF) << 16) | ((p[0] & 0xFF) << 24);
00763 goto scale_it;
00764 }
00765 sqlite3_result_int64(ctx, (p[3] & 0xFF) |
00766 ((p[2] & 0xFF) << 8) |
00767 ((p[1] & 0xFF) << 16) |
00768 ((p[0] & 0xFF) << 24));
00769 break;
00770 case TYPE_BIGINT_LE:
00771 if (bc->do_y_scale) {
00772 v = (p[0] & 0xFFLL) | ((p[1] & 0xFFLL) << 8) |
00773 ((p[2] & 0xFFLL) << 16) | ((p[3] & 0xFFLL) << 24) |
00774 ((p[4] & 0xFFLL) << 32) | ((p[5] & 0xFFLL) << 40) |
00775 ((p[6] & 0xFFLL) << 48) | ((p[6] & 0xFFLL) << 56);
00776 goto scale_it;
00777 }
00778 sqlite3_result_int64(ctx, (p[0] & 0xFFLL) |
00779 ((p[1] & 0xFFLL) << 8) |
00780 ((p[2] & 0xFFLL) << 16) |
00781 ((p[3] & 0xFFLL) << 24) |
00782 ((p[4] & 0xFFLL) << 32) |
00783 ((p[5] & 0xFFLL) << 40) |
00784 ((p[6] & 0xFFLL) << 48) |
00785 ((p[7] & 0xFFLL) << 56));
00786 break;
00787 case TYPE_BIGINT_BE:
00788 if (bc->do_y_scale) {
00789 v = (p[7] & 0xFFLL) | ((p[6] & 0xFFLL) << 8) |
00790 ((p[5] & 0xFFLL) << 16) | ((p[4] & 0xFFLL) << 24) |
00791 ((p[3] & 0xFFLL) << 32) | ((p[2] & 0xFFLL) << 40) |
00792 ((p[1] & 0xFFLL) << 48) | ((p[0] & 0xFFLL) << 56);
00793 goto scale_it;
00794 }
00795 sqlite3_result_int64(ctx, (p[7] & 0xFFLL) |
00796 ((p[6] & 0xFFLL) << 8) |
00797 ((p[5] & 0xFFLL) << 16) |
00798 ((p[4] & 0xFFLL) << 24) |
00799 ((p[3] & 0xFFLL) << 32) |
00800 ((p[2] & 0xFFLL) << 40) |
00801 ((p[1] & 0xFFLL) << 48) |
00802 ((p[0] & 0xFFLL) << 56));
00803 break;
00804 case TYPE_FLOAT:
00805 v = ((float *) p)[0];
00806 goto scale_it;
00807 case TYPE_DOUBLE:
00808 v = ((double *) p)[0];
00809 if (bc->do_y_scale) {
00810 scale_it:
00811 v = v * bc->y_scale + bc->y_offset;
00812 }
00813 sqlite3_result_double(ctx, v);
00814 break;
00815 default:
00816 put_null:
00817 sqlite3_result_null(ctx);
00818 break;
00819 }
00820 break;
00821 default:
00822 i += bc->fix_cols - 3;
00823 if ((i < 0) || (i >= bc->num_cols)) {
00824 sqlite3_result_null(ctx);
00825 } else {
00826 sqlite3_result_value(ctx, sqlite3_column_value(bc->select, i));
00827 }
00828 break;
00829 }
00830 return SQLITE_OK;
00831 }
00832
00840 static int
00841 b2xy_rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *rowidp)
00842 {
00843 b2xy_cursor *bc = (b2xy_cursor *) cur;
00844
00845 *rowidp = bc->rowid;
00846 return SQLITE_OK;
00847 }
00848
00855 static int
00856 b2xy_eof(sqlite3_vtab_cursor *cur)
00857 {
00858 b2xy_cursor *bc = (b2xy_cursor *) cur;
00859
00860 return bc->select ? 0 : 1;
00861 }
00862
00869 static int
00870 b2xy_next(sqlite3_vtab_cursor *cur)
00871 {
00872 b2xy_cursor *bc = (b2xy_cursor *) cur;
00873 b2xy_table *bt = bc->table;
00874 int rc, dofetch = 0;
00875
00876 if (!bc->select) {
00877 return SQLITE_OK;
00878 }
00879 if (bc->val) {
00880 bc->index += 1;
00881 }
00882 if (!bc->val) {
00883 dofetch = 1;
00884 } else if (bc->do_x_sl && bc->x_length) {
00885 if (bc->index >= bc->x_start + bc->x_length) {
00886 dofetch = 1;
00887 }
00888 } else if ((bc->index + 1) * TYPE_SIZE(bc->type) > bc->val_len) {
00889 dofetch = 1;
00890 }
00891 if (dofetch) {
00892 refetch:
00893 rc = sqlite3_step(bc->select);
00894
00895 if (rc == SQLITE_SCHEMA) {
00896 rc = sqlite3_step(bc->select);
00897 }
00898 if (rc != SQLITE_ROW) {
00899 sqlite3_finalize(bc->select);
00900 bc->select = 0;
00901 return SQLITE_OK;
00902 }
00903 bc->rowid_from_key = 0;
00904 bc->index = bc->x_start;
00905 bc->val = (char *) sqlite3_column_blob(bc->select, 1);
00906 bc->val_len = sqlite3_column_bytes(bc->select, 1);
00907 if (!bc->val) {
00908 if (bc->do_x_sl && bc->x_length) {
00909 bc->val = (char *) sqlite3_column_text(bc->select, 1);
00910 if (!bc->val) {
00911 goto refetch;
00912 }
00913 } else {
00914 goto refetch;
00915 }
00916 }
00917 if (!(bc->do_x_sl && bc->x_length) &&
00918 (((bc->index + 1) * TYPE_SIZE(bc->type) > bc->val_len))) {
00919 goto refetch;
00920 }
00921 bc->key = sqlite3_column_value(bc->select, 0);
00922 if (sqlite3_column_type(bc->select, 0) == SQLITE_INTEGER) {
00923 bc->rowid_from_key = 1;
00924 bc->rowid = sqlite3_column_int64(bc->select, 0);
00925 }
00926 bc->do_x_scale = 0;
00927 bc->x_scale = 1.0;
00928 bc->x_offset = 0.0;
00929 if (bt->x_scale_column) {
00930 bc->x_scale = sqlite3_column_double(bc->select, bc->x_scale_col);
00931 bc->do_x_scale++;
00932 }
00933 if (bt->x_offset_column) {
00934 bc->x_offset = sqlite3_column_double(bc->select, bc->x_offset_col);
00935 bc->do_x_scale++;
00936 }
00937 bc->do_y_scale = 0;
00938 bc->y_scale = 1.0;
00939 bc->y_offset = 0.0;
00940 if (bt->y_scale_column) {
00941 bc->y_scale = sqlite3_column_double(bc->select, bc->y_scale_col);
00942 bc->do_y_scale++;
00943 }
00944 if (bt->y_offset_column) {
00945 bc->y_offset = sqlite3_column_double(bc->select, bc->y_offset_col);
00946 bc->do_y_scale++;
00947 }
00948 }
00949 if (!bc->rowid_from_key) {
00950 bc->rowid++;
00951 }
00952 return SQLITE_OK;
00953 }
00954
00965 static int
00966 b2xy_filter(sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr,
00967 int argc, sqlite3_value **argv)
00968 {
00969 b2xy_cursor *bc = (b2xy_cursor *) cur;
00970 b2xy_table *bt = bc->table;
00971 char *query, *tmp, *op = 0;
00972 int rc;
00973
00974 bc->rowid_from_key = 0;
00975 bc->rowid = 0;
00976 if (bc->select) {
00977 sqlite3_finalize(bc->select);
00978 bc->select = 0;
00979 }
00980 bc->fix_cols = 2;
00981 query = sqlite3_mprintf("select \"%s\",\"%s\"", bt->key_column,
00982 bt->blob_column);
00983 if (!query) {
00984 return SQLITE_NOMEM;
00985 }
00986 if (bt->x_scale_column) {
00987 tmp = sqlite3_mprintf("%s,\"%s\"", query, bt->x_scale_column);
00988 sqlite3_free(query);
00989 if (!tmp) {
00990 return SQLITE_NOMEM;
00991 }
00992 query = tmp;
00993 bc->x_scale_col = bc->fix_cols;
00994 bc->fix_cols++;
00995 }
00996 if (bt->x_offset_column) {
00997 tmp = sqlite3_mprintf("%s,\"%s\"", query, bt->x_offset_column);
00998 sqlite3_free(query);
00999 if (!tmp) {
01000 return SQLITE_NOMEM;
01001 }
01002 query = tmp;
01003 bc->x_offset_col = bc->fix_cols;
01004 bc->fix_cols++;
01005 }
01006 if (bt->y_scale_column) {
01007 tmp = sqlite3_mprintf("%s,\"%s\"", query, bt->y_scale_column);
01008 sqlite3_free(query);
01009 if (!tmp) {
01010 return SQLITE_NOMEM;
01011 }
01012 query = tmp;
01013 bc->y_scale_col = bc->fix_cols;
01014 bc->fix_cols++;
01015 }
01016 if (bt->y_offset_column) {
01017 tmp = sqlite3_mprintf("%s,\"%s\"", query, bt->y_offset_column);
01018 sqlite3_free(query);
01019 if (!tmp) {
01020 return SQLITE_NOMEM;
01021 }
01022 query = tmp;
01023 bc->y_offset_col = bc->fix_cols;
01024 bc->fix_cols++;
01025 }
01026 tmp = sqlite3_mprintf("%s%s from %s", query, bt->other_columns,
01027 bt->fq_master_table);
01028 sqlite3_free(query);
01029 if (!tmp) {
01030 return SQLITE_NOMEM;
01031 }
01032 query = tmp;
01033 if (idxNum && (argc > 0)) {
01034 switch (idxNum) {
01035 case SQLITE_INDEX_CONSTRAINT_EQ:
01036 op = "=";
01037 break;
01038 case SQLITE_INDEX_CONSTRAINT_GT:
01039 op = ">";
01040 break;
01041 case SQLITE_INDEX_CONSTRAINT_LE:
01042 op = "<=";
01043 break;
01044 case SQLITE_INDEX_CONSTRAINT_LT:
01045 op = "<";
01046 break;
01047 case SQLITE_INDEX_CONSTRAINT_GE:
01048 op = ">=";
01049 break;
01050 case SQLITE_INDEX_CONSTRAINT_MATCH:
01051 op = "like";
01052 break;
01053 }
01054 if (op) {
01055 tmp = sqlite3_mprintf("%s where \"%s\" %s ?",
01056 query, bt->key_column, op);
01057 sqlite3_free(query);
01058 if (!tmp) {
01059 return SQLITE_NOMEM;
01060 }
01061 query = tmp;
01062 }
01063 }
01064 if (idxStr) {
01065 tmp = sqlite3_mprintf("%s %s", query, idxStr);
01066 sqlite3_free(query);
01067 if (!tmp) {
01068 return SQLITE_NOMEM;
01069 }
01070 query = tmp;
01071 }
01072 bc->num_cols = bc->fix_cols;
01073 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
01074 rc = sqlite3_prepare_v2(bt->db, query, -1, &bc->select, 0);
01075 #else
01076 rc = sqlite3_prepare(bt->db, query, -1, &bc->select, 0);
01077 if (rc == SQLITE_SCHEMA) {
01078 rc = sqlite3_prepare(bt->db, query, -1, &bc->select, 0);
01079 }
01080 #endif
01081 sqlite3_free(query);
01082 if (rc == SQLITE_OK) {
01083 bc->num_cols = sqlite3_column_count(bc->select);
01084 if (op) {
01085 sqlite3_bind_value(bc->select, 1, argv[0]);
01086 }
01087 }
01088 return (rc == SQLITE_OK) ? b2xy_next(cur) : rc;
01089 }
01090
01099 static int
01100 b2xy_bestindex(sqlite3_vtab *tab, sqlite3_index_info *info)
01101 {
01102 b2xy_table *bt = (b2xy_table *) tab;
01103 int i, key_order = 0, consumed = 0;
01104
01105
01106 info->idxNum = 0;
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 for (i = 0; i < info->nConstraint; ++i) {
01117 if (info->aConstraint[i].usable) {
01118 if ((info->aConstraint[i].iColumn == 0) &&
01119 (info->aConstraint[i].op != 0)) {
01120 info->idxNum = info->aConstraint[i].op;
01121 info->aConstraintUsage[i].argvIndex = 1;
01122 info->aConstraintUsage[i].omit = 1;
01123 info->estimatedCost = 1.0;
01124 break;
01125 }
01126 }
01127 }
01128
01129
01130
01131
01132
01133
01134
01135 for (i = 0; i < info->nOrderBy; i++) {
01136 if (info->aOrderBy[i].iColumn == 0) {
01137 key_order = info->aOrderBy[i].desc ? -1 : 1;
01138 consumed++;
01139 } else if ((info->aOrderBy[i].iColumn == 1) &&
01140 !info->aOrderBy[i].desc) {
01141 consumed++;
01142 }
01143 }
01144 if (consumed) {
01145
01146 for (i = 0; i < info->nOrderBy; i++) {
01147 if ((info->aOrderBy[i].iColumn == 1) &&
01148 info->aOrderBy[i].desc) {
01149 consumed = 0;
01150 } else if (info->aOrderBy[i].iColumn > 1) {
01151 consumed = 0;
01152 }
01153 }
01154 }
01155 if (consumed && key_order) {
01156 info->idxStr = sqlite3_mprintf("ORDER BY \"%s\" %s",
01157 bt->key_column,
01158 (key_order < 0) ? "DESC" : "ASC");
01159 info->needToFreeIdxStr = 1;
01160 }
01161 info->orderByConsumed = consumed;
01162 return SQLITE_OK;
01163 }
01164
01165 #if (SQLITE_VERSION_NUMBER > 3004000)
01166
01173 static int
01174 b2xy_rename(sqlite3_vtab *tab, const char *newname)
01175 {
01176 return SQLITE_OK;
01177 }
01178
01179 #endif
01180
01181 static const sqlite3_module b2xy_module = {
01182 1,
01183 b2xy_create,
01184 b2xy_create,
01185 b2xy_bestindex,
01186 b2xy_destroy,
01187 b2xy_destroy,
01188 b2xy_open,
01189 b2xy_close,
01190 b2xy_filter,
01191 b2xy_next,
01192 b2xy_eof,
01193 b2xy_column,
01194 b2xy_rowid,
01195 0,
01196 0,
01197 0,
01198 0,
01199 0,
01200 0,
01201 #if (SQLITE_VERSION_NUMBER > 3004000)
01202 b2xy_rename,
01203 #endif
01204 };
01205
01212 typedef struct {
01213 int max;
01214 int idx;
01215 char *str;
01216 } strbuf;
01217
01224 static int
01225 init_strbuf(strbuf *sb)
01226 {
01227 int n = 1024;
01228
01229 if ((sb->max <= 0) || !sb->str) {
01230 sb->str = sqlite3_malloc(n);
01231 if (!sb->str) {
01232 return SQLITE_NOMEM;
01233 }
01234 sb->max = n;
01235 }
01236 sb->idx = 0;
01237 return SQLITE_OK;
01238 }
01239
01246 static int
01247 expand_strbuf(strbuf *sb)
01248 {
01249 int n;
01250 char *str;
01251
01252 if ((sb->max <= 0) || !sb->str) {
01253 return init_strbuf(sb);
01254 }
01255 n = sb->max * 2;
01256 str = sqlite3_realloc(sb->str, n);
01257 if (!str) {
01258 return SQLITE_NOMEM;
01259 }
01260 sb->max = n;
01261 sb->str = str;
01262 return SQLITE_OK;
01263 }
01264
01270 static void
01271 drop_strbuf(strbuf *sb)
01272 {
01273 if (sb->str) {
01274 sqlite3_free(sb->str);
01275 sb->str = 0;
01276 }
01277 sb->max = 0;
01278 }
01279
01287 static int
01288 print_strbuf(strbuf *sb, const char *fmt, ...)
01289 {
01290 int i, n, rc;
01291 va_list ap;
01292
01293 va_start(ap, fmt);
01294 for (i = 0; i < 2; i++) {
01295 if (sb->max - (sb->idx + 1) < 256) {
01296 rc = expand_strbuf(sb);
01297 if (rc != SQLITE_OK) {
01298 goto done;
01299 }
01300 }
01301 rc = SQLITE_NOMEM;
01302 n = vsnprintf(sb->str + sb->idx, sb->max - sb->idx, fmt, ap);
01303 if ((n >= 0) && ((sb->idx + n) < (sb->max - 1))) {
01304 sb->idx += n;
01305 rc = SQLITE_OK;
01306 break;
01307 }
01308 }
01309 done:
01310 va_end(ap);
01311 return rc;
01312 }
01313
01314 #define PATH_MODE_TK ((void *) 0)
01315 #define PATH_MODE_SVG ((void *) 1)
01316 #define PATH_MODE_BLT_X ((void *) 2)
01317 #define PATH_MODE_BLT_Y ((void *) 3)
01318 #define PATH_MODE_BLT ((void *) 4)
01319 #define PATH_MODE_TK3D ((void *) 5)
01320
01340 static void
01341 common_path_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01342 {
01343 void *mode = sqlite3_user_data(ctx);
01344 char *data;
01345 int i, linebreak, size, type = TYPE_CHAR;
01346 int do_x_scale = 0, do_y_scale = 0, do_z_scale = 0;
01347 double x_scale, x_offset, y_scale, y_offset, z0, z_scale, z_offset;
01348 strbuf sb;
01349
01350 if (nargs < 1) {
01351 sqlite3_result_error(ctx, "need at least 1 argument", -1);
01352 return;
01353 }
01354 if (nargs > 1) {
01355 type = string_to_type((const char *) sqlite3_value_text(args[1]));
01356 if (!type) {
01357 sqlite3_result_error(ctx, "bad type name", -1);
01358 return;
01359 }
01360 }
01361 data = (char *) sqlite3_value_blob(args[0]);
01362 size = sqlite3_value_bytes(args[0]) / TYPE_SIZE(type);
01363 if (!data ||
01364 ((mode != PATH_MODE_BLT_X) && (mode != PATH_MODE_BLT_Y) &&
01365 (size < 2)) || (size < 1)) {
01366 goto nullorempty;
01367 }
01368 x_scale = 1;
01369 x_offset = 0;
01370 if (nargs > 2) {
01371 x_scale = sqlite3_value_double(args[2]);
01372 do_x_scale++;
01373 }
01374 if (nargs > 3) {
01375 x_offset = sqlite3_value_double(args[3]);
01376 do_x_scale++;
01377 }
01378 y_scale = 1;
01379 y_offset = 0;
01380 if (nargs > 4) {
01381 y_scale = sqlite3_value_double(args[4]);
01382 do_y_scale++;
01383 }
01384 if (nargs > 5) {
01385 y_offset = sqlite3_value_double(args[5]);
01386 do_y_scale++;
01387 }
01388 z0 = 0;
01389 z_scale = 1;
01390 z_offset = 0;
01391 if ((mode == PATH_MODE_TK3D) && (nargs > 6)) {
01392 z0 = sqlite3_value_double(args[6]);
01393 }
01394 if ((mode == PATH_MODE_TK3D) && (nargs > 7)) {
01395 z_scale = sqlite3_value_double(args[7]);
01396 do_z_scale++;
01397 }
01398 if ((mode == PATH_MODE_TK3D) && (nargs > 8)) {
01399 z_offset = sqlite3_value_double(args[8]);
01400 do_z_scale++;
01401 }
01402 memset(&sb, 0, sizeof (sb));
01403 if (init_strbuf(&sb) != SQLITE_OK) {
01404 goto nullorempty;
01405 }
01406 linebreak = 100;
01407 for (i = 0; i < size; i++, data += TYPE_SIZE(type)) {
01408 double x, y = 0, z = z0;
01409 char *fmt;
01410
01411 if (do_z_scale) {
01412 z = z0 * z_scale + z_offset;
01413 }
01414 if (do_x_scale) {
01415 x = i * x_scale + x_offset;
01416 } else {
01417 x = i;
01418 }
01419 switch (type) {
01420 case TYPE_CHAR:
01421 y = data[0];
01422 break;
01423 case TYPE_UCHAR:
01424 y = data[0] & 0xFF;
01425 break;
01426 case TYPE_SHORT_LE:
01427 y = (data[0] & 0xFF) | (data[1] << 8);
01428 break;
01429 case TYPE_USHORT_LE:
01430 y = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8);
01431 break;
01432 case TYPE_SHORT_BE:
01433 y = (data[1] & 0xFF) | (data[0] << 8);
01434 break;
01435 case TYPE_USHORT_BE:
01436 y = (data[1] & 0xFF) | ((data[0] & 0xFF) << 8);
01437 break;
01438 case TYPE_INT_LE:
01439 y = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8) |
01440 ((data[2] & 0xFF) << 16) | (data[3] << 24);
01441 break;
01442 case TYPE_UINT_LE:
01443 y = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8) |
01444 ((data[2] & 0xFF) << 16) | ((data[3] & 0xFF) << 24);
01445 break;
01446 case TYPE_INT_BE:
01447 y = (data[3] & 0xFF) | ((data[2] & 0xFF) << 8) |
01448 ((data[1] & 0xFF) << 16) | (data[0] << 24);
01449 break;
01450 case TYPE_UINT_BE:
01451 y = (data[3] & 0xFF) | ((data[2] & 0xFF) << 8) |
01452 ((data[1] & 0xFF) << 16) | ((data[0] & 0xFF) << 24);
01453 break;
01454 case TYPE_FLOAT:
01455 y = ((float *) data)[0];
01456 break;
01457 case TYPE_DOUBLE:
01458 y = ((double *) data)[0];
01459 break;
01460 }
01461 if (do_y_scale) {
01462 y = y * y_scale + y_offset;
01463 }
01464 if ((mode == PATH_MODE_BLT_X) || (mode == PATH_MODE_BLT_Y)) {
01465 double v = (mode == PATH_MODE_BLT_X) ? x : y;
01466
01467 if (print_strbuf(&sb, (i == 0) ? "%g" : " %g", v) != SQLITE_OK) {
01468 drop_strbuf(&sb);
01469 break;
01470 }
01471 continue;
01472 }
01473 if ((mode == PATH_MODE_SVG) && (i == 0)) {
01474 fmt = "M %g %g";
01475 } else if ((mode == PATH_MODE_SVG) && (i == 1)) {
01476 fmt = " L %g %g";
01477 } else if ((mode == PATH_MODE_SVG) && (sb.idx >= linebreak)) {
01478 fmt = "\nL %g %g";
01479 linebreak = sb.idx + 100;
01480 } else if (i == 0) {
01481 fmt = (mode == PATH_MODE_TK3D) ? "%g %g %g" : "%g %g";
01482 } else {
01483 fmt = (mode == PATH_MODE_TK3D) ? " %g %g %g" : " %g %g";
01484 }
01485 if (print_strbuf(&sb, fmt, x, y, z) != SQLITE_OK) {
01486 drop_strbuf(&sb);
01487 break;
01488 }
01489 }
01490 if (sb.str) {
01491 sqlite3_result_text(ctx, sb.str, sb.idx, sqlite3_free);
01492 sb.str = 0;
01493 return;
01494 }
01495 nullorempty:
01496 if ((mode == PATH_MODE_BLT_X) || (mode == PATH_MODE_BLT_Y)) {
01497 sqlite3_result_text(ctx, "", 0, SQLITE_STATIC);
01498 } else {
01499 sqlite3_result_null(ctx);
01500 }
01501 }
01502
01509 typedef struct {
01510 int init;
01511 int count;
01512 int linebreak;
01513 void *mode;
01514 strbuf sb;
01515 } path_aggctx;
01516
01537 static void
01538 common_path_step(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01539 {
01540 path_aggctx *pag;
01541 int type;
01542 char *fmt;
01543 double x, y, z = 0;
01544 double x_scale, y_scale, x_offset, y_offset, z_scale, z_offset;
01545
01546 if (nargs < 2) {
01547 return;
01548 }
01549 pag = sqlite3_aggregate_context(ctx, sizeof (*pag));
01550 if (!pag->init) {
01551 if (init_strbuf(&pag->sb) != SQLITE_OK) {
01552 return;
01553 }
01554 pag->linebreak = 100;
01555 pag->count = 0;
01556 pag->mode = sqlite3_user_data(ctx);
01557 pag->init = 1;
01558 }
01559 type = sqlite3_value_type(args[0]);
01560 if ((type != SQLITE_INTEGER) && (type != SQLITE_FLOAT)) {
01561 return;
01562 }
01563 type = sqlite3_value_type(args[1]);
01564 if ((type != SQLITE_INTEGER) && (type != SQLITE_FLOAT)) {
01565 return;
01566 }
01567 x = sqlite3_value_double(args[0]);
01568 y = sqlite3_value_double(args[1]);
01569 x_scale = 1;
01570 x_offset = 0;
01571 if (nargs > 2) {
01572 type = sqlite3_value_type(args[2]);
01573 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01574 x_scale = sqlite3_value_double(args[2]);
01575 }
01576 }
01577 if (nargs > 3) {
01578 type = sqlite3_value_type(args[3]);
01579 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01580 x_offset = sqlite3_value_double(args[3]);
01581 }
01582 }
01583 y_scale = 1;
01584 y_offset = 0;
01585 if (nargs > 4) {
01586 type = sqlite3_value_type(args[4]);
01587 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01588 y_scale = sqlite3_value_double(args[4]);
01589 }
01590 }
01591 if (nargs > 5) {
01592 type = sqlite3_value_type(args[5]);
01593 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01594 y_offset = sqlite3_value_double(args[5]);
01595 }
01596 }
01597 z_scale = 1;
01598 z_offset = 0;
01599 if ((pag->mode == PATH_MODE_TK3D) && (nargs > 6)) {
01600 z = sqlite3_value_double(args[6]);
01601 if (nargs > 7) {
01602 type = sqlite3_value_type(args[7]);
01603 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01604 z_scale = sqlite3_value_double(args[7]);
01605 }
01606 }
01607 if (nargs > 8) {
01608 type = sqlite3_value_type(args[8]);
01609 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01610 z_offset = sqlite3_value_double(args[8]);
01611 }
01612 }
01613 z = z * z_scale + z_offset;
01614 }
01615 x = x * x_scale + x_offset;
01616 y = y * y_scale + y_offset;
01617 if ((pag->mode == PATH_MODE_SVG) && (pag->count == 0)) {
01618 fmt = "M %g %g";
01619 } else if ((pag->mode == PATH_MODE_SVG) && (pag->count == 1)) {
01620 fmt = " L %g %g";
01621 } else if ((pag->mode == PATH_MODE_SVG) &&
01622 (pag->sb.idx >= pag->linebreak)) {
01623 fmt = "\nL %g %g";
01624 pag->linebreak = pag->sb.idx + 100;
01625 } else if (pag->count == 0) {
01626 fmt = (pag->mode == PATH_MODE_TK3D) ? "%g %g %g" : "%g %g";
01627 } else {
01628 fmt = (pag->mode == PATH_MODE_TK3D) ? " %g %g %g" : " %g %g";
01629 }
01630 if (print_strbuf(&pag->sb, fmt, x, y, z) != SQLITE_OK) {
01631 drop_strbuf(&pag->sb);
01632 pag->init = 0;
01633 } else {
01634 pag->count++;
01635 }
01636 }
01637
01643 static void
01644 common_path_finalize(sqlite3_context *ctx)
01645 {
01646 path_aggctx *pag = sqlite3_aggregate_context(ctx, sizeof (*pag));
01647
01648 if (pag->init) {
01649 if ((pag->count > 1) || (pag->mode == PATH_MODE_BLT)) {
01650 sqlite3_result_text(ctx, pag->sb.str, pag->sb.idx, sqlite3_free);
01651 pag->sb.str = 0;
01652 pag->init = 0;
01653 return;
01654 }
01655 drop_strbuf(&pag->sb);
01656 }
01657 if (pag->mode == PATH_MODE_BLT) {
01658 sqlite3_result_text(ctx, "", 0, SQLITE_STATIC);
01659 } else {
01660 sqlite3_result_null(ctx);
01661 }
01662 }
01663
01677 static void
01678 blt_vec_step(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01679 {
01680 path_aggctx *pag;
01681 int type;
01682 double v, scale, offset;
01683
01684 if (nargs < 1) {
01685 return;
01686 }
01687 pag = sqlite3_aggregate_context(ctx, sizeof (*pag));
01688 if (!pag->init) {
01689 if (init_strbuf(&pag->sb) != SQLITE_OK) {
01690 return;
01691 }
01692 pag->count = 0;
01693 pag->mode = PATH_MODE_BLT;
01694 pag->init = 1;
01695 }
01696 type = sqlite3_value_type(args[0]);
01697 if ((type != SQLITE_INTEGER) && (type != SQLITE_FLOAT)) {
01698 return;
01699 }
01700 v = sqlite3_value_double(args[0]);
01701 scale = 1;
01702 offset = 0;
01703 if (nargs > 1) {
01704 type = sqlite3_value_type(args[1]);
01705 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01706 scale = sqlite3_value_double(args[2]);
01707 }
01708 }
01709 if (nargs > 2) {
01710 type = sqlite3_value_type(args[2]);
01711 if ((type == SQLITE_INTEGER) || (type == SQLITE_FLOAT)) {
01712 offset = sqlite3_value_double(args[3]);
01713 }
01714 }
01715 v = v * scale + offset;
01716 if (print_strbuf(&pag->sb, (pag->count == 0) ? "%g" : " %g", v)
01717 != SQLITE_OK) {
01718 drop_strbuf(&pag->sb);
01719 pag->init = 0;
01720 } else {
01721 pag->count++;
01722 }
01723 }
01724
01732 static void
01733 subblob_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01734 {
01735 int insize, outsize, start, itemsize = 1, itemskip = 0;
01736 int i, k, n;
01737 char *indata, *outdata;
01738
01739 if (nargs < 3) {
01740 sqlite3_result_error(ctx, "need at least 1 argument", -1);
01741 return;
01742 }
01743 indata = (char *) sqlite3_value_blob(args[0]);
01744 insize = sqlite3_value_bytes(args[0]);
01745 if (!indata || (insize <= 0)) {
01746 isnull:
01747 sqlite3_result_null(ctx);
01748 return;
01749 }
01750 start = sqlite3_value_int(args[1]);
01751 if (start < 0) {
01752 start = insize - start;
01753 if (start < 0) {
01754 start = 0;
01755 }
01756 } else if (start > 0) {
01757 start--;
01758 }
01759 if (start >= insize) {
01760 goto isnull;
01761 }
01762 outsize = sqlite3_value_int(args[2]);
01763 if (outsize > insize - start) {
01764 outsize = insize - start;
01765 }
01766 if (outsize <= 0) {
01767 goto isnull;
01768 }
01769 if (nargs > 3) {
01770 itemsize = sqlite3_value_int(args[3]);
01771 if ((itemsize <= 0) || (itemsize > outsize)) {
01772 goto isnull;
01773 }
01774 }
01775 if (nargs > 4) {
01776 itemskip = sqlite3_value_int(args[4]);
01777 if (itemskip < 0) {
01778 goto isnull;
01779 }
01780 }
01781 outdata = sqlite3_malloc(outsize);
01782 if (!outdata) {
01783 sqlite3_result_error(ctx, "out of memory", -1);
01784 return;
01785 }
01786 for (i = n = 0; i < outsize; i++) {
01787 for (k = 0; k < itemsize; k++) {
01788 outdata[i + k] = indata[start];
01789 n++;
01790 start++;
01791 if (start >= insize) {
01792 break;
01793 }
01794 }
01795 start += itemskip;
01796 if (start >= insize) {
01797 break;
01798 }
01799 }
01800 if (n > 0) {
01801 sqlite3_result_blob(ctx, outdata, n, sqlite3_free);
01802 return;
01803 }
01804 sqlite3_result_null(ctx);
01805 sqlite3_free(outdata);
01806 }
01807
01814 typedef struct {
01815 sqlite3_context *ctx;
01816 sqlite3_value *value;
01817 sqlite_int64 count;
01818 } rownumber_ctx;
01819
01827 static void
01828 rownumber_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01829 {
01830 rownumber_ctx *rn = sqlite3_get_auxdata(ctx, 0);
01831
01832 if (!rn || (rn->ctx != ctx) || (rn->value != args[0])) {
01833 rn = sqlite3_malloc(sizeof (*rn));
01834 if (rn) {
01835 rn->ctx = ctx;
01836 rn->value = args[0];
01837 rn->count = 0;
01838 }
01839 sqlite3_set_auxdata(ctx, 0, rn, sqlite3_free);
01840 } else {
01841 rn->count++;
01842 }
01843 sqlite3_result_int64(ctx, rn ? rn->count : 0);
01844 }
01845
01853 #ifndef STANDALONE
01854 static
01855 #endif
01856 int
01857 b2xy_init(sqlite3 *db)
01858 {
01859 sqlite3_create_function(db, "subblob", -1, SQLITE_ANY, (void *) 0,
01860 subblob_func, 0, 0);
01861 sqlite3_create_function(db, "tk_path_from_blob", -1, SQLITE_UTF8,
01862 PATH_MODE_TK, common_path_func, 0, 0);
01863 sqlite3_create_function(db, "svg_path_from_blob", -1, SQLITE_UTF8,
01864 PATH_MODE_SVG, common_path_func, 0, 0);
01865 sqlite3_create_function(db, "blt_vec_x", -1, SQLITE_UTF8,
01866 PATH_MODE_BLT_X, common_path_func, 0, 0);
01867 sqlite3_create_function(db, "blt_vec_y", -1, SQLITE_UTF8,
01868 PATH_MODE_BLT_Y, common_path_func, 0, 0);
01869 sqlite3_create_function(db, "tk3d_path_from_blob", -1, SQLITE_UTF8,
01870 PATH_MODE_TK3D, common_path_func, 0, 0);
01871 sqlite3_create_function(db, "tk_path", -1, SQLITE_ANY, PATH_MODE_TK,
01872 0, common_path_step, common_path_finalize);
01873 sqlite3_create_function(db, "svg_path", -1, SQLITE_ANY, PATH_MODE_SVG,
01874 0, common_path_step, common_path_finalize);
01875 sqlite3_create_function(db, "blt_vec", -1, SQLITE_ANY, PATH_MODE_BLT,
01876 0, blt_vec_step, common_path_finalize);
01877 sqlite3_create_function(db, "tk3d_path", -1, SQLITE_ANY, PATH_MODE_TK3D,
01878 0, common_path_step, common_path_finalize);
01879 sqlite3_create_function(db, "rownumber", 1, SQLITE_ANY, 0,
01880 rownumber_func, 0, 0);
01881 return sqlite3_create_module(db, "blobtoxy", &b2xy_module, 0);
01882 }
01883
01884 #ifndef STANDALONE
01885
01894 int
01895 sqlite3_extension_init(sqlite3 *db, char **errmsg,
01896 const sqlite3_api_routines *api)
01897 {
01898 SQLITE_EXTENSION_INIT2(api);
01899 return b2xy_init(db);
01900 }
01901
01902 #endif
01903
01904
01905
01906
01907
01908
01909
01910
01911