/**************************************************
* unit:    struct            release 0.12         *
* STRUCT.H - Provides some big and little endian abstraction functions,
*	      for manipulating with structures.	
*   Copyright (C) 1999-2020  Jaroslav Fojtik
**************************************************/
#ifndef _STRUCT_H_
#define _STRUCT_H_

#include "typedfs.h"


/*
#undef LO_ENDIAN	//Signalise that system is native LowEndian
#define HI_ENDIAN	//Signalise that system is native HighEndian
#define EXPAND_OPS	//hack to speed up 
*/

#if defined(LO_ENDIAN) && defined(HI_ENDIAN)
 #error Cannot define both LO_ENDIAN and HI_ENDIAN together!
#endif

/* Ensure that prototypes are correctly declared even for C. */
#ifdef __cplusplus
extern "C" {
#endif
/* functions from struct.c */

#ifdef EXPAND_OPS
 #ifdef LO_ENDIAN
  #define RdWORD_LoEnd(num,f)		fread((num),1,2,f)
  #define RdDWORD_LoEnd(num,f)		fread((num),1,4,f)
  #define RdQWORD_LoEnd(num,f)		fread((num),1,8,f)
  #define WrWORD_LoEnd(num,f)		fwrite((&num),1,2,f)
  #define WrDWORD_LoEnd(num,f)		fwrite((&num),1,4,f)
  #define WrQWORD_LoEnd(num,f)		fwrite((&num),1,8,f)
 #endif
 #ifdef HI_ENDIAN
  #define RdWORD_HiEnd(num,f)		fread((num),1,2,f)
  #define RdDWORD_HiEnd(num,f)		fread((num),1,4,f)
/* this speedup is not working on MSB - never mind
  #define WrWORD_HiEnd(num,f)		fwrite((&num),1,2,f)
  #define WrDWORD_HiEnd(num,f)		fwrite((&num),1,4,f)
*/
 #endif
#endif

#ifndef RdWORD_LoEnd
 int RdWORD_LoEnd(WORD *num, FILE *f);
#endif
#ifndef RdDWORD_LoEnd
 int RdDWORD_LoEnd(DWORD *num, FILE *f);
#endif
#ifndef RdWORD_HiEnd
 int RdWORD_HiEnd(WORD *num, FILE *f);
#endif
#ifndef RdDWORD_HiEnd
 int RdDWORD_HiEnd(DWORD *num, FILE *f);
#endif

#ifndef WrWORD_LoEnd
 int WrWORD_LoEnd(WORD num, FILE *f);
#endif
#ifndef WrWORD_HiEnd
 int WrWORD_HiEnd(WORD num, FILE *f); 
#endif
#ifndef WrDWORD_LoEnd
 int WrDWORD_LoEnd(DWORD num, FILE *f);
#endif
#ifndef WrDWORD_HiEnd
 int WrDWORD_HiEnd(DWORD num, FILE *f);
#endif

#if defined(__u64_defined)
 #ifndef RdQORD_HiEnd
  int RdQWORD_HiEnd(QWORD *num, FILE *f);
 #endif
 #ifndef RdQWORD_LoEnd
  int RdQWORD_LoEnd(QWORD *num, FILE *f);
 #endif
 #ifndef WrDWORD_LoEnd
  int WrQWORD_LoEnd(QWORD num, FILE *f);
 #endif
 #ifndef WrDWORD_HiEnd
  int WrQWORD_HiEnd(QWORD num, FILE *f);
 #endif
#endif

WORD fil_sreadU16(const BYTE *in);
DWORD fil_sreadU32(const BYTE *in);

int loadstruct(FILE *F,const char *description, ...);
int savestruct(FILE *F,const char *description, ...);

#ifdef __cplusplus
}
#endif


#endif