Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!zaphod.mps.ohio-state.edu!magnus.ircc.ohio-state.edu!csn!spot.Colorado.EDU!frechett From: frechett@spot.Colorado.EDU (-=Runaway Daemon=-) Newsgroups: comp.sys.handhelds Subject: Re: Why ASC over UUENCODE? Message-ID: <1991Feb14.044839.11612@csn.org> Date: 14 Feb 91 04:48:39 GMT References: <1991Feb13.101558.5056@lth.se> <59678@eerie.acsu.Buffalo.EDU> <1991Feb14.015132.10732@nntp-server.caltech.edu> Sender: news@csn.org (news) Organization: University of Colorado, Boulder Lines: 291 Nntp-Posting-Host: spot.colorado.edu In article <1991Feb14.015132.10732@nntp-server.caltech.edu> madler@pooh.caltech.edu (Mark Adler) writes: [...] >I believe the wide availability of uuencode/decode for many machines >(a fact apparently still disputed) makes it more portable than ASC which >is available on only one machine (the HP-48SX). This is particularily ^^^^^^^^^^^ >important when you want to save time and memory by doing a binary download >into your calculator. > >One solution is to have a portable ->ASC-> converter, but why bother when ^^^^^^^^ ^^^^^ >uu* is already in place, and is more efficient (by 50%) in mail bandwidth? > >Mark Adler >madler@pooh.caltech.edu DESC: A C version of the ASC-> decoder. Works on most any machine with C. >Article 1430 of comp.sys.handhelds: >Path: csn!ncar!elroy.jpl.nasa.gov!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.wilsonpm >From: akcs.wilsonpm@hpcvbbs.UUCP (Pete M. Wilson) >Newsgroups: comp.sys.handhelds >Subject: Re: ASC-> for UNIX >Message-ID: <2798e77c:1547.1comp.sys.handhelds;1@hpcvbbs.UUCP> >Date: 20 Jan 91 01:40:06 GMT >References: <1990Dec31.080317.12174@csn.org> >Lines: 267 This is my C version of ASC->. It was written on a PC & compiled with Microsoft C & Turbo C++. I used ANSI C functions (mostly). I hope it will help you. Pete P.S. If I can get it uploaded! # additional notes. May have to edit section on strerror as some machines # don't understand. I changed to stderr.. Crude but it works. ------------------------------CUT HERE-------------------------------- This programs reads an up to 127K ASCII (RPL) file consisting of a string intended for ASC-> and converts it into a binary object file. This program was compiled with Microsoft C 5.1 and Turbo C. ANSI C conventions are mostly followed. The original algorithm for CRC computation was extracted from Li Sheng's posting to comp.sys.handhelds. 01/19/91 PMW created */ #include #include #include #include #include #define MAX_READ_SIZE 127 #if !defined(FILENAME_MAX) #define FILENAME_MAX 65 #endif #if !defined(EXIT_FAILURE) #define EXIT_FAILURE 1 #endif #if !defined(EXIT_SUCCESS) #define EXIT_SUCCESS 0 #endif #define HEX2INT(hc) ((unsigned int) (isdigit(hc) ? (hc)-'0' : (hc)-'A'+10)) int FileExists(char *f) { FILE *tf; if ((tf = fopen(f, "rb")) != NULL) { fclose(tf); return 1; } else return 0; } long FileSize(FILE *f) { long origPos = ftell(f), fileSize = 0; fseek(f, 0L, SEEK_END); fileSize = ftell(f); fseek(f, origPos, SEEK_SET); return fileSize; } typedef unsigned char BYTE; typedef unsigned int WORD; #define CALC_CRC(c, i) (((((c)^(i)) & 0xF) * 0x1081) ^ ((c) >> 4)) WORD crcBlock(BYTE *mb, size_t len) { WORD crc = 0, bObjSize = len/2; while (bObjSize--) { crc = CALC_CRC(crc, (WORD) (*mb) & 0xF); crc = CALC_CRC(crc, (WORD) ((*mb) >> 4)); ++mb; } if (len & 1) crc = CALC_CRC(crc, (WORD) (*mb) & 0xF); return crc; } void CopyLine(BYTE **mb, char **s, WORD *objSize) { char *ts = *s; BYTE *tmb = *mb; WORD ls = 0; while (isxdigit(ts[0]) && isxdigit(ts[1])) { *tmb++ = (BYTE) (HEX2INT(ts[0]) + (HEX2INT(ts[1]) << 4)); ls += 2; ts += 2; } if (isxdigit(ts[0]) && ts[1] == '"') { /* we ended on a nibble boundary!! */ BYTE crc1, crc2; /* correct crc by nibble shifting end */ crc2 = (BYTE) ((tmb[-1] >> 4) + (HEX2INT(ts[0]) << 4)); crc1 = (BYTE) ((tmb[-2] >> 4) + ((tmb[-1] & 0xF) << 4)); /* fix memory buffer */ tmb[-2] &= 0xf; tmb[-1] = crc1; *tmb++ = crc2; ++ls; ++ts; } *s = ts; *mb = tmb; *objSize += ls; } #define READLN(s, f) fgets((s), sizeof(s), (f)) void ReadFile(char *filepath, BYTE **mb, WORD *objSize) { FILE *infile; char lineBuf[250], *p; WORD bufSize; long fileSize; BYTE *wmb; if (!strchr(filepath, '.')) strcat(filepath, ".rpl"); if (!(infile = fopen(filepath, "r"))) { fprintf(stderr, "asc2bin: can't open %s\n", filepath); exit(EXIT_FAILURE); } fileSize = FileSize(infile); if (fileSize > MAX_READ_SIZE*1024L) { fprintf(stderr, "asc2bin: File %s is too long\n", filepath); exit(EXIT_FAILURE); } bufSize = 4+(WORD) (fileSize / 2); /* approximate byte size of object */ if (!(*mb = (BYTE *) malloc(bufSize))) { fprintf(stderr, "asc2bin: Unable to allocate %u bytes\n", bufSize); exit(EXIT_FAILURE); } wmb = *mb; /* find string */ while (!feof(infile)) { if (!READLN(lineBuf, infile)) { if (feof(infile)) fputs("asc2bin: Unable to locate string\n", stderr); else fprintf(stderr, "asc2bin: Read error: %s\n", strerror(errno)); fclose(infile); exit(EXIT_FAILURE); } if (*lineBuf == '"') break; } *objSize = 0; /* put string into buffer */ p = &lineBuf[1]; /* skip opening quote */ CopyLine(&wmb, &p, objSize); /* copy remainder into buffer */ while (*p != '"' && !feof(infile)) { if (!READLN(lineBuf, infile)) { if (feof(infile)) fputs("asc2bin: Unable to locate closing quote\n", stderr); else fprintf(stderr, "asc2bin: Read error: %s\n", strerror(errno)); fclose(infile); exit(EXIT_FAILURE); } p = lineBuf; CopyLine(&wmb, &p, objSize); } fclose(infile); } void WriteFile(char *filepath, BYTE *mb, WORD objSize) { FILE *outfile; char *extpos = strchr(filepath, '.'); strcpy(extpos+1, "bin"); if (FileExists(filepath)) { fprintf(stderr, "asc2bin: file already exists: %s\n", filepath); exit(EXIT_FAILURE); } if (!(outfile = fopen(filepath, "wb"))) { fprintf(stderr, "asc2bin: unable to create %s\n", filepath); exit(EXIT_FAILURE); } fputs("HPHP48-C", outfile); /* my own version */ while (objSize--) fputc(*mb++, outfile); fclose(outfile); } main(int argc, char *argv[]) { char filepath[FILENAME_MAX]; BYTE *mb; WORD objSize, rcrc, crc,bObjSize; /* NOTE: objSize is in nibbles! */ if (argc < 2) { fputs("usage: asc2bin infile[.ext]\n", stderr); fputs("\treads infile.ext and creates infile.bin\n", stderr); fputs("\tif omitted, .ext is assumed to be .rpl\n", stderr); exit(EXIT_FAILURE); } strcpy(filepath, argv[1]); ReadFile(filepath, &mb, &objSize); if (objSize < 2) { fputs("asc2bin: String too short to include crc\n", stderr); exit(EXIT_FAILURE); } objSize -= 4; /* nibbles */ bObjSize = objSize / 2 + (objSize & 1); rcrc = (WORD) mb[bObjSize] + ((WORD) mb[bObjSize+1] << 8); crc = crcBlock(mb, objSize); if (crc != rcrc) { fprintf(stderr, "asc2bin: Calculated CRC # %Xh does not match read CRC # %Xh\n", crc, rcrc); exit(EXIT_FAILURE); } WriteFile(filepath, mb, bObjSize); return EXIT_SUCCESS; } ------------------------------CUT HERE-------------------------------- NOTE: I forgot that some of my lines would wrap because of the line number - The code will need to be cleaned up. I'll upload the source & a self-unzipping PC archive (with executable) in user.programs.