Exemple #1
0
/* --- entry point --- */
chardef	*getnextchar ( FILE *fp )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
chardef	*new_chardef(), *nextchar=(chardef *)NULL; /*ptr returned to caller*/
int	delete_chardef();		/* free allocated memory if error */
int	findnextchar(), charnum,location; /* get header line for next char */
int	rasterizechar();		/* ascii image --> raster pixmap */
int	parsestat=(-999), parsecorner(); /* get col,row from ".<--" line */
char	*readaline();			/* read next line from fp */
/* --------------------------------------------------------------------------
initialization
-------------------------------------------------------------------------- */
while ( parsestat == (-999) ) {		/* flush entirely blank characters */
  /* --- find and interpret header line for next character --- */
  charnum = findnextchar(fp,&location);	/* read and parse header line */
  if ( charnum < 0 ) goto error;	/* eof or error, no more chars */
  /* --- allocate a new chardef struct and begin populating it --- */
  if ( nextchar == (chardef *)NULL )	/* haven't allocated chardef yet */
    if ( (nextchar=new_chardef())	/* allocate a new chardef */
    ==   (chardef *)NULL ) goto error;	/* and quit if we failed */
  nextchar->charnum = charnum;		/* store charnum in struct */
  nextchar->location = location;	/* and location */
  /* --- get upper-left corner line --- */
  parsestat = parsecorner(readaline(fp), /* parse corner line */
    &(nextchar->toprow),&(nextchar->topleftcol)); /* row and col from line */
  } /* --- end-of-while(parsestat)  --- */
if ( !parsestat ) goto error;		/* quit if parsecorner() failed */
/* --------------------------------------------------------------------------
interpret character image (and parse terminating corner line)
-------------------------------------------------------------------------- */
/* --- read ascii character image and interpret as integer bitmap --- */
if ( rasterizechar(fp,&nextchar->image) != 1 ) /* parse image of char */
  goto error;				/* and quit if failed */
/* --- get lower-left corner line --- */
if ( !parsecorner(readaline(NULL),	/* reread and parse corner line */
&(nextchar->botrow),&(nextchar->botleftcol)) ) /* row and col from line */
  goto error;				/* and quit if failed */
/* --------------------------------------------------------------------------
done
-------------------------------------------------------------------------- */
goto end_of_job;			/* skip error return if successful */
error:
  if ( nextchar != (chardef *)NULL )	/* have an allocated chardef */
    delete_chardef(nextchar);		/* so deallocate it */
  nextchar = (chardef *)NULL;		/* and reset ptr to null for error */
end_of_job:
  return ( nextchar );			/* back with chardef or null */
} /* --- end-of-function getnextchar() --- */
Exemple #2
0
/* --- entry point --- */
int	findnextchar ( FILE *fp, int *location )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
static	char keyword[99]="beginning of char "; /*signals start of next char*/
char	*readaline(), *line;	/* read next line from fp */
char	*strstr(), *strchr(), *delim; /* search line for substring, char */
char	token[99];		/* token extracted from line */
int	charnum = (-1);		/* character number returned to caller */
/* --------------------------------------------------------------------------
keep reading lines until eof or keyword found
-------------------------------------------------------------------------- */
while ( (line=readaline(fp)) != NULL ) /* read lines until eof */
  {
  if ( msglevel >= 999 )	/* very, very verbose output requested */
    fprintf(msgfp,"nextchar> line = %s\n",line);
  if ( (delim=strstr(line,keyword)) != NULL ) /* found keyword on line */
    {
    /* --- get character number from line --- */
    strcpy(token,delim+strlen(keyword)); /* char num follows keyword */
    charnum = atoi(token);	/* interpret token as integer charnum */
    /* --- get location at beginning of line --- */
    if ( location != (int *)NULL )  /* caller wants location returned */
      if ( (delim=strchr(line,':')) != NULL ) /* location precedes colon */
	{ *delim = '\000';	/* terminate line after location */
	  *location = atoi(line); } /* interpret location as integer */
    break;			/* back to caller with charnum */
    } /* --- end-of-if(delim!=NULL) --- */
  } /* --- end-of-while(line!=NULL) --- */
return ( charnum );		/* back to caller with char number or -1 */
} /* --- end-of-function findnextchar() --- */
/* program entry point
 */
