[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pdf-devel] libgnupdf AUTHORS ChangeLog src/Makefile.am src...
From: |
Aleksander Morgado |
Subject: |
[pdf-devel] libgnupdf AUTHORS ChangeLog src/Makefile.am src... |
Date: |
Tue, 24 Jun 2008 23:22:58 +0000 |
CVSROOT: /cvsroot/pdf
Module name: libgnupdf
Changes by: Aleksander Morgado <aleksander_m> 08/06/24 23:22:58
Modified files:
. : AUTHORS ChangeLog
src : Makefile.am
src/base : pdf-fsys.h
Added files:
src/base : pdf-time-context.c pdf-time-context.h
pdf-time-string.c pdf-time-string.h pdf-time.c
pdf-time.h
Log message:
First draft of the Time Module
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/AUTHORS?cvsroot=pdf&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/ChangeLog?cvsroot=pdf&r1=1.265&r2=1.266
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/Makefile.am?cvsroot=pdf&r1=1.48&r2=1.49
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-fsys.h?cvsroot=pdf&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-time-context.c?cvsroot=pdf&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-time-context.h?cvsroot=pdf&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-time-string.c?cvsroot=pdf&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-time-string.h?cvsroot=pdf&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-time.c?cvsroot=pdf&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libgnupdf/src/base/pdf-time.h?cvsroot=pdf&rev=1.1
Patches:
Index: AUTHORS
===================================================================
RCS file: /cvsroot/pdf/libgnupdf/AUTHORS,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- AUTHORS 24 Jun 2008 12:31:42 -0000 1.32
+++ AUTHORS 24 Jun 2008 23:22:56 -0000 1.33
@@ -93,6 +93,9 @@
src/base/pdf-text-ucd-gencat.c src/base/pdf-text-ucd-combclass.h
src/base/pdf-text-ucd-combclass.c src/base/pdf-text-ucd-case.h
src/base/pdf-text-case.c build-aux/pdf-text-generate-ucd.c
+ src/base/pdf-time-context.h src/base/pdf-time-context.c
+ src/base/pdf-time-string.h src/base/pdf-time-string.c
+ src/base/pdf-time.h src/base/pdf-time.c
build-aux/pdf-text-download-and-generate-ucd.sh
build-aux/README.regenerateUCD
torture/unit/base/text/pdf-text-check-host-encoding.c
Index: ChangeLog
===================================================================
RCS file: /cvsroot/pdf/libgnupdf/ChangeLog,v
retrieving revision 1.265
retrieving revision 1.266
diff -u -b -r1.265 -r1.266
--- ChangeLog 24 Jun 2008 22:42:55 -0000 1.265
+++ ChangeLog 24 Jun 2008 23:22:56 -0000 1.266
@@ -1,3 +1,22 @@
+2008-06-25 Aleksander Morgado Juez <address@hidden>
+
+ * src/base/pdf-time-context.h: New file
+
+ * src/base/pdf-time-context.c: New file
+
+ * src/base/pdf-time-string.h: New file
+
+ * src/base/pdf-time-string.c: New file
+
+ * src/base/pdf-time.h: New file
+
+ * src/base/pdf-time.c: New file.
+
+ * src/base/pdf-fsys.h: Remove temporary typedef of pdf_time_t.
+
+ * src/Makefile.am (TIME_MODULE_SOURCES): Added compilation of the time
module.
+ (PUBLIC_HDRS): Add pdf-time.h in the public library header.
+
2008-06-25 Aleksander Morgado <address@hidden>
* src/base/pdf-types.h: Added macros for the new pdf_i64_* functions.
Also
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/pdf/libgnupdf/src/Makefile.am,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -b -r1.48 -r1.49
--- src/Makefile.am 15 Jun 2008 12:46:09 -0000 1.48
+++ src/Makefile.am 24 Jun 2008 23:22:56 -0000 1.49
@@ -64,6 +64,10 @@
base/pdf-text-ucd.h \
base/pdf-text.c base/pdf-text.h
+TIME_MODULE_SOURCES = base/pdf-time-context.c base/pdf-time-context.h \
+ base/pdf-time-string.c base/pdf-time-string.h \
+ base/pdf-time.c base/pdf-time.h
+
BASE_LAYER_SOURCES = base/pdf-base.c base/pdf-base.h \
$(ALLOC_MODULE_SOURCES) \
$(TYPES_MODULE_SOURCES) \
@@ -72,7 +76,8 @@
$(ERROR_MODULE_SOURCES) \
$(LIST_MODULE_SOURCES) \
$(TEXT_MODULE_SOURCES) \
- $(HASH_MODULE_SOURCES)
+ $(HASH_MODULE_SOURCES) \
+ $(TIME_MODULE_SOURCES)
# Library sources
@@ -102,6 +107,7 @@
base/pdf-alloc.h \
base/pdf-list.h \
base/pdf-hash.h \
+ base/pdf-time.h \
base/pdf-text.h \
base/pdf-fsys.h \
base/pdf-stm-f-a85.h \
Index: src/base/pdf-fsys.h
===================================================================
RCS file: /cvsroot/pdf/libgnupdf/src/base/pdf-fsys.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- src/base/pdf-fsys.h 22 May 2008 20:36:23 -0000 1.2
+++ src/base/pdf-fsys.h 24 Jun 2008 23:22:57 -0000 1.3
@@ -32,6 +32,7 @@
#include <pdf-list.h>
#include <pdf-hash.h>
#include <pdf-text.h>
+#include <pdf-time.h>
/* #include <pdf-time.h> */
/*
@@ -40,9 +41,6 @@
/* BEGIN PUBLIC */
-/* FIXME */
-#define pdf_time_t int
-
/* Filesystem item properties */
struct pdf_fsys_item_props_s
{
Index: src/base/pdf-time-context.c
===================================================================
RCS file: src/base/pdf-time-context.c
diff -N src/base/pdf-time-context.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/base/pdf-time-context.c 24 Jun 2008 23:22:57 -0000 1.1
@@ -0,0 +1,79 @@
+/* -*- mode: C -*- Time-stamp: ""
+ *
+ * File: pdf-time-context.c
+ * Date: Sun May 18 13:08:37 2008
+ *
+ * GNU PDF Library - Time Module Context management
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <time.h>
+
+#include <pdf-time-context.h>
+
+
+typedef struct pdf_time_context_s {
+ pdf_i32_t local_time_gmt_offset; /* Seconds west of GMT */
+ pdf_bool_t local_time_daylight_save; /* True if Daylight saving times */
+} pdf_time_context_t;
+
+
+/* This context will be initialized only once at program startup, and it will
+ * be treated as constant from then on, so there shouldn't be any problem
+ * with multiple threading and reentrancy */
+static pdf_time_context_t time_context;
+
+
+
+/* Initialize time context. Must be done only once at program startup!.
+ * Not thread-safe! */
+pdf_status_t
+pdf_time_context_init(void)
+{
+ extern pdf_time_context_t time_context;
+
+ tzset();
+
+ /* Set GMT offset */
+ time_context.local_time_gmt_offset = 60*timezone;
+ /* Set flag to indicate if Daylight saving times are applied in the system
+ * if needed */
+ time_context.local_time_daylight_save = (daylight == 0) ? PDF_FALSE :
PDF_TRUE;
+
+ PDF_DEBUG_BASE("Initializing Time module...");
+ PDF_DEBUG_BASE("GMT offset: %d min", time_context.local_time_gmt_offset);
+ PDF_DEBUG_BASE("Daylight saving? %s",time_context.local_time_daylight_save ?
\
+ "yes":"no");
+
+ return PDF_OK;
+}
+
+
+/* Get the GMT offset of the local time configuration. The offset is obtained
as
+ * seconds west of GMT */
+pdf_i32_t
+pdf_time_context_get_gmt_offset(void)
+{
+ extern pdf_time_context_t time_context;
+ return time_context.local_time_gmt_offset;
+}
+
+
+/* End of pdf-time-context.c */
Index: src/base/pdf-time-context.h
===================================================================
RCS file: src/base/pdf-time-context.h
diff -N src/base/pdf-time-context.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/base/pdf-time-context.h 24 Jun 2008 23:22:57 -0000 1.1
@@ -0,0 +1,48 @@
+/* -*- mode: C -*- Time-stamp: ""
+ *
+ * File: pdf-time-context.h
+ * Date: Mon Apr 28 23:23:04 2008
+ *
+ * GNU PDF Library - Header file for the Time module Context
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PDF_TIME_CONTEXT_H
+#define PDF_TIME_CONTEXT_H
+
+#include <stdio.h>
+#include <pdf-time.h>
+
+
+/* Initialize time context. Must be done only once at program startup!.
+ * Not thread-safe! */
+pdf_status_t
+pdf_time_context_init(void);
+
+
+/* Get the GMT offset of the local time configuration. The offset is obtained
as
+ * minutes west of GMT */
+pdf_i32_t
+pdf_time_context_get_gmt_offset(void);
+
+
+
+#endif /* PDF_TIME_CONTEXT_H */
+
+/* End of pdf-time-context.h */
Index: src/base/pdf-time-string.c
===================================================================
RCS file: src/base/pdf-time-string.c
diff -N src/base/pdf-time-string.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/base/pdf-time-string.c 24 Jun 2008 23:22:57 -0000 1.1
@@ -0,0 +1,217 @@
+/* -*- mode: C -*- Time-stamp: ""
+ *
+ * File: pdf-time-string.c
+ * Date: Sun May 18 13:08:37 2008
+ *
+ * GNU PDF Library - Time Module String utilities
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <pdf-base.h>
+#include <pdf-time-string.h>
+
+
+
+
+
+
+pdf_status_t
+pdf_time_from_string_pdf(pdf_time_t time_var,
+ const pdf_char_t *time_str)
+{
+ /* TODO */
+ return PDF_ERROR;
+}
+
+pdf_status_t
+pdf_time_from_string_asn1(pdf_time_t time_var,
+ const pdf_char_t *time_str)
+{
+ /* TODO */
+ return PDF_ERROR;
+}
+
+pdf_status_t
+pdf_time_from_string_generalized_asn1(pdf_time_t time_var,
+ const pdf_char_t *time_str)
+{
+ /* TODO */
+ return PDF_ERROR;
+}
+
+pdf_status_t
+pdf_time_from_string_iso8601(pdf_time_t time_var,
+ const pdf_char_t *time_str)
+{
+ /*
+ * Year:
+ * YYYY (eg 1997)
+ * Year and month:
+ * YYYY-MM (eg 1997-07)
+ * Complete date:
+ * YYYY-MM-DD (eg 1997-07-16)
+ * Complete date plus hours and minutes:
+ * YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
+ * Complete date plus hours, minutes and seconds:
+ * YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
+ * Complete date plus hours, minutes, seconds and a decimal fraction of a
+ * secondca
+ * YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
+ *
+ * where:
+ *
+ * YYYY = four-digit year
+ * MM = two-digit month (01=January, etc.)
+ * DD = two-digit day of month (01 through 31)
+ * hh = two digits of hour (00 through 23) (am/pm NOT allowed)
+ * mm = two digits of minute (00 through 59)
+ * ss = two digits of second (00 through 59)
+ * s = one or more digits representing a decimal fraction of a second
+ * TZD = time zone designator (Z or +hh:mm or -hh:mm)
+ *
+ */
+ struct pdf_time_cal_s calendar;
+ pdf_char_t *duplicate;
+ pdf_char_t *walker;
+ pdf_size_t time_str_length = strlen((char *)time_str);
+
+ /* Check minimum length */
+ if(time_str_length < 4)
+ {
+ PDF_DEBUG_BASE("Invalid ISO-8601 time string (too short): '%s'",
+ time_str);
+ return PDF_EBADDATA;
+ }
+
+ /* Initialize text walker */
+ duplicate = (pdf_char_t *)pdf_alloc(time_str_length+1);
+ if(duplicate == NULL)
+ {
+ PDF_DEBUG_BASE("Problem allocating memory");
+ return PDF_ENOMEM;
+ }
+ memcpy(duplicate, time_str, time_str_length);
+ walker = duplicate;
+
+ /* Reset calendar */
+ memset(&calendar, 0, sizeof(calendar));
+
+ /* Get year */
+ duplicate[4] = '\0';
+ calendar.year = atoi((char *)duplicate);
+
+ /* Get month */
+ if(time_str_length >= 7)
+ {
+ duplicate[7] = '\0';
+ calendar.month = atoi((char *)(&duplicate[5]));
+
+ /* Get day */
+ if(time_str_length >= 10)
+ {
+ duplicate[10] = '\0';
+ calendar.day = atoi((char *)(&duplicate[8]));
+
+ /* Get hour and minutes */
+ if(time_str_length >= 16+1) /* 1 is the minimum length for TZD */
+ {
+ char next_field = duplicate[16];
+
+ /* Get hour */
+ duplicate[13] = '\0';
+ calendar.hour = atoi((char *)(&duplicate[11]));
+ /* Get minutes */
+ duplicate[16] = '\0';
+ calendar.hour = atoi((char *)(&duplicate[14]));
+
+ /* Get Time Zone information */
+ if(duplicate[time_str_length-1] == 'Z')
+ {
+ /* Time is given in UTC... do nothing */
+ duplicate[time_str_length-1] = '\0';
+ }
+ else
+ {
+ /* Need to parse time zone offset */
+ pdf_i32_t hours_tz;
+ pdf_i32_t minutes_tz;
+ minutes_tz = atoi((char *)(&duplicate[time_str_length-2]));
+ duplicate[time_str_length-3] = '\0';
+ hours_tz = atoi((char *)(&duplicate[time_str_length-5]));
+
+ calendar.gmt_offset = 60*(minutes_tz + 60*hours_tz);
+ if(duplicate[time_str_length-6] == '-')
+ {
+ calendar.gmt_offset *= (-1);
+ }
+ }
+
+ /* Read seconds if available */
+ if(next_field == ':')
+ {
+ /* Ok, seconds available. Decimal part of the seconds will be
+ * ignored if it's available */
+ duplicate[19] = '\0';
+ calendar.second = atoi((char *)(&duplicate[17]));
+ }
+ }
+ }
+ }
+
+ /* Get time value from break-down calendar */
+ return pdf_time_from_cal(time_var, calendar);
+}
+
+
+/* Get Date as a string in PDF format */
+pdf_char_t *
+pdf_time_to_string_pdf(const pdf_time_t time_var)
+{
+ return NULL;
+}
+
+
+/* Get Date as a string in ASN1 format */
+pdf_char_t *
+pdf_time_to_string_asn1(const pdf_time_t time_var)
+{
+ return NULL;
+}
+
+/* Get Date as a string in Generalized ASN1 format */
+pdf_char_t *
+pdf_time_to_string_generalized_asn1(const pdf_time_t time_var)
+{
+ return NULL;
+}
+
+/* Get Date as a string in ISO8601 format */
+pdf_char_t *
+pdf_time_to_string_iso8601(const pdf_time_t time_var)
+{
+ return NULL;
+}
+
+
+
+/* End of pdf-time-string.c */
Index: src/base/pdf-time-string.h
===================================================================
RCS file: src/base/pdf-time-string.h
diff -N src/base/pdf-time-string.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/base/pdf-time-string.h 24 Jun 2008 23:22:57 -0000 1.1
@@ -0,0 +1,76 @@
+/* -*- mode: C -*- Time-stamp: ""
+ *
+ * File: pdf-time-string.h
+ * Date: Mon Jun 02 19:42:25 2008
+ *
+ * GNU PDF Library - Header file for the Time module String utilities
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PDF_TIME_STRING_H
+#define PDF_TIME_STRING_H
+
+#include <stdio.h>
+#include <pdf-time.h>
+
+
+/* Set time object contents based on Date in PDF format */
+pdf_status_t
+pdf_time_from_string_pdf(pdf_time_t time_var,
+ const pdf_char_t *time_str);
+
+
+/* Set time object contents based on Date in ASN1 format */
+pdf_status_t
+pdf_time_from_string_asn1(pdf_time_t time_var,
+ const pdf_char_t *time_str);
+
+/* Set time object contents based on Date in Generalized ASN1 format */
+pdf_status_t
+pdf_time_from_string_generalized_asn1(pdf_time_t time_var,
+ const pdf_char_t *time_str);
+
+/* Set time object contents based on Date in ISO-8601 format */
+pdf_status_t
+pdf_time_from_string_iso8601(pdf_time_t time_var,
+ const pdf_char_t *time_str);
+
+
+
+/* Get Date as a string in PDF format */
+pdf_char_t *
+pdf_time_to_string_pdf(const pdf_time_t time_var);
+
+
+/* Get Date as a string in ASN1 format */
+pdf_char_t *
+pdf_time_to_string_asn1(const pdf_time_t time_var);
+
+/* Get Date as a string in Generalized ASN1 format */
+pdf_char_t *
+pdf_time_to_string_generalized_asn1(const pdf_time_t time_var);
+
+/* Get Date as a string in ISO8601 format */
+pdf_char_t *
+pdf_time_to_string_iso8601(const pdf_time_t time_var);
+
+
+#endif /* PDF_TIME_STRING_H */
+
+/* End of pdf-time-string.h */
Index: src/base/pdf-time.c
===================================================================
RCS file: src/base/pdf-time.c
diff -N src/base/pdf-time.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/base/pdf-time.c 24 Jun 2008 23:22:57 -0000 1.1
@@ -0,0 +1,1055 @@
+/* -*- mode: C -*- Time-stamp: ""
+ *
+ * File: pdf-time.c
+ * Date: Mon Apr 28 23:23:04 2008
+ *
+ * GNU PDF Library - Time Module source
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <time.h>
+#include <pdf-base.h>
+#include <pdf-time.h>
+#include <pdf-time-context.h>
+#include <pdf-time-string.h>
+
+
+#define PDF_SECS_PER_DAY 86400
+#define PDF_SECS_PER_HOUR 3600
+#define PDF_SECS_PER_MIN 60
+#define PDF_MINS_PER_HOUR 60
+#define PDF_HOURS_PER_DAY 24
+#define PDF_MINS_PER_DAY 1440
+#define PDF_DAYS_IN_YEAR 365
+#define PDF_DAYS_IN_LEAP_YEAR 366
+
+enum pdf_time_cal_type_e {
+ PDF_TIME_CAL_LOCAL,
+ PDF_TIME_CAL_UTC
+};
+
+enum pdf_time_month_e {
+ PDF_TIME_JANUARY = 1,
+ PDF_TIME_FEBRUARY = 2,
+ PDF_TIME_MARCH = 3,
+ PDF_TIME_APRIL = 4,
+ PDF_TIME_MAY = 5,
+ PDF_TIME_JUNE = 6,
+ PDF_TIME_JULY = 7,
+ PDF_TIME_AUGUST = 8,
+ PDF_TIME_SEPTEMBER = 9,
+ PDF_TIME_OCTOBER = 10,
+ PDF_TIME_NOVEMBER = 11,
+ PDF_TIME_DECEMBER = 12,
+ PDF_TIME_NMONTHS
+};
+
+/* Returns PDF_TRUE if the Olimpic Games [were/will be] celebrated in the given
+ * year */
+static pdf_bool_t
+pdf_time_is_leap_year_p(pdf_u32_t year)
+{
+ /* A leap year is divisable by 4, but not by 100, except if divisable by
+ * 400 */
+ return (((year % 4 == 0) && \
+ ((year % 100 != 0) || \
+ (year % 400 == 0))) ? \
+ PDF_TRUE : PDF_FALSE);
+}
+
+
+/* Returns number of days in the given month */
+static pdf_u32_t
+pdf_time_get_days_in_month(const pdf_u32_t year,
+ const enum pdf_time_month_e month)
+{
+ switch(month)
+ {
+ case PDF_TIME_JANUARY:
+ case PDF_TIME_MARCH:
+ case PDF_TIME_MAY:
+ case PDF_TIME_JULY:
+ case PDF_TIME_AUGUST:
+ case PDF_TIME_OCTOBER:
+ case PDF_TIME_DECEMBER:
+ return 31;
+ case PDF_TIME_APRIL:
+ case PDF_TIME_JUNE:
+ case PDF_TIME_SEPTEMBER:
+ case PDF_TIME_NOVEMBER:
+ return 30;
+ case PDF_TIME_FEBRUARY:
+ return (pdf_time_is_leap_year_p(year) ? 29 : 28);
+ default:
+ return 0;
+ }
+}
+
+
+/* Returns number of days before the given month */
+static pdf_u32_t
+pdf_time_get_days_before_month(const pdf_u32_t year,
+ const enum pdf_time_month_e month)
+{
+ enum pdf_time_month_e walk = PDF_TIME_JANUARY;
+ pdf_u32_t sum = 0;
+ while(walk != month) {
+ sum += pdf_time_get_days_in_month(year, walk++);
+ }
+ return sum;
+}
+
+
+/* Get Break-Down calendar from pdf_time_t */
+static pdf_status_t
+pdf_time_get_cal (const pdf_time_t time_var,
+ const enum pdf_time_cal_type_e cal_type,
+ struct pdf_time_cal_s *p_cal_time)
+{
+ /* Based on glibc's __offtime function */
+ /*
http://www.google.com/codesearch?hl=en&q=__offtime+package:http://ftp.gnu.org/gnu/glibc/glibc-2.0.6.tar.gz+show:4uegyBj4-9E:ODNa8i3UKHE:ukTdqrHC4hw&sa=N&cd=1&ct=rc&cs_p=http://ftp.gnu.org/gnu/glibc/glibc-2.0.6.tar.gz&cs_f=glibc-2.0.6/time/offtime.c
*/
+
+ pdf_i64_t days;
+ pdf_i64_t aux64;
+ pdf_i64_t remaining;
+ pdf_i32_t years;
+ pdf_i32_t months;
+
+
+ days = pdf_i64_new(0,0);
+ aux64 = pdf_i64_new(0,0);
+ remaining = pdf_i64_new(0,0);
+
+
+ /* Get date as days */
+ pdf_i64_div_i32_divisor(&days, time_var->seconds, PDF_SECS_PER_DAY);
+ /* Get time in seconds */
+ pdf_i64_mod_i32_divisor(&remaining, time_var->seconds, PDF_SECS_PER_DAY);
+
+ /* Get hours */
+ pdf_i64_div_i32_divisor(&aux64, remaining, PDF_SECS_PER_HOUR);
+ p_cal_time->hour = pdf_i64_to_i32(aux64);
+
+ /* Get remaining */
+ pdf_i64_mod_i32_divisor(&remaining, remaining, PDF_SECS_PER_HOUR);
+
+ /* Get minutes */
+ pdf_i64_div_i32_divisor(&aux64, remaining, PDF_MINS_PER_HOUR);
+ p_cal_time->minute = pdf_i64_to_i32(aux64);
+ /* Get seconds */
+ pdf_i64_mod_i32_divisor(&aux64, remaining, PDF_MINS_PER_HOUR);
+ p_cal_time->second = pdf_i64_to_i32(aux64);
+
+
+ /* Seems that Unix origin time was thursday */
+ pdf_i64_add_i32(&aux64, days, 4);
+ pdf_i64_mod_i32_divisor(&aux64, aux64, 7);
+ p_cal_time->dow = pdf_i64_to_i32(aux64);
+
+
+ years = 1970;
+ /* while (days < 0 || days >= (__isleap (y) ? 366 : 365)) */
+ while((pdf_i64_cmp_i32(days, 0) < 0) || \
+ (pdf_i64_cmp_i32(days, \
+ (pdf_time_is_leap_year_p(years) ? \
+ PDF_DAYS_IN_YEAR+1 : \
+ PDF_DAYS_IN_YEAR)) >= 0))
+ {
+ pdf_i32_t yg;
+ yg = years;
+
+ pdf_i64_div_i32_divisor(&aux64, days, PDF_DAYS_IN_YEAR);
+ yg += pdf_i64_to_i32(aux64);
+ pdf_i64_mod_i32_divisor(&aux64, days, PDF_DAYS_IN_YEAR);
+ yg -= (pdf_i64_cmp_i32(aux64, 0) < 0);
+
+#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+
+ pdf_i64_subtraction_i32_sub(&days, days, ((yg - years)*PDF_DAYS_IN_YEAR
+ \
+ LEAPS_THRU_END_OF (yg - 1) - \
+ LEAPS_THRU_END_OF (years - 1)
));
+ years = yg;
+ }
+
+ /* Set year */
+ p_cal_time->year = years;// - 1900;
+
+ for (months = 11; \
+ pdf_i64_to_i32(days) <
pdf_time_get_days_before_month(p_cal_time->year,months); \
+ --months)
+ continue;
+
+ pdf_i64_subtraction_i32_sub(&days, \
+ days, \
+
pdf_time_get_days_before_month(p_cal_time->year,months));
+
+ /* Set month and day of month */
+ p_cal_time->month = months;
+ p_cal_time->day = pdf_i64_to_i32(days) + 1;
+
+ return PDF_OK;
+}
+
+
+
+/* Function to normalize a given date after having added YEARS */
+static void
+pdf_time_calendar_add_years(struct pdf_time_cal_s *p_calendar,
+ const pdf_i32_t delta_years)
+{
+ /* ADD years */
+ p_calendar->year += delta_years;
+
+ /* The only thing to normalize is in case we reach Feb.29 in a non-leap
+ * year */
+ if( (!pdf_time_is_leap_year_p(p_calendar->year)) && \
+ (p_calendar->month == PDF_TIME_FEBRUARY) && \
+ (p_calendar->day == 29) )
+ {
+ p_calendar->day = 28;
+ }
+}
+
+/* Function to normalize a given date after having added MONTHS */
+static void
+pdf_time_calendar_add_months(struct pdf_time_cal_s *p_calendar,
+ const pdf_i32_t delta_months)
+{
+ if(delta_months > 0)
+ {
+ p_calendar->month += delta_months;
+ while(p_calendar->month > 12)
+ {
+ p_calendar->month -= 12;
+ p_calendar->year++;
+ }
+ }
+ else if(delta_months < 0)
+ {
+ p_calendar->month -= delta_months;
+ while(p_calendar->month < 1)
+ {
+ p_calendar->month += 12;
+ p_calendar->year--;
+ }
+ }
+
+ /* After having added months, we could need to normalize the days */
+ if(pdf_time_get_days_in_month(p_calendar->year,
+ p_calendar->month) < p_calendar->day)
+ {
+ p_calendar->day = pdf_time_get_days_in_month(p_calendar->year,
+ p_calendar->month);
+ }
+}
+
+/* Function to normalize a given date after having added DAYS */
+static void
+pdf_time_calendar_add_days(struct pdf_time_cal_s *p_calendar,
+ const pdf_i32_t delta_days)
+{
+ pdf_i32_t delta = delta_days;
+
+ /* ADD days */
+ if(delta_days > 0)
+ {
+ pdf_i32_t days_in_month;
+
+ /* Initialize days in month */
+ days_in_month = pdf_time_get_days_in_month(p_calendar->year, \
+ (enum
pdf_time_month_e)p_calendar->month);
+ while(delta > (days_in_month - p_calendar->day))
+ {
+ /* Go to start of next month */
+ p_calendar->day = 1;
+ pdf_time_calendar_add_months(p_calendar, 1);
+
+ /* Update remaining delta and new days_in_month */
+ delta -= (days_in_month - p_calendar->day +1);
+ days_in_month = pdf_time_get_days_in_month(p_calendar->year, \
+ (enum
pdf_time_month_e)p_calendar->month);
+ }
+ /* Add final delta, which doesn't require month change */
+ p_calendar->day += delta;
+ }
+
+ /* SUBSTRACT days */
+ else if(delta_days < 0)
+ {
+ pdf_i32_t days_in_month;
+
+ /* Initialize days in month */
+ days_in_month = pdf_time_get_days_in_month(p_calendar->year, \
+ (enum
pdf_time_month_e)p_calendar->month);
+ while(delta < days_in_month)
+ {
+ /* Go to end of previous month */
+ p_calendar->day = 1;
+ pdf_time_calendar_add_months(p_calendar, -1);
+
+ /* Update remaining delta and new days_in_month */
+ delta -= (days_in_month - p_calendar->day +1);
+ days_in_month = pdf_time_get_days_in_month(p_calendar->year, \
+ (enum
pdf_time_month_e)p_calendar->month);
+ }
+ /* Add final delta, which doesn't require month change */
+ p_calendar->day += delta;
+ }
+}
+
+/* Function to normalize a given date after having added HOURS */
+static void
+pdf_time_calendar_add_hours(struct pdf_time_cal_s *p_calendar,
+ const pdf_i32_t delta_hours)
+{
+ pdf_i32_t days;
+ pdf_i32_t remaining_hours;
+
+ /* No real problem with hours, as 1 day is always 24h */
+ days = delta_hours / PDF_HOURS_PER_DAY;
+ remaining_hours = delta_hours % PDF_HOURS_PER_DAY;
+
+ /* Add remaining hours */
+ p_calendar->hour += remaining_hours;
+ /* If we went back to the previous day, correct time and add 1 day more
+ * to remove */
+ if(p_calendar->hour < 0)
+ {
+ p_calendar->hour += PDF_HOURS_PER_DAY;
+ days--;
+ }
+ /* If we went forward to the next day, correct time and add 1 day more
+ * to add */
+ else if(p_calendar->hour >= PDF_HOURS_PER_DAY)
+ {
+ p_calendar->hour -= PDF_HOURS_PER_DAY;
+ days++;
+ }
+
+ /* Add/Remove days... */
+ pdf_time_calendar_add_days(p_calendar, days);
+}
+
+/* Function to normalize a given date after having added MINUTES */
+static void
+pdf_time_calendar_add_minutes(struct pdf_time_cal_s *p_calendar,
+ const pdf_i32_t delta_minutes)
+{
+ pdf_i32_t hours;
+ pdf_i32_t remaining_minutes;
+
+ /* No real problem with minutes, as 1 hour is always 60minutes */
+ hours = delta_minutes / PDF_MINS_PER_HOUR;
+ remaining_minutes = delta_minutes % PDF_MINS_PER_HOUR;
+
+ /* Add remaining minutes */
+ p_calendar->minute += remaining_minutes;
+
+ /* If we went back to the previous hour, correct time and add 1 hour more
+ * to remove */
+ if(p_calendar->minute < 0)
+ {
+ p_calendar->minute += PDF_MINS_PER_HOUR;
+ hours--;
+ }
+ /* If we went forward to the next day, correct time and add 1 hour more
+ * to add */
+ else if(p_calendar->minute >= PDF_MINS_PER_HOUR)
+ {
+ p_calendar->minute -= PDF_MINS_PER_HOUR;
+ hours++;
+ }
+
+ /* Add/Remove hours... */
+ pdf_time_calendar_add_hours(p_calendar, hours);
+}
+
+
+/* Function to normalize a given date after having added SECONDS */
+static void
+pdf_time_calendar_add_seconds(struct pdf_time_cal_s *p_calendar,
+ const pdf_i32_t delta_seconds)
+{
+ pdf_i32_t minutes;
+ pdf_i32_t remaining_seconds;
+
+ /* No real problem with minutes, as 1 hour is always 60minutes */
+ minutes = delta_seconds / PDF_SECS_PER_MIN;
+ remaining_seconds = delta_seconds % PDF_SECS_PER_MIN;
+
+ /* Add remaining seconds */
+ p_calendar->second += remaining_seconds;
+
+ /* If we went back to the previous minute, correct time and add 1 minute more
+ * to remove */
+ if(p_calendar->second < 0)
+ {
+ p_calendar->second += PDF_SECS_PER_MIN;
+ minutes--;
+ }
+ /* If we went forward to the next minute, correct time and add 1 minute more
+ * to add */
+ else if(p_calendar->second >= PDF_SECS_PER_MIN)
+ {
+ p_calendar->second -= PDF_SECS_PER_MIN;
+ minutes++;
+ }
+
+ /* Add/Remove minutes... */
+ pdf_time_calendar_add_minutes(p_calendar, minutes);
+}
+
+
+
+
+
+
+/* --------------------- Time Module Initialization -------------------------
*/
+
+/* Initialize Time module. Warning! Not thread-safe, must be used only once
when
+ * the program starts. It will be in charge of detecting currently configured
+ * time zone (GMT offset) and so on. */
+pdf_status_t
+pdf_time_init(void)
+{
+ /* Start Time context */
+ return pdf_time_context_init();
+}
+
+
+/* --------------------- Time Creation and Destruction ----------------------
*/
+
+/* Create new pdf_time_t object */
+pdf_time_t
+pdf_time_new (void)
+{
+ /* Allocate object & Initialize all contents */
+ pdf_time_t element = (pdf_time_t) pdf_alloc (sizeof(struct pdf_time_s));
+ if(element != NULL)
+ {
+ /* Create pdf_i64_t */
+ element->seconds = pdf_i64_new(0,0);
+ pdf_time_clear(element);
+ }
+
+ /* Set output element...*/
+ return element;
+}
+
+/* Duplicate pdf_time_t object */
+pdf_time_t
+pdf_time_dup (const pdf_time_t orig)
+{
+ pdf_time_t element = pdf_time_new();
+ if((element != NULL) && \
+ (pdf_time_copy(orig, element)!=PDF_OK))
+ {
+ pdf_time_destroy(element);
+ element = NULL;
+ }
+ return element;
+}
+
+
+/* Destroy pdf_time_t object */
+pdf_status_t
+pdf_time_destroy (pdf_time_t time_var)
+{
+ pdf_time_clear(time_var); /* Just in case additional contents are stored */
+ pdf_dealloc(time_var);
+ return PDF_OK;
+}
+
+/* ------------------------- Managing Time Values ---------------------------
*/
+
+/* Copy the contents of a given pdf_time_t object */
+pdf_status_t
+pdf_time_copy (const pdf_time_t orig,
+ pdf_time_t copy)
+{
+
+ pdf_i64_copy (orig->seconds, &(copy->seconds));
+ copy->gmt_offset = orig->gmt_offset;
+ return PDF_OK;
+}
+
+/* Clear contents of the pdf_time_t object */
+pdf_status_t
+pdf_time_clear (pdf_time_t time_var)
+{
+ /* Set time as January 1st, 1970 */
+ pdf_i64_assign_quick(&time_var->seconds, 0);
+ /* UTC */
+ time_var->gmt_offset = 0;
+ return PDF_OK;
+}
+
+
+
+/*
+* Based on the work done by Perl guys in DateTime:
+*
http://search.cpan.org/dist/DateTime/lib/DateTime.pm#Adding_a_Duration_to_a_Datetime
+*
+* "DateTime.pm always adds (or subtracts) days, then months, minutes, and then
+* seconds and nanoseconds. If there are any boundary overflows, these are
+* normalized at each step. For the days and months (the calendar) the local
+* (not UTC) values are used. For minutes and seconds, the local values are
+* used. This generally just works.
+*
+* This means that adding one month and one day to February 28, 2003 will
+* produce the date April 1, 2003, not March 29, 2003."
+*
+* Thanks to S.Jansen for the link!
+*/
+static pdf_status_t
+pdf_time_add_cal_span_with_sign (pdf_time_t time_var,
+ const struct pdf_time_cal_span_s cal_span,
+ int sign)
+{
+ pdf_status_t status = PDF_ERROR;
+
+ /* Check allowed sign values */
+ if( (sign == -1) && \
+ (sign == 1) )
+ {
+ struct pdf_time_cal_s calendar;
+
+ /* Create Calendar type from the time object */
+ if(pdf_time_get_utc_cal (time_var, &calendar) == PDF_OK)
+ {
+ pdf_time_calendar_add_days(&calendar, sign * cal_span.days);
+ pdf_time_calendar_add_months(&calendar, sign * cal_span.months);
+ pdf_time_calendar_add_years(&calendar, sign * cal_span.years);
+ pdf_time_calendar_add_hours(&calendar, sign * cal_span.hours);
+ pdf_time_calendar_add_minutes(&calendar, sign * cal_span.minutes);
+ pdf_time_calendar_add_seconds(&calendar, sign * cal_span.seconds);
+
+ status = pdf_time_from_cal(time_var, calendar);
+ }
+ }
+
+ return status;
+}
+
+/* Add the time span represented by cal_span to the text object. */
+pdf_status_t
+pdf_time_add_cal_span (pdf_time_t time_var,
+ const struct pdf_time_cal_span_s cal_span)
+{
+ return pdf_time_add_cal_span_with_sign(time_var, cal_span, 1);
+}
+
+/* Substract the time span represented by cal_span from the text object */
+pdf_status_t
+pdf_time_sub_cal_span (pdf_time_t time_var,
+ const struct pdf_time_cal_span_s cal_span)
+{
+ return pdf_time_add_cal_span_with_sign(time_var, cal_span, -1);
+}
+
+/* Add the time span contained in time_span to time. As the time span is stored
+ * in seconds, the adding is direct. */
+pdf_status_t
+pdf_time_add_span (pdf_time_t time_var,
+ const pdf_time_span_t time_span)
+{
+ pdf_i64_add ((&time_var->seconds),
+ time_var->seconds,
+ time_span);
+ return PDF_OK;
+}
+
+/* Subtract the time span contained in time_span to time. As the time span is
+ * stored in seconds. */
+pdf_status_t
+pdf_time_sub_span (pdf_time_t time_var,
+ const pdf_time_span_t time_span)
+{
+ pdf_i64_subtraction ((&time_var->seconds),
+ time_var->seconds,
+ time_span);
+ return PDF_OK;
+}
+
+
+/* Fill local_cal with the local calendar time of object. */
+pdf_status_t
+pdf_time_get_local_cal (const pdf_time_t time_var,
+ struct pdf_time_cal_s *p_local_cal)
+{
+ return pdf_time_get_cal(time_var, PDF_TIME_CAL_LOCAL,
+ p_local_cal);
+}
+
+/* Get the UTC calendar time of a given time variable. */
+pdf_status_t
+pdf_time_get_utc_cal (const pdf_time_t time_var,
+ struct pdf_time_cal_s *p_utc_cal)
+{
+ return pdf_time_get_cal(time_var, PDF_TIME_CAL_UTC,
+ p_utc_cal);
+}
+
+
+/* Set the value of a time variable to a given calendar time. */
+pdf_status_t
+pdf_time_from_cal (pdf_time_t time_var,
+ const struct pdf_time_cal_s cal_time)
+{
+ pdf_i64_t aux;
+ pdf_i32_t walker;
+
+ if((time_var == NULL) || \
+ (cal_time.year < 1970))
+ {
+ PDF_DEBUG_BASE("Invalid arguments received");
+ return PDF_EBADDATA;
+ }
+
+ /* Initialize days to 0 */
+ aux = pdf_i64_new(0,0);
+
+ /* Add days per year until the current year in the calendar */
+ walker = 1970;
+ while(walker < cal_time.year)
+ {
+ pdf_i64_add_i32(&aux, aux, \
+ (pdf_time_is_leap_year_p(walker) ? \
+ PDF_DAYS_IN_LEAP_YEAR : PDF_DAYS_IN_YEAR));
+ walker++;
+ }
+
+ /* Add days per month until the current month in the calendar */
+ pdf_i64_add_i32(&aux, aux, pdf_time_get_days_before_month(cal_time.year,
+ cal_time.month));
+
+ /* Add days in current month */
+ pdf_i64_add_i32(&aux, aux, cal_time.day);
+
+ /* Set date as seconds in the output variable */
+ pdf_i64_mult_i32(&(time_var->seconds), aux, PDF_SECS_PER_DAY);
+
+ /* Add hours as seconds */
+ pdf_i64_add_i32(&(time_var->seconds), \
+ (time_var->seconds), \
+ cal_time.hour * PDF_SECS_PER_HOUR);
+ /* Add minutes as seconds */
+ pdf_i64_add_i32(&(time_var->seconds), \
+ (time_var->seconds), \
+ cal_time.minute * PDF_SECS_PER_MIN);
+ /* Finally, add seconds */
+ pdf_i64_add_i32(&(time_var->seconds), \
+ (time_var->seconds), \
+ cal_time.second);
+
+ return PDF_OK;
+}
+
+/* Set the local time offset of time to the one used by the operating system.
*/
+pdf_status_t
+pdf_time_set_local_offset (pdf_time_t time_var)
+{
+ if(time_var->gmt_offset != 0)
+ {
+ PDF_DEBUG_BASE("Time object already in local timescale");
+ return PDF_EBADDATA;
+ }
+ time_var->gmt_offset = pdf_time_context_get_gmt_offset();
+ return PDF_OK;
+}
+
+
+/* ----------------------- Getting Time Intervals ---------------------------
*/
+
+/* Get time interval as Calendar Span */
+pdf_status_t
+pdf_time_diff_cal (const pdf_time_t time1,
+ const pdf_time_t time2,
+ struct pdf_time_cal_span_s *p_cal_span)
+{
+
+ struct pdf_time_cal_s calendar1;
+ struct pdf_time_cal_s calendar2;
+
+ if( (p_cal_span != NULL) && \
+ (pdf_time_get_cal(time1,
+ PDF_TIME_CAL_UTC,
+ &calendar1) == PDF_OK) && \
+ (pdf_time_get_cal(time2,
+ PDF_TIME_CAL_UTC,
+ &calendar2) == PDF_OK) )
+ {
+ p_cal_span->years = calendar2.year - calendar1.year;
+ p_cal_span->months = calendar2.month - calendar1.month;
+ p_cal_span->days = calendar2.day - calendar1.day;
+ p_cal_span->hours = calendar2.hour - calendar1.hour;
+ p_cal_span->minutes = calendar2.minute - calendar1.minute;
+ p_cal_span->seconds = calendar2.second - calendar1.second;
+ return PDF_OK;
+ }
+ return PDF_ERROR;
+}
+
+/* Get time interval as Span */
+pdf_status_t
+pdf_time_diff (const pdf_time_t time1,
+ const pdf_time_t time2,
+ pdf_time_span_t *p_time_span)
+{
+ pdf_i64_subtraction(p_time_span, time1->seconds, time2->seconds);
+ return PDF_OK;
+}
+
+
+/* ---------------------------- Time comparison -----------------------------
*/
+
+/* Compares two times. */
+pdf_i32_t
+pdf_time_cmp (const pdf_time_t time1,
+ const pdf_time_t time2)
+{
+ return (pdf_i32_t)pdf_i64_cmp(time1->seconds, time2->seconds);
+}
+
+
+/* ---------------------- Time printing and parsing -------------------------
*/
+
+/* Create a string representation of a given time. */
+pdf_char_t *
+pdf_time_to_string (const pdf_time_t time_var,
+ const enum pdf_time_format_e time_format)
+{
+ switch(time_format)
+ {
+ case PDF_TIME_FORMAT_PDF:
+ return pdf_time_to_string_pdf(time_var);
+ case PDF_TIME_FORMAT_ISO_8601:
+ return pdf_time_to_string_iso8601(time_var);
+ case PDF_TIME_FORMAT_ASN1:
+ return pdf_time_to_string_asn1(time_var);
+ case PDF_TIME_FORMAT_GENERALIZED_ASN1:
+ return pdf_time_to_string_generalized_asn1(time_var);
+ default:
+ return NULL;
+ }
+}
+
+
+
+/* Get a string containing a time specification in some format and fill a time
+ * variable with the parsed values. */
+pdf_status_t
+pdf_time_from_string (pdf_time_t time_var,
+ const pdf_char_t *time_str,
+ const enum pdf_time_format_e time_format)
+{
+ switch(time_format)
+ {
+ case PDF_TIME_FORMAT_PDF:
+ return pdf_time_from_string_pdf(time_var, time_str);
+ case PDF_TIME_FORMAT_ISO_8601:
+ return pdf_time_from_string_iso8601(time_var, time_str);
+ case PDF_TIME_FORMAT_ASN1:
+ return pdf_time_from_string_asn1(time_var, time_str);
+ case PDF_TIME_FORMAT_GENERALIZED_ASN1:
+ return pdf_time_from_string_generalized_asn1(time_var, time_str);
+ default:
+ return PDF_ERROR;
+ }
+}
+
+
+/* ---------------------- Getting the Current Time --------------------------
*/
+
+/* Set the value of object to the current local time used by the operating
+ * system. */
+pdf_status_t
+pdf_time_set_to_current_local_time (pdf_time_t time_var)
+{
+ if(pdf_time_set_to_current_utc_time(time_var) == PDF_OK)
+ {
+ /* And correct time with GMT offset */
+ pdf_i64_add_i32(&(time_var->seconds),
+ time_var->seconds,
+ pdf_time_context_get_gmt_offset());
+ /* And store applied offset in the gmt_offset */
+ time_var->gmt_offset = pdf_time_context_get_gmt_offset();
+ return PDF_OK;
+ }
+ else
+ {
+ return PDF_ERROR;
+ }
+}
+
+
+/* Set the value of object to the current UTC time used by the operating
+ * system. */
+pdf_status_t
+pdf_time_set_to_current_utc_time (pdf_time_t time_var)
+{
+ time_t time_now = time(NULL);
+ if(time_now != -1)
+ {
+ /* At least until 2038 this call will work correctly... */
+ pdf_i64_assign_quick(&(time_var->seconds), (pdf_i32_t)time_now);
+ time_var->gmt_offset = 0;
+ }
+ return PDF_OK;
+}
+
+
+/* ----------------- Time Span Creation and Destruction ---------------------
*/
+/* Note: It seems quite weird to manage the time span as any other pdf_X
object,
+ * taking into account that it's just a typedef of pdf_i64_t, BUT, keeping the
+ * common interface would allow easy updates in the future if needed */
+
+/* Create new time span object */
+pdf_time_span_t
+pdf_time_span_new (void)
+{
+ return pdf_i64_new(0,0);
+}
+
+
+/* Duplicate time span object */
+pdf_time_span_t
+pdf_time_span_dup (const pdf_time_span_t span)
+{
+ pdf_time_span_t new_span;
+ new_span = pdf_time_span_new();
+ pdf_time_span_copy(span, &new_span);
+ return new_span;
+}
+
+
+/* Destroy time span object */
+pdf_status_t
+pdf_time_span_destroy (pdf_time_span_t *p_span)
+{
+ return PDF_OK;
+}
+
+
+/* --------------------- Managing Time Span Values --------------------------
*/
+
+/* Set the value of a time span from a 64 bits signed number */
+pdf_status_t
+pdf_time_span_set (pdf_time_span_t *p_span,
+ const pdf_i32_t high_value,
+ const pdf_u32_t low_value)
+{
+ pdf_i64_assign(p_span, high_value, low_value);
+ return PDF_OK;
+}
+
+
+/* Set the value of a time span from a 32 bits signed number. */
+pdf_status_t
+pdf_time_span_set_from_i32 (pdf_time_span_t *p_span,
+ const pdf_i32_t seconds)
+{
+ pdf_i64_assign_quick(p_span, seconds);
+ return PDF_OK;
+}
+
+
+/* Change sign of time span */
+pdf_status_t
+pdf_time_span_negate (pdf_time_span_t *p_span)
+{
+ pdf_i64_neg(p_span, *p_span);
+ return PDF_OK;
+}
+
+
+/* Add two time spans and store the result in another time span. */
+pdf_status_t
+pdf_time_span_add (const pdf_time_span_t span1,
+ const pdf_time_span_t span2,
+ pdf_time_span_t *p_result)
+{
+ pdf_i64_add((pdf_i64_t *)p_result, span1, span2);
+ return PDF_OK;
+}
+
+/* Copy the value of a time span into another time span. */
+pdf_status_t
+pdf_time_span_copy (const pdf_time_span_t orig,
+ pdf_time_span_t *p_dest)
+{
+ pdf_i64_copy(orig, (pdf_i64_t *)p_dest);
+ return PDF_OK;
+}
+
+/* Difference two time spans and store the result (maybe negative) into another
+ * time span. */
+pdf_status_t
+pdf_time_span_diff (const pdf_time_span_t span1,
+ const pdf_time_span_t span2,
+ pdf_time_span_t *p_result)
+{
+ pdf_i64_subtraction(p_result, span1, span2);
+ return PDF_OK;
+}
+
+/* Get the value of a time span in seconds. */
+pdf_i64_t
+pdf_time_span_to_secs (const pdf_time_span_t span)
+{
+ return span;
+}
+
+
+/* ------------------------- Time Span Comparison ---------------------------
*/
+
+/* Compare two time spans */
+pdf_i32_t
+pdf_time_span_cmp (const pdf_time_span_t span1,
+ const pdf_time_span_t span2)
+{
+ return (pdf_i64_cmp(span1, span2));
+}
+
+
+/* ---------------------- Calendar Spans Management -------------------------
*/
+
+
+/* Add two calendar spans. Since the calendar spans are relative (some years
+ * has more days than another) the calendar spans are first resolved from a
+ * base time to get the number of seconds, and then that number is stored in
+ * the resulting calendar span */
+pdf_status_t
+pdf_time_add_cal_span_with_base (const struct pdf_time_cal_span_s span1,
+ const struct pdf_time_cal_span_s span2,
+ const pdf_time_t base_time,
+ struct pdf_time_cal_span_s *p_result)
+{
+ pdf_time_t time1;
+ pdf_time_t time2;
+ pdf_i32_t cmp_ret = 0;
+ pdf_status_t ret_code = PDF_ERROR;
+
+ time1 = pdf_time_dup(base_time);
+ time2 = pdf_time_dup(base_time);
+
+ if( (time1 != NULL) && \
+ (time2 != NULL) && \
+ (pdf_time_add_cal_span(time1, span1) == PDF_OK) && \
+ (pdf_time_add_cal_span(time2, span2) == PDF_OK) )
+ {
+ pdf_time_span_t span_time1;
+ pdf_time_span_t span_time2;
+ pdf_i64_t span_seconds;
+ pdf_i64_t result;
+
+ span_time1 = pdf_time_span_new();
+ span_time2 = pdf_time_span_new();
+
+ /* Get spans in seconds */
+ pdf_time_diff(time1, base_time, &span_time1);
+ pdf_time_diff(time2, base_time, &span_time2);
+
+ /* Now add two time spans */
+ pdf_time_span_add(span_time1, span_time2, &span_time1);
+
+ /* Get span in seconds */
+ span_seconds = pdf_time_span_to_secs(span_time1);
+
+ /* We will store the values in the calendar in days as the maximum value,
+ * in the way that no months/years will be stored */
+ p_result->years = 0;
+ p_result->months = 0;
+
+ pdf_i64_div_i32_divisor(&result, span_seconds, PDF_SECS_PER_DAY);
+ p_result->days = pdf_i64_to_i32(result);
+ pdf_i64_mod_i32_divisor(&span_seconds, span_seconds, PDF_SECS_PER_DAY);
+
+ pdf_i64_div_i32_divisor(&result, span_seconds, PDF_SECS_PER_HOUR);
+ p_result->hours = pdf_i64_to_i32(result);
+ pdf_i64_mod_i32_divisor(&span_seconds, span_seconds, PDF_SECS_PER_HOUR);
+
+ pdf_i64_div_i32_divisor(&result, span_seconds, PDF_SECS_PER_MIN);
+ p_result->minutes = pdf_i64_to_i32(result);
+ pdf_i64_mod_i32_divisor(&span_seconds, span_seconds, PDF_SECS_PER_MIN);
+
+ p_result->seconds = pdf_i64_to_i32(span_seconds);
+
+ pdf_time_span_destroy(&span_time1);
+ pdf_time_span_destroy(&span_time2);
+
+ ret_code = PDF_OK;
+ }
+
+ pdf_time_destroy(time1);
+ pdf_time_destroy(time2);
+ return ret_code;
+}
+
+/* Compare two calendar spans previously resolved with a given base time. */
+pdf_i32_t
+pdf_time_cal_span_cmp (const struct pdf_time_cal_span_s span1,
+ const struct pdf_time_cal_span_s span2,
+ const pdf_time_t base_time,
+ pdf_status_t *p_ret_code)
+{
+ /* Probably the best way to do it is convert the cal spans into pdf_time_t
+ * and then compare the pdf_time_ts */
+ pdf_time_t time1;
+ pdf_time_t time2;
+ pdf_i32_t cmp_ret = 0;
+ pdf_status_t ret_code = PDF_ERROR;
+
+ time1 = pdf_time_dup(base_time);
+ time2 = pdf_time_dup(base_time);
+
+ if( (time1 != NULL) && \
+ (time2 != NULL) && \
+ (pdf_time_add_cal_span(time1, span1) == PDF_OK) && \
+ (pdf_time_add_cal_span(time2, span2) == PDF_OK) )
+ {
+ cmp_ret = pdf_time_cmp(time1, time2);
+ ret_code = PDF_OK;
+ }
+
+ if(p_ret_code != NULL)
+ {
+ *p_ret_code = ret_code;
+ }
+
+ pdf_time_destroy(time1);
+ pdf_time_destroy(time2);
+ return cmp_ret;
+}
+
+/* Compute the difference between two calendar spans relative to a given base
+ * time and store it in a given calendar span. */
+pdf_status_t
+pdf_time_cal_span_diff (const struct pdf_time_cal_span_s span1,
+ const struct pdf_time_cal_span_s span2,
+ const pdf_time_t base_time,
+ struct pdf_time_cal_span_s *p_result)
+{
+ /* TODO */
+ return PDF_ERROR;
+}
+
+
+/* End of pdf-time.c */
Index: src/base/pdf-time.h
===================================================================
RCS file: src/base/pdf-time.h
diff -N src/base/pdf-time.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/base/pdf-time.h 24 Jun 2008 23:22:58 -0000 1.1
@@ -0,0 +1,327 @@
+/* -*- mode: C -*- Time-stamp: ""
+ *
+ * File: pdf-time.h
+ * Date: Mon Apr 28 23:23:04 2008
+ *
+ * GNU PDF Library - Header file for the Time module
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PDF_TIME_H
+#define PDF_TIME_H
+
+#include <stdio.h>
+#include <pdf-types.h>
+
+
+/* BEGIN PUBLIC */
+
+
+/* A variable of type pdf_time_t contains information about a particular date
+ * and time. It is stored in seconds since 1 January 1970 (UTC). Additionally
+ * an extra variable specifies the local time, as the offset between UTC and
+ * the local time. */
+struct pdf_time_s {
+ pdf_i64_t seconds;
+ /* A GMT offset, seconds west of GMT */
+ pdf_i32_t gmt_offset;
+};
+typedef int intaleks;
+typedef struct pdf_time_s *pdf_time_t;
+
+
+/* A variable of type pdf_time_span_t represents a span of time. */
+typedef pdf_i64_t pdf_time_span_t;
+
+/* This structure holds information about a specific time represented in
+ * calendar items: years, months, days, day of week, hours, minutes, seconds
+ * and the relative offset with GMT. */
+struct pdf_time_cal_s {
+ /* A year number. */
+ pdf_u32_t year;
+ /* A month number. The valid range is 1..12. */
+ pdf_u32_t month;
+ /* A day number. The valid range is 1..31. */
+ pdf_u32_t day;
+ /* Day of the week. The valid range is 1..7 (Monday to Sunday). */
+ pdf_u32_t dow;
+ /* An hour. The valid range is 0..23. */
+ pdf_u32_t hour;
+ /* A minute. The valid range is 0..59. */
+ pdf_u32_t minute;
+ /* A second. The valid range is 0..59. */
+ pdf_u32_t second;
+ /* A GMT offset. */
+ pdf_i32_t gmt_offset;
+};
+
+
+/* This structure holds information about a time span represented in calendar
+ * items: years, months, days, hours, minutes and seconds. */
+struct pdf_time_cal_span_s {
+ pdf_bool_t sign;
+ pdf_u32_t years;
+ pdf_u32_t months;
+ pdf_u32_t days;
+ pdf_u32_t hours;
+ pdf_u32_t minutes;
+ pdf_u32_t seconds;
+};
+
+
+/* Enumeration containing the several supported time formats used to convert a
+ * time to a string representation or to parse a time from a string
+ * representation. */
+enum pdf_time_format_e {
+ PDF_TIME_FORMAT_PDF,
+ PDF_TIME_FORMAT_ISO_8601,
+ PDF_TIME_FORMAT_ASN1,
+ PDF_TIME_FORMAT_GENERALIZED_ASN1
+};
+
+
+/* --------------------- Time Module Initialization -------------------------
*/
+
+/* Initialize Time module. Warning! Not thread-safe, must be used only once
when
+ * the program starts. It will be in charge of detecting currently configured
+ * time zone (GMT offset) and so on. */
+pdf_status_t
+pdf_time_init(void);
+
+
+/* --------------------- Time Creation and Destruction ----------------------
*/
+
+/* Create new pdf_time_t object */
+pdf_time_t
+pdf_time_new (void);
+
+/* Duplicate pdf_time_t object */
+pdf_time_t
+pdf_time_dup (const pdf_time_t orig);
+
+/* Destroy pdf_time_t object */
+pdf_status_t
+pdf_time_destroy (pdf_time_t time_var);
+
+
+/* ------------------------- Managing Time Values ---------------------------
*/
+
+/* Copy the contents of a given pdf_time_t object */
+pdf_status_t
+pdf_time_copy (const pdf_time_t orig,
+ pdf_time_t copy);
+
+/* Clear contents of the pdf_time_t object */
+pdf_status_t
+pdf_time_clear (pdf_time_t time_var);
+
+
+/* Add the time span represented by cal_span to the text object */
+pdf_status_t
+pdf_time_add_cal_span (pdf_time_t time_var,
+ const struct pdf_time_cal_span_s cal_span);
+
+/* Substract the time span represented by cal_span from the text object */
+pdf_status_t
+pdf_time_sub_cal_span (pdf_time_t time_var,
+ const struct pdf_time_cal_span_s cal_span);
+
+/* Add the time span contained in time_span to time. */
+pdf_status_t
+pdf_time_add_span (pdf_time_t time_var,
+ const pdf_time_span_t time_span);
+
+/* Subtract the time span contained in time_span to time. */
+pdf_status_t
+pdf_time_sub_span (pdf_time_t time_var,
+ const pdf_time_span_t time_span);
+
+/* Fill local_cal with the local calendar time of object. */
+pdf_status_t
+pdf_time_get_local_cal (const pdf_time_t time_var,
+ struct pdf_time_cal_s *p_local_cal);
+
+/* Get the UTC calendar time of a given time variable. */
+pdf_status_t
+pdf_time_get_utc_cal (const pdf_time_t time_var,
+ struct pdf_time_cal_s *p_utc_cal);
+
+/* Set the value of a time variable to a given calendar time. */
+pdf_status_t
+pdf_time_from_cal (pdf_time_t time_var,
+ const struct pdf_time_cal_s cal_time);
+
+/* Set the local time offset of time to the one used by the operating system.
*/
+pdf_status_t
+pdf_time_set_local_offset (pdf_time_t time_var);
+
+
+
+/* ----------------------- Getting Time Intervals ---------------------------
*/
+
+/* Get time interval as Calendar Span */
+pdf_status_t
+pdf_time_diff_cal (const pdf_time_t time1,
+ const pdf_time_t time2,
+ struct pdf_time_cal_span_s *p_cal_span);
+
+/* Get time interval as Span */
+pdf_status_t
+pdf_time_diff (const pdf_time_t time1,
+ const pdf_time_t time2,
+ pdf_time_span_t *p_time_span);
+
+
+/* ---------------------------- Time comparison -----------------------------
*/
+
+/* Compares two times. */
+pdf_i32_t
+pdf_time_cmp (const pdf_time_t time1,
+ const pdf_time_t time2);
+
+
+/* ---------------------- Time printing and parsing -------------------------
*/
+
+/* Create a string representation of a given time. */
+pdf_char_t *
+pdf_time_to_string (const pdf_time_t time_var,
+ const enum pdf_time_format_e time_format);
+
+
+/* Get a string containing a time specification in some format and fill a time
+ * variable with the parsed values. */
+pdf_status_t
+pdf_time_from_string (pdf_time_t time_var,
+ const pdf_char_t *time_str,
+ const enum pdf_time_format_e time_format);
+
+
+/* ---------------------- Getting the Current Time --------------------------
*/
+
+/* Set the value of object to the current local time used by the operating
+ * system. */
+pdf_status_t
+pdf_time_set_to_current_local_time (pdf_time_t time_var);
+
+
+/* Set the value of object to the current UTC time used by the operating
+ * system. */
+pdf_status_t
+pdf_time_set_to_current_utc_time (pdf_time_t time_var);
+
+
+/* ----------------- Time Span Creation and Destruction ---------------------
*/
+
+/* Create new time span object */
+pdf_time_span_t
+pdf_time_span_new (void);
+
+/* Duplicate time span object */
+pdf_time_span_t
+pdf_time_span_dup (const pdf_time_span_t span);
+
+
+/* Destroy time span object */
+pdf_status_t
+pdf_time_span_destroy (pdf_time_span_t *p_span);
+
+
+/* --------------------- Managing Time Span Values --------------------------
*/
+
+/* Set the value of a time span from a 64 bits signed number */
+pdf_status_t
+pdf_time_span_set (pdf_time_span_t *p_span,
+ const pdf_i32_t high_value,
+ const pdf_u32_t low_value);
+
+
+/* Set the value of a time span from a 32 bits signed number. */
+pdf_status_t
+pdf_time_span_set_from_i32 (pdf_time_span_t *p_span,
+ const pdf_i32_t seconds);
+
+
+/* Change sign of time span */
+pdf_status_t
+pdf_time_span_negate (pdf_time_span_t *p_span);
+
+
+/* Add two time spans and store the result in another time span. */
+pdf_status_t
+pdf_time_span_add (const pdf_time_span_t span1,
+ const pdf_time_span_t span2,
+ pdf_time_span_t *p_result);
+
+/* Copy the value of a time span into another time span. */
+pdf_status_t
+pdf_time_span_copy (const pdf_time_span_t orig,
+ pdf_time_span_t *p_dest);
+
+/* Difference two time spans and store the result (maybe negative) into another
+ * time span. */
+pdf_status_t
+pdf_time_span_diff (const pdf_time_span_t span1,
+ const pdf_time_span_t span2,
+ pdf_time_span_t *p_result);
+
+/* Get the value of a time span in seconds. */
+pdf_i64_t
+pdf_time_span_to_secs (const pdf_time_span_t span);
+
+
+/* ------------------------- Time Span Comparison ---------------------------
*/
+
+/* Compare two time spans */
+pdf_i32_t
+pdf_time_span_cmp (const pdf_time_span_t span1,
+ const pdf_time_span_t span2);
+
+
+/* ---------------------- Calendar Spans Management -------------------------
*/
+
+/* Add two calendar spans. Since the calendar spans are relative (some years
+ * has more days than another) the calendar spans are first resolved from a
+ * base time. */
+pdf_status_t
+pdf_time_add_cal_span_with_base (const struct pdf_time_cal_span_s span1,
+ const struct pdf_time_cal_span_s span2,
+ const pdf_time_t base_time,
+ struct pdf_time_cal_span_s *p_result);
+
+/* Compare two calendar spans previously resolved with a given base time. */
+pdf_i32_t
+pdf_time_cal_span_cmp (const struct pdf_time_cal_span_s span1,
+ const struct pdf_time_cal_span_s span2,
+ const pdf_time_t base_time,
+ pdf_status_t *p_ret_code);
+
+/* Compute the difference between two calendar spans relative to a given base
+ * time and store it in a given calendar span. */
+pdf_status_t
+pdf_time_cal_span_diff (const struct pdf_time_cal_span_s span1,
+ const struct pdf_time_cal_span_s span2,
+ const pdf_time_t base_time,
+ struct pdf_time_cal_span_s *p_result);
+
+
+/* END PUBLIC */
+
+#endif /* PDF_TIME_H */
+
+/* End of pdf-time.h */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [pdf-devel] libgnupdf AUTHORS ChangeLog src/Makefile.am src...,
Aleksander Morgado <=