/* --- 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() --- */
/* --- 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); }
/* 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 //} }
/* 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); }
/* --- 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; } }