libfcns.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 640 行 · 第 1/2 页
C
640 行
/*************************************************************************** * * * db.* * * open source database kernel * * * * Copyright (c) 2000 Centura Software Corporation. All rights reserved. * * * * Use of this software, whether in source code format, or in executable, * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this * * distribution of source code files. * * * **************************************************************************/#include "db.star.h"/* Internal function prototypes */static int INTERNAL_FCN rec_okay(int, int *, RECORD_ENTRY **, DB_TASK *);/* ====================================================================== Check for valid (external) set number and return (internal) set number and task->set_table pointer.*/int INTERNAL_FCN nset_check(register int nset, int *set, SET_ENTRY **set_ptr, DB_TASK *task){ nset -= SETMARK; if (nset < 0 || nset >= TABLE_SIZE(Size_st)) return (dberr(S_INVSET)); *set_ptr = &task->set_table[*set = NUM2INT(nset, st_offset)]; return (task->db_status);}/* ====================================================================== Check for valid (external) field number and return (internal) record and field numbers and pointers.*/int INTERNAL_FCN nfld_check( register long nfld, int *rec, int *fld, RECORD_ENTRY **rec_ptr, FIELD_ENTRY **fld_ptr, DB_TASK *task){ int trec; int tfld; if (!rec_okay(trec = (int) (nfld / FLDMARK), rec, rec_ptr, task) || (tfld = (int) (nfld - trec * FLDMARK)) < 0 || tfld >= TABLE_SIZE(Size_fd) || (*rec_ptr)->rt_fdtot <= 0) return (dberr(S_INVFLD)); *fld_ptr = &task->field_table[*fld = tfld + (*rec_ptr)->rt_fields]; return (task->db_status);}/* ====================================================================== Check for valid (external) record number and return (internal) record number and pointer.*/int INTERNAL_FCN nrec_check(int nrec, int *rec, RECORD_ENTRY **rec_ptr, DB_TASK *task){ if (rec_okay(nrec - RECMARK, rec, rec_ptr, task)) return (task->db_status); return (dberr(S_INVREC));}/* ====================================================================== Internal record number check*/static int INTERNAL_FCN rec_okay(register int nrec, int *rec, RECORD_ENTRY **rec_ptr, DB_TASK *task){ if (nrec < 0 || nrec >= TABLE_SIZE(Size_rt)) return FALSE; *rec_ptr = &task->record_table[*rec = NUM2INT(nrec, rt_offset)]; return TRUE;}/* ====================================================================== Compare values of two unsigned character arrays*/static int INTERNAL_FCN uchar_cmp(unsigned char *uc1, unsigned char *uc2, int len, int string){ int result = 0; while (!result && len--) { if (string && (*uc1 == 0 || *uc2 == 0)) return (int)*uc1 - (int)*uc2; result = (int)*uc1++ - (int)*uc2++; } return result;}/* ====================================================================== Compare values of two unsigned long values*/static int INTERNAL_FCN ulong_cmp(unsigned long ul1, unsigned long ul2){ if (ul1 < ul2) return -1; if (ul1 > ul2) return 1; return 0;}/* ====================================================================== Compare values of two db.* data fields*/int EXTERNAL_FCN fldcmp( FIELD_ENTRY *fld_ptr, const char *f1, const char *f2, DB_TASK *task){ /* returns < 0 if f1 < f2, = 0 if f1 == f2, > 0 if f1 > f2 */ int kt_lc; int elt; int result; int len; int cur_len; int sub_len; int entries; int ufld; short key_num; unsigned int ui1, ui2; unsigned long ul1, ul2; unsigned short us1, us2; int i1, i2; long l1, l2; short s1, s2; float F1, F2; double d1, d2; FIELD_ENTRY *fld_last; FIELD_ENTRY *sfld_ptr; KEY_ENTRY *key_ptr; short *dptr; unsigned char *uc1; unsigned char *uc2; len = fld_ptr->fd_len; result = 0; /* compute number of array elements */ entries = 1; for (elt = 0, dptr = fld_ptr->fd_dim; elt < MAXDIMS && *dptr; ++elt, ++dptr) entries *= *dptr; ufld = fld_ptr->fd_flags & UNSIGNEDFLD; switch (fld_ptr->fd_type) { case CHARACTER: uc1 = (unsigned char *) f1; uc2 = (unsigned char *) f2; if (fld_ptr->fd_dim[1]) { /* multiply-dimentioned array */ if (ufld) return uchar_cmp(uc1, uc2, entries, 0); return memcmp(f1, f2, entries); } if (task->ctbl_activ) return ctblcmp(uc1, uc2, len, task); /* unsigned char string or single unsigned char */ if (ufld) return uchar_cmp(uc1, uc2, entries, 1); /* single-dimensioned array -- string */ if (fld_ptr->fd_dim[0]) { if (task->dboptions & MBSSORT) { if (task->dboptions & IGNORECASE) return vmbsnicmp(f1, f2, len); return vmbsncmp(f1, f2, len); } else { if (task->dboptions & IGNORECASE) return strnicmp(f1, f2, len); return strncmp(f1, f2, len); } } /* single char */ return (int) *f1 - (int) *f2; case REGINT: for (elt = 0; !result && elt < entries; ++elt) { if (ufld) { memcpy(&ui1, f1 + elt * sizeof(int), sizeof(int)); memcpy(&ui2, f2 + elt * sizeof(int), sizeof(int)); result = ulong_cmp((unsigned long) ui1, (unsigned long) ui2); } else { memcpy(&i1, f1 + elt * sizeof(int), sizeof(int)); memcpy(&i2, f2 + elt * sizeof(int), sizeof(int)); if (i1 < i2) result = -1; else if (i1 > i2) result = 1; } } break; case LONGINT: for (elt = 0; !result && elt < entries; ++elt) { if (ufld) { memcpy(&ul1, f1 + (elt * sizeof(long)), sizeof(long)); memcpy(&ul2, f2 + (elt * sizeof(long)), sizeof(long)); result = ulong_cmp(ul1, ul2); } else { memcpy(&l1, f1 + (elt * sizeof(long)), sizeof(long)); memcpy(&l2, f2 + (elt * sizeof(long)), sizeof(long)); if (l1 < l2) result = -1; else if (l1 > l2) result = 1; } } break; case WIDECHAR: ufld = 1; /* If it's not a one-dimensional array, just drop through and treat it like an array of unsigned shorts (or a single unsigned short value. */ if (fld_ptr->fd_dim[0] > 0 && fld_ptr->fd_dim[1] == 0) { if (task->dboptions & IGNORECASE) return vwcsnicoll((const wchar_t *)f1, (const wchar_t *)f2, len / sizeof(wchar_t)); return vwcsncoll((const wchar_t *)f1, (const wchar_t *)f2, len / sizeof(wchar_t)); } case SHORTINT: for (elt = 0; !result && elt < entries; ++elt) { if (ufld) { memcpy(&us1, f1 + (elt * sizeof(short)), sizeof(short)); memcpy(&us2, f2 + (elt * sizeof(short)), sizeof(short)); result = ulong_cmp((unsigned long)us1, (unsigned long) us2); } else { memcpy(&s1, f1 + (elt * sizeof(short)), sizeof(short)); memcpy(&s2, f2 + (elt * sizeof(short)), sizeof(short)); if (s1 < s2) result = -1; else if (s1 > s2) result = 1; } } break; case FLOAT: for (elt = 0; elt < entries; ++elt) { memcpy(&F1, f1 + (elt * sizeof(float)), sizeof(float)); memcpy(&F2, f2 + (elt * sizeof(float)), sizeof(float)); if (F1 < F2) { result = -1; break; } else if (F1 > F2) { result = 1; break; } } break; case DOUBLE: for (elt = 0; elt < entries; ++elt) { memcpy(&d1, f1 + (elt * sizeof(double)), sizeof(double));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?