lib: added WIN32 check for usb_set_configuration()
[barry.git] / src / vbase.cc
blob9d7ec09d562903afdcb983704f701ab07086f75d
1 //
2 // \file vbase.cc
3 // vformat support routines in base class
4 //
6 /*
7 Copyright (C) 2006-2010, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "vbase.h"
23 //#include "trace.h"
24 #include "vformat.h" // comes from opensync, but not a public header yet
25 #include "tzwrapper.h"
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <stdint.h>
29 #include <string.h>
30 #include <glib.h>
31 #include <sstream>
33 using namespace std;
35 namespace Barry { namespace Sync {
37 //////////////////////////////////////////////////////////////////////////////
38 // vTimeConverter
40 std::string vTimeConverter::unix2vtime(const time_t *timestamp)
42 struct tm split;
43 if( !gmtime_r(timestamp, &split) ) {
44 ostringstream oss;
45 oss << "gmtime_r() failed on time_t of ";
46 if( timestamp )
47 oss << *timestamp;
48 else
49 oss << "(null pointer)";
50 throw Barry::ConvertError(oss.str());
53 return tm_to_iso(&split, true);
56 time_t vTimeConverter::vtime2unix(const char *vtime)
58 return TzWrapper::iso_mktime(vtime);
62 // The following implementation is taken from opensync's
63 // opensync_time.c implementation with the following copyright
64 // notices at the top as of July 2010:
66 // * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
67 // * Copyright (C) 2006-2008 Daniel Gollub <gollub@b1-systems.de>
68 // * Copyright (C) 2007 Chris Frey <cdfrey@netdirect.ca>
70 // License: LGPL 2.1 or later
72 int vTimeConverter::alarmduration2sec(const char *alarm)
74 int i, secs, digits = 0;
75 int is_digit = 0;
76 int sign = 1; // when ical stamp doesn't start with '-' => seconds after event
77 int days = 0, weeks = 0, hours = 0, minutes = 0, seconds = 0;
78 int len = strlen(alarm);
80 for (i=0; i < len; i++) {
82 switch (alarm[i]) {
83 case '-':
84 sign = -1; // seconds before event - change the sign
85 case 'P':
86 case 'T':
87 is_digit = 0;
88 break;
89 case 'W':
90 is_digit = 0;
91 weeks = digits;
92 break;
93 case 'D':
94 is_digit = 0;
95 days = digits;
96 break;
97 case 'H':
98 is_digit = 0;
99 hours = digits;
100 break;
101 case 'M':
102 is_digit = 0;
103 minutes = digits;
104 break;
105 case 'S':
106 is_digit = 0;
107 seconds = digits;
108 break;
109 case '0':
110 case '1':
111 case '2':
112 case '3':
113 case '4':
114 case '5':
115 case '6':
116 case '7':
117 case '8':
118 case '9':
119 if (is_digit)
120 break;
122 if (sscanf((char*)(alarm+i),"%d",&digits) == EOF)
123 return -1;
125 is_digit = 1;
126 break;
130 secs = (weeks * 7 * 24 * 3600) + (days * 24 * 3600) + (hours * 3600) + (minutes * 60) + seconds;
132 secs = secs * sign; // change sign if the alarm is in seconds before event (leading '-')
134 return secs;
139 //////////////////////////////////////////////////////////////////////////////
140 // vAttr
142 std::string vAttr::GetName()
144 std::string ret;
146 if( !m_attr )
147 return ret;
149 const char *name = b_vformat_attribute_get_name(m_attr);
150 if( name )
151 ret = name;
152 return ret;
155 std::string vAttr::GetValue(int nth)
157 std::string ret;
158 const char *value = 0;
160 if( m_attr ) {
161 if( b_vformat_attribute_is_single_valued(m_attr) ) {
162 if( nth == 0 )
163 value = b_vformat_attribute_get_value(m_attr);
165 else {
166 value = b_vformat_attribute_get_nth_value(m_attr, nth);
170 if( value )
171 ret = value;
173 return ret;
176 std::string vAttr::GetDecodedValue()
178 std::string ret;
179 GString *value = NULL;
181 if( m_attr ) {
182 if( b_vformat_attribute_is_single_valued(m_attr) ) {
183 value = b_vformat_attribute_get_value_decoded(m_attr);
187 if( value )
188 ret.assign(value->str, value->len);
190 return ret;
193 std::string vAttr::GetParam(const char *name, int nth)
195 std::string ret;
197 if( !m_attr )
198 return ret;
200 b_VFormatParam *param = b_vformat_attribute_find_param(m_attr, name, 0);
201 if( !param )
202 return ret;
204 const char *value = b_vformat_attribute_param_get_nth_value(param, nth);
205 if( value )
206 ret = value;
208 return ret;
211 /// Does an exhaustive search through the attribute, searching for all
212 /// param values that exist for the given name, and returns all values
213 /// in a comma delimited string.
214 std::string vAttr::GetAllParams(const char *name)
216 std::string ret;
218 if( !m_attr )
219 return ret;
221 b_VFormatParam *param = 0;
222 for( int level = 0;
223 (param = b_vformat_attribute_find_param(m_attr, name, level));
224 level++ )
226 const char *value = 0;
227 for( int nth = 0;
228 (value = b_vformat_attribute_param_get_nth_value(param, nth));
229 nth++ )
231 if( ret.size() )
232 ret += ",";
233 ret += value;
237 return ret;
241 //////////////////////////////////////////////////////////////////////////////
242 // vCalendar
244 vBase::vBase()
245 : m_format(0)
249 vBase::~vBase()
251 if( m_format ) {
252 b_vformat_free(m_format);
253 m_format = 0;
257 void vBase::SetFormat(b_VFormat *format)
259 if( m_format ) {
260 b_vformat_free(m_format);
261 m_format = 0;
263 m_format = format;
266 void vBase::Clear()
268 if( m_format ) {
269 b_vformat_free(m_format);
270 m_format = 0;
274 vAttrPtr vBase::NewAttr(const char *name)
276 // Trace trace("vBase::NewAttr");
278 // trace.logf("creating valueless attr: %s", name);
280 vAttrPtr attr(b_vformat_attribute_new(NULL, name));
281 if( !attr.Get() )
282 throw Barry::ConvertError("resource error allocating vformat attribute");
283 return attr;
286 vAttrPtr vBase::NewAttr(const char *name, const char *value)
288 // Trace trace("vBase::NewAttr");
291 some vCard values are positional (like name), so blank should be allowed...
293 if( strlen(value) == 0 ) {
294 trace.logf("attribute '%s' contains no data, skipping", name);
295 return vAttrPtr();
299 // trace.logf("creating attr: %s, %s", name, value);
301 vAttrPtr attr(b_vformat_attribute_new(NULL, name));
302 if( !attr.Get() )
303 throw ConvertError("resource error allocating vformat attribute");
305 b_vformat_attribute_add_value(attr.Get(), value);
306 return attr;
309 void vBase::AddAttr(vAttrPtr attr)
311 // Trace trace("vBase::AddAttr");
313 if( !attr.Get() ) {
314 // trace.log("attribute contains no data, skipping");
315 return;
318 b_vformat_add_attribute(m_format, attr.Extract());
321 void vBase::AddValue(vAttrPtr &attr, const char *value)
323 // Trace trace("vBase::AddValue");
324 if( !attr.Get() ) {
325 // trace.log("attribute pointer contains no data, skipping");
326 return;
329 if( strlen(value) == 0 ) {
330 trace.log("attribute value is empty, skipping");
331 return;
334 b_vformat_attribute_add_value(attr.Get(), value);
337 void vBase::AddEncodedValue(vAttrPtr &attr, b_VFormatEncoding encoding, const char *value, int len)
339 // Trace trace("vBase::AddValue");
340 if( !attr.Get() ) {
341 // trace.log("attribute pointer contains no data, skipping");
342 return;
345 attr.Get()->encoding = encoding;
346 attr.Get()->encoding_set = TRUE;
348 b_vformat_attribute_add_value_decoded(attr.Get(), value, len);
351 void vBase::AddParam(vAttrPtr &attr, const char *name, const char *value)
353 // Trace trace("vBase::AddParam");
355 if( !attr.Get() ) {
356 // trace.log("attribute pointer contains no data, skipping");
357 return;
360 if( strlen(value) == 0 ) {
361 trace.log("parameter value is empty, skipping");
362 return;
366 b_VFormatParam *pParam = b_vformat_attribute_param_new(name);
367 b_vformat_attribute_param_add_value(pParam, value);
368 b_vformat_attribute_add_param(attr.Get(), pParam);
371 std::string vBase::GetAttr(const char *attrname, const char *block)
373 // Trace trace("vBase::GetAttr");
374 // trace.logf("getting attr: %s", attrname);
376 std::string ret;
377 const char *value = 0;
379 bool needs_freeing = false;
381 b_VFormatAttribute *attr = b_vformat_find_attribute(m_format, attrname, 0, block);
382 if( attr ) {
383 if( b_vformat_attribute_is_single_valued(attr) ) {
384 value = b_vformat_attribute_get_value(attr);
385 needs_freeing = true;
387 else {
388 // FIXME, this is hardcoded
389 value = b_vformat_attribute_get_nth_value(attr, 0);
393 if( value )
394 ret = value;
396 if( needs_freeing )
397 g_free((char *)value);
399 // trace.logf("attr value: %s", ret.c_str());
400 return ret;
403 std::vector<std::string> vBase::GetValueVector(const char *attrname, const char *block)
405 // Trace trace("vBase::GetValueVector");
406 // trace.logf("getting value vector for: %s", attrname);
408 std::vector<std::string> ret;
409 const char *value = 0;
410 bool needs_freeing = false;
412 b_VFormatAttribute *attr = b_vformat_find_attribute(m_format, attrname, 0, block);
413 if( attr ) {
414 if( b_vformat_attribute_is_single_valued(attr) ) {
415 value = b_vformat_attribute_get_value(attr);
416 needs_freeing = true;
417 } else {
418 // nasty, but avoids tweaking vformat.
419 int idx = 0;
420 do {
421 value = b_vformat_attribute_get_nth_value(attr, idx++);
422 if( value ) {
423 ret.push_back(value);
425 } while( value );
429 if( needs_freeing )
430 g_free((char *)value);
432 return ret;
435 vAttr vBase::GetAttrObj(const char *attrname, int nth, const char *block)
437 // Trace trace("vBase::GetAttrObj");
438 // trace.logf("getting attr: %s", attrname);
440 return vAttr(b_vformat_find_attribute(m_format, attrname, nth, block));
443 std::vector<std::string> vBase::Tokenize(const std::string& str, const char delim)
445 std::vector<std::string> tokens;
446 std::string::size_type delimPos = 0, tokenPos = 0, pos = 0;
448 if( str.length() < 1 ) {
449 return tokens;
452 while( 1 ) {
453 delimPos = str.find_first_of(delim, pos);
454 tokenPos = str.find_first_not_of(delim, pos);
456 if( std::string::npos != delimPos ) {
457 if( std::string::npos != tokenPos ) {
458 if( tokenPos < delimPos ) {
459 tokens.push_back(str.substr(pos, delimPos-pos));
460 } else {
461 tokens.push_back("");
463 } else {
464 tokens.push_back("");
466 pos = delimPos + 1;
467 } else {
468 if( std::string::npos != tokenPos ){
469 tokens.push_back(str.substr(pos));
470 } else {
471 tokens.push_back("");
473 break;
476 return tokens;
479 std::string vBase::ToStringList(const std::vector<std::string> &list, const char delim)
481 std::string str;
482 for( unsigned int idx = 0; idx < list.size(); idx++ ) {
483 if( idx ) {
484 str += delim;
486 str += list[idx];
488 return str;
491 }} // namespace Barry::Sync