Exemplo n.º 1
0
long dbPutSpecial(DBADDR *paddr,int pass)
{
    long int	(*pspecial)()=NULL;
    struct rset	*prset;
    dbCommon 	*precord = paddr->precord;
    long	status=0;
    long	special=paddr->special;

    prset = dbGetRset(paddr);
    if(special<100) { /*global processing*/
	if((special==SPC_NOMOD) && (pass==0)) {
	    status = S_db_noMod;
	    recGblDbaddrError(status,paddr,"dbPut");
	    return(status);
	}else if(special==SPC_SCAN){
	    if(pass==0)
		scanDelete(precord);
	    else
		scanAdd(precord);
	}else if((special==SPC_AS) && (pass==1)) {
            if(spcAsCallback) (*spcAsCallback)(precord);
	}
    }else {
	if( prset && (pspecial = (prset->special))) {
	    status=(*pspecial)(paddr,pass);
	    if(status) return(status);
	} else if(pass==0){
	    recGblRecSupError(S_db_noSupport,paddr,"dbPut", "special");
	    return(S_db_noSupport);
	}
    }
    return(0);
}
Exemplo n.º 2
0
/* Convert Float to String */
static long cvt_f_st(
    epicsFloat32 *from,
    char *to,
    const dbAddr *paddr)
{
    struct rset *prset = 0;
    long status = 0;
    long precision = 6;

    if(paddr) prset = dbGetRset(paddr);

    if (prset && prset->get_precision)
        status = (*prset->get_precision)(paddr, &precision);
    cvtFloatToString(*from, to, (unsigned short)precision);
    return(status);
}
Exemplo n.º 3
0
/* Convert Double to String */
static long cvt_d_st(
     epicsFloat64 *from,
     char *to,
     const dbAddr *paddr)
 {
   struct rset *prset = 0;
   long status = 0;
   long precision = 6;

   if(paddr) prset = dbGetRset(paddr);
 
   if (prset && prset->get_precision)
     status = (*prset->get_precision)(paddr, &precision);
   cvtDoubleToString(*from, to, precision);
   return(status);
 }