int main(int argc, char **argv) {
        unsigned int  nlines, nwords, wordcount;
        unsigned long totalcharacters;

        nlines = 0;
	nwords = 0;
	totalcharacters = 0;
        showargs(argc, argv);
        while (readaline() != 0) {
                wordcount = makeintowords(buffer);
                nwords += wordcount;
                totalcharacters += analyzewords(buffer);
                nlines++;
        }
        printstatistics(nlines, nwords, totalcharacters);
        return(0);
}
Exemple #4
0
/*
After a connection, handle the messages.
*/
void handle(int sock){
	//printf("Im handle.\n");
	//return 0;

	int n;
	char msgR[1000];
	char msgS[1000];

	n = readaline(sock, msgR, 1000);
	

	if (strcmp(msgR, "JOIN") == 0){
		printf("====Handle: Got JOIN====\n");

		node node_new;
		n = readaline(sock, msgR, 1000);
		printf("Got JOIN:%s\n", msgR);
		(&node_new)->id = stringToLong(msgR);

		n = readaline(sock, msgR, 1000);
		printf("Got JOIN:%s\n", msgR);
		strcpy((&node_new)->ip, msgR);

		n = readaline(sock, msgR, 1000);
		printf("Got JOIN:%s\n", msgR);
		(&node_new)->port = atoi(msgR);

		node *pre_toJoin = malloc(sizeof(node));
		node *suc_toJoin = malloc(sizeof(node));
		int result = joinIn(node_new, pre_toJoin, suc_toJoin);

		if (result == 1 || result == 2){
			sendto(sock, "JOIN_SUCC\n", 10, 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("=====Handle: JOIN_SUCC=====\n");

			sprintf(msgS, "%ld", pre_toJoin->id);
			strcat(msgS, "\n");
			sendto(sock, msgS, strlen(msgS), 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("handle.JOIN_SUCC.predecessor's id:%s\n", msgS);
			strcpy(msgS, pre_toJoin->ip);
			strcat(msgS, "\n");
			sendto(sock, msgS, strlen(msgS), 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("handle.JOIN_SUCC.predecessor's ip:%s\n", msgS);
			sprintf(msgS, "%d", pre_toJoin->port);
			strcat(msgS, "\n");
			sendto(sock, msgS, strlen(msgS), 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("handle.JOIN_SUCC.predecessor's port:%s\n", msgS);

			sprintf(msgS, "%ld", suc_toJoin->id);
			strcat(msgS, "\n");
			sendto(sock, msgS, strlen(msgS), 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("handle.JOIN_SUCC.successor's id:%s\n", msgS);
			strcpy(msgS, suc_toJoin->ip);
			strcat(msgS, "\n");
			sendto(sock, msgS, strlen(msgS), 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("handle.JOIN_SUCC.successor's ip:%s\n", msgS);
			sprintf(msgS, "%d", suc_toJoin->port);
			strcat(msgS, "\n");
			sendto(sock, msgS, strlen(msgS), 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			printf("handle.JOIN_SUCC.successor's port:%s\n", msgS);

			if (result == 2){
				node nodes_info[1];
				nodes_info[0] = node_new;
				int number_node = 1;
				sendNtoN(nodes_info, number_node, "PRE",
						*suc_toJoin);
			}
		} 
		else{
			sendto(sock, "JOIN_WAIT\n", 10, 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));
			node nodes_info[1];
			nodes_info[0] = node_new;
			int number_node = 1;
			sendNtoN(nodes_info, number_node, "JOIN_FD", *successor0);
		}
	} 
	else if (strcmp(msgR, "JOIN_FD") == 0){
		printf("=====Handle: Got JOIN_FD=====\n");
		node node_new;
		n = readaline(sock, msgR, 1000);
		(&node_new)->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy((&node_new)->ip, msgR);
		n = readaline(sock, msgR, 1000);
		(&node_new)->port = atoi(msgR);
		node *pre_toJoin = malloc(sizeof(node));
		node *suc_toJoin = malloc(sizeof(node));
		int result = joinIn(node_new, pre_toJoin, suc_toJoin);

		if (result == 1 || result == 2){
			node nodes_info[2];
			nodes_info[0] = *pre_toJoin;
			nodes_info[1] = *suc_toJoin;
			int number_node = 2;
			sendNtoN(nodes_info, number_node, "JOIN_SUCC", node_new);

			if (result == 2){
				node nodes_info[1];
				nodes_info[0] = node_new;
				int number_node = 1;
				sendNtoN(nodes_info, number_node, "PRE",
						*suc_toJoin);
			}
		} 
		else{
			sendto(sock, "JOIN_WAIT\n", 10, 0,
					(struct sockaddr *) &client_addr, sizeof(client_addr));

			node nodes_info[1];
			nodes_info[0] = node_new;
			int number_node = 1;
			sendNtoN(nodes_info, number_node, "JOIN_FD", *successor0);
		}
	} 
	else if (strcmp(msgR, "JOIN_SUCC") == 0){
		printf("====Handle: Got %s=====\n", msgR);

		n = readaline(sock, msgR, 1000);
		predecessor0->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(predecessor0->ip, msgR);
		n = readaline(sock, msgR, 1000);
		predecessor0->port = atoi(msgR);
		n = readaline(sock, msgR, 1000);
		successor0->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(successor0->ip, msgR);
		n = readaline(sock, msgR, 1000);
		successor0->port = atoi(msgR);
		initFTable();

		/*
		 printf("predecessor0:\n");
		 printNode(*predecessor0);
		 printf("successor0:\n");
		 printNode(*successor0);
		 */
		//updateFTable();
		node node_new[2];
		node_new[0] = *current;
		node_new[1].id = 0;
		sendNtoN(node_new, 2, "UPDATE", *successor0);

	} 
	else if (strcmp(msgR, "PRE") == 0){
		printf("====Handle: Got %s=====\n", msgR);

		n = readaline(sock, msgR, 1000);
		predecessor0->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(predecessor0->ip, msgR);
		n = readaline(sock, msgR, 1000);
		predecessor0->port = atoi(msgR);
		/*
		 printf("predecessor0:\n");
		 printNode(*predecessor0);
		 printf("successor0:\n");
		 printNode(*successor0);
		 */
	} 
	else if (strcmp(msgR, "SUCC") == 0){
		printf("====Handle: Got %s=====\n", msgR);

		n = readaline(sock, msgR, 1000);
		successor0->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(successor0->ip, msgR);
		n = readaline(sock, msgR, 1000);
		successor0->port = atoi(msgR);
		/*
		 printf("predecessor0:\n");
		 printNode(*predecessor0);
		 printf("successor0:\n");
		 printNode(*successor0);
		 */
	} 
	else if (strcmp(msgR, "UPDATE") == 0){
		printf("====Handle: Got %s=====\n", msgR);

		node node_new;
		n = readaline(sock, msgR, 1000);
		node_new.id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(node_new.ip, msgR);
		n = readaline(sock, msgR, 1000);
		node_new.port = atoi(msgR);
		

		int power;
		n = readaline(sock, msgR, 1000);
		power = atoi(msgR);
		n = readaline(sock, msgR, 1000);
		n = readaline(sock, msgR, 1000);
		if (node_new.id != current->id){
			updateFTable(node_new.id, -1, 1);
			if (power < FINGERTABLE_SIZE ){
				int i;
				int j = 0;
				char results[FINGERTABLE_SIZE * 2][1000];
				for (i = power; i <= FINGERTABLE_SIZE - 1; i++){

					long bound = 0;
					if (node_new.id + (long) pow(2, i) >= KEY_SIZE ){
						bound = node_new.id + (long) pow(2, i) - KEY_SIZE;
					} 
					else{
						bound = node_new.id + (long) pow(2, i);
					}

					if (current->id >= bound){
						sprintf(results[j++], "%ld", bound);
						sprintf(results[j++], "%ld", current->id);
					} 
					else if(successor0->id > current->id && current->id < predecessor0->id
							&& predecessor0->id >= successor0->id && bound > current->id){
						sprintf(results[j++], "%ld", bound);
						sprintf(results[j++], "%ld", current->id);
					} 
					else{
						break;
					}
				}
				power = i;
				if (j > 0)
					sendStoN("FTABLE_UPDATE", results, j, node_new);
			}
			node nodes_new[2];
			nodes_new[0] = node_new;
			nodes_new[1].id = power;
			sendNtoN(nodes_new, 2, "UPDATE", *successor0);
		}
	} 
	else if (strcmp(msgR, "FTABLE_UPDATE") == 0){
		printf("====Handle: Got %s=====\n", msgR);
		int size;
		n = readaline(sock, msgR, 1000);
		size = atoi(msgR);
		
		int i;
		long start;
		long nodeId;
		for (i = 0; i <= size - 1; i += 2){

			n = readaline(sock, msgR, 1000);
			start = stringToLong(msgR);
			n = readaline(sock, msgR, 1000);
			nodeId = stringToLong(msgR);
			insertFTable(start, nodeId);
		}
	} 
	else if (strcmp(msgR, "LEAVE_PRE") == 0){
		printf("====Handle: Got %s=====\n", msgR);

		n = readaline(sock, msgR, 1000);
		predecessor0->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(predecessor0->ip, msgR);
		n = readaline(sock, msgR, 1000);
		predecessor0->port = stringToLong(msgR);
		/*
		 printf("predecessor0:\n");
		 printNode(*predecessor0);
		 printf("successor0:\n");
		 printNode(*successor0);
		 */
	} 
	else if (strcmp(msgR, "LEAVE_SUC") == 0){
		printf("====Handle: Got %s=====\n", msgR);
		n = readaline(sock, msgR, 1000);
		successor0->id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(successor0->ip, msgR);
		n = readaline(sock, msgR, 1000);
		successor0->port = atoi(msgR);
		/*
		 printf("predecessor0:\n");
		 printNode(*predecessor0);
		 printf("successor0:\n");
		 printNode(*successor0);
		 */
	} 
	else if (strcmp(msgR, "UPDATE_LEAVE") == 0){
		printf("====Handle: Got %s=====\n", msgR);
		node node_leave;
		n = readaline(sock, msgR, 1000);
		node_leave.id = stringToLong(msgR);		
		n = readaline(sock, msgR, 1000);
		strcpy(node_leave.ip, msgR);		
		n = readaline(sock, msgR, 1000);
		node_leave.port = atoi(msgR);		
		node node_suc;
		n = readaline(sock, msgR, 1000);
		node_suc.id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(node_suc.ip, msgR);	
		n = readaline(sock, msgR, 1000);
		node_suc.port = atoi(msgR);	
		if (node_leave.id != current->id){
			updateFTable(node_leave.id, node_suc.id, 0);
			node nodes_new[2];
			nodes_new[0] = node_leave;
			nodes_new[1] = node_suc;
			sendNtoN(nodes_new, 2, "UPDATE_LEAVE", *successor0);
		} else{
			*quitUpdate = 1;
		}
	} 
	//Search part
	else if (strcmp(msgR, "LOOKUP") == 0){
		printf("=====Handle: Get LOOKUP Message=====\n");

		long key;
		node node_source;
		n = readaline(sock, msgR, 1000);
		printf("handle: lookup message:%s\n", msgR);
		key = stringToLong(msgR);

		n = readaline(sock, msgR, 1000);
		printf("handle: lookup message:%s\n", msgR);
		n = readaline(sock, msgR, 1000);
		printf("handle: lookup message:%s\n", msgR);
		n = readaline(sock, msgR, 1000);
		node_source.id = stringToLong(msgR);
		printf("handle: lookup message:%s\n", msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(node_source.ip, msgR);
		printf("handle: lookup message:%s\n", msgR);
		n = readaline(sock, msgR, 1000);
		node_source.port = atoi(msgR);
		printf("handle: lookup message:%s\n", msgR);
		if (node_source.id == current->id){
			printf("Key not found\n");
		} 
		else{
			node result;
			result = lookup(key, node_source);
			if (result.id != -1){
				printf("The key belongs to the node:\n");
				printNode(*current);
				printf("Not found.\n");
				node node_found[1];
				node_found[0] = *current;
				sendNtoN(node_found, 1, "FOUND", node_source);
			}
		}
	}
	//Receive a "FOUND" message, print the message out  
	else if (strcmp(msgR, "FOUND") == 0){
		printf("handle: Got FOUND: %s\n", msgR);
		node node_found;
		n = readaline(sock, msgR, 1000);
		node_found.id = stringToLong(msgR);
		n = readaline(sock, msgR, 1000);
		strcpy(node_found.ip, msgR);
		n = readaline(sock, msgR, 1000);
		node_found.port = atoi(msgR);
		printf("Key found on node:\n");
		printNode(node_found);
	} 
	//else if (strcmp(msgR, "IS_ALIVE") == 0){
		//printf("====Handle: Got %s=====\n", msgR);
		//send back a confirm message
	//}
}
Exemple #5
0
/*
In main function: Join in a ring
*/
void join(char** argv){
	// struct sockaddr_in {
	// 	short int sin_family; /* 通信类型 */
	// 	unsigned short int sin_port; /* 端口 */
	// 	struct in_addr sin_addr; /* Internet 地址 */
	// 	unsigned char sin_zero[8]; /* 与sockaddr结构的长度相同*/
	// };
	struct sockaddr_in serveraddr, clientaddr;
	int serversock;
	int n;
	char sendline[1000];
	char recvline[1000];

	//init parameters
	serversock = socket(AF_INET, SOCK_STREAM, 0);
	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	
	if (inet_addr(argv[2]) != -1){
		printf("Join: server ip is: %s\n", argv[2]);
		serveraddr.sin_addr.s_addr = inet_addr(argv[2]);
	}
	else{
		printf("Join error: server address error");
	}

	printf("Join: server port is: %s\n", argv[3]);
	serveraddr.sin_port = htons(atoi(argv[3]));

	//connect to server
	printf("Join: connect to the server...\n");
	n = connect(serversock, (struct sockaddr *) &serveraddr, sizeof(serveraddr));
	if (n == 0){
		printf("Join: connceted!\n");
	}
	else{
		printf("error:%s\n",strerror(errno));
		perror("Join: connect failed.\n");
	}
	

	strcpy(sendline, "JOIN");
	strcat(sendline, "\n");
	sendto(serversock, sendline, strlen(sendline), 0,
			(struct sockaddr *) &serveraddr, sizeof(serveraddr));
	printf("Join: send join message:%s\n", sendline);

	sprintf(sendline, "%ld", current->id);
	strcat(sendline, "\n");
	sendto(serversock, sendline, strlen(sendline), 0,
			(struct sockaddr *) &serveraddr, sizeof(serveraddr));
	printf("Join: send my id:%s\n", sendline);

	strcpy(sendline, current->ip);
	strcat(sendline, "\n");
	sendto(serversock, sendline, strlen(sendline), 0,
			(struct sockaddr *) &serveraddr, sizeof(serveraddr));
	printf("Join: send my ip:%s\n", sendline);

	sprintf(sendline, "%d", current->port);
	strcat(sendline, "\n");
	sendto(serversock, sendline, strlen(sendline), 0,
			(struct sockaddr *) &serveraddr, sizeof(serveraddr));
	printf("Join: send my port:%s\n", sendline);


	n = readaline(serversock, recvline, 1000);
	//printf("recv:%s\n", recvline);

	if (strcmp(recvline, "JOIN_SUCC") == 0){
		printf("JOIN_SUCC: begin to read receive message\n");
		n = readaline(serversock, recvline, 1000);
		predecessor0->id = stringToLong(recvline);
		printf("Join: receive predecessor id:%s\n", recvline);

		n = readaline(serversock, recvline, 1000);
		strcpy(predecessor0->ip, recvline);
		printf("Join: receive predecessor ip:%s\n", recvline);

		n = readaline(serversock, recvline, 1000);
		predecessor0->port = atoi(recvline);
		printf("Join: receive predecessor port:%s\n", recvline);

		n = readaline(serversock, recvline, 1000);
		successor0->id = stringToLong(recvline);
		printf("Join: receive successor id:%s\n", recvline);

		n = readaline(serversock, recvline, 1000);
		strcpy(successor0->ip, recvline);
		printf("Join: receive successor ip:%s\n", recvline);

		n = readaline(serversock, recvline, 1000);
		successor0->port = atoi(recvline);
		printf("Join: receive successor port:%s\n", recvline);

		initFTable();
		printf("Join: init fingertable finished.\n");
		printNode(* current);
		printNode(* predecessor0);
		printNode(* successor0);
		
		node newN[2];
		newN[0] = *current;
		newN[1].id = 0;
		printf("Send UPDATE info to successor.\n");
		sendNtoN(newN, 2, "UPDATE", *successor0);

	}
	close(serversock);

}
Exemple #6
0
/* --- entry point --- */
int	rasterizechar ( FILE *fp, raster *image )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
char	*readaline(), *line;	/* read next scan line for char from fp */
unsigned char bitvec[1024][128]; /* scan lines parsed up to 1024x1024 bits */
int	bitcmp();		/* compare bit strings */
int	height = 0,		/* #scan lines in fp comprising char */
	width = 0;		/* #chars on longest scan line */
int	iscan,			/* bitvec[] index */
	ibit;			/* bit along scan (i.e., 0...width-1) */
int	isokay = 0;		/* returned status, init for failure */
/* --- bitmap and .gf-formatted image info (we'll choose smallest) --- */
int	iformat = gformat;	/*0=best, 1=bitmap, 2=8-bit.gf, 3=4-bit.gf*/
unsigned char gfpixcount[2][65536]; /* .gf black/white flips (max=64K) */
int	npixcounts[2] = {9999999,9999999}; /* #counts for 8-bit,4-bit .gf */
int	nbytes1=9999999,nbytes2=9999999,nbytes3=9999999;/*#bytes for format*/
/* --------------------------------------------------------------------------
read lines till ".<--" terminator, and construct one vector[] int per line
-------------------------------------------------------------------------- */
memset(bitvec,0,128*1024);	/* zero-fill bitvec[] */
while ( (line=readaline(fp)) != NULL ) /* read lines until eof */
  {
  /* --- allocations and declarations --- */
  int	icol, ncols=strlen(line); /* line[] column index, #cols in line[] */
  /* --- check for end-of-char (when we encounter corner line) --- */
  if ( memcmp(line,CORNER_STUB,strlen(CORNER_STUB)) == 0 ) /* corner line */
    break;			/* so done with loop */
  /* --- parse line (encode asterisks comprising character image) --- */
  memset(bitvec[height],0,128);	/* first zero out all bits */
  for ( icol=0; icol<ncols; icol++ ) /* now check line[] for asterisks */
    if ( line[icol] == '*' )	/* we want to set this bit */
      {	setlongbit(bitvec[height],icol); /* set bit */
	if ( icol >= width ) width=icol+1; } /* and check for new width */
  height++;			/* bump character height */
  } /* --- end-of-while(line!=NULL) --- */
if ( height<1 || width<1 )	/* some problem parsing character */
  goto end_of_job;		/* so quit */
/* --------------------------------------------------------------------------
init image values
-------------------------------------------------------------------------- */
if ( image->pixmap != NULL )	/* hmm, somebody already allocated memory */
  free((void *)image->pixmap);	/* so just free it */
image->width = width;		/* set image width within raster struct */
image->height = height;		/* and height */
image->format = gformat;	/* set format (will be reset below) */
image->pixsz = 1;		/* #bits per pixel (or #counts in .gf fmt) */
if ( gformat==0 || gformat==1 )	/* bitmap representation allowed */
  { nbytes1 = pixmapsz(image);	/* #bytes needed for bitmap */
    iformat = 1; }		/* default to bitmap format */
/* --------------------------------------------------------------------------
perform .gf-like compression on image in bitvec
-------------------------------------------------------------------------- */
if ( gformat == 0		/* choose optimal/smallest respresentation */
||   gformat==2 || gformat==3 )	/* .gf-like compressed representation */
 {
 /* --- try both 8-bits/count and 4-bits/count for best compression --- */
 int	maxbitcount[2] = {254,14}; /* don't count too much in one byte */
 int	repeatcmds[2]  = {255,15}; /* opcode for repeat/duplicate count */
 int	minbytes = 0;		/* #bytes needed for smallest format */
 for ( iformat=2; iformat<=3; iformat++ ) { /* 2=8-bit packing, 3=4-bit */
  int	gfbitcount = 0,		/* count of consecutive gfbitval's */
	gfbitval = 0,		/* begin with count of leading 0's */
	pixcount = 0;		/* #packed bytes (#black/white flips) */
  unsigned char *gfcount = gfpixcount[iformat-2]; /*counts for this format*/
  if ( gformat!=0 && gformat!=iformat ) /* this format not allowed */
    continue;			/* so just skip it */
  for ( iscan=0; iscan<height; iscan++ ) /* for each integer in bitvec[] */
   {
   int	bitval = 0;		/* current actual pixel value */
   int	nrepeats=0, nextreps=0;	/* #duplicate lines below current,next line*/
   /* --- check for repeated/duplicate scan lines --- */
   if ( isrepeat		/* we're storing scan line repeat counts */
   &&   iscan < height-1 ) {	/* current scan line isn't the last line */
    /* --- count repeats --- */
    int jscan = iscan;		/* compare current scan with lines below it*/
    while ( ++jscan < height ) { /* until last scan line */
     if (nrepeats == jscan-iscan-1) /*no intervening non-identical lines*/
      if ( bitcmp(bitvec[iscan],bitvec[jscan],width) == 0 ) /* identical */
       nrepeats++;		/* so bump repeat count */
     if ( jscan > iscan+1 )	/* we're below next line */
      if (nextreps == jscan-iscan-2) /*no intervening non-identical lines*/
       if ( bitcmp(bitvec[iscan+1],bitvec[jscan],width) == 0 )/*identical*/
	nextreps++; }		/* so bump next lline repeat count */
    /* --- set repeat command and count --- */
    if ( nrepeats > 0 ) {	/* found repeated lines below current */
     int maxrepeats = maxbitcount[iformat-2]; /*max count/repeats per byte*/
     if ( nrepeats > maxrepeats ) nrepeats=maxrepeats; /* don't exceed max */
     {setbyfmt(iformat,gfcount,pixcount,repeatcmds[iformat-2]);} /*set cmd*/
     {setbyfmt(iformat,gfcount,pixcount+1,nrepeats);} /* set #repeats */
     pixcount += 2; }		/* don't bump pixcount within macros */
    } /* --- end-of-if(isrepeat) --- */
   /* --- set bit counts for current scan line --- */
   for ( ibit=0; ibit<width; ibit++ )	/* for all bits in this scanline */
    {
    bitval = getlongbit(bitvec[iscan],ibit); /* check actual pixel value */
    if ( bitval != gfbitval ) {	/* black-to-white edge (or vice versa) */
      {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
      pixcount++;		/* don't bump pixcount within macro */
      gfbitcount = 0;		/* reset consecutive bit count */
      gfbitval = 1-gfbitval; }	/* flip bit to be counted */
    else			/* check count if continuing with same val */
     if ( gfbitcount >= maxbitcount[iformat-2] ) { /* max count per byte */
      {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
      clearbyfmt(iformat,gfcount,pixcount+1); /*followed by dummy 0 count*/
      pixcount += 2;		/* don't bump pixcount within macros */
      gfbitcount = 0; }		/* reset consecutive bit count */
    if ( bitval == gfbitval )	/* same bit val as preceding, or first new */
      gfbitcount++;		/* so just count another pixel */
    } /* --- end-of-for(ibit) --- */
   /* --- adjust for repeated scan lines --- */
   iscan += nrepeats;		/* skip repeated/duplicate scan lines */
   if ( nrepeats>0 || nextreps>0 ) /* emit count to align on full scan */
    if ( iscan < height-1 )	/* have another scan line below this one */
     if ( gfbitcount > 0 ) {	/* should always have some final count */
      {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
      pixcount++;		/* don't bump pixcount within macro */
      gfbitcount = 0;		/* reset consecutive bit count */
      if ( bitval == getlongbit(bitvec[iscan+1],0) ) { /* same bit value */
       clearbyfmt(iformat,gfcount,pixcount); /*so we need a dummy 0 count*/
       pixcount++; }		/* don't bump pixcount within macros */
      else			/* bitval flips at start of next line */
       gfbitval = 1-gfbitval;	/* so flip bit to be counted */
      } /* --- end-of-if(nrepeats...gfbitcount>0) --- */
   } /* --- end-of-for(iscan) --- */
   /* --- store final count --- */
   if ( gfbitcount > 0 ) {	/* have a final count */
     {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
     pixcount++; }		/* don't bump pixcount within macro */
   else				/* ended exactly after maxbitcount? */
    if ( getbyfmt(iformat,gfcount,pixcount-1) == 0 )/*have dummy 0 trailer?*/
     pixcount--;		/* remove unneeded dummy trailer */
   /* --- save count to choose smallest --- */
   npixcounts[iformat-2] = pixcount; /* save count */
   } /* --- end-of-for(iformat) --- */
 /* --- check for optimal/smallest format --- */
 nbytes2=npixcounts[0];  nbytes3=(1+npixcounts[1])/2; /* #bytes for count */
 iformat = (nbytes2<nbytes3? 2:3); /* choose smallest format */
 minbytes = (iformat==2?nbytes2:nbytes3); /* #bytes for smallest format */
 if ( gformat == 0 )		/* bitmap representation also permitted */
  if ( nbytes1 <= minbytes )	/* and it's the optimal/smallest format */
   iformat = 1;			/* so flip format */
 /* --- move results to returned image --- */
 if ( iformat != 1 ) {		/* using a .gf format */
  if ( (image->pixmap = (unsigned char *)malloc(minbytes)) /* alloc pixmap */
  == NULL ) goto end_of_job;	/* quit if failed to allocate pixmap */
  memcpy(image->pixmap,gfpixcount[iformat-2],minbytes); /*copy local counts*/
  image->format = iformat;	/* signal byte counts or nibble counts */
  image->pixsz = npixcounts[iformat-2]; /*#counts in pixmap for gformat=2,3*/
  } /* --- end-of-if(iformat!=1) --- */
 } /* --- end-of-if(gformat==2) --- */
/* --------------------------------------------------------------------------
copy each integer in bitvec[] to raster pixmap, bit by bit
-------------------------------------------------------------------------- */
if ( iformat == 1 )		/* bit-by-bit representation of image */
 {
 int	ipixel = 0;		/* pixmap index */
 /* --- first allocate image raster pixmap for character --- */
 if ( (image->pixmap = (unsigned char *)malloc(pixmapsz(image)))
 == NULL ) goto end_of_job;	/* quit if failed to allocate pixmap */
 image->format = iformat;	/* reset format */
 /* --- now store bit image in allocated raster --- */
 for ( iscan=0; iscan<height; iscan++ )	/* for each integer in bitvec[] */
  for ( ibit=0; ibit<width; ibit++ )	/* for all bits in this scanline */
    {
    if ( getlongbit(bitvec[iscan],ibit) != 0 ) /* check current scan pixel */
      { setlongbit(image->pixmap,ipixel); }
    else				/*turn off corresponding raster bit*/
      { unsetlongbit(image->pixmap,ipixel); }
    ipixel++;				/* bump image raster pixel */
    } /* --- end-of-for(iscan,ibit) --- */
 } /* --- end-of-if(gformat==1) --- */
/* --------------------------------------------------------------------------
done
-------------------------------------------------------------------------- */
isokay = 1;				/* reset flag for success */
 end_of_job:
  return ( isokay );			/* back with 1=success, 0=failure */
} /* --- end-of-function rasterizechar() --- */
int
_assuan_read_line (assuan_context_t ctx)
{
  char *line = ctx->inbound.line;
  int nread, atticlen;
  int rc;
  char *endp = 0;

  if (ctx->inbound.eof)
    return -1;

  atticlen = ctx->inbound.attic.linelen;
  if (atticlen)
    {
      memcpy (line, ctx->inbound.attic.line, atticlen);
      ctx->inbound.attic.linelen = 0;

      endp = memchr (line, '\n', atticlen);
      if (endp)
	/* Found another line in the attic.  */
	{
	  rc = 0;
	  nread = atticlen;
	  atticlen = 0;
	}
      else
	/* There is pending data but not a full line.  */
        {
          assert (atticlen < LINELENGTH);
          rc = readaline (ctx, line + atticlen,
			 LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
        }
    }
  else
    /* No pending data.  */
    rc = readaline (ctx, line, LINELENGTH,
                   &nread, &ctx->inbound.eof);
  if (rc)
    {
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx, strerror (errno));
      return ASSUAN_Read_Error;
    }
  if (!nread)
    {
      assert (ctx->inbound.eof);
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      return -1;
    }

  ctx->inbound.attic.pending = 0;
  nread += atticlen;

  if (! endp)
    endp = memchr (line, '\n', nread);

  if (endp)
    {
      int n = endp - line + 1;
      if (n < nread)
	/* LINE contains more than one line.  We copy it to the attic
	   now as handlers are allowed to modify the passed
	   buffer.  */
	{
	  int len = nread - n;
	  memcpy (ctx->inbound.attic.line, endp + 1, len);
	  ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0;
	  ctx->inbound.attic.linelen = len;
	}

      if (endp != line && endp[-1] == '\r')
	endp --;
      *endp = 0;

      ctx->inbound.linelen = endp - line;
      if (ctx->log_fp)
	{
	  fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ",
		   assuan_get_assuan_log_prefix (),
                   (unsigned int)getpid (), (void *)ctx);
	  if (ctx->confidential)
	    fputs ("[Confidential data not shown]", ctx->log_fp);
	  else
	    _assuan_log_print_buffer (ctx->log_fp,
				      ctx->inbound.line,
				      ctx->inbound.linelen);
	  putc ('\n', ctx->log_fp);
	}
      return 0;
    }
  else
    {
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      *line = 0;
      ctx->inbound.linelen = 0;
      return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
	: ASSUAN_Line_Too_Long;
    }
}