#ifndef __RSKSWASNTYPES_H__
#define __RSKSWASNTYPES_H__

#include "RSKSW_bin.h"
#include "RSKSW_bigint.h"

#ifdef __ANDROID__
#include "../cmvp/include/ks_der.h"
#else
#include "ks_der.h"
#endif
#include <time.h>

//#define ASN1_MASK_TAG_NUMBER			0x1F
//#define ASN1_MASK_CONSTRUCTED			0x20
//
//#define	KSW_ASN1_ENCODE_START(buf, pos, eval)			\
//{													\
//    (pos) = 0;										\
//    (buf) = (KSW_BYTE *) (eval);						\
//}
//
//#define	KSW_ASN1_DECODE_START(buf, pos, eval)			\
//{													\
//    (pos) = 0;										\
//    (buf) = (KSW_BYTE *) (eval);						\
//}
//
//#define	KSW_ASN1_TYPE_ENCODE(buf, pos, tag)				\
//{													\
//    (buf)[(pos)++] = (tag);							\
//}
//
//#define	KSW_ASN1_TYPE_DECODE(buf, pos, tag)				\
//{													\
//    (tag) = (buf)[(pos)++];							\
//}
//
//#define	KSW_ASN1_VALUE_ENCODE(buf, pos, val, len)		\
//if (len > 0) {										\
//    memcpy(buf + pos, val, len);					\
//    pos += len;										\
//}
//
//#define	KSW_ASN1_VALUE_DECODE_PINTEGER(buf, pos, len, bigint)	\
//{													\
//    if ((bigint) == NULL)							\
//        (bigint) = KSW_Big_Create((len + 3) / 4);	\
//        if ((bigint) == NULL) {							\
//            errorCode = RSKSW_ERR_MALLOC_FAILED;	\
//            goto error;									\
//        }												\
//    errorCode = KSW_Big_ByteSequenceToInt((bigint), buf + pos, len);	\
//    if (errorCode != 0) goto error;					\
//    pos += len;										\
//}

int RSKSW_asn1_x509_length_decode(ks_uint8 *buf, int *pos, int *len);
#define	KSW_ASN1_LENGTH_ENCODE(buf, pos, len, len_count)	\
{													\
ks_uint8		c, i;								\
\
c = 0;											\
if ((len) >= 0x80) {							\
c += 1;										\
for (i=1; i<4; i++) 						\
if ((len) >> (i << 3)) c++;				\
(buf)[(pos)++] = 0x80 ^ c;					\
for (i=0; i<c; i++)							\
(buf)[(pos)++] = ((len) >> ((c-i-1) << 3));	\
}												\
else											\
(buf)[(pos)++] = (len);						\
len_count = c + 1;								\
}

//int	asn1_length_encode(ks_uint8 *buf, int *pos, int len);

//	in/out	: buf, pos
//	out		: len, len_count
//

#define	KSW_ASN1_LENGTH_DECODE(buf, pos, len, len_count)	\
{													\
ks_uint8		c, i;								\
\
c = 0;											\
if ((buf)[(pos)] & 0x80) {						\
c = (buf)[(pos)++] & 0x7F;					\
(len) = 0;									\
for (i=0; i<c; i++)							\
(len) = (len) * 256 + (buf)[(pos)++];	\
}												\
else											\
(len) = (buf)[(pos)++] & 0x7F;				\
len_count = c + 1;								\
}
//
//#define	KSW_ASN1_LENGTH_CHECK(pos, len, total)			\
//if ((pos + len) > total) {							\
//    errorCode = RSKSW_ERR_ASN1_BAD_LENGTH;			\
//    goto error;										\
//}
//
//#define	KSW_ASN1_TYPE_CHECK(buf, pos, tag)				\
//if ((buf)[(pos)++] != (tag)) {						\
//    errorCode = RSKSW_ERR_ASN1_BAD_DATA;				\
//    goto error;										\
//}


#ifdef	__cplusplus
extern "C" {
#endif

//
//	BIT_STRING
//
typedef BIN BIT_STRING;

BIT_STRING	*RSKSW_BIN_To_BIT_STRING				(BIN *bin);
void		RSKSW_BIT_STRING_Free					(BIT_STRING *bit_STRING);

//
//	INTEGER
//
typedef BIN INTEGER;

INTEGER 	*RSKSW_BIN_To_INTEGER					(BIN *bin);
void		RSKSW_INTEGER_Free 					(INTEGER *integer);

//
//	OBJECT_IDENTIFIER
//
typedef BIN OBJECT_IDENTIFIER;

OBJECT_IDENTIFIER *RSKSW_BIN_To_OBJECT_IDENTIFIER	(BIN *bin);
void		RSKSW_OBJECT_IDENTIFIER_Free			(OBJECT_IDENTIFIER *object_IDENTIFIER);

//
//	ASN_ANY
//
typedef BIN ASN_ANY;

ASN_ANY 	*RSKSW_BIN_To_ASN_ANY					(BIN *bin);
void		RSKSW_ASN_ANY_Free 					(ASN_ANY *asn_ANY);

//
//	Time
//
typedef BIN Time;

Time		*RSKSW_BIN_To_Time 					(BIN *bin);
void		RSKSW_Time_Free						(Time *time);

//
//	AlgorithmIdentifier
//
typedef struct _AlgorithmIdentifier {
	OBJECT_IDENTIFIER	*algorithm;
	ASN_ANY 			*parameters;
} AlgorithmIdentifier;

AlgorithmIdentifier *RSKSW_AlgorithmIdentifier_New ( void );
AlgorithmIdentifier *RSKSW_BIN_To_AlgorithmIdentifier(BIN *bin);
void		RSKSW_AlgorithmIdentifier_Free 		(AlgorithmIdentifier *algorithmIdentifier);



void RSKSW_time2utc(time_t t, ks_uint8 *buf, int pos);

#ifdef	__cplusplus
}
#endif

#endif