Exemplo n.º 4
0
/* Get Enumerated to String */
static long cvt_e_st_get(
    epicsEnum16 *from,
    char *to,
    const dbAddr *paddr)
{
    struct rset *prset = 0;
    long status;

    if(paddr) prset = dbGetRset(paddr);

    if (prset && prset->get_enum_str)
        return (*prset->get_enum_str)(paddr, to);

    status = S_db_noRSET;
    recGblRecSupError(status, paddr, "dbGetField", "get_enum_str");

    return(S_db_badDbrtype);
}
Exemplo n.º 5
0
/* Convert String to Enumerated */
static long cvt_st_e(
    char *from,
    epicsEnum16 *to,
    const dbAddr *paddr)
{
    struct rset 		*prset = 0;
    long 		status;
    epicsEnum16	*pfield= (epicsEnum16*)(paddr->pfield);
    unsigned int		nchoices,ind;
    int			nargs,nchars;
    struct dbr_enumStrs	enumStrs;

    if(paddr && (prset=dbGetRset(paddr))
            && (prset->put_enum_str)) {
        status = (*prset->put_enum_str)(paddr,from);
        if(!status) return(0);
        if(prset->get_enum_strs) {
            status = (*prset->get_enum_strs)(paddr,&enumStrs);
            if(!status) {
                nchoices = enumStrs.no_str;
                nargs = sscanf(from,"%u%n",&ind,&nchars);
                if(nargs==1 && nchars==strlen(from) && ind<nchoices) {
                    *pfield = ind;
                    return(0);
                }
                status = S_db_badChoice;
            }
        } else {
            status=S_db_noRSET;
        }
    } else {
        status=S_db_noRSET;
    }
    if(status == S_db_noRSET) {
        recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
    } else {
        recGblRecordError(status,(void *)paddr->precord,from);
    }
    return(status);
}
Exemplo n.º 6
0
static void hookPass1(initHookState state)
{
    DBENTRY entry;
    DBADDR  addr;
    if(state!=initHookAfterInitDatabase)
        return;
    testDiag("initHookAfterInitDatabase");

    dbInitEntry(pdbbase, &entry);

    if(dbFindRecord(&entry, "rec0.VAL")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val);
        testOk1(dbPutString(&entry, "4")==0);
        testOk(prec->val==4, "VAL %d==4", (int)prec->val);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* Can't restore links in pass 1 */

    if(dbNameToAddr("rec1.VAL", &addr)) {
        testFail("missing rec1");
        testSkip(3, "missing record");
    } else {
        struct rset *prset = dbGetRset(&addr);
        dbfType ftype = addr.field_type;
        long count=-1, offset=-1, maxcount = addr.no_elements;
        testOk1(prset && prset->get_array_info && prset->put_array_info);
        testOk1((*prset->get_array_info)(&addr, &count, &offset)==0);
        /* count is ignored */
        testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0);
        testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0);
    }

    dbFinishEntry(&entry);
}
Exemplo n.º 7
0
dbChannel * dbChannelCreate(const char *name)
{
    const char *pname = name;
    DBENTRY dbEntry;
    dbChannel *chan = NULL;
    char *cname;
    dbAddr *paddr;
    dbFldDes *pflddes;
    long status;
    short dbfType;

    if (!name || !*name || !pdbbase)
        return NULL;

    status = pvNameLookup(&dbEntry, &pname);
    if (status)
        goto finish;

    chan = freeListCalloc(dbChannelFreeList);
    if (!chan)
        goto finish;
    cname = malloc(strlen(name) + 1);
    if (!cname)
        goto finish;

    strcpy(cname, name);
    chan->name = cname;
    ellInit(&chan->filters);
    ellInit(&chan->pre_chain);
    ellInit(&chan->post_chain);

    paddr = &chan->addr;
    pflddes = dbEntry.pflddes;
    dbfType = pflddes->field_type;

    paddr->precord = dbEntry.precnode->precord;
    paddr->pfield = dbEntry.pfield;
    paddr->pfldDes = pflddes;
    paddr->no_elements = 1;
    paddr->field_type = dbfType;
    paddr->field_size = pflddes->size;
    paddr->special = pflddes->special;
    paddr->dbr_field_type = mapDBFToDBR[dbfType];

    if (paddr->special == SPC_DBADDR) {
        struct rset *prset = dbGetRset(paddr);

        /* Let record type modify paddr */
        if (prset && prset->cvt_dbaddr) {
            status = prset->cvt_dbaddr(paddr);
            if (status)
                goto finish;
            dbfType = paddr->field_type;
        }
    }

    /* Handle field modifiers */
    if (*pname) {
        if (*pname == '$') {
            /* Some field types can be accessed as char arrays */
            if (dbfType == DBF_STRING) {
                paddr->no_elements = paddr->field_size;
                paddr->field_type = DBF_CHAR;
                paddr->field_size = 1;
                paddr->dbr_field_type = DBR_CHAR;
            } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
                /* Clients see a char array, but keep original dbfType */
                paddr->no_elements = PVNAME_STRINGSZ + 12;
                paddr->field_size = 1;
                paddr->dbr_field_type = DBR_CHAR;
            } else {
                status = S_dbLib_fieldNotFound;
                goto finish;
            }
            pname++;
        }

        if (*pname == '[') {
            status = parseArrayRange(chan, pname, &pname);
            if (status) goto finish;
        }

        /* JSON may follow */
        if (*pname == '{') {
            status = chf_parse(chan, &pname);
            if (status) goto finish;
        }

        /* Make sure there's nothing else */
        if (*pname) {
            status = S_dbLib_fieldNotFound;
            goto finish;
        }
    }

