#ifndef XK_EMV_H /***********************************************************************************************/
#define XK_EMV_H

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************************************************/

struct xk_emv_decoder {
  // Current state
  const unsigned char *ve_data;		// Points to data inside the tagged block
  unsigned short ve_data_length;	// Number of bytes inside data
  unsigned short ve_tag_length;		// Size of tag in bytes (1..4)
  unsigned short ve_tag;		// Tag code
  unsigned short ve_is_nested;		// Tagged block contains nested tagged data
  const unsigned char *ve_block;	// Points to first byte of tagged block
  unsigned short ve_block_length;	// Total length of tagged block, including tag and length bytes

  // Data buffer
  const unsigned char *ve_start;
  const unsigned char *ve_walk;
  const unsigned char *ve_end;
};

// Initialization
void xk_emv_init(struct xk_emv_decoder *ve, const void *data, unsigned int length);
void xk_emv_reset(struct xk_emv_decoder *ve);

// For parsing a tag list, e.g. the PDOL
int xk_emv_next_tag_length(struct xk_emv_decoder *ve);

  // For parsing a tag len data structure
int xk_emv_next_tag_length_data(struct xk_emv_decoder *ve);

// Find a specific tag. On success, the current state part of the structure is filled in.
// Further invocations of find with the same tag number will find further instances
// of the tag until the last instance is found.
// A deep search will descend into any nested tag and search there, too.
int xk_emv_find(struct xk_emv_decoder *ve, unsigned int wanted_tag);
int xk_emv_deep_find(struct xk_emv_decoder *ve, unsigned int wanted_tag);

// Description of a tag
const char *xk_emv_tag_name(unsigned int tag);

/****************************************************************************************************************/

#ifdef __cplusplus
}
#endif

#endif
