dattput.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /** \file
  2. Functions to write attributes.
  3. These functions read and write attributes.
  4. Copyright 2010 University Corporation for Atmospheric
  5. Research/Unidata. See \ref copyright file for more info. */
  6. #include "ncdispatch.h"
  7. /** \name Writing Attributes
  8. Functions to write attributes. */
  9. /*! \{ */
  10. /*!
  11. \ingroup attributes
  12. Write a string attribute.
  13. The function nc_put_att_string adds or changes a variable attribute or
  14. global attribute of an open netCDF dataset. The string type is only
  15. available in netCDF-4/HDF5 files, when ::NC_CLASSIC_MODEL has not been
  16. used in nc_create().
  17. \param ncid NetCDF or group ID, from a previous call to nc_open(),
  18. nc_create(), nc_def_grp(), or associated inquiry functions such as
  19. nc_inq_ncid().
  20. \param varid Variable ID of the variable to which the attribute will
  21. be assigned or ::NC_GLOBAL for a global or group attribute.
  22. \param name Attribute \ref object_name. \ref attribute_conventions may
  23. apply.
  24. \param len Number of values provided for the attribute.
  25. \param value Pointer to one or more values.
  26. \returns ::NC_NOERR No error.
  27. \returns ::NC_EINVAL Trying to set global _FillValue.
  28. \returns ::NC_ENOTVAR Couldn't find varid.
  29. \returns ::NC_EBADTYPE Fill value and var must be same type.
  30. \returns ::NC_ENOMEM Out of memory
  31. \returns ::NC_ELATEFILL Fill values must be written while the file
  32. is still in initial define mode.
  33. */
  34. int
  35. nc_put_att_string(int ncid, int varid, const char *name,
  36. size_t len, const char** value)
  37. {
  38. NC* ncp;
  39. int stat = NC_check_id(ncid, &ncp);
  40. if(stat != NC_NOERR) return stat;
  41. return ncp->dispatch->put_att(ncid, varid, name, NC_STRING,
  42. len, (void*)value, NC_STRING);
  43. }
  44. /*!
  45. \ingroup attributes
  46. Write a text attribute.
  47. Add or change a text attribute. If this attribute is new,
  48. or if the space required to store the attribute is greater than
  49. before, the netCDF dataset must be in define mode.
  50. Although it's possible to create attributes of all types, text and
  51. double attributes are adequate for most purposes.
  52. Use the nc_put_att function to create attributes of any type,
  53. including user-defined types. We recommend using the type safe
  54. versions of this function whenever possible.
  55. \param ncid NetCDF or group ID, from a previous call to nc_open(),
  56. nc_create(), nc_def_grp(), or associated inquiry functions such as
  57. nc_inq_ncid().
  58. \param varid Variable ID of the variable to which the attribute will
  59. be assigned or ::NC_GLOBAL for a global attribute.
  60. \param name Attribute \ref object_name. \ref attribute_conventions may
  61. apply.
  62. \param len Number of values provided for the attribute.
  63. \param value Pointer to one or more values.
  64. \returns ::NC_NOERR No error.
  65. \returns ::NC_EINVAL Trying to set global _FillValue.
  66. \returns ::NC_ENOTVAR Couldn't find varid.
  67. \returns ::NC_EBADTYPE Fill value and var must be same type.
  68. \returns ::NC_ENOMEM Out of memory
  69. \returns ::NC_ELATEFILL Fill values must be written while the file
  70. is still in initial define mode.
  71. \note With netCDF-4 files, nc_put_att will notice if you are writing a
  72. _Fill_Value_ attribute, and will tell the HDF5 layer to use the
  73. specified fill value for that variable.
  74. \section Example
  75. Here is an example using nc_put_att_double() to add a variable
  76. attribute named valid_range for a netCDF variable named rh and
  77. nc_put_att_text() to add a global attribute named title to an existing
  78. netCDF dataset named foo.nc:
  79. \code
  80. #include <netcdf.h>
  81. ...
  82. int status;
  83. int ncid;
  84. int rh_id;
  85. static double rh_range[] = {0.0, 100.0};
  86. static char title[] = "example netCDF dataset";
  87. ...
  88. status = nc_open("foo.nc", NC_WRITE, &ncid);
  89. if (status != NC_NOERR) handle_error(status);
  90. ...
  91. status = nc_redef(ncid);
  92. if (status != NC_NOERR) handle_error(status);
  93. status = nc_inq_varid (ncid, "rh", &rh_id);
  94. if (status != NC_NOERR) handle_error(status);
  95. ...
  96. status = nc_put_att_double (ncid, rh_id, "valid_range",
  97. NC_DOUBLE, 2, rh_range);
  98. if (status != NC_NOERR) handle_error(status);
  99. status = nc_put_att_text (ncid, NC_GLOBAL, "title",
  100. strlen(title), title)
  101. if (status != NC_NOERR) handle_error(status);
  102. ...
  103. status = nc_enddef(ncid);
  104. if (status != NC_NOERR) handle_error(status);
  105. \endcode
  106. */
  107. int
  108. nc_put_att_text(int ncid, int varid, const char *name,
  109. size_t len, const char *value)
  110. {
  111. NC* ncp;
  112. int stat = NC_check_id(ncid, &ncp);
  113. if(stat != NC_NOERR) return stat;
  114. return ncp->dispatch->put_att(ncid, varid, name, NC_CHAR, len,
  115. (void *)value, NC_CHAR);
  116. }
  117. /*! \} */
  118. /*!
  119. \ingroup attributes
  120. Write an attribute.
  121. The function nc_put_att_ type adds or changes a variable attribute or
  122. global attribute of an open netCDF dataset. If this attribute is new,
  123. or if the space required to store the attribute is greater than
  124. before, the netCDF dataset must be in define mode.
  125. With netCDF-4 files, nc_put_att will notice if you are writing a
  126. _Fill_Value_ attribute, and will tell the HDF5 layer to use the
  127. specified fill value for that variable.
  128. Although it's possible to create attributes of all types, text and
  129. double attributes are adequate for most purposes.
  130. \param ncid NetCDF or group ID, from a previous call to nc_open(),
  131. nc_create(), nc_def_grp(), or associated inquiry functions such as
  132. nc_inq_ncid().
  133. \param varid Variable ID of the variable to which the attribute will
  134. be assigned or ::NC_GLOBAL for a global or group attribute.
  135. \param name Attribute \ref object_name. \ref attribute_conventions may
  136. apply.
  137. \param xtype \ref data_type of the attribute.
  138. \param len Number of values provided for the attribute.
  139. \param value Pointer to one or more values.
  140. \returns ::NC_NOERR No error.
  141. \returns ::NC_EINVAL Trying to set global _FillValue.
  142. \returns ::NC_ENOTVAR Couldn't find varid.
  143. \returns ::NC_EBADTYPE Fill value and var must be same type.
  144. \returns ::NC_ENOMEM Out of memory
  145. \returns ::NC_ELATEFILL Fill values must be written while the file
  146. is still in initial define mode.
  147. \section Example
  148. Here is an example using nc_put_att_double() to add a variable
  149. attribute named valid_range for a netCDF variable named rh and
  150. nc_put_att_text() to add a global attribute named title to an existing
  151. netCDF dataset named foo.nc:
  152. \code
  153. #include <netcdf.h>
  154. ...
  155. int status;
  156. int ncid;
  157. int rh_id;
  158. static double rh_range[] = {0.0, 100.0};
  159. static char title[] = "example netCDF dataset";
  160. ...
  161. status = nc_open("foo.nc", NC_WRITE, &ncid);
  162. if (status != NC_NOERR) handle_error(status);
  163. ...
  164. status = nc_redef(ncid);
  165. if (status != NC_NOERR) handle_error(status);
  166. status = nc_inq_varid (ncid, "rh", &rh_id);
  167. if (status != NC_NOERR) handle_error(status);
  168. ...
  169. status = nc_put_att_double (ncid, rh_id, "valid_range",
  170. NC_DOUBLE, 2, rh_range);
  171. if (status != NC_NOERR) handle_error(status);
  172. status = nc_put_att_text (ncid, NC_GLOBAL, "title",
  173. strlen(title), title)
  174. if (status != NC_NOERR) handle_error(status);
  175. ...
  176. status = nc_enddef(ncid);
  177. if (status != NC_NOERR) handle_error(status);
  178. \endcode
  179. */
  180. /*! \{*/
  181. int
  182. nc_put_att(int ncid, int varid, const char *name, nc_type xtype,
  183. size_t len, const void *value)
  184. {
  185. NC* ncp;
  186. int stat = NC_check_id(ncid, &ncp);
  187. if(stat != NC_NOERR) return stat;
  188. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  189. value, xtype);
  190. }
  191. int
  192. nc_put_att_schar(int ncid, int varid, const char *name,
  193. nc_type xtype, size_t len, const signed char *value)
  194. {
  195. NC *ncp;
  196. int stat = NC_check_id(ncid, &ncp);
  197. if(stat != NC_NOERR) return stat;
  198. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  199. (void *)value, NC_BYTE);
  200. }
  201. int
  202. nc_put_att_uchar(int ncid, int varid, const char *name,
  203. nc_type xtype, size_t len, const unsigned char *value)
  204. {
  205. NC* ncp;
  206. int stat = NC_check_id(ncid, &ncp);
  207. if(stat != NC_NOERR) return stat;
  208. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  209. (void *)value, NC_UBYTE);
  210. }
  211. int
  212. nc_put_att_short(int ncid, int varid, const char *name,
  213. nc_type xtype, size_t len, const short *value)
  214. {
  215. NC* ncp;
  216. int stat = NC_check_id(ncid, &ncp);
  217. if(stat != NC_NOERR) return stat;
  218. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  219. (void *)value, NC_SHORT);
  220. }
  221. int
  222. nc_put_att_int(int ncid, int varid, const char *name,
  223. nc_type xtype, size_t len, const int *value)
  224. {
  225. NC* ncp;
  226. int stat = NC_check_id(ncid, &ncp);
  227. if(stat != NC_NOERR) return stat;
  228. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  229. (void *)value, NC_INT);
  230. }
  231. int
  232. nc_put_att_long(int ncid, int varid, const char *name,
  233. nc_type xtype, size_t len, const long *value)
  234. {
  235. NC* ncp;
  236. int stat = NC_check_id(ncid, &ncp);
  237. if(stat != NC_NOERR) return stat;
  238. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  239. (void *)value, longtype);
  240. }
  241. int
  242. nc_put_att_float(int ncid, int varid, const char *name,
  243. nc_type xtype, size_t len, const float *value)
  244. {
  245. NC* ncp;
  246. int stat = NC_check_id(ncid, &ncp);
  247. if(stat != NC_NOERR) return stat;
  248. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  249. (void *)value, NC_FLOAT);
  250. }
  251. int
  252. nc_put_att_double(int ncid, int varid, const char *name,
  253. nc_type xtype, size_t len, const double *value)
  254. {
  255. NC* ncp;
  256. int stat = NC_check_id(ncid, &ncp);
  257. if(stat != NC_NOERR) return stat;
  258. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  259. (void *)value, NC_DOUBLE);
  260. }
  261. int
  262. nc_put_att_ubyte(int ncid, int varid, const char *name,
  263. nc_type xtype, size_t len, const unsigned char *value)
  264. {
  265. NC* ncp;
  266. int stat = NC_check_id(ncid, &ncp);
  267. if(stat != NC_NOERR) return stat;
  268. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  269. (void *)value, NC_UBYTE);
  270. }
  271. int
  272. nc_put_att_ushort(int ncid, int varid, const char *name,
  273. nc_type xtype, size_t len, const unsigned short *value)
  274. {
  275. NC* ncp;
  276. int stat = NC_check_id(ncid, &ncp);
  277. if(stat != NC_NOERR) return stat;
  278. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  279. (void *)value, NC_USHORT);
  280. }
  281. int
  282. nc_put_att_uint(int ncid, int varid, const char *name,
  283. nc_type xtype, size_t len, const unsigned int *value)
  284. {
  285. NC* ncp;
  286. int stat = NC_check_id(ncid, &ncp);
  287. if(stat != NC_NOERR) return stat;
  288. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  289. (void *)value, NC_UINT);
  290. }
  291. int
  292. nc_put_att_longlong(int ncid, int varid, const char *name,
  293. nc_type xtype, size_t len,
  294. const long long *value)
  295. {
  296. NC* ncp;
  297. int stat = NC_check_id(ncid, &ncp);
  298. if(stat != NC_NOERR) return stat;
  299. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  300. (void *)value, NC_INT64);
  301. }
  302. int
  303. nc_put_att_ulonglong(int ncid, int varid, const char *name,
  304. nc_type xtype, size_t len,
  305. const unsigned long long *value)
  306. {
  307. NC* ncp;
  308. int stat = NC_check_id(ncid, &ncp);
  309. if(stat != NC_NOERR) return stat;
  310. return ncp->dispatch->put_att(ncid, varid, name, xtype, len,
  311. (void *)value, NC_UINT64);
  312. }