This is codebook.c in view mode; [Download] [Up]
/* -*- c -*- */
/*
Webster Access, a program to use NeXT online Webster dictionary.
Copyright (C) 1994 Benoit Grange, ben@fizz.fdn.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#import <libc.h>
#import <mach/mach.h>
#import <mach/boolean.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <sys/file.h>
#import <errno.h>
#import "codebook.h"
#import "WebsterExceptions.h"
#define CBENTSIZE 6
static char *cbAddress = NULL;
static int cbNbEntries = 0;
int initCodebook(const char *fileName)
/*
Loads the codebook file into memory
RETURNs number of entries if ok, 0 if failed
*/
{
int fd;
struct stat statbuf;
kern_return_t err;
if ((fd = open(fileName, O_RDONLY))<0)
NX_RAISE(websterNoCodebook, fileName, NULL);
if (fstat(fd, &statbuf)<0)
NX_RAISE(websterInternalError, fileName, NULL);
if (statbuf.st_size % CBENTSIZE)
NX_RAISE(websterBadCodebook, fileName, NULL);
if ((err = map_fd(fd, 0L, (vm_address_t *)&cbAddress, TRUE, statbuf.st_size)) != KERN_SUCCESS)
NX_RAISE(websterInternalError, fileName, NULL);
cbNbEntries = statbuf.st_size / CBENTSIZE;
return cbNbEntries;
}
void decodeEntry(const void *inbuffer, int length,
void **new, int *newLength)
/*
Given an encoded memory buffer, returns a decoded buffer
One must free the returned buffer
*/
{
register const unsigned char* buffer = inbuffer;
int curlen = 0, maxlen = 0;
unsigned char *p = NULL;
unsigned short index;
while (length > 0) {
// Find index in codebook
// If the byte has its upper bit set, this is a single byte offset
// Else it it a double byte offset
if (*buffer & 0x80) {
index = (-*buffer) & 0xFF;
length--;
buffer++;
} else {
index = ((((unsigned short)buffer[0])) << 8) + buffer[1];
length -= 2;
buffer += 2;
if (length < 0) break;
}
if (index == 0) {
// If index is zero, insert direcly next char from encoded buffer into decoded buffer
if (curlen+1 > maxlen) {
if (maxlen) maxlen *= 2;
else maxlen = 256;
p = p?realloc(p, maxlen):malloc(maxlen);
if (!p) { *new = 0; return; };
}
p[curlen++] = *buffer;
length--;
buffer++;
} else if (index < cbNbEntries) {
unsigned char *entry = cbAddress + (CBENTSIZE * (index-1));
int i = CBENTSIZE;
while (i-- && (*entry != 0xff)) {
if (curlen+2 > maxlen) {
if (maxlen) maxlen *= 2;
else maxlen = 256;
p = p?realloc(p, maxlen):malloc(maxlen);
if (!p) { *new = 0; return; };
}
p[curlen++] = *entry;
entry++;
} /* loop output entry */
} /* ouptut entry */ else {
fprintf(stderr, "bigram %04X is not in codebook\n", (unsigned)index);
}
} /* output full text */
if (length < 0) fprintf(stderr, "botched decoding bigrams\n");
p = realloc(p, curlen);
*new = p;
*newLength = curlen;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.