📄 token.c
字号:
cur=head; for (col=0;col<info->num_cols;col++) { curcol=info->columns[col]; curcol->column_namelen = cur->column_namelen; strncpy(curcol->column_name, cur->column_name, sizeof(curcol->column_name)); prev=cur; cur=cur->next; free(prev->column_name); free(prev); } return TDS_SUCCEED;} /* ** tds_process_col_info() is the other half of result set processing** under TDS 4.2. It follows tds_process_col_name(). It contains all the ** column type and size information.** This is a 4.2 only function*/static int tds_process_col_info(TDSSOCKET *tds){int col,hdrsize;TDSCOLINFO *curcol;TDSRESULTINFO *info;TDS_SMALLINT tabnamesize;int bytes_read = 0;int rest;/* XXX do a best check for alignment than this */union { void *p; int i; } align_struct;const int align = sizeof(align_struct);int remainder;char ci_flags[4]; hdrsize = tds_get_smallint(tds); info = tds->res_info; for (col=0; col<info->num_cols; col++) { curcol=info->columns[col]; /* Used to ignore next 4 bytes, now we'll actually parse (some of) the data in them. (mlilback, 11/7/01) */ tds_get_n(tds, ci_flags, 4); curcol->column_nullable = ci_flags[3] & 0x01; curcol->column_writeable = (ci_flags[3] & 0x08) > 0; curcol->column_identity = (ci_flags[3] & 0x10) > 0; /* on with our regularly scheduled code (mlilback, 11/7/01) */ curcol->column_type = tds_get_byte(tds); curcol->column_varint_size = tds_get_varint_size(curcol->column_type); tdsdump_log(TDS_DBG_INFO1, "%L processing result. type = %d, varint_size %d\n", curcol->column_type, curcol->column_varint_size); switch(curcol->column_varint_size) { case 4: curcol->column_size = tds_get_int(tds); /* junk the table name -- for now */ tabnamesize = tds_get_smallint(tds);#ifdef NCBI_FTDS tds_get_n(tds,curcol->full_column_name,tabnamesize); curcol->full_column_name[tabnamesize]='.'; strcpy(curcol->full_column_name+tabnamesize+1,curcol->column_name);#else tds_get_n(tds,NULL,tabnamesize);#endif bytes_read += 5+4+2+tabnamesize; break; case 1: curcol->column_size = tds_get_byte(tds); bytes_read += 5+1; break; case 0: curcol->column_size = get_size_by_type(curcol->column_type); bytes_read += 5+0; break; } if (is_blob_type(curcol->column_type)) { curcol->column_offset = info->row_size; } else { curcol->column_offset = info->row_size; info->row_size += curcol->column_size + 1; } if (IS_TDS42(tds)) { remainder = info->row_size % align; if (remainder) info->row_size += (align - remainder); } } /* get the rest of the bytes */ rest = hdrsize - bytes_read; if (rest > 0) { tdsdump_log(TDS_DBG_INFO1,"NOTE:tds_process_col_info: draining %d bytes\n", rest); tds_get_n(tds, NULL, rest); } info->current_row = tds_alloc_row(info); return TDS_SUCCEED;}/*** tds_process_param_result() processes output parameters of a stored ** procedure. This differs from regular row/compute results in that there** is no total number of parameters given, they just show up singley.*/static int tds_process_param_result(TDSSOCKET *tds){int hdrsize;int column_type;int column_size, actual_size; hdrsize = tds_get_smallint(tds); tds_get_string(tds, NULL, tds_get_byte(tds)); /* column name */ tds_get_n(tds, NULL, 5); /* unknown */ column_type = tds_get_byte(tds); /* datatype */ if (!is_fixed_type(column_type)) { column_size = tds_get_byte(tds); actual_size = tds_get_byte(tds); tds_get_n(tds, NULL, actual_size); } else { column_size = get_size_by_type(column_type); tds_get_n(tds, NULL, column_size); } return TDS_SUCCEED;}static int tds_process_param_result_tokens(TDSSOCKET *tds){int marker; while ((marker=tds_get_byte(tds))==TDS_PARAM_TOKEN) { tds_process_param_result(tds); } tds_unget_byte(tds); return TDS_SUCCEED;}/*** tds_process_compute_result() processes compute result sets. These functions** need work but since they get little use, nobody has complained!** It is very similar to normal result sets.*/static int tds_process_compute_result(TDSSOCKET *tds){int hdrsize;int col, num_cols;TDSCOLINFO *curcol;TDSCOMPUTEINFO *info;int remainder; info = tds->comp_info; /* should not occur...but just in case */ if (info) tds_free_compute_results(info); hdrsize = tds_get_smallint(tds); /* unknown always 1 ? */ tds_get_smallint(tds); num_cols = tds_get_byte(tds); tds->comp_info = tds_alloc_compute_results(num_cols); info = tds->comp_info; for (col=0;col<num_cols;col++) { curcol=info->columns[col]; /* user type and some other stuff? */ tds_get_n(tds,NULL,6); /* column type */ curcol->column_type = tds_get_byte(tds); /* column size */ if (!is_fixed_type(curcol->column_type)) { curcol->column_size = tds_get_byte(tds); } else { curcol->column_size = get_size_by_type(curcol->column_type); } curcol->column_offset = info->row_size; info->row_size += curcol->column_size + 1; /* actually this 4 should be a machine dependent #define */ remainder = info->row_size & 0x3; if (remainder) info->row_size += (4 - remainder); tds_get_byte(tds); } tds_get_n(tds,NULL,tds_get_smallint(tds)); return TDS_SUCCEED;}/*** tds7_process_result() is the TDS 7.0 result set processing routine. It ** is responsible for populating the tds->res_info structure.** This is a TDS 7.0 only function*/static int tds7_process_result(TDSSOCKET *tds){int col, num_cols;int colnamelen;TDS_SMALLINT tabnamelen;TDSCOLINFO *curcol;TDSRESULTINFO *info;TDS_SMALLINT collate_type;int remainder; tds_free_all_results(tds); /* read number of columns and allocate the columns structure */ num_cols = tds_get_smallint(tds); tds->res_info = tds_alloc_results(num_cols); info = tds->res_info; /* tell the upper layers we are processing results */ tds->state = TDS_PENDING; /* loop through the columns populating COLINFO struct from ** server response */ for (col=0;col<num_cols;col++) { curcol = info->columns[col]; /* User defined data type of the column */ curcol->column_usertype = tds_get_smallint(tds); curcol->column_flags = tds_get_smallint(tds); /* Flags */ curcol->column_nullable = curcol->column_flags & 0x01; curcol->column_writeable = (curcol->column_flags & 0x08) > 0; curcol->column_identity = (curcol->column_flags & 0x10) > 0; curcol->column_type = tds_get_byte(tds); curcol->column_type_save = curcol->column_type; collate_type = (curcol->column_flags & 0x2) || is_collate_type(curcol->column_type); curcol->column_varint_size = tds_get_varint_size(curcol->column_type); switch(curcol->column_varint_size) { case 4: curcol->column_size = tds_get_int(tds); break; case 2: curcol->column_size = tds_get_smallint(tds); break; case 1: curcol->column_size = tds_get_byte(tds); break; case 0: curcol->column_size = get_size_by_type(curcol->column_type); break; } curcol->column_unicodedata = 0; if (is_unicode(curcol->column_type)) curcol->column_unicodedata = 1; curcol->column_type = tds_get_cardinal_type(curcol->column_type); /* numeric and decimal have extra info */ if (is_numeric_type(curcol->column_type)) { curcol->column_prec = tds_get_byte(tds); /* precision */ curcol->column_scale = tds_get_byte(tds); /* scale */ } if (IS_TDS80(tds)) { if (collate_type) tds_get_n(tds, curcol->collation, 5); } if (is_blob_type(curcol->column_type)) { tabnamelen = tds_get_smallint(tds);#ifdef NCBI_FTDS tds_get_string(tds,curcol->full_column_name,tabnamelen); curcol->full_column_name[tabnamelen]='.';#else tds_get_string(tds, NULL, tabnamelen);#endif } /* under 7.0 lengths are number of characters not ** number of bytes...tds_get_string handles this */ colnamelen = tds_get_byte(tds); tds_get_string(tds,curcol->column_name, colnamelen); /* the column_offset is the offset into the row buffer ** where this column begins, text types are no longer ** stored in the row buffer because the max size can ** be too large (2gig) to allocate */ curcol->column_offset = info->row_size; if (!is_blob_type(curcol->column_type)) { info->row_size += curcol->column_size + 1; }#ifdef NCBI_FTDS else { strcpy(curcol->full_column_name+tabnamelen+1,curcol->column_name); }#endif if (is_numeric_type(curcol->column_type)) { info->row_size += sizeof(TDS_NUMERIC) + 1; }#ifdef NCBI_FTDS else if(curcol->column_type == SYBVARBINARY) { info->row_size+= sizeof(TDS_INT); /* to prevent memory corruption */ }#endif /* actually this 4 should be a machine dependent #define */ if(remainder = info->row_size & 0x3) { info->row_size += (4 - remainder); } } /* all done now allocate a row for tds_process_row to use */ info->current_row = tds_alloc_row(info); return TDS_SUCCEED;}/*** tds_process_result() is the TDS 5.0 result set processing routine. It ** is responsible for populating the tds->res_info structure.** This is a TDS 5.0 only function*/static int tds_process_result(TDSSOCKET *tds){int hdrsize;int colnamelen;int col, num_cols;TDSCOLINFO *curcol;TDSRESULTINFO *info;int remainder; tds_free_all_results(tds); hdrsize = tds_get_smallint(tds); /* read number of columns and allocate the columns structure */ num_cols = tds_get_smallint(tds); tds->res_info = tds_alloc_results(num_cols); info = tds->res_info; /* tell the upper layers we are processing results */ tds->state = TDS_PENDING; /* loop through the columns populating COLINFO struct from ** server response */ for (col=0;col<info->num_cols;col++) { curcol=info->columns[col]; colnamelen = tds_get_byte(tds); tds_get_n(tds,curcol->column_name, colnamelen); curcol->column_name[colnamelen]='\0'; curcol->column_flags = tds_get_byte(tds); /* Flags */ curcol->column_nullable = (curcol->column_flags & 0x20) > 1; curcol->column_usertype = tds_get_smallint(tds); tds_get_smallint(tds); /* another unknown */ curcol->column_type = tds_get_byte(tds); curcol->column_varint_size = tds_get_varint_size(curcol->column_type); tdsdump_log(TDS_DBG_INFO1, "%L processing result. type = %d, varint_size %d\n", curcol->column_type, curcol->column_varint_size); switch(curcol->column_varint_size) { case 4: curcol->column_size = tds_get_int(tds); /* junk the table name -- for now */ tds_get_n(tds,NULL,tds_get_smallint(tds)); break; case 1: curcol->column_size = tds_get_byte(tds); break; case 0: curcol->column_size = get_size_by_type(curcol->column_type); break; /* FIXME can varint_size be 2 ?? */ } tdsdump_log(TDS_DBG_INFO1, "%L processing result. column_size %d\n", curcol->column_size); /* numeric and decimal have extra info */ if (is_numeric_type(curcol->column_type)) { curcol->column_prec = tds_get_byte(tds); /* precision */ curcol->column_scale = tds_get_byte(tds); /* scale */ } curcol->column_offset = info->row_size; if (is_numeric_type(curcol->column_type)) { info->row_size += sizeof(TDS_NUMERIC) + 1; } else if (!is_blob_type(curcol->column_type)) { info->row_size += curcol->column_size + 1; }#ifdef NCBI_FTDS else if(curcol->column_type == SYBVARBINARY) { info->row_size+= sizeof(TDS_INT); /* to prevent memory corruption */ }#endif /* actually this 4 should be a machine dependent #define */ remainder = info->row_size & 0x3; if (remainder) info->row_size += (4 - remainder); tds_get_byte(tds); /* ? */ } info->current_row = tds_alloc_row(info); return TDS_SUCCEED;}/*** tds_process_compute() processes compute rows and places them in the row** buffer. It's in a bit of disrepair and may not have tracked the row** buffer changes completely.*/static int tds_process_compute(TDSSOCKET *tds){int colsize, i;TDSCOLINFO *curcol;TDSCOMPUTEINFO *info;int compid;unsigned char *dest; info = tds->comp_info; compid = tds_get_smallint(tds); /* compute id? */ for (i=0;i<info->num_cols;i++) { curcol = info->columns[i]; if (!is_fixed_type(curcol->column_type)) { colsize = tds_get_byte(tds); } else { colsize = get_size_by_type(curcol->column_type); } dest = &(info->current_row[curcol->column_offset]); tds_get_n(tds,dest,colsize);#ifndef NCBI_FTDS dest[colsize]='\0';#endif } return TDS_SUCCEED;}/*** tds_process_row() processes rows and places them in the row buffer. There** is also some special handling for some of the more obscure datatypes here.*/static int tds_process_row(TDSSOCKET *tds){int colsize, i;TDSCOLINFO *curcol;TDSRESULTINFO *info;unsigned char *dest;TDS_NUMERIC *num;TDS_VARBINARY *varbin;int len; TDS_SMALLINT cur_col_type; info = tds->res_info; if (!info) return TDS_FAIL; info->row_count++;#ifdef NCBI_FTDS memset(info->current_row,'\0',info->null_info_size); /*** clear nulls ***/#endif for (i=0;i<info->num_cols;i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -