/* d4open.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif #ifdef S4OFF_MEMO extern char f4memo_null_char ; #endif DATA4 *S4FUNCTION d4open( CODE4 *c4, char *name ) { int rc, i_fields, i_memo ; unsigned field_data_len, count ; char name_buf[258], field_buf[2], *info ; DATA4 *d4 ; DATA4HEADER_FULL full_header ; INDEX4 *i4 ; FIELD4IMAGE *image ; #ifdef S4VBASIC if ( c4parm_check( c4, 1, E4_D4OPEN ) ) return 0 ; #endif if ( c4 == 0 || name == 0 ) #ifdef S4DEBUG e4severe( e4parm, E4_D4OPEN ) ; #else return 0 ; #endif if ( c4->error_code < 0 ) return 0 ; #ifdef S4DEBUG if ( c4->debug_int != 0x5281 ) e4severe( e4result, E4_RESULT_D4I ) ; #ifndef S4WIN32 u4name_piece( name_buf, sizeof( name_buf ), name, 0, 0 ) ; if ( d4data( c4, name_buf ) ) { e4( c4, e4info, E4_INFO_DAO ) ; return 0 ; } #endif #endif if ( c4->data_memory == 0 ) { c4->data_memory = mem4create( c4, c4->mem_start_data, sizeof(DATA4), c4->mem_expand_data, 0 ) ; if ( c4->data_memory == 0 ) { e4( c4, e4memory, 0 ) ; return 0 ; } } d4 = (DATA4 *) mem4alloc( c4->data_memory ) ; if ( d4 == 0 ) { e4( c4, e4memory, 0 ) ; return 0 ; } #ifdef S4VBASIC d4->debug_int = 0x5281 ; #endif d4->code_base = c4 ; #ifndef S4SINGLE d4->locks = &d4->locked_record ; d4->n_locks = 1 ; #endif d4->memo_file.file.hand = -1 ; u4ncpy( name_buf, name, sizeof(name_buf) ) ; #ifdef S4UNIX u4name_ext( name_buf, sizeof(name_buf), "dbf", 0 ) ; #else u4name_ext( name_buf, sizeof(name_buf), "DBF", 0 ) ; #endif rc = file4open( &d4->file, c4, name_buf, 1 ) ; if ( rc ) { d4close( d4 ) ; return 0 ; } l4add( &c4->data_list, &d4->link ) ; u4name_piece( d4->alias, sizeof(d4->alias), name_buf, 0,0 ) ; if ( file4read_all( &d4->file, 0L, &full_header, sizeof( full_header ) ) < 0 ) { d4close( d4 ) ; return 0 ; } #ifdef S4BYTE_SWAP full_header.num_recs = x4reverse_long( (void *)&full_header.num_recs ) ; full_header.header_len = x4reverse_short( (void *)&full_header.header_len ) ; full_header.record_len = x4reverse_short( (void *)&full_header.record_len ) ; #endif #ifdef S4DEMO if ( full_header.num_recs > 200L) { e4( c4, e4demo, 0 ) ; d4close(d4) ; return 0 ; } #endif #ifdef S4DEBUG if ( full_header.num_recs < 0L || full_header.num_recs > ( 1 + ( file4len ( &d4->file ) - full_header.header_len ) / full_header.record_len ) ) e4severe( e4info, E4_DATA_COR ) ; #endif memcpy( (void *)&d4->version, (void *)&full_header.version, (4+(sizeof(S4LONG))+(sizeof(short))) ) ; d4->num_recs = -1L ; d4->has_mdx = full_header.has_mdx ; field_data_len = full_header.header_len-sizeof(full_header) ; if ( full_header.header_len <= sizeof(full_header) ) { e4( c4, e4data, d4->file.name ) ; d4close(d4) ; return 0 ; } info = (char *) u4alloc_free( c4, field_data_len ) ; if ( info == 0 ) { e4( c4, e4memory, 0 ) ; d4close(d4) ; return 0 ; } if ( file4read_all( &d4->file, (long) sizeof(full_header), info,field_data_len) < 0 ) { u4free(info) ; e4( c4, e4data, 0 ) ; d4close(d4) ; return 0 ; } /* count the number of fields */ for (count=0; count < field_data_len; count+= 32 ) if ( info[count] == 0xD ) break ; d4->n_fields = (int) (count/32) ; if ( field_data_len/32 < (unsigned) d4->n_fields ) { u4free(info) ; e4( c4, e4data, d4->file.name ) ; d4close(d4) ; return 0 ; } d4->fields = (FIELD4 *) u4alloc_free( c4, sizeof(FIELD4) * (long) d4->n_fields ) ; if ( d4->fields == 0 ) e4( c4, e4memory, 0 ) ; d4->record_width = 1 ; if ( !(c4->error_code < 0) ) for ( i_fields = 0; i_fields < d4->n_fields; i_fields++ ) { image = (FIELD4IMAGE *) (info+ i_fields*32) ; u4ncpy( d4->fields[i_fields].name, image->name, sizeof(d4->fields->name) ) ; u4ncpy( field_buf, &image->type, 2 ) ; c4upper( field_buf ) ; d4->fields[i_fields].type = *field_buf ; if ( d4->fields[i_fields].type == 'N' || d4->fields[i_fields].type == 'F') { d4->fields[i_fields].len = image->len ; d4->fields[i_fields].dec = image->dec ; } else { if ( d4->fields[i_fields].type == 'L' || d4->fields[i_fields].type == 'D' || d4->fields[i_fields].type == 'M' || d4->fields[i_fields].type == 'G' || d4->fields[i_fields].type == 'B' ) d4->fields[i_fields].len = image->len ; else d4->fields[i_fields].len = image->len + (image->dec << 8) ; d4->fields[i_fields].dec = 0 ; } if ( d4->fields[i_fields].type == 'M' || d4->fields[i_fields].type == 'G' || d4->fields[i_fields].type == 'B' ) { d4->n_fields_memo++ ; #ifdef S4MEMO_OFF d4->fields[i_fields].memo = (F4MEMO *)&f4memo_null_char ; #endif } #ifdef S4VBASIC d4->fields[i_fields].debug_int = 0x5281 ; #endif d4->fields[i_fields].offset = d4->record_width ; d4->record_width += d4->fields[i_fields].len ; d4->fields[i_fields].data = d4 ; } u4free( info ) ; #ifndef S4MEMO_OFF if ( d4->n_fields_memo > 0 && ! (c4->error_code< 0) ) { i_memo = 0 ; d4->fields_memo = (F4MEMO *)u4alloc_free( c4, (long)sizeof(F4MEMO) * d4->n_fields_memo ) ; if ( d4->fields_memo == 0 ) e4( c4, e4memory, 0 ) ; else for ( i_fields = 0; i_fields < d4->n_fields; i_fields++ ) if ( d4->fields[i_fields].type == 'M' || d4->fields[i_fields].type == 'G' || d4->fields[i_fields].type == 'B' ) { d4->fields[i_fields].memo = d4->fields_memo+i_memo ; d4->fields_memo[i_memo].status = 1 ; d4->fields_memo[i_memo].field = d4->fields+i_fields ; i_memo++ ; } } #endif if ( d4->record_width != full_header.record_len && ! (c4->error_code<0) ) e4( c4, e4data, d4->file.name ) ; if ( c4->error_code < 0 ) { d4close(d4) ; return 0 ; } d4->record = (char *) u4alloc_free( c4, d4->record_width + 1 ) ; d4->record_old = (char *) u4alloc_free( c4, d4->record_width+1 ) ; if ( d4->record == 0 || d4->record_old == 0 ) { e4( c4, e4memory, 0 ) ; d4close(d4) ; return 0 ; } memset( d4->record, ' ', d4->record_width ) ; memset( d4->record_old, ' ', d4->record_width ) ; d4->rec_num = d4->rec_num_old = -1 ; #ifndef S4OPTIMIZE_OFF file4optimize( &d4->file, c4->optimize, OPT4DBF ) ; #endif #ifndef S4INDEX_OFF #ifdef N4OTHER if ( c4->auto_open ) { i4 = i4open( d4, 0 ) ; if ( i4 == 0 ) { d4close(d4) ; return 0 ; } } #else if ( d4->has_mdx && c4->auto_open ) { i4 = i4open( d4, 0 ) ; if ( i4 == 0 ) { d4close(d4) ; return 0 ; } #ifdef S4MDX if ( !i4->header.is_production ) i4close(i4); #endif } #endif #endif #ifndef S4MEMO_OFF if ( d4->version & 0x80 ) { #ifdef S4MFOX #ifdef S4UNIX u4name_ext( name_buf, sizeof(name_buf), "fpt", 1 ) ; #else u4name_ext( name_buf, sizeof(name_buf), "FPT", 1 ) ; #endif #else #ifdef S4UNIX u4name_ext( name_buf, sizeof(name_buf), "dbt", 1 ) ; #else u4name_ext( name_buf, sizeof(name_buf), "DBT", 1 ) ; #endif #endif if ( memo4file_open( &d4->memo_file, d4, name_buf ) < 0 ) { d4close(d4) ; return 0 ; } } #endif return d4 ; } #ifdef S4VB_DOS DATA4 * d4open_v( CODE4 *c4, char *name ) { return d4open( c4, c4str(name) ) ; } #endif