finish:
    if (status && chan) {
        dbChannelDelete(chan);
        chan = NULL;
    }
    dbFinishEntry(&dbEntry);
    return chan;
}
Exemplo n.º 8
0
long dbGet(DBADDR *paddr, short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    char *pbuf = pbuffer;
    void *pfieldsave = paddr->pfield;
    db_field_log *pfl = (db_field_log *)pflin;
    short field_type;
    long capacity, no_elements, offset;
    struct rset *prset;
    long status = 0;

    if (options && *options)
        getOptions(paddr, &pbuf, options, pflin);
    if (nRequest && *nRequest == 0)
        return 0;

    if (!pfl || pfl->type == dbfl_type_rec) {
        field_type = paddr->field_type;
        no_elements = capacity = paddr->no_elements;

        /* Update field info from record
         * may modify paddr->pfield
         */
        if (paddr->pfldDes->special == SPC_DBADDR &&
            (prset = dbGetRset(paddr)) &&
            prset->get_array_info) {
            status = prset->get_array_info(paddr, &no_elements, &offset);
        } else
            offset = 0;
    } else {
        field_type = pfl->field_type;
        no_elements = capacity = pfl->no_elements;
        offset = 0;
    }

    if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) {
        status = getLinkValue(paddr, dbrType, pbuf, nRequest);
        goto done;
    }

    if (paddr->special == SPC_ATTRIBUTE) {
        status = getAttrValue(paddr, dbrType, pbuf, nRequest);
        goto done;
    }

    /* Check for valid request */
    if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbGet: Request type is %d\n", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        status = S_db_badDbrtype;
        goto done;
    }

    if (offset == 0 && (!nRequest || no_elements == 1)) {
        if (nRequest)
            *nRequest = 1;
        if (!pfl || pfl->type == dbfl_type_rec) {
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (paddr->pfield, pbuf, paddr);
        } else {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.field_type = pfl->field_type;
            localAddr.field_size = pfl->field_size;
            localAddr.no_elements = pfl->no_elements;
            if (pfl->type == dbfl_type_val)
                localAddr.pfield = (char *) &pfl->u.v.field;
            else
                localAddr.pfield = (char *)  pfl->u.r.field;
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (localAddr.pfield, pbuf, &localAddr);
        }
    } else {
        long n;
        GETCONVERTFUNC convert;

        if (nRequest) {
            if (no_elements < *nRequest)
                *nRequest = no_elements;
            n = *nRequest;
        } else {
            n = 1;
        }
        convert = dbGetConvertRoutine[field_type][dbrType];
        if (!convert) {
            char message[80];

            sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
                    field_type, dbrType);
            recGblDbaddrError(S_db_badDbrtype, paddr, message);
            status = S_db_badDbrtype;
            goto done;
        }
        /* convert data into the caller's buffer */
        if (n <= 0) {
            ;/*do nothing*/
        } else if (!pfl || pfl->type == dbfl_type_rec) {
            status = convert(paddr, pbuf, n, capacity, offset);
        } else {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.field_type = pfl->field_type;
            localAddr.field_size = pfl->field_size;
            localAddr.no_elements = pfl->no_elements;
            if (pfl->type == dbfl_type_val)
                localAddr.pfield = (char *) &pfl->u.v.field;
            else
                localAddr.pfield = (char *)  pfl->u.r.field;
            status = convert(&localAddr, pbuf, n, capacity, offset);
        }
    }
done:
    paddr->pfield = pfieldsave;
    return status;
}
Exemplo n.º 9
0
/*
 *  Fill out a database structure (*paddr) for
 *    a record given by the name "pname."
 *
 *    Returns error codes from StaticLib module, not
 *        from dbAccess.
 */
long dbNameToAddr(const char *pname, DBADDR *paddr)
{
    DBENTRY dbEntry;
    dbFldDes *pflddes;
    long status = 0;
    short dbfType;

    if (!pname || !*pname || !pdbbase)
        return S_db_notFound;

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecordPart(&dbEntry, &pname);
    if (status) goto finish;

    if (*pname == '.') ++pname;
    status = dbFindFieldPart(&dbEntry, &pname);
    if (status == S_dbLib_fieldNotFound)
        status = dbGetAttributePart(&dbEntry, &pname);
    if (status) goto finish;

    pflddes = dbEntry.pflddes;
    dbfType = pflddes->field_type;

    paddr->precord = dbEntry.precnode->precord;
    paddr->pfield = dbEntry.pfield;
    paddr->pfldDes = pflddes;
    paddr->no_elements = 1;
    paddr->field_type  = dbfType;
    paddr->field_size  = pflddes->size;
    paddr->special     = pflddes->special;
    paddr->dbr_field_type = mapDBFToDBR[dbfType];

    if (paddr->special == SPC_DBADDR) {
        struct rset *prset = dbGetRset(paddr);

        /* Let record type modify paddr */
        if (prset && prset->cvt_dbaddr) {
            status = prset->cvt_dbaddr(paddr);
            if (status)
                goto finish;
            dbfType = paddr->field_type;
        }
    }

    /* Handle field modifiers */
    if (*pname++ == '$') {
        /* Some field types can be accessed as char arrays */
        if (dbfType == DBF_STRING) {
            paddr->no_elements = paddr->field_size;
            paddr->field_type = DBF_CHAR;
            paddr->field_size = 1;
            paddr->dbr_field_type = DBR_CHAR;
        } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
            /* Clients see a char array, but keep original dbfType */
            paddr->no_elements = PVNAME_STRINGSZ + 12;
            paddr->field_size = 1;
            paddr->dbr_field_type = DBR_CHAR;
        } else {
            status = S_dbLib_fieldNotFound;
            goto finish;
        }
    }

