1/*
2	struct_timeval.c
3
4	Custom serializer for struct timeval
5
6	Compile this file and link it with your code.
7
8	Changes:
9	Feb 8, 2008: fixed local time to internal GMT conversion
10
11gSOAP XML Web services tools
12Copyright (C) 2000-2008, Robert van Engelen, Genivia Inc., All Rights Reserved.
13This part of the software is released under ONE of the following licenses:
14GPL, the gSOAP public license, OR Genivia's license for commercial use.
15--------------------------------------------------------------------------------
16gSOAP public license.
17
18The contents of this file are subject to the gSOAP Public License Version 1.3
19(the "License"); you may not use this file except in compliance with the
20License. You may obtain a copy of the License at
21http://www.cs.fsu.edu/~engelen/soaplicense.html
22Software distributed under the License is distributed on an "AS IS" basis,
23WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24for the specific language governing rights and limitations under the License.
25
26The Initial Developer of the Original Code is Robert A. van Engelen.
27Copyright (C) 2000-2008, Robert van Engelen, Genivia, Inc., All Rights Reserved.
28--------------------------------------------------------------------------------
29GPL license.
30
31This program is free software; you can redistribute it and/or modify it under
32the terms of the GNU General Public License as published by the Free Software
33Foundation; either version 2 of the License, or (at your option) any later
34version.
35
36This program is distributed in the hope that it will be useful, but WITHOUT ANY
37WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
38PARTICULAR PURPOSE. See the GNU General Public License for more details.
39
40You should have received a copy of the GNU General Public License along with
41this program; if not, write to the Free Software Foundation, Inc., 59 Temple
42Place, Suite 330, Boston, MA 02111-1307 USA
43
44Author contact information:
45engelen@genivia.com / engelen@acm.org
46
47This program is released under the GPL with the additional exemption that
48compiling, linking, and/or using OpenSSL is allowed.
49--------------------------------------------------------------------------------
50A commercial use license is available from Genivia, Inc., contact@genivia.com
51--------------------------------------------------------------------------------
52*/
53
54// soapH.h generated by soapcpp2 from .h file containing #import "struct_timeval.h":
55#include "soapH.h"
56
57void soap_default_xsd__dateTime(struct soap *soap, struct timeval *a)
58{ memset(a, 0, sizeof(struct timeval));
59}
60
61void soap_serialize_xsd__dateTime(struct soap *soap, struct timeval const *a)
62{ }
63
64int soap_out_xsd__dateTime(struct soap *soap, const char *tag, int id, const struct timeval *a, const char *type)
65{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_xsd__dateTime), type)
66   || soap_string_out(soap, soap_xsd__dateTime2s(soap, *a), 0))
67    return soap->error;
68  return soap_element_end_out(soap, tag);
69}
70
71const char *soap_xsd__dateTime2s(struct soap *soap, const struct timeval a)
72{ char *s = soap->tmpbuf;
73  size_t n;
74  soap_dateTime2s(soap, a.tv_sec); /* assuming result is in tmpbuf! */
75  n = strlen(s);
76  if (s[n-1] == 'Z')
77    n--;
78  sprintf(s + n, ".%0.6dZ", a.tv_usec);
79  return s;
80}
81
82struct timeval *soap_in_xsd__dateTime(struct soap *soap, const char *tag, struct timeval *a, const char *type)
83{ if (soap_element_begin_in(soap, tag, 0, NULL))
84    return NULL;
85  if (*soap->type
86   && soap_match_tag(soap, soap->type, type)
87   && soap_match_tag(soap, soap->type, ":dateTime"))
88  { soap->error = SOAP_TYPE;
89    soap_revert(soap);
90    return NULL;
91  }
92  a = (struct timeval*)soap_id_enter(soap, soap->id, a, SOAP_TYPE_xsd__dateTime, sizeof(struct timeval), 0, NULL, NULL, NULL);
93  if (*soap->href)
94    a = (struct timeval*)soap_id_forward(soap, soap->href, a, 0, SOAP_TYPE_xsd__dateTime, 0, sizeof(struct timeval), 0, NULL);
95  else if (a)
96  { if (soap_s2xsd__dateTime(soap, soap_value(soap), a))
97      return NULL;
98  }
99  if (soap->body && soap_element_end_in(soap, tag))
100    return NULL;
101  return a;
102}
103
104int soap_s2xsd__dateTime(struct soap *soap, const char *s, struct timeval *a)
105{ memset((void*)a, 0, sizeof(struct timeval));
106  if (s)
107  { char rest[32];
108    const char *t;
109    struct tm tm;
110    memset((void*)&tm, 0, sizeof(struct tm));
111    rest[sizeof(rest)-1] = '\0';
112    if (strchr(s, '-'))
113      t = "%d-%d-%dT%d:%d:%d%31s";
114    else if (strchr(s, ':'))
115      t = "%4d%2d%2dT%d:%d:%d%31s";
116    else /* parse non-XSD-standard alternative ISO 8601 format */
117      t = "%4d%2d%2dT%2d%2d%2d%31s";
118    if (sscanf(s, t, &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, rest) < 6)
119      return soap->error = SOAP_TYPE;
120    tm.tm_wday = -1;
121    tm.tm_yday = -1;
122    if (tm.tm_year == 1)
123      tm.tm_year = 70;
124    else
125      tm.tm_year -= 1900;
126    tm.tm_mon--;
127    tm.tm_isdst = 0;
128    if (*rest)
129    { if (*rest == '.')
130      { for (s = rest + 1; *s; s++)
131          if (*s < '0' || *s > '9')
132            break;
133        a->tv_usec = (long)atol(rest + 1);
134      }
135      else
136      { s = rest;
137        a->tv_usec = 0;
138      }
139    }
140    if (*s)
141    { if (*s == '+' || *s == '-')
142      { int h = 0, m = 0;
143        if (s[3] == ':')
144        { /* +hh:mm */
145	  sscanf(s, "%d:%d", &h, &m);
146          if (h < 0)
147            m = -m;
148        }
149        else /* +hhmm */
150        { m = (int)atol(s);
151          h = m / 100;
152          m = m % 100;
153        }
154        tm.tm_hour -= h;
155        tm.tm_min -= m;
156	/* put hour and min in range */
157        tm.tm_hour += tm.tm_min / 60;
158        tm.tm_min %= 60;
159        if (tm.tm_min < 0)
160          tm.tm_min += 60;
161        tm.tm_mday += tm.tm_hour / 24;
162        tm.tm_hour %= 24;
163        if (tm.tm_hour < 0)
164          tm.tm_hour += 24;
165	/* note: day of the month may be out of range, timegm() handles it */
166      }
167      a->tv_sec = soap_timegm(&tm);
168    }
169    else
170      a->tv_sec = mktime(&tm);
171  }
172  return soap->error;
173}
174