/*
 * Softcam plugin to VDR (C++)
 *
 * This code 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 code 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.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>
#include <vdr/tools.h>
//bveb: This lines no longer needed
/*
#include <vdr/thread.h>
*/
#include "common.h"
#include "misc.h"
#include "..\\main.h"
/*
#define DEV_DVB_ADAPTER "/dev/dvb/adapter"
#define PATH_MAX        512
*/

// -----------------------------------------------------------------------------
/*
static const char *DvbName(const char *Name, int n)
{
  static char buffer[PATH_MAX];
  snprintf(buffer, sizeof(buffer), "%s%d/%s%d", DEV_DVB_ADAPTER, n, Name, 0);
  return buffer;
}

int DvbOpen(const char *Name, int n, int Mode, bool ReportError)
{
  const char *FileName=DvbName(Name,n);
  int fd=open(FileName,Mode);
  if(fd<0 && ReportError) LOG_ERROR_STR(FileName);
  return fd;
}

#define PER_LINE 16

void LogDump(const unsigned char *buffer, int n, const char *format, ...)
{
#ifdef LOG_DUMP
  static cMutex logMutex;
  static FILE *f=0;

  time_t t=time(0);
  logMutex.Lock();
  if(!f) f=fopen(LOG_DUMP,"a");
  if(f) {
    struct tm *tm=localtime(&t);
    char timestr[32];
    strftime(timestr,sizeof(timestr),"%b %d %T",tm);
    fprintf(f,"%s (size=%d/0x%04x) ",timestr,n,n);
    va_list ap;
    va_start(ap,format);
    vfprintf(f,format,ap);
    va_end(ap);
    fprintf(f,"\n");
    for(int i=0 ; i<n ;) {
      fprintf(f,"%04x:",i);
      for(int l=0 ; l<PER_LINE && i<n ; l++) fprintf(f," %02x",buffer[i++]);
      fprintf(f,"\n");
      }
    fflush(f);
    }
  logMutex.Unlock();
#endif
}

void HexDump(const unsigned char *buffer, int n)
{
#ifdef DEBUG
  printf("dump: n=%d/0x%04x\n",n,n);
  for(int i=0 ; i<n ; i+=8) {
    printf("%04x: ",i);
    for(int l=0 ; l<8 && i+l<n ; l++) printf("%02x ",buffer[i+l]);
    printf("\n");
    }
#endif
}

#ifdef DEBUG
static cMutex filelog;
#endif

FILE *LogStart(const char *name)
{
  FILE *f=0;
#ifdef DEBUG
#ifdef DEBUG_LOG_FILE
  if(!name) name=DEBUG_LOG_FILE;
#endif

  if(name) {
    filelog.Lock();
    f=fopen(name,"a");
    if(f) {
      time_t t=time(0);
      char *tt=strdup(ctime(&t));
      int l=strlen(tt);
      if(l) tt[l-1]=0;
      fprintf(f,"%s: ",tt);
      free(tt);
      }
    else filelog.Unlock();
    }
#endif
  return(f);
}

void LogEnd(FILE *f)
{
#ifdef DEBUG
  fflush(f); fclose(f);
  filelog.Unlock();
#endif
}
*/
const char *HexStr(char *str, const unsigned char *mem, int len)
{
  for(int i=0 ; i<len ; i++) sprintf(&str[i*2],"%02X",mem[i]);
  return str;
}
const char *HexStrSpaced(char *str, const unsigned char *mem, int len)
{
  for(int i=0 ; i<len ; i++) sprintf(&str[i*3],"%02X ",mem[i]);
  return str;
}
static int HexDigit(int asc)
{
  if(asc>='A') return toupper(asc)-'A'+10;
  return asc-'0';
}

int GetChar(char * &line, int *store, int count)
{
  line=skipspace(line);
  char *sline=line;
  *store=0;
  while(count) {
    if(line[0]==0 || !isalnum(line[0])) break;
    *store<<=8; *store+=line[0];
    line++; count--;
    }
  if(!count && (!*line || isspace(*line) || *line==';')) return sline-line;
  *store=0;
  line=sline;
  return 0;
}

static int GetHexBase(char * &line, unsigned char *store, int count, bool fixedLen, bool asc)
{
  line=skipspace(line);
  char *sline=line;
  unsigned char *sstore=store;
  int scount=count;
  while(count) {
    if(line[0]==0 || line[1]==0 || !isxdigit(line[0]) || !isxdigit(line[1])) break;
    if(asc) {
       *store++=line[0]; *store++=line[1];
       }
    else {
      int d1=HexDigit(line[0]);
      int d0=HexDigit(line[1]);
      *store++=(d1<<4) + d0;
      }
    line+=2; count--;
    }
  if(asc) *store=0; // make sure strings are NULL terminated
  if((!count || (!fixedLen && count!=scount)) &&
     (!*line || isspace(*line) || *line==';') ) return scount-count;
  memset(sstore,0,scount);
  line=sline;
  return 0;
}

int GetHex(char * &line, unsigned char *store, int count, bool fixedLen)
{
  return GetHexBase(line,store,count,fixedLen,false);
}

int GetHexAsc(char * &line, unsigned char *store, int count)
{
  return GetHexBase(line,store,count/2,true,true)*2;
}

unsigned long long Bin2LongLong(unsigned char *mem, int len)
{
  unsigned long long k=0;
  for(int i=0 ; i<len ; i++) { k<<=8; k+=mem[i]; }
  return k;
}