finish:
    dbFinishEntry(&dbEntry);
    return status;
}
Exemplo n.º 10
0
/*
 * This code relies on *poriginal being aligned and all increments done by the
 * blocks only changing the buffer pointer in a way that does not break alignment.
 */
static void getOptions(DBADDR *paddr, char **poriginal, long *options,
        void *pflin)
{
	db_field_log	*pfl= (db_field_log *)pflin;
	struct rset	*prset;
        short		field_type;
	dbCommon	*pcommon;
	char		*pbuffer = *poriginal;

        if (!pfl || pfl->type == dbfl_type_rec)
            field_type = paddr->field_type;
        else
            field_type = pfl->field_type;
	prset=dbGetRset(paddr);
	/* Process options */
	pcommon = paddr->precord;
	if( (*options) & DBR_STATUS ) {
	    unsigned short *pushort = (unsigned short *)pbuffer;

            if (!pfl || pfl->type == dbfl_type_rec) {
                *pushort++ = pcommon->stat;
                *pushort++ = pcommon->sevr;
            } else {
                *pushort++ = pfl->stat;
                *pushort++ = pfl->sevr;
            }
	    *pushort++ = pcommon->acks;
	    *pushort++ = pcommon->ackt;
	    pbuffer = (char *)pushort;
	}
	if( (*options) & DBR_UNITS ) {
	    memset(pbuffer,'\0',dbr_units_size);
	    if( prset && prset->get_units ){
		(*prset->get_units)(paddr, pbuffer);
		pbuffer[DB_UNITS_SIZE-1] = '\0';
	    } else {
		*options ^= DBR_UNITS; /*Turn off DBR_UNITS*/
	    }
	    pbuffer += dbr_units_size;
	}
	if( (*options) & DBR_PRECISION ) {
	    memset(pbuffer, '\0', dbr_precision_size);
	    if((field_type==DBF_FLOAT || field_type==DBF_DOUBLE)
	    &&  prset && prset->get_precision ){
		(*prset->get_precision)(paddr,pbuffer);
	    } else {
		*options ^= DBR_PRECISION; /*Turn off DBR_PRECISION*/
	    }
	    pbuffer += dbr_precision_size;
	}
	if( (*options) & DBR_TIME ) {
	    epicsUInt32 *ptime = (epicsUInt32 *)pbuffer;

            if (!pfl || pfl->type == dbfl_type_rec) {
                *ptime++ = pcommon->time.secPastEpoch;
                *ptime++ = pcommon->time.nsec;
            } else {
                *ptime++ = pfl->time.secPastEpoch;
                *ptime++ = pfl->time.nsec;
	    }
	    pbuffer = (char *)ptime;
	}
	if( (*options) & DBR_ENUM_STRS )
	    get_enum_strs(paddr, &pbuffer, prset, options);
	if( (*options) & (DBR_GR_LONG|DBR_GR_DOUBLE ))
	    get_graphics(paddr, &pbuffer, prset, options);
	if((*options) & (DBR_CTRL_LONG | DBR_CTRL_DOUBLE ))
	    get_control(paddr, &pbuffer, prset, options);
	if((*options) & (DBR_AL_LONG | DBR_AL_DOUBLE ))
	    get_alarm(paddr, &pbuffer, prset, options);
	*poriginal = pbuffer;
}
Exemplo n.º 11
0
long dbPut(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    dbCommon *precord = paddr->precord;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long special      = paddr->special;
    void *pfieldsave  = paddr->pfield;
    struct rset *prset = dbGetRset(paddr);
    long status = 0;
    long offset;
    dbFldDes *pfldDes;
    int isValueField;

    if (special == SPC_ATTRIBUTE)
        return S_db_noMod;

    if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) {
        return putAckt(paddr, pbuffer, 1, 1, 0);
    } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) {
        return putAcks(paddr, pbuffer, 1, 1, 0);
    } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbPut: Request type is %d", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    if (special) {
        status = dbPutSpecial(paddr, 0);
        if (status) return status;
    }

    if (paddr->pfldDes->special == SPC_DBADDR &&
        prset && prset->get_array_info) {
        long dummy;

        status = prset->get_array_info(paddr, &dummy, &offset);
        /* paddr->pfield may be modified */
        if (status) goto done;
    } else
        offset = 0;

    if (no_elements <= 1) {
        status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
            paddr->pfield, paddr);
        nRequest = 1;
    } else {
        if (no_elements < nRequest)
            nRequest = no_elements;
        status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
            nRequest, no_elements, offset);
    }

    /* update array info */
    if (!status &&
        paddr->pfldDes->special == SPC_DBADDR &&
        prset && prset->put_array_info) {
        status = prset->put_array_info(paddr, nRequest);
    }

    /* Always do special processing if needed */
    if (special) {
        long status2 = dbPutSpecial(paddr, 1);
        if (status2) goto done;
    }
    if (status) goto done;

    /* Propagate monitor events for this field, */
    /* unless the field is VAL and PP is true. */
    pfldDes = paddr->pfldDes;
    isValueField = dbIsValueField(pfldDes);
    if (isValueField) precord->udf = FALSE;
    if (precord->mlis.count &&
        !(isValueField && pfldDes->process_passive))
        db_post_events(precord, pfieldsave, DBE_VALUE | DBE_LOG);
    /* If this field is a property (metadata) field,
     * then post a property change event (even if the field
     * didn't change).
     */
    if (precord->mlis.count && pfldDes->prop)
        db_post_events(precord, NULL, DBE_PROPERTY);
