ftp.nice.ch/pub/next/unix/text/Webster.a5.s.tar.gz#/Webster/Library/Sources/codebook.c

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.