/* Collection of code snippets by Arne Vajhøj */
/* (from articles on eksperten.dk / vajhoej.dk written sometime between 2004 and now) */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <fabdef.h>
#include <secdef.h>
#include <starlet.h>

#define PAGE_SIZE 8192
#define PAGELET_SIZE 512
#define DISKBLOCK_SIZE 512

#define BY2U(n, unit_size) (n - 1) / unit_size + 1

#include "high_res_timer.h"

#define OFFSET 0
#define SIZE 1000000000

static void test(char *fnm)
{
    struct FAB myfab;
    void *range[2];
    unsigned short chan;
    long int stat;
    char *b;
    TIMECOUNT_T t1, t2;
    int n, ix;
    t1 = GET_TIMECOUNT;
    myfab = cc$rms_fab;
    myfab.fab$l_fna = fnm;
    myfab.fab$b_fns = strlen(fnm);
    myfab.fab$l_fop = FAB$M_UFO;
    myfab.fab$b_fac = FAB$M_GET;
    stat = sys$open(&myfab, 0, 0);
    if((stat & 1) == 0)
    {
        printf("Error opening file\n");
        exit(1);
    }
    range[0] = 0;
    range[1] = 0;
    chan = myfab.fab$l_stv;
    stat = sys$crmpsc(range, range, 0, SEC$M_EXPREG, 0, 0, 0, chan, BY2U(SIZE, PAGELET_SIZE), BY2U(OFFSET, DISKBLOCK_SIZE), 0, 0);
    if((stat & 1) == 0) 
    {
        printf("Error mapping file\n");
        exit(1);
    }
    b = range[0];
    n = 0;
    for(ix = 0; ix < SIZE; ix++)
    {
        if(b[ix] == '\n')
        {
            n++;
        }
    }
    printf("%d lines\n", n);
    sys$deltva(range, 0, 0);
    sys$close(&myfab, 0, 0);
    t2 = GET_TIMECOUNT;
    printf("Map file to memory : %d ms\n", (int)((t2 - t1) * 1000 / UNITS_PER_SECOND));
}

int main(int argc, char *argv[])
{
    int i;
    for(i = 0; i < 3; i++)
    {
        test(argv[1]);
    }
    return 0;
}
