#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>

#ifdef STANDARD

// Use the normal Linux network calls
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define cs461_socket socket
#define cs461_bind bind
#define cs461_listen listen
#define cs461_accept accept
#define cs461_connect connect
#define cs461_read read
#define cs461_write write
#define cs461_close close

#endif

static int 
catchError(int returnValue, 
           int badValue, 
           char *message)
    // Just a guard routine for making system calls
{
    if (returnValue == badValue) {
        perror(message);
        exit(1);
    }
    return returnValue;
}

void
setBuffer(char *buf, int size)
{
    int i;

    for (i = 0; i < size; i++) buf[i] = i % 127;
}

void
checkBuffer(char *buf, int size)
{
    int i;

    for (i = 0; i < size; i++) {
        if (buf[i] == i % 127) continue;
        fprintf(stderr, "memory corruption error\n");
        exit(1);
    }
}

#define BUFSIZE (1024 * 32)

void
ioError(void)
{
    fprintf(stderr, "peer terminated early\n");
    exit(1);
}

void
doRecv(
    int fd)
{
    char bufmem[BUFSIZE];
    char *buf = bufmem;
    int progress;

    progress = 0;
    while (progress < BUFSIZE) {
        int retval;
       
        catchError(retval = cs461_read(fd, buf, BUFSIZE - progress), 
                   -1, "read");
        // printf("recv %d bytes\n", retval);
        if (retval == 0) ioError();
        progress += retval;
        buf += retval;
    }
    checkBuffer(bufmem, BUFSIZE);
    printf("recv success\n");    
}

void
doSend(
    int fd)
{
    char bufmem[BUFSIZE];
    char *buf = bufmem;
    int progress;

    setBuffer(bufmem, BUFSIZE);
    progress = 0;
    while (progress < BUFSIZE) {
        int retval;
       
        catchError(retval = cs461_write(fd, buf, BUFSIZE - progress),
                   -1, "write");
        // printf("send %d bytes\n", retval);
        if (retval == 0) ioError();
        progress += retval;
        buf += retval;
    }
    printf("send success\n");
}