done:
    paddr->pfield = pfieldsave;
    return status;
}
Exemplo n.º 12
0
long epicsShareAPI dbGet(DBADDR *paddr, short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    db_field_log *pfl = (db_field_log *)pflin;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long offset;
    struct rset *prset;
    long status = 0;

    if (options && *options) {
        char *pbuf = pbuffer;

        getOptions(paddr, &pbuf, options, pflin);
        pbuffer = pbuf;
    }
    if (nRequest && *nRequest == 0) return 0;

    if (paddr->special == SPC_ATTRIBUTE) {
        char *pbuf = pbuffer;
        int maxlen;

        if (!paddr->pfield) return S_db_badField;

        switch (dbrType) {
        case DBR_STRING:
            maxlen = MAX_STRING_SIZE - 1;
            if (nRequest && *nRequest > 1) *nRequest = 1;
            break;

        case DBR_CHAR:
        case DBR_UCHAR:
            if (nRequest && *nRequest > 0) {
                maxlen = *nRequest - 1;
                break;
            }
            /* else fall through ... */
        default:
            return S_db_badDbrtype;
        }

        strncpy(pbuf, (char *)paddr->pfield, maxlen);
        pbuf[maxlen] = 0;
        return 0;
    }

    /* Check for valid request */
    if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbGet: Request type is %d\n", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    /* check for array */
    if (paddr->special == SPC_DBADDR &&
        no_elements > 1 &&
        (prset = dbGetRset(paddr)) &&
        prset->get_array_info) {
        status = prset->get_array_info(paddr, &no_elements, &offset);
    } else
        offset = 0;

    if (offset == 0 && (!nRequest || no_elements == 1)) {
        if (nRequest) *nRequest = 1;
        if (pfl != NULL) {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.pfield = (char *)&pfl->field;
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (localAddr.pfield, pbuffer, &localAddr);
        } else {
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (paddr->pfield, pbuffer, paddr);
        }
    } else {
        long n;
        long (*convert)();

        if (nRequest) {
            if (no_elements<(*nRequest)) *nRequest = no_elements;
            n = *nRequest;
        } else {
            n = 1;
        }
        convert = dbGetConvertRoutine[field_type][dbrType];
        if (!convert) {
            char message[80];

            sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
                    field_type, dbrType);
            recGblDbaddrError(S_db_badDbrtype, paddr, message);
            return S_db_badDbrtype;
        }
        /* convert database field  and place it in the buffer */
        if (n <= 0) {
            ;/*do nothing*/
        } else if (pfl) {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.pfield = (char *)&pfl->field;
            status = convert(&localAddr, pbuffer, n, no_elements, offset);
        } else {
            status = convert(paddr, pbuffer, n, no_elements, offset);
        }
    }
    return status;
}
Exemplo n.º 13
0
/*
 *  Fill out a database structure (*paddr) for
 *    a record given by the name "pname."
 *
 *    Returns error codes from StaticLib module, not
 *        from dbAccess.
 */
