pdf-devel
[Top][All Lists]
Advanced

[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 */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]