/* Copyright (C) 2003-2005 Datapark corp. All rights reserved.
   Copyright (C) 2000-2002 Lavtech.com corp. All rights reserved.

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
*/

#ifndef _DPS_UTILS_H
#define _DPS_UTILS_H

#include <stdio.h>

/* for time_t */
#include <time.h>

/* for va_list */
#include <stdarg.h>

#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>

#include "dps_config.h"

/* This is used in DpsTime_t2Str and in its callers */
#define DPS_MAXTIMESTRLEN	35


/* Some useful MACROs */
#define DPS_STREND(s)		(s+strlen(s))
#define DPS_FREE(x)		{if((x)!=NULL){DpsFree((void*)x);x=NULL;}}
#define DPS_SKIP(s,set)		while((*s)&&(strchr(set,*s)))s++;
#define DPS_SKIPN(s,set)	while((*s)&&(!strchr(set,*s)))s++;

/* NULL safe atoi*/
#define DPS_ATOI(x)		((x)?atoi(x):0)
#define DPS_ATOF(x)		((x)?atof(x):0.0)
#define DPS_ATOU(x)		((x)?(urlid_t)strtoll(x, (char**)NULL,10):0)
#define DPS_NULL2EMPTY(x)	((x)?(x):"")


typedef struct {
  size_t allocated_size;
  size_t data_size;
  size_t page_size;
  int    freeme;
  char   *data;
} DPS_DSTR;


DPS_DSTR *DpsDSTRInit(DPS_DSTR *dstr, size_t page_size);
void DpsDSTRFree(DPS_DSTR *dstr);
size_t DpsDSTRAppend(DPS_DSTR *dstr, const void *data, size_t append_size);
size_t DpsDSTRAppendStr(DPS_DSTR *dstr, const char *data);
size_t DpsDSTRAppendUni(DPS_DSTR *dstr, const dpsunicode_t *data);



/* Misc functions */
extern __C_LINK int	__DPSCALL	DpsInit(void);
extern char * DpsGetStrToken(char * s,char ** last);
extern char * DpsTrim(char * p, const char * delim);
extern char * DpsRTrim(char* p, const char * delim);
extern char * DpsUnescapeCGIQuery(char *d, const char *s);
extern __C_LINK char * __DPSCALL DpsEscapeURL(char *d,const char *s);
extern char * DpsEscapeURI(char *d,const char *s);
extern char * DpsRemove2Dot(char *path);
extern char * DpsBuildParamStr(char * dst,size_t len,const char * src,char ** argv,size_t argc);
extern char * DpsStrRemoveChars(char * str, const char * sep);
extern char * DpsStrRemoveDoubleChars(char * str, const char * sep);

/* This should convert Last-Modified time returned by webserver
 * to time_t (seconds since the Epoch). -kir
 */
extern time_t DpsHttpDate2Time_t(const char * date);

extern time_t DpsFTPDate2Time_t(char *date);

/***********************************************************
 * converts time_str to time_t (seconds)
 * time_str can be exactly number of seconds
 * or in the form 'xxxA[yyyB[zzzC]]'
 * (Spaces are allowed between xxx and A and yyy and so on)
 *   there xxx, yyy, zzz are numbers (can be negative!)
 *         A, B, C can be one of the following:
 *		s - second
 *		M - minute	
 *		h - hour
 *		d - day
 *		m - month
 *		y - year
 *	(these letters are as in strptime/strftime functions)
 *
 * Examples:
 * 1234 - 1234 seconds
 * 4h30M - 4 hours and 30 minutes (will return 9000 seconds)
 * 1y6m-15d - 1 year and six month minus 15 days (will return 45792000 s)
 * 1h-60M+1s - 1 hour minus 60 minutes plus 1 second (will return 1 s)
 */
time_t Dps_dp2time_t(const char * time_str);


/* This one for printing HTTP Last-Modified: header */
extern void DpsTime_t2HttpStr(time_t t, char * time_str);
/* This one deals with timezone offset */
extern int DpsInitTZ(void);
extern unsigned long DpsStartTimer(void);


/* Probably string missing functions */

#ifndef HAVE_BZERO
extern __C_LINK void __DPSCALL bzero(void *b, size_t len);
#endif

#ifndef HAVE_STRCASECMP
extern __C_LINK int __DPSCALL strcasecmp(const char *s1, const char *s2);
#endif

#ifndef HAVE_STRNCASECMP
extern int strncasecmp(const char *s1, const char *s2, size_t n);
#endif

#ifndef HAVE_STRCASESTR
extern char * strcasestr(register const char *s1, register const char *s2);
#endif

#ifndef HAVE_VSNPRINTF
extern int vsnprintf(char *str, size_t size, const char  *fmt,  va_list ap);
#endif

extern __C_LINK int __DPSCALL dps_snprintf(char *str, size_t size, const char *fmt, ...);
#ifndef HAVE_SNPRINTF
#define snprintf dps_snprintf
#endif

extern char *dps_strtok_r(char *s, const char *delim, char **save_ptr);
#ifndef HAVE_STRTOK_R
#define strtok_r dps_rstok_r
#endif

#if !defined(HAVE_STRNDUP) || defined(EFENCE)
extern char *DpsStrndup(const char *str, size_t len);
#endif
#ifndef HAVE_STRNDUP
#define strndup DpsStrndup
#endif

#ifndef HAVE_HSTRERROR
extern const char *h_errlist[];
# define hstrerror(err)  ((err) <= 4 ? h_errlist[(err)] : "unknown error")
#endif

#ifndef HAVE_INET_NET_PTON
int inet_net_pton(int af, const char *src, void *dst, size_t size);
#endif

extern __C_LINK int __DPSCALL DpsHex2Int(int h);
extern __C_LINK int __DPSCALL DpsInt2Hex(int i);


#define BASE64_LEN(len) (4 * (((len) + 2) / 3) +2)
extern __C_LINK size_t __DPSCALL dps_base64_encode (const char *s, char *store, size_t length);
extern __C_LINK size_t __DPSCALL dps_base64_decode (char * dst, const char * src, size_t len);
extern char * dps_rfc1522_decode(char * dst, const char *src);

/* Build directory */
extern int   DpsBuild(char * path, int mode);

/* SetEnv */
extern int DpsSetEnv(const char * name,const char * value);
extern void DpsUnsetEnv(const char * name);

extern void DpsUniRemoveDoubleSpaces(dpsunicode_t * ustr);
extern void DpsUniPrint(const char *head, dpsunicode_t * ustr);

extern void DpsWriteLock(int fd);
extern void DpsUnLock(int fd);
extern void DpsReadLock(int fd);
extern void DpsReadLockFILE(FILE *f);
extern __C_LINK void __DPSCALL DpsWriteLockFILE(FILE *f);
extern __C_LINK void __DPSCALL DpsUnLockFILE(FILE *f);

#endif /* _DPS_UTILS_H */
