/********************************************************************************
*                                                                               *
*                          M e m o r y   M a p   T e s t                        *
*                                                                               *
*********************************************************************************
* Copyright (C) 2004,2026 by Jeroen van der Zijp.   All Rights Reserved.        *
********************************************************************************/
#include "fx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
  Notes:

  - Test FXMappedFile capabilities.

*/

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

enum ACTION {
  TEST_NONE,
  TEST_READ,
  TEST_WRITE
  };


void printusage(){
  fprintf(stderr,"Usage: \n\n");
  fprintf(stderr,"   memmap read <length> <filename>\n\n");
  fprintf(stderr," or\n\n");
  fprintf(stderr,"   memmap write <length> <filename>\n");
  }


// Start the whole thing
int main(int argc,char** argv){
  FXString filename=FXString::null;
  ACTION action=TEST_READ;
  FXival index;
  FXival length=0;
  FXival offset=0;
  char* base;

  // What to test
  FXMappedFile map;

  // Show how to use
  if(argc<4){
    printusage();
    exit(0);
    }

  // Get action
  if(strcmp(argv[1],"read")==0){
    action=TEST_READ;
    }
  else if(strcmp(argv[1],"write")==0){
    action=TEST_WRITE;
    }
  else{
    printusage();
    exit(0);
    }

  // Get size
  if(sscanf(argv[2],"%td",&length)<1){
    printusage();
    exit(0);
    }

  // Get filename
  filename=argv[3];

  // Show process id
  fprintf(stderr,"Process id=%d\n",FXProcess::current());

  // Test reading
  if(action==TEST_READ){

    // Wait for return
    fprintf(stderr,"Press return to map:\n");
    //getchar();

    // Map
    base=(char*)map.open(filename,FXIO::Reading,FXIO::AllReadWrite,length,offset);
    if(base==nullptr){
      fprintf(stderr,"map.open returned NULL\n");
      exit(1);
      }

    fprintf(stderr,"actual length = %td\n",map.length());

    // Touch it
    for(index=0; index<map.length(); index++){
      if(base[index]!='Z') fprintf(stderr,"base[%td]=%d\n",index,base[index]);
      }

    // Wait for return
    fprintf(stderr,"Press return to unmap:\n");
    getchar();

    // Unmap
    map.close();

    // Wait for return
    fprintf(stderr,"Press return to quit:\n");
    getchar();
    }

  // Test writing
  else if(action==TEST_WRITE){

    // Wait for return
    fprintf(stderr,"Press return to map:\n");
   // getchar();

    // Map
    base=(char*)map.open(filename,FXIO::Writing,FXIO::AllReadWrite,length,offset);
    if(base==nullptr){
      fprintf(stderr,"openMap returned NULL\n");
      exit(1);
      }


    fprintf(stderr,"actual length = %td\n",map.length());
    fxmessage("base: %p\n", base);

    // Write it
    for(index=0; index<map.length(); index++){
      base[index]='Z';
      }

    // Wait for return
    fprintf(stderr,"Press return to unmap:\n");
    getchar();

    // Unmap
    map.close();

    // Wait for return
    fprintf(stderr,"Press return to quit:\n");
    getchar();
    }

  return 1;
  }

