campo-sirio/cb/source/d4create.c
alex af15e0698b Codebase
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:01:08 +00:00

1162 lines
33 KiB
C
Executable File

/* d4create.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
#include "d4all.h"
#ifdef __TURBOC__
#pragma hdrstop
#endif /* __TUROBC__ */
#ifndef S4OFF_WRITE
DATA4 *S4FUNCTION d4createTemp( CODE4 *c4, const FIELD4INFO *fieldData, const TAG4INFO *tagInfo )
{
int oldTemp ;
DATA4 *data ;
#ifdef S4VBASIC
if ( c4parm_check( c4, 1, E91401 ) )
return 0 ;
#endif /* S4VBASIC */
#ifdef E4PARM_HIGH
if ( c4 == 0 || fieldData == 0 )
{
error4( c4, e4parm_null, E91401 ) ;
return 0 ;
}
#endif
oldTemp = c4->createTemp ;
c4->createTemp = 1 ;
data = d4create( c4, (char *)0, fieldData, tagInfo ) ;
c4->createTemp = oldTemp ;
if ( data == 0 )
{
#ifdef E4STACK
error4stack( c4, e4data, E91401 ) ;
#endif
return 0 ;
}
return data ;
}
#ifndef S4CLIENT
#ifdef P4ARGS_USED
#pragma argsused
#endif
static void d4createClose( CODE4 *c4, DATA4 *d4 )
{
#ifndef S4OFF_TRAN
int oldStatus ;
#endif
if ( d4 == 0 )
return ;
#ifdef S4OFF_TRAN
d4close( d4 ) ;
#else
oldStatus = code4tranStatus( c4 ) ;
code4tranStatusSet( c4, r4off ) ;
d4close( d4 ) ;
code4tranStatusSet( c4, oldStatus ) ;
#endif
}
#endif
DATA4 *S4FUNCTION d4create( CODE4 *c4, const char *name, const FIELD4INFO *fieldData, const TAG4INFO *tagInfo )
{
#ifdef S4CLIENT
SOCKET4 *socket ;
CONNECTION4 *connection ;
CONNECTION4CREATE_INFO_IN dataIn ;
CONNECTION4FIELD_INFO finfo ;
CONNECTION4TAG_INFO tinfo ;
CONNECTION4UNIQUE_INFO_IN uniqueInfoIn ;
CONNECTION4UNIQUE_TAG_INFO uniqueTagInfo ;
unsigned int len, len2, len3, offset, j ;
int oldAccessMode ;
#else
int oldReadOnly ;
#ifndef S4OFF_TRAN
int saveStatus ;
#endif
#endif
char nameBuf[258] ;
int rc, i, oldAutoOpen ;
DATA4FILE *d4 ;
DATA4 *data ;
TAG4 *tag ;
#ifdef S4VBASIC
if ( c4parm_check( c4, 1, E91401 ) )
return 0 ;
#endif /* S4VBASIC */
#ifdef E4PARM_HIGH
if ( c4 == 0 || fieldData == 0 )
{
error4( c4, e4parm_null, E91401 ) ;
return 0 ;
}
if ( name == 0 && c4->createTemp != 1 )
{
error4( c4, e4parm_null, E91401 ) ;
return 0 ;
}
#endif
if ( error4code( c4 ) < 0 )
return 0 ;
#ifdef E4ANALYZE
if ( c4->debugInt != 0x5281 )
{
error4( c4, e4info, E81301 ) ;
return 0 ;
}
#endif
#ifdef S4STAND_ALONE
#ifndef S4OFF_TRAN
if ( c4->logOpen ) /* open now so that can turn off during create */
{
rc = code4logOpen( c4, 0, 0 ) ;
if ( rc < 0 )
return 0 ;
else
error4set( c4, 0 ) ; /* remove r4open if it already existed */
}
#endif
#endif
if ( c4->createTemp == 1 )
{
#ifndef S4OFF_CATALOG
if ( cat4avail( c4->catalog ) == 1 )
c4->catalog->valid = 0 ;
#endif
}
else
{
#ifdef S4CLIENT
d4 = dfile4data( c4, name ) ;
#else
u4nameCurrent( nameBuf, sizeof( nameBuf ), name ) ;
u4nameExt( nameBuf, sizeof( nameBuf ), "dbf", 0 ) ;
#ifndef S4CASE_SEN
c4upper(nameBuf);
#endif
d4 = dfile4data( c4, nameBuf ) ;
#endif
if ( d4 != 0 )
{
error4describe( c4, e4create, E81304, name, (char *)0, (char *)0 ) ;
return 0 ;
}
}
#ifdef S4CLIENT
if ( c4->defaultServer == 0 )
{
rc = code4connect( c4, 0, DEF4PROCESS_ID, 0, 0, 0 ) ;
if ( rc == 0 )
{
if ( c4->defaultServer == 0 )
{
error4( c4, e4connection, E84302 ) ;
return 0 ;
}
rc = code4dateFormatSet( c4, code4dateFormat( c4 ) ) ;
}
if ( rc != 0 )
{
if ( c4->defaultServer != 0 )
{
socket4initUndo( c4->defaultServer ) ;
socket4free( c4->defaultServer ) ;
c4->defaultServer = 0 ;
}
return 0 ;
}
}
socket = c4->defaultServer ;
if ( socket == 0 )
{
error4( c4, e4connection, E81303 ) ;
return 0 ;
}
connection = socket->connect ;
#ifdef E4ANALYZE
if ( connection == 0 )
{
error4( c4, e4connection, E91401 ) ;
return 0 ;
}
#endif
connection4assign( connection, CON4CREATE, 0, 0 ) ;
memset( &dataIn, 0, sizeof( dataIn ) ) ; /* avoids requiring memsets for name and zero assigns */
if ( c4->createTemp == 1 )
{
dataIn.createTemp = 1 ;
dataIn.log = LOG4TRANS ;
}
else
dataIn.log = c4->log ;
dataIn.safety = c4->safety ;
dataIn.readOnly = c4->readOnly ; /* catalog purposes */
dataIn.compatibility = c4->compatibility ;
if ( name != 0 )
{
#ifdef E4MISC
if ( strlen( name ) > LEN4PATH )
error4describe( c4, e4create, E84301, name, (char *)0, (char *)0 ) ;
#endif
strncpy( dataIn.name, name, LEN4PATH ) ;
}
if ( tagInfo == 0 )
i = 0 ;
else
for( i = 0 ; tagInfo[i].name != 0; i++ )
;
dataIn.numTags = i ;
for( i = 0 ; fieldData[i].name != 0; i++ )
;
dataIn.numFields = i ;
len = 0 ;
for ( j = 0 ; j != dataIn.numFields ; j++ )
{
len += sizeof( CONNECTION4FIELD_INFO ) ;
len += strlen( fieldData[j].name ) + 1 ;
}
dataIn.fieldInfoLen = len ;
connection4addData( connection, &dataIn, sizeof(CONNECTION4CREATE_INFO_IN), 0 ) ;
offset = sizeof( CONNECTION4CREATE_INFO_IN ) ;
for ( j = 0 ; j != dataIn.numFields ; j++ )
{
len = strlen( fieldData[j].name ) + 1 ;
finfo.name.offset = offset + sizeof(CONNECTION4FIELD_INFO) ;
finfo.type = fieldData[j].type ;
finfo.len = fieldData[j].len ;
finfo.dec = fieldData[j].dec ;
finfo.nulls = fieldData[j].nulls ;
connection4addData( connection, &finfo, sizeof(CONNECTION4FIELD_INFO), 1 ) ;
connection4addData( connection, fieldData[j].name, len, 0 ) ;
offset += ( len + sizeof( CONNECTION4FIELD_INFO ) ) ;
}
for ( j = 0 ; j != dataIn.numTags ; j++ )
{
len = strlen( tagInfo[j].name ) + 1 ;
offset += sizeof( CONNECTION4TAG_INFO ) ;
tinfo.name.offset = offset ;
len2 = strlen( tagInfo[j].expression ) + 1 ;
offset += len ;
tinfo.expression.offset = offset ;
offset += len2 ;
if ( tagInfo[j].filter == 0 )
{
len3 = 0 ;
tinfo.filter.offset = 0 ;
}
else
{
len3 = strlen( tagInfo[j].filter ) + 1 ;
tinfo.filter.offset = offset ;
}
offset += len3 ;
tinfo.unique = tagInfo[j].unique ;
tinfo.descending = tagInfo[j].descending ;
connection4addData( connection, &tinfo, sizeof(CONNECTION4TAG_INFO), 1 ) ;
connection4addData( connection, tagInfo[j].name, len, 0 ) ;
connection4addData( connection, tagInfo[j].expression, len2, 0 ) ;
if ( len3 != 0 )
connection4addData( connection, tagInfo[j].filter, len3, 0 ) ;
}
connection4send( connection ) ;
rc = connection4receive( connection ) ;
if ( rc < 0 )
{
#ifdef E4STACK
error4stack( c4, rc, E91401 ) ;
#endif
return 0 ;
}
if ( connection4type( connection ) != CON4CREATE )
{
#ifdef E4STACK
error4stack( c4, e4connection, E91401 ) ;
#endif
return 0 ;
}
rc = connection4status( connection ) ;
if ( rc != 0 )
{
if ( c4->errCreate == 0 )
error4set( c4, r4noCreate ) ;
else
connection4errorDescribe( connection, c4, rc, E91401, name, 0, 0 ) ;
return 0 ;
}
oldAutoOpen = c4->autoOpen ;
if ( tagInfo == 0 )
c4->autoOpen = 0 ;
else
{
if ( tagInfo[0].name == 0 )
c4->autoOpen = 0 ;
else
c4->autoOpen = 1 ;
}
if ( c4->createTemp == 0 )
{
if ( connection4len( connection ) != 0 )
{
c4->autoOpen = oldAutoOpen ;
#ifdef E4STACK
error4stack( c4, e4packetLen, E91401 ) ;
#endif
return 0 ;
}
if ( dataIn.numTags == 0 )
c4->openForCreate = 2 ;
else
c4->openForCreate = 1 ;
data = d4open( c4, name ) ;
c4->openForCreate = 0 ;
}
else
{
oldAccessMode = c4->accessMode ;
c4->accessMode = OPEN4DENY_RW ;
if ( name == 0 )
{
if ( connection4len( connection ) > sizeof( nameBuf ) + 1 )
{
c4->accessMode = oldAccessMode ;
c4->autoOpen = oldAutoOpen ;
error4( c4, e4packetLen, E91401 ) ;
return 0 ;
}
memcpy( nameBuf, connection4data( connection ), (unsigned int)connection4len( connection ) ) ;
nameBuf[connection4len( connection )] = 0 ;
if ( dataIn.numTags == 0 )
c4->openForCreate = 2 ;
else
c4->openForCreate = 1 ;
data = d4open( c4, nameBuf ) ;
c4->openForCreate = 0 ;
}
else
{
if ( dataIn.numTags == 0 )
c4->openForCreate = 2 ;
else
c4->openForCreate = 1 ;
data = d4open( c4, name ) ;
c4->openForCreate = 0 ;
}
c4->accessMode = oldAccessMode ;
}
c4->autoOpen = oldAutoOpen ;
if ( data == 0 )
return 0 ;
/* set the unique settings... */
code4indexFormat( c4 ) ; /* need to call this to avoid corruption in d4tag() call below which asks
this question calling the server destroying com struct */
uniqueInfoIn.numTags = dataIn.numTags ;
connection4assign( connection, CON4UNIQUE_SET, data4clientId( data ), data4serverId( data ) ) ;
connection4addData( connection, &uniqueInfoIn, sizeof(CONNECTION4UNIQUE_INFO_IN), 0 ) ;
for ( j = 0 ; j != dataIn.numTags ; j++ )
{
if ( tagInfo[j].unique == c4->errDefaultUnique )
uniqueInfoIn.numTags-- ;
else
{
tag = d4tag( data, tagInfo[j].name ) ;
if ( tag == 0 )
{
rc = error4describe( data->codeBase, e4name, E81406, d4alias( data ), tagInfo[j].name, 0 ) ;
break ;
}
uniqueTagInfo.unique = tagInfo[j].unique ;
tag->errUnique = tagInfo[j].unique ;
memcpy( uniqueTagInfo.alias, tag->tagFile->alias, LEN4TAG_ALIAS ) ;
connection4addData( connection, &uniqueTagInfo, sizeof(CONNECTION4UNIQUE_TAG_INFO), 1 ) ;
}
}
connection4send( connection ) ;
rc = connection4receive( connection ) ;
if ( rc == 0 )
{
rc = connection4status( connection ) ;
if ( rc < 0 )
connection4error( connection, c4, rc, E91401 ) ;
}
if ( rc < 0 )
{
d4close( data ) ;
return 0 ;
}
return data ;
#else
if ( c4->createTemp == 1 )
{
data = 0 ;
rc = dfile4create( c4, name, fieldData, tagInfo, &data ) ;
if ( rc < 0 )
{
d4createClose( c4, data ) ;
return 0 ;
}
}
else
{
#ifndef S4OFF_TRAN
saveStatus = code4tranStatus( c4 ) ;
code4tranStatusSet( c4, r4off ) ;
#endif
oldReadOnly = c4->readOnly ;
c4->readOnly = 0 ;
rc = dfile4create( c4, name, fieldData, tagInfo, 0 ) ;
c4->readOnly = oldReadOnly ;
#ifndef S4OFF_TRAN
if ( saveStatus != 0 ) /* which may have resulted in transaction enabling when file created, so leave */
code4tranStatusSet( c4, saveStatus ) ;
#endif
if ( rc < 0 )
{
#ifdef E4STACK
error4stack( c4, (short)rc, E91401 ) ;
#endif
return 0 ;
}
if ( rc != 0 )
return 0 ;
oldAutoOpen = c4->autoOpen ;
if ( tagInfo == 0 )
c4->autoOpen = 0 ;
else
{
if ( tagInfo[0].name == 0 )
c4->autoOpen = 0 ;
else /* make sure on */
c4->autoOpen = 1 ;
}
data = d4open( c4, name ) ;
c4->autoOpen = oldAutoOpen ;
if ( data == 0 )
return 0 ;
}
/* set the unique settings... */
if ( tagInfo != 0 )
for ( i = 0 ; tagInfo[i].name != 0 ; i++ )
{
tag = d4tag( data, tagInfo[i].name ) ;
if ( tag == 0 )
{
error4describe( data->codeBase, e4name, E81406, d4alias( data ), tagInfo[i].name, 0 ) ;
return data ;
}
tag->errUnique = tagInfo[i].unique ;
}
return data ;
#endif
}
#ifndef S4CLIENT
#ifndef S4OFF_MEMO
#ifndef CREATE4MEMO_EXT
#ifdef S4MFOX
#define CREATE4MEMO_EXT "fpt"
#else
#define CREATE4MEMO_EXT "mdx"
#endif
#endif
#endif
int dfile4create( CODE4 *c4, const char *name, const FIELD4INFO *fieldData, const TAG4INFO *tagInfo, DATA4 **temp )
{
unsigned int nFlds ;
int i, rc, oldAutoOpen, tempFreeSet, oldCT2 ;
#ifndef S4OFF_MULTI
int oldAccessMode ;
#endif
#ifndef S4OFF_MEMO
int hasMemo ;
#endif
long calcRecordLen, lheaderLen ;
char buf[258], buffer[0x800] ;
FILE4SEQ_WRITE seqWrite ;
DATA4 *data ;
DATA4HEADER_FULL createHeader ;
DATA4FILE *dfile ;
FIELD4IMAGE createFieldImage ;
FILE4 file ;
char *tempName ;
unsigned int len ;
#ifdef S4CLIPPER
#ifndef S4OFF_INDEX
char nameBuf[258] ;
#endif
#endif
#ifdef E4MISC
int dec ;
#endif
#ifndef S4OFF_MEMO
int isMemo, oldCreateTemp ;
MEMO4FILE m4file ;
#endif
#ifdef S4SERVER
int oldKeepOpen ;
#endif
#ifndef S4OFF_TRAN
int oldStatus = 0 ;
#endif
#ifdef S4FOX
int hasNulls = 0 ;
#endif
#ifdef S4VBASIC
if ( c4parm_check( c4, 1, E91102 ) )
return -1 ;
#endif /* S4VBASIC */
#ifdef E4PARM_LOW
if ( c4 == 0 || fieldData == 0 )
return error4( c4, e4parm_null, E91102 ) ;
if ( name == 0 && c4->createTemp != 1 )
return error4( c4, e4parm_null, E91102 ) ;
#endif
if ( error4code( c4 ) < 0 )
return e4codeBase ;
if ( name != 0 )
{
u4nameCurrent( buf, sizeof( buf ), name ) ;
u4nameExt( buf, sizeof(buf), "dbf", 0 ) ;
/* an unused dfile may be removed to allow re-create */
#ifndef S4CASE_SEN
c4upper( buf ) ;
#endif
dfile = dfile4data( c4, buf ) ;
if ( dfile != 0 )
{
rc = dfile4closeLow( dfile ) ;
if ( rc < 0 )
return error4stack( c4, (short)rc, E91102 ) ;
dfile = dfile4data( c4, buf ) ;
if ( dfile != 0 ) /* datafile already open -- can't create */
return error4describe( c4, e4create, E81304, buf, (char *)0, (char *)0 ) ;
}
}
#ifndef S4OFF_MEMO
isMemo = 0 ;
#endif
calcRecordLen = 1L ;
nFlds = 0 ;
for ( ; fieldData[nFlds].name ; nFlds++ )
{
#ifdef S4FOX
if ( c4->compatibility == 30 )
if ( fieldData[nFlds].nulls == r4null )
hasNulls++ ;
#endif
#ifndef S4OFF_MEMO
if ( fieldData[nFlds].type == r4memo || fieldData[nFlds].type == r4gen
#ifndef S4FOX
|| fieldData[nFlds].type == r4bin
#endif
)
isMemo = 1 ;
#endif
switch( fieldData[nFlds].type )
{
case r4num:
case r4float:
case r4str:
#ifndef S4FOX
case r4bin:
#endif
calcRecordLen += fieldData[nFlds].len ;
break ;
case r4memo:
case r4gen:
#ifdef S4OFF_MEMO
#ifdef E4MISC
return error4( c4, e4notMemo, E91102 ) ;
#endif
#else
#ifdef S4FOX
if ( c4->compatibility == 30 )
calcRecordLen += 4 ;
else
#endif
calcRecordLen += 10 ;
break ;
#endif
case r4date:
calcRecordLen += 8 ;
break ;
case r4log:
calcRecordLen += 1 ;
break ;
#ifdef S4FOX
case r4memoBin:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
calcRecordLen += 4 ;
break ;
case r4charBin:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
calcRecordLen += fieldData[nFlds].len ;
break ;
case r4currency:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
calcRecordLen += 8 ;
break ;
case r4dateTime:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
calcRecordLen += 8 ;
break ;
case r4double:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
calcRecordLen += 8 ;
break ;
case r4int:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
calcRecordLen += 4 ;
break ;
#endif
default:
return error4( c4, e4data, E81404 ) ;
}
}
if ( calcRecordLen >= USHRT_MAX ) /* Increment for deletion flag. */
{
if ( name == 0 )
return error4( c4, e4recordLen, E81407 ) ;
else
return error4describe( c4, e4recordLen, E91102, name, 0, 0 ) ;
}
lheaderLen = (long)nFlds * 32 + 34 ;
#ifdef S4FOX
if ( c4->compatibility == 30 )
if ( hasNulls > 0 ) /* extra field for null settings */
{
lheaderLen += 32 ;
calcRecordLen += (hasNulls+7)/8 ;
}
#endif
if ( lheaderLen >= USHRT_MAX )
{
if ( name == 0 )
return error4( c4, e4recordLen, E81408 ) ;
else
return error4describe( c4, e4create, E81405, name, 0, 0 ) ;
}
tempFreeSet = 0 ;
tempName = 0 ;
if ( name != 0 )
{
#ifdef S4SERVER
#ifndef S4OFF_CATALOG
if ( c4->createTemp != 1 && cat4avail( c4->catalog ) )
{
u4ncpy( buf, cat4pathName( c4->catalog ), (unsigned int)cat4pathNameLen( c4->catalog ) ) ;
for ( i = 0 ; i < cat4pathNameLen( c4->catalog ) ; i++ )
if ( buf[i] == ' ' )
{
buf[i] = 0 ;
break ;
}
}
#endif /* S4OFF_CATALOG */
#endif /* S4SERVER */
if ( c4->createTemp == 1 ) /* take care of setting as temp later */
{
c4->createTemp = 0 ;
rc = file4create( &file, c4, buf, 1 ) ;
c4->createTemp = 1 ;
}
else
rc = file4create( &file, c4, buf, 1 ) ;
}
else
{
oldCT2 = c4->createTemp ;
c4->createTemp = 0 ;
rc = file4tempLow( &file, c4, 0 ) ; /* need to set as non-remove to get name input */
c4->createTemp = oldCT2 ;
if ( rc == 0 )
{
file.isTemp = 1 ;
if ( file.name != 0 )
{
len = strlen( file.name ) ;
if ( len > sizeof( buf ) + 1 )
len = sizeof( buf ) - 1 ;
memcpy( buf, file.name, len ) ;
buf[len] = 0 ;
tempName = file.nameBuf ;
}
#ifdef E4DEBUG
else
{
file4close( &file ) ;
error4( c4, e4info, E91102 ) ;
}
#endif
tempFreeSet = 1 ;
}
}
if ( rc < 0 )
return error4stack( c4, (short)rc, E91102 ) ;
if ( rc != 0 ) /* maybe r4create */
return rc ;
rc = file4seqWriteInit( &seqWrite, &file, 0L, buffer, sizeof(buffer) ) ;
if ( rc < 0 )
{
file4close( &file ) ;
return error4stack( c4, (short)rc, E91102 ) ;
}
/* Write the header */
memset( (void *)&createHeader, 0, sizeof(createHeader) ) ;
#ifdef S4FOX
if ( c4->compatibility == 30 ) /* 3.0 file */
{
createHeader.version = 0x30 ;
#ifndef S4OFF_MEMO
if ( isMemo )
createHeader.hasMdxMemo |= 0x02 ;
#endif
}
else
{
#ifndef S4OFF_MEMO
if ( isMemo )
createHeader.version = (char)0xF5 ;
else
#endif
createHeader.version = (char)0x03 ;
}
#else
#ifndef S4OFF_MEMO
if ( isMemo )
#ifdef S4MNDX
createHeader.version = (char)0x83 ;
#endif /* S4MNDX */
#ifdef S4MMDX
createHeader.version = (char)0x8B ;
#endif /* S4MMDX */
else
#endif /* S4OFF_MEMO */
createHeader.version = (char)0x03 ;
#endif /* S4FOX */
u4yymmdd( &createHeader.yy ) ;
createHeader.headerLen = (unsigned short)(32*(nFlds+1) + 1) ;
#ifdef S4FOX
if ( c4->compatibility == 30 ) /* 3.0 file */
{
if ( hasNulls > 0 ) /* extra field for null settings */
createHeader.headerLen += 32 ;
createHeader.headerLen += 263 ; /* visual fox reserves an extra 263 bytes */
}
#endif
createHeader.recordLen = (unsigned short)calcRecordLen ;
#ifdef S4FOX
createHeader.codePage = (char)c4->codePage ; /* write codepage stamp */
#endif
#ifdef S4BYTE_SWAP
createHeader.numRecs = x4reverseLong( (void *)&createHeader.numRecs ) ;
createHeader.headerLen = x4reverseShort( (void *)&createHeader.headerLen ) ;
createHeader.recordLen = x4reverseShort( (void *)&createHeader.recordLen ) ;
#endif /* S4BYTE_SWAP */
rc = file4seqWrite( &seqWrite, (char *) &createHeader, sizeof(createHeader) ) ;
if ( rc < 0 )
{
file4seqWriteFlush( &seqWrite ) ;
file4close( &file ) ;
return error4stack( c4, (short)rc, E91102 ) ;
}
#ifdef S4FOX
calcRecordLen = 1L ;
#endif
for ( i = 0; i < (int)nFlds; i++ )
{
memset( (void *)&createFieldImage, 0, sizeof(createFieldImage) ) ;
u4ncpy( createFieldImage.name, fieldData[i].name, sizeof(createFieldImage.name));
c4trimN( createFieldImage.name, sizeof(createFieldImage.name) ) ;
c4upper( createFieldImage.name ) ;
createFieldImage.type = (char)fieldData[i].type ;
c4upper( &createFieldImage.type ) ;
#ifdef S4FOX
createFieldImage.offset = (short)calcRecordLen ;
calcRecordLen += fieldData[i].len ;
if ( fieldData[i].nulls == r4null )
createFieldImage.nullBinary |= 0x02 ;
#endif
switch( createFieldImage.type )
{
case r4str:
createFieldImage.len = (unsigned char)(fieldData[i].len & 0xFF) ;
createFieldImage.dec = (unsigned char)(fieldData[i].len>>8) ;
break ;
#ifndef S4OFF_MEMO
case r4memo:
case r4gen:
#ifndef S4FOX
case r4bin:
#endif
#ifdef S4FOX
if ( c4->compatibility == 30 ) /* 3.0 file */
createFieldImage.len = 4 ;
else
createFieldImage.len = 10 ;
#else
createFieldImage.len = 10 ;
#endif
createFieldImage.dec = 0 ;
break ;
#endif
case r4date:
createFieldImage.len = 8 ;
createFieldImage.dec = 0 ;
break ;
case r4log:
createFieldImage.len = 1 ;
createFieldImage.dec = 0 ;
break ;
case r4num:
case r4float:
createFieldImage.len = (unsigned char)fieldData[i].len ;
createFieldImage.dec = (unsigned char)fieldData[i].dec ;
#ifdef E4MISC
len = fieldData[i].len ;
dec = fieldData[i].dec ;
if ( ( len > F4MAX_NUMERIC || len < 1 || len <= 2 && dec != 0 || dec < 0 ) ||
( (unsigned int)dec > len - F4DECIMAL_OFFSET && dec > 0 ) || ( dec > F4MAX_DECIMAL ) )
return error4( c4, e4data, E81404 ) ;
#endif
break ;
#ifdef S4FOX
case r4charBin:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
createFieldImage.type = r4str ;
createFieldImage.len = (unsigned char)(fieldData[i].len & 0xFF) ;
createFieldImage.dec = (unsigned char)(fieldData[i].len>>8) ;
createFieldImage.nullBinary |= 0x04 ;
break ;
case r4memoBin:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
createFieldImage.type = r4memo ;
createFieldImage.dec = 0 ;
createFieldImage.len = 4 ;
createFieldImage.nullBinary |= 0x04 ;
break ;
case r4currency:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
createFieldImage.len = 8 ;
createFieldImage.dec = 4 ;
createFieldImage.nullBinary |= 0x04 ;
break ;
case r4dateTime:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
createFieldImage.len = 8 ;
createFieldImage.dec = 0 ;
createFieldImage.nullBinary |= 0x04 ;
break ;
case r4int:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
createFieldImage.len = 4 ;
createFieldImage.dec = 0 ;
createFieldImage.nullBinary |= 0x04 ;
break ;
case r4double:
if ( c4->compatibility != 30 )
return error4( c4, e4data, E81404 ) ;
createFieldImage.len = 8 ;
createFieldImage.dec = (unsigned char)fieldData[i].dec ;
createFieldImage.nullBinary |= 0x04 ;
break ;
#endif
default:
return error4( c4, e4data, E81404 ) ;
}
rc = file4seqWrite( &seqWrite, &createFieldImage, sizeof(createFieldImage) ) ;
if ( rc < 0 )
break ;
}
#ifdef S4FOX
if ( rc == 0 )
if ( hasNulls > 0 ) /* need to add the special field */
{
memset( (void *)&createFieldImage, 0, sizeof(createFieldImage) ) ;
u4ncpy( createFieldImage.name, "_NullFlags", sizeof(createFieldImage.name));
c4trimN( createFieldImage.name, sizeof(createFieldImage.name) ) ;
createFieldImage.offset = (short)calcRecordLen ;
createFieldImage.type = r4system ;
createFieldImage.nullBinary = 0x05 ;
createFieldImage.len = (hasNulls+7)/8 ; /* 1 byte for every 8 nulls */
createFieldImage.dec = 0 ;
rc = file4seqWrite( &seqWrite, &createFieldImage, sizeof(createFieldImage) ) ;
}
#endif
if ( rc == 0 )
{
#ifdef S4FOX
if ( c4->compatibility == 30 ) /* 3.0 file */
{
rc = file4seqWriteRepeat( &seqWrite, 1, '\015' ) ;
if ( rc == 0 )
rc = file4seqWriteRepeat( &seqWrite, 263, '\0' ) ;
}
else
rc = file4seqWrite( &seqWrite, "\015\032", 2 ) ;
#else
rc = file4seqWrite( &seqWrite, "\015\032", 2 ) ;
#endif
}
file4seqWriteFlush( &seqWrite ) ;
if ( rc == 0 && tempFreeSet == 1 )
{
file.doAllocFree = 0 ;
file.isTemp = 0 ;
}
file4close( &file ) ;
if ( rc < 0 )
return error4stack( c4, (short)rc, E91102 ) ;
#ifndef S4OFF_MEMO
hasMemo = 0 ;
#ifdef S4FOX
if ( c4->compatibility == 30 )
{
if ( createHeader.hasMdxMemo & 0x02 )
hasMemo = 1 ;
}
else
if ( createHeader.version & 0x80 )
hasMemo = 1 ;
#else
if ( createHeader.version & 0x80 )
hasMemo = 1 ;
#endif
if ( hasMemo )
{
oldCreateTemp = c4->createTemp ;
c4->createTemp = 0 ;
if ( name == 0 )
rc = memo4fileCreate( &m4file, c4, 0, tempName ) ;
else
{
u4nameExt( buf, sizeof(buf), CREATE4MEMO_EXT, 1 ) ;
rc = memo4fileCreate( &m4file, c4, 0, buf ) ;
}
c4->createTemp = oldCreateTemp ;
if ( rc == 0 )
file4close( &m4file.file ) ;
}
#endif
if ( rc < 0 )
{
if ( tempFreeSet == 1 && tempName != 0 )
u4free( tempName ) ;
return error4stack( c4, (short)rc, E91102 ) ;
}
oldAutoOpen = c4->autoOpen ;
#ifndef S4OFF_MULTI
oldAccessMode = c4->accessMode ;
c4->accessMode = OPEN4DENY_RW ;
#endif
if ( tagInfo == 0 )
c4->autoOpen = 0 ;
else
{
if ( tagInfo[0].name == 0 )
c4->autoOpen = 0 ;
}
#ifdef S4CLIPPER
c4->autoOpen = 0 ;
#endif
#ifndef S4OFF_TRAN
if ( name == 0 || c4->createTemp == 1 )
{
oldStatus = code4tranStatus( c4 ) ;
code4tranStatusSet( c4, r4off ) ;
}
#endif
if ( name == 0 )
data = d4open( c4, tempName ) ;
else
data = d4open( c4, name ) ;
if ( tempFreeSet == 1 && tempName != 0 )
u4free( tempName ) ;
if ( name == 0 || c4->createTemp == 1 )
{
#ifndef S4OFF_TRAN
code4tranStatusSet( c4, oldStatus ) ;
#endif
if ( data != 0 )
{
if ( tempFreeSet == 1 )
if ( data->dataFile->file.name != 0 )
data->dataFile->file.doAllocFree = 1 ;
data->dataFile->file.isTemp = 1 ;
#ifndef S4OFF_TRAN
data->logVal = LOG4TRANS ;
#endif
#ifndef S4OFF_MEMO
if ( createHeader.version & 0x80 )
if ( c4->createTemp == 1 )
{
#ifdef E4ANALYZE
if ( data->dataFile->memoFile.file.hand <= 0 )
error4( 0, e4struct, E91102 ) ;
#endif
data->dataFile->memoFile.file.isTemp = 1 ;
}
#endif
}
}
c4->autoOpen = oldAutoOpen ;
if ( data == 0 )
error4( c4, e4open, E91102 ) ;
else
{
#ifdef S4SERVER
data->accessMode = OPEN4DENY_RW ;
#endif
#ifdef S4OFF_INDEX
#ifdef E4MISC
if ( tagInfo )
error4( c4, e4notIndex, E91102 ) ;
#endif
#else
if ( tagInfo )
#ifdef S4CLIPPER
if ( name == 0 )
{
if ( i4create( data, 0, tagInfo ) == 0 )
if ( c4->errorCode >= 0 )
error4( c4, e4create, E91102 ) ;
}
else
{
/* 03/06/96 AS --> fix #25 changes.60 */
u4namePiece( nameBuf, sizeof( nameBuf ), name, 1, 0 ) ;
if ( i4create( data, nameBuf, tagInfo ) == 0 )
if ( c4->errorCode >= 0 )
error4( c4, e4create, E91102 ) ;
}
#else
if ( i4create( data, 0, tagInfo ) == 0 )
if ( c4->errorCode >= 0 )
error4( c4, e4create, E91102 ) ;
#endif
#endif
}
#ifndef S4OFF_MULTI
c4->accessMode = oldAccessMode ;
#endif
rc = error4code( c4 ) ;
if ( rc < 0 || data == 0 )
d4createClose( c4, data ) ;
else
{
if ( c4->createTemp != 1 )
{
dfile = data->dataFile ;
#ifdef S4SERVER
oldKeepOpen = c4->server->keepOpen ;
c4->server->keepOpen = 1 ;
#endif
d4createClose( c4, data ) ;
#ifdef S4SERVER
c4->server->keepOpen = oldKeepOpen ;
/* the server case requires an explict low close as well */
dfile4closeLow( dfile ) ;
#endif
}
else
*temp = data ;
}
return error4code( c4 ) ;
}
#endif /* not S4CLIENT */
#endif /* S4OFF_WRITE */
#ifdef S4VB_DOS
DATA4 *d4create_v ( CODE4 *c4 , char *name, FIELD4INFO *f4, TAG4INFO *t4 )
{
return d4create( c4, c4str(name), f4, t4 ) ;
}
DATA4 *d4createData ( CODE4 *c4, char *name, FIELD4INFO *f4 )
{
return d4create( c4, c4str(name), f4, 0 ) ;
}
#endif