static void
icaltimezone_expand_changes		(icaltimezone	*zone,
					 int		 end_year)
{
    icalarray *changes;
    icalcomponent *comp;

#if 0
    printf ("\nExpanding changes for: %s to year: %i\n", zone->tzid, end_year);
#endif

    changes = icalarray_new (sizeof (icaltimezonechange), 32);
    if (!changes)
	return;

    /* Scan the STANDARD and DAYLIGHT subcomponents. */
    comp = icalcomponent_get_first_component (zone->component,
					      ICAL_ANY_COMPONENT);
    while (comp) {
	icaltimezone_expand_vtimezone (comp, end_year, changes);
	comp = icalcomponent_get_next_component (zone->component,
						 ICAL_ANY_COMPONENT);
    }

    /* Sort the changes. We may have duplicates but I don't think it will
       matter. */
    icalarray_sort (changes, icaltimezone_compare_change_fn);

    if (zone->changes)
	icalarray_free (zone->changes);

    zone->changes = changes;
    zone->end_year = end_year;
}
Example #2
0
icalarray *icalarray_copy	(icalarray	*originalarray)
{
    icalarray *array = icalarray_new(originalarray->element_size, originalarray->increment_size);
    int chunks = originalarray->space_allocated / originalarray->increment_size;
    int chunk;

    if (!array)
        return NULL;

    array->num_elements = originalarray->num_elements;
    array->space_allocated = originalarray->space_allocated;

    array->chunks = malloc(chunks * sizeof (void *));
    if (array->chunks) {
      for (chunk = 0; chunk < chunks; chunk++) {
          array->chunks[chunk] = icalarray_alloc_chunk(array);
          if (array->chunks[chunk])
              memcpy(array->chunks[chunk], originalarray->chunks[chunk],
                     array->increment_size * array->element_size);
      }

    } else {
	icalerror_set_errno(ICAL_ALLOCATION_ERROR);
    }

    return array;
}
/** This parses the zones.tab file containing the names and locations
   of the builtin timezones. It creates the builtin_timezones array
   which is an icalarray of icaltimezone structs. It only fills in the
   location, latitude and longtude fields; the rest are left
   blank. The VTIMEZONE component is loaded later if it is needed. The
   timezones in the zones.tab file are sorted by their name, which is
   useful for binary searches. */
static void
icaltimezone_parse_zone_tab		(void)
{
    char *filename;
    FILE *fp;
    char buf[1024];  /* Used to store each line of zones.tab as it is read. */
    char location[1024]; /* Stores the city name when parsing buf. */
    unsigned int filename_len;
    int latitude_degrees, latitude_minutes, latitude_seconds;
    int longitude_degrees, longitude_minutes, longitude_seconds;
    icaltimezone zone;

    icalerror_assert (builtin_timezones == NULL,
		      "Parsing zones.tab file multiple times");

    builtin_timezones = icalarray_new (sizeof (icaltimezone), 32);

    filename_len = strlen (get_zone_directory()) + strlen (ZONES_TAB_FILENAME)
	+ 2;

    filename = (char*) malloc (filename_len);
    if (!filename) {
	icalerror_set_errno(ICAL_NEWFAILED_ERROR);
	return;
    }

    snprintf (filename, filename_len, "%s/%s", get_zone_directory(),
	      ZONES_TAB_FILENAME);

    fp = fopen (filename, "r");
    free (filename);
    if (!fp) {
	icalerror_set_errno(ICAL_FILE_ERROR);
	return;
    }

    while (fgets (buf, sizeof(buf), fp)) {
	if (*buf == '#') continue;

	/* The format of each line is: "latitude longitude location". */
	if (sscanf (buf, "%4d%2d%2d %4d%2d%2d %s",
		    &latitude_degrees, &latitude_minutes,
		    &latitude_seconds,
		    &longitude_degrees, &longitude_minutes,
		    &longitude_seconds,
		    location) != 7) {
	    fprintf (stderr, "Invalid timezone description line: %s\n", buf);
	    continue;
	}

	icaltimezone_init (&zone);
	zone.location = strdup (location);

	if (latitude_degrees >= 0)
	    zone.latitude = (double) latitude_degrees
		+ (double) latitude_minutes / 60
		+ (double) latitude_seconds / 3600;
	else
	    zone.latitude = (double) latitude_degrees
		- (double) latitude_minutes / 60
		- (double) latitude_seconds / 3600;

	if (longitude_degrees >= 0)
	    zone.longitude = (double) longitude_degrees
		+ (double) longitude_minutes / 60
		+ (double) longitude_seconds / 3600;
	else
	    zone.longitude = (double) longitude_degrees
		- (double) longitude_minutes / 60
		- (double) longitude_seconds / 3600;

	icalarray_append (builtin_timezones, &zone);

#if 0
	printf ("Found zone: %s %f %f\n",
		location, zone.latitude, zone.longitude);
#endif
	free (zone.location);
    }

    fclose (fp);
}
icalarray*
icaltimezone_array_new			(void)
{
    return icalarray_new (sizeof (icaltimezone), 16);
}