예제 #1
0
파일: attr.c 프로젝트: UMhaus/VTK
/* Common dispatcher for put cases */
static int
dispatchput(void **xpp, size_t nelems, const void* tp,
            nc_type atype, nc_type memtype)
{
    switch (memtype) {
    case NC_CHAR:
        return ncx_pad_putn_text(xpp,nelems, (char *)tp);
    case NC_BYTE:
        return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype);
    case NC_SHORT:
        return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype);
    case NC_INT:
          return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype);
    case NC_FLOAT:
        return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype);
    case NC_DOUBLE:
        return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype);
    case NC_UBYTE: /*Synthetic*/
        return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype);
    case NC_INT64:
          return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype);
    case NC_NAT:
        return NC_EBADTYPE;
    default:
        break;
    }
    return NC_EBADTYPE;
}
int
nc_put_att_float(int ncid, int varid, const char *name,
  nc_type type, size_t nelems, const float *value)
{
  int status;
  NC *ncp;
  NC_attrarray *ncap;
  NC_attr **attrpp;
  NC_attr *old = NULL;
  NC_attr *attrp;

  status = NC_check_id(ncid, &ncp);
  if(status != NC_NOERR)
    return status;

  if(NC_readonly(ncp))
    return NC_EPERM;

  ncap = NC_attrarray0(ncp, varid);
  if(ncap == NULL)
    return NC_ENOTVAR;

  status = nc_cktype(type);
  if(status != NC_NOERR)
    return status;

  if(type == NC_CHAR)
    return NC_ECHAR;

    /* cast needed for braindead systems with signed size_t */
  if((unsigned long) nelems > X_INT_MAX) /* backward compat */
    return NC_EINVAL; /* Invalid nelems */

  if(nelems != 0 && value == NULL)
    return NC_EINVAL; /* Null arg */

  attrpp = NC_findattr(ncap, name);
  if(attrpp != NULL) /* name in use */
  {
    if(!NC_indef(ncp) )
    {
      const size_t xsz = ncx_len_NC_attrV(type, nelems);
      attrp = *attrpp; /* convenience */
  
      if(xsz > attrp->xsz)
        return NC_ENOTINDEFINE;
      /* else, we can reuse existing without redef */
      
      attrp->xsz = xsz;
      attrp->type = type;
      attrp->nelems = nelems;

      if(nelems != 0)
      {
        void *xp = attrp->xvalue;
        status = ncx_pad_putn_Ifloat(&xp, nelems,
          value, type);
      }
      
      set_NC_hdirty(ncp);

      if(NC_doHsync(ncp))
      {
        const int lstatus = NC_sync(ncp);
        /*
         * N.B.: potentially overrides NC_ERANGE
         * set by ncx_pad_putn_Ifloat
         */
        if(lstatus != ENOERR)
          return lstatus;
      }

      return status;
    }
    /* else, redefine using existing array slot */
    old = *attrpp;
  } 
  else
  {
    if(!NC_indef(ncp))
      return NC_ENOTINDEFINE;

    if(ncap->nelems >= NC_MAX_ATTRS)
      return NC_EMAXATTS;
  }

  status = NC_check_name(name);
  if(status != NC_NOERR)
    return status;

  attrp = new_NC_attr(name, type, nelems);
  if(attrp == NULL)
    return NC_ENOMEM;

  if(nelems != 0)
  {
    void *xp = attrp->xvalue;
    status = ncx_pad_putn_Ifloat(&xp, nelems,
      value, type);
  }

  if(attrpp != NULL)
  {
    assert(old != NULL);
    *attrpp = attrp;
    free_NC_attr(old);
  }
  else
  {
    const int lstatus = incr_NC_attrarray(ncap, attrp);
    /*
     * N.B.: potentially overrides NC_ERANGE
     * set by ncx_pad_putn_Ifloat
     */
    if(lstatus != NC_NOERR)
    {
      free_NC_attr(attrp);
      return lstatus;
    }
  }

  return status;
}