123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- /*
- *
- * provides DateTime functions for timestamp management:
- *
- * Authors: Michael Shapiro & Bill Brown, CERL
- * grid3 functions by Michael Pelizzari, LMCO
- *
- * G_init_timestamp()
- * G_set_timestamp()
- * G_set_timestamp_range()
- * G_format_timestamp()
- * G_scan_timestamp()
- * G_get_timestamps()
- * G_read_raster_timestamp()
- * G_remove_raster_timestamp()
- * G_read_vector_timestamp()
- * G_remove_vector_timestamp()
- * G_read_grid3_timestamp()
- * G_remove_grid3_timestamp()
- * G_write_raster_timestamp()
- * G_write_vector_timestamp()
- * G_write_grid3_timestamp()
- *
- * COPYRIGHT: (C) 2000 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *
- * The timestamp values must use the format as described in the GRASS
- * datetime library. The source tree for this library should have a
- * description of the format. For convience, the formats as of Feb, 1996
- * are reproduced here:
- *
- * There are two types of datetime values: absolute and relative. Absolute
- * values specify exact dates and/or times. Relative values specify a span
- * of time. Some examples will help clarify:
- *
- * Absolute
- *
- * The general format for absolute values is:
- *
- * day month year [bc] hour:minute:seconds timezone
- *
- * day is 1-31
- * month is jan,feb,...,dec
- * year is 4 digit year
- * [bc] if present, indicates dates is BC
- * hour is 0-23 (24 hour clock)
- * mintue is 0-59
- * second is 0-59.9999 (fractions of second allowed)
- * timezone is +hhmm or -hhmm (eg, -0600)
- *
- * parts can be missing
- *
- * 1994 [bc]
- * Jan 1994 [bc]
- * 15 jan 1000 [bc]
- * 15 jan 1994 [bc] 10 [+0000]
- * 15 jan 1994 [bc] 10:00 [+0100]
- * 15 jan 1994 [bc] 10:00:23.34 [-0500]
- *
- * Relative
- *
- * There are two types of relative datetime values, year- month and day-second.
- *
- * The formats are:
- *
- * [-] # years # months
- * [-] # days # hours # minutes # seconds
- *
- * The words years, months, days, hours, minutes, seconds are literal words,
- * and the # are the numeric values.
- *
- * Examples:
- *
- * 2 years
- * 5 months
- * 2 years 5 months
- * 100 days
- * 15 hours 25 minutes 35.34 seconds
- * 100 days 25 minutes
- * 1000 hours 35.34 seconds
- *
- * The following are illegal because it mixes year-month and day-second
- * (because the number of days in a month or in a year vary):
- *
- * 3 months 15 days
- * 3 years 10 days
- *
- *
- */
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- void G_init_timestamp(struct TimeStamp *ts)
- {
- ts->count = 0;
- }
- void G_set_timestamp(struct TimeStamp *ts, const DateTime * dt)
- {
- datetime_copy(&ts->dt[0], dt);
- ts->count = 1;
- }
- void G_set_timestamp_range(struct TimeStamp *ts,
- const DateTime * dt1, const DateTime * dt2)
- {
- datetime_copy(&ts->dt[0], dt1);
- datetime_copy(&ts->dt[1], dt2);
- ts->count = 2;
- }
- int G__read_timestamp(FILE * fd, struct TimeStamp *ts)
- {
- char buf[1024];
- char comment[2];
- while (fgets(buf, sizeof(buf), fd)) {
- if (sscanf(buf, "%1s", comment) != 1 || *comment == '#')
- continue;
- return (G_scan_timestamp(ts, buf) > 0 ? 0 : -1);
- }
- return -2; /* nothing in the file */
- }
- /*!
- * \brief output TimeStamp structure to a file as a formatted string
- *
- * A handy fd might be "stdout".
- *
- * Returns:
- * 0 on success
- * -1 error
- *
- * \param fd file descriptor
- * \param ts TimeStamp struct
- * \return int exit value
- */
- int G__write_timestamp(FILE * fd, const struct TimeStamp *ts)
- {
- char buf[1024];
- if (G_format_timestamp(ts, buf) < 0)
- return -1;
- fprintf(fd, "%s\n", buf);
- return 0;
- }
- /*!
- * \brief Create text string from TimeStamp structure
- *
- * Fills string *buf with info from TimeStamp structure *ts in a pretty
- * way. The TimeStamp struct is defined in gis.h and populated with e.g.
- * G_read_raster_timestamp().
- *
- * Returns:
- * 1 on success
- * -1 error
- *
- * \param ts TimeStamp structure containing time info
- * \param buf string to receive formatted timestamp
- * \return int exit value
- */
- int G_format_timestamp(const struct TimeStamp *ts, char *buf)
- {
- char temp1[128], temp2[128];
- *buf = 0;
- if (ts->count > 0) {
- if (datetime_format(&ts->dt[0], temp1) != 0)
- return -1;
- }
- if (ts->count > 1) {
- if (datetime_format(&ts->dt[1], temp2) != 0)
- return -1;
- }
- if (ts->count == 1)
- strcpy(buf, temp1);
- else if (ts->count == 2)
- sprintf(buf, "%s / %s", temp1, temp2);
- return 1;
- }
- /*!
- * \brief Fill a TimeStamp structure from a datetime string
- *
- * Populate a TimeStamp structure (defined in gis.h) from a text string.
- * Checks to make sure text string is in valid GRASS datetime format.
- *
- * Returns:
- * 1 on success
- * -1 error
- *
- * \param ts TimeStamp structure to be populated
- * \param buf String containing formatted time info
- * \return int exit code
- */
- int G_scan_timestamp(struct TimeStamp *ts, const char *buf)
- {
- char temp[1024], *t;
- const char *slash;
- DateTime dt1, dt2;
- G_init_timestamp(ts);
- for (slash = buf; *slash; slash++)
- if (*slash == '/')
- break;
- if (*slash) {
- t = temp;
- while (buf != slash)
- *t++ = *buf++;
- *t = 0;
- buf++;
- if (datetime_scan(&dt1, temp) != 0 || datetime_scan(&dt2, buf) != 0)
- return -1;
- G_set_timestamp_range(ts, &dt1, &dt2);
- }
- else {
- if (datetime_scan(&dt2, buf) != 0)
- return -1;
- G_set_timestamp(ts, &dt2);
- }
- return 1;
- }
- /*!
- * \brief copy TimeStamp into [two] Datetimes structs
- *
- * Use to copy the TimeStamp information into Datetimes, as the members of
- * struct TimeStamp shouldn't be accessed directly.
- *
- * count=0 means no datetimes were copied
- * count=1 means 1 datetime was copied into dt1
- * count=2 means 2 datetimes were copied
- *
- * \param ts source TimeStamp structure
- * \param dt1 first DateTime struct to be filled
- * \param dt2 second DateTime struct to be filled
- * \param count return code
- * \return
- */
- void G_get_timestamps(const struct TimeStamp *ts,
- DateTime * dt1, DateTime * dt2, int *count)
- {
- *count = 0;
- if (ts->count > 0) {
- datetime_copy(dt1, &ts->dt[0]);
- *count = 1;
- }
- if (ts->count > 1) {
- datetime_copy(dt2, &ts->dt[1]);
- *count = 2;
- }
- }
- /* write timestamp file
- * 1 ok
- * -1 error - can't create timestamp file
- * -2 error - invalid datetime in ts
- */
- static int write_timestamp(const char *maptype, const char *dir,
- const char *name, const struct TimeStamp *ts)
- {
- FILE *fd;
- int stat;
- fd = G_fopen_new_misc(dir, "timestamp", name);
- if (fd == NULL) {
- G_warning(_("Can't create timestamp file for %s map %s in mapset %s"),
- maptype, name, G_mapset());
- return -1;
- }
- stat = G__write_timestamp(fd, ts);
- fclose(fd);
- if (stat == 0)
- return 1;
- G_warning(_("Invalid timestamp specified for %s map %s in mapset %s"),
- maptype, name, G_mapset());
- return -2;
- }
- /* read timestamp file
- * 0 no timestamp file
- * 1 ok
- * -1 error - can't open timestamp file
- * -2 error - invalid datetime values in timestamp file
- */
- static int read_timestamp(const char *maptype, const char *dir,
- const char *name, const char *mapset,
- struct TimeStamp *ts)
- {
- FILE *fd;
- int stat;
- if (!G_find_file2_misc(dir, "timestamp", name, mapset))
- return 0;
- fd = G_fopen_old_misc(dir, "timestamp", name, mapset);
- if (fd == NULL) {
- G_warning(_("Can't open timestamp file for %s map %s in mapset %s"),
- maptype, name, mapset);
- return -1;
- }
- stat = G__read_timestamp(fd, ts);
- fclose(fd);
- if (stat == 0)
- return 1;
- G_warning(_("Invalid timestamp file for %s map %s in mapset %s"),
- maptype, name, mapset);
- return -2;
- }
- #define RAST_MISC "cell_misc"
- #define VECT_MISC "dig_misc"
- #define GRID3 "grid3"
- /*!
- * \brief Read timestamp from raster map
- *
- * Returns:
- * 1 on success
- * 0 or negative on error.
- *
- * \param name map name
- * \param mapset mapset the map lives in
- * \param ts TimeStamp struct to populate
- * \return int
- */
- int G_read_raster_timestamp(const char *name, const char *mapset,
- struct TimeStamp *ts)
- {
- return read_timestamp("raster", RAST_MISC, name, mapset, ts);
- }
- /*!
- * \brief
- *
- * Only timestamp files in current mapset can be removed
- * Returns:
- * 0 if no file
- * 1 if successful
- * -1 on fail
- *
- * \param name
- * \return int
- */
- int G_remove_raster_timestamp(const char *name)
- {
- return G_remove_misc(RAST_MISC, "timestamp", name);
- }
- /*!
- * \brief Read vector timestamp
- *
- * Is this used anymore with the new GRASS 6 vector engine???
- *
- * Returns 1 on success. 0 or negative on error.
- *
- * \param name
- * \param mapset
- * \param ts
- * \return int
- */
- int G_read_vector_timestamp(const char *name, const char *mapset,
- struct TimeStamp *ts)
- {
- return read_timestamp("vector", VECT_MISC, name, mapset, ts);
- }
- /*!
- * \brief
- *
- * Is this used anymore with the new GRASS 6 vector engine???
- *
- * Only timestamp files in current mapset can be removed
- * Returns:
- * 0 if no file
- * 1 if successful
- * -1 on fail
- *
- * \param name
- * \return int
- */
- int G_remove_vector_timestamp(const char *name)
- {
- return G_remove_misc(VECT_MISC, "timestamp", name);
- }
- /*!
- * \brief read grid3 timestamp
- *
- * Returns 1 on success. 0 or
- * negative on error.
- *
- * \param name
- * \param mapset
- * \param ts
- * \return int
- */
- int G_read_grid3_timestamp(const char *name, const char *mapset,
- struct TimeStamp *ts)
- {
- return read_timestamp("grid3", GRID3, name, mapset, ts);
- }
- /*!
- * \brief remove grid3 timestamp
- *
- * Only timestamp files in current mapset can be removed
- * Returns:
- * 0 if no file
- * 1 if successful
- * -1 on fail
- *
- * \param name
- * \return int
- */
- int G_remove_grid3_timestamp(const char *name)
- {
- return G_remove_misc(GRID3, "timestamp", name);
- }
- /*!
- * \brief
- *
- * Returns:
- * 1 on success.
- * -1 error - can't create timestamp file
- * -2 error - invalid datetime in ts
- *
- * \param name
- * \param ts
- * \return int
- */
- int G_write_raster_timestamp(const char *name, const struct TimeStamp *ts)
- {
- return write_timestamp("raster", RAST_MISC, name, ts);
- }
- /*!
- * \brief
- *
- * Returns:
- * 1 on success.
- * -1 error - can't create timestamp file
- * -2 error - invalid datetime in ts
- *
- * \param name
- * \param ts
- * \return int
- */
- int G_write_vector_timestamp(const char *name, const struct TimeStamp *ts)
- {
- return write_timestamp("vector", VECT_MISC, name, ts);
- }
- /*!
- * \brief write grid3 timestamp
- *
- * Returns:
- * 1 on success.
- * -1 error - can't create timestamp file
- * -2 error - invalid datetime in ts
- *
- * \param name
- * \param ts
- * \return int
- */
- int G_write_grid3_timestamp(const char *name, const struct TimeStamp *ts)
- {
- return write_timestamp("grid3", GRID3, name, ts);
- }
|