long epicsShareAPI dbNameToAddr(const char *pname, DBADDR *paddr)
{
    DBENTRY dbEntry;
    dbFldDes *pflddes;
    struct rset *prset;
    long status = 0;
    long no_elements = 1;
    short dbfType, dbrType, field_size;

    if (!pname || !*pname || !pdbbase)
        return S_db_notFound;

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecordPart(&dbEntry, &pname);
    if (status) goto finish;

    if (*pname == '.') ++pname;
    status = dbFindFieldPart(&dbEntry, &pname);
    if (status == S_dbLib_fieldNotFound)
        status = dbGetAttributePart(&dbEntry, &pname);
    if (status) goto finish;

    paddr->precord = dbEntry.precnode->precord;
    paddr->pfield = dbEntry.pfield;
    pflddes = dbEntry.pflddes;

    dbfType = pflddes->field_type;
    dbrType = mapDBFToDBR[dbfType];
    field_size = pflddes->size;

    if (*pname++ == '$') {
        /* Some field types can be accessed as char arrays */
        if (dbfType == DBF_STRING) {
            dbfType     = DBF_CHAR;
            dbrType     = DBR_CHAR;
            no_elements = field_size;
            field_size  = 1;
        } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
            /* Clients see a char array, but keep original dbfType */
            dbrType     = DBR_CHAR;
            no_elements = PVNAME_STRINGSZ + 12;
            field_size = 1;
        } else {
            status = S_dbLib_fieldNotFound;
            goto finish;
        }
    }

    paddr->pfldDes     = pflddes;
    paddr->field_type  = dbfType;
    paddr->dbr_field_type = dbrType;
    paddr->field_size  = field_size;
    paddr->special     = pflddes->special;
    paddr->no_elements = no_elements;

    if ((paddr->special == SPC_DBADDR) &&
        (prset = dbGetRset(paddr)) &&
        prset->cvt_dbaddr)
        /* cvt_dbaddr routine may change any of these elements of paddr:
         *     pfield, no_elements, element_offset, field_type,
         *     dbr_field_type, field_size, and/or special.
         */
        status = prset->cvt_dbaddr(paddr);

finish:
    dbFinishEntry(&dbEntry);
    return status;
}
Exemplo n.º 14
0
long epicsShareAPI dbPut(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    dbCommon *precord = paddr->precord;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long special      = paddr->special;
    long offset;
    long status = 0;
    dbFldDes *pfldDes;
    int isValueField;

    if (special == SPC_ATTRIBUTE) return S_db_noMod;

    if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) {
        return putAckt(paddr, (unsigned short *)pbuffer, 1, 1, 0);
    } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) {
        return putAcks(paddr, (unsigned short *)pbuffer, 1, 1, 0);
    } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbPut: Request type is %d", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    if (special) {
        status = dbPutSpecial(paddr, 0);
        if (status) return status;
    }

    if (no_elements <= 1) {
        status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
            paddr->pfield, paddr);
    } else {
        struct rset *prset = dbGetRset(paddr);

        if (paddr->special == SPC_DBADDR &&
            prset && prset->get_array_info) {
            long dummy;

            status = prset->get_array_info(paddr, &dummy, &offset);
        }
        else
            offset = 0;
        if (no_elements < nRequest) nRequest = no_elements;
        if (!status)
            status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
                nRequest, no_elements, offset);

        /* update array info */
        if (!status &&
            paddr->special == SPC_DBADDR &&
            prset && prset->put_array_info) {
            status = prset->put_array_info(paddr, nRequest);
        }
    }
    if (status) return status;

    /* check if special processing is required */
    if (special) {
        status = dbPutSpecial(paddr,1);
        if (status) return status;
    }

    /* Propagate monitor events for this field, */
    /* unless the field field is VAL and PP is true. */
    pfldDes = paddr->pfldDes;
    isValueField = dbIsValueField(pfldDes);
    if (isValueField) precord->udf = FALSE;
    if (precord->mlis.count &&
        !(isValueField && pfldDes->process_passive))
        db_post_events(precord, paddr->pfield, DBE_VALUE | DBE_LOG);

    return status;
}