home *** CD-ROM | disk | FTP | other *** search
- /* -*-C-*-
- *******************************************************************************
- *
- * File: SimpleString.m
- * RCS: /usr/local/sources/CVS/EnhanceMail/SimpleString.m,v 1.6 1997/11/15 16:56:40 tom Exp
- * Description:
- * Author: Carl Edman
- * Created: Tue Oct 17 23:45:45 1995
- * Modified: Sat Jun 22 19:10:45 1996 (Carl Edman) cedman@capitalist.princeton.edu
- * Language: C
- * Package: N/A
- * Status: Experimental (Do Not Distribute)
- *
- * (C) Copyright 1995, but otherwise this file is perfect freeware.
- *
- *******************************************************************************
- */
-
- #import "SimpleString.h"
- #import "EnhanceMail.h"
-
- #define START 64
-
- #define BYTE_LENGTH(self) (self->cur - self->data)
- #define MUSTGROW(self,len) (self->cur+(len)>=self->data+malloc_size(self->data))
-
-
- @implementation SimpleString
-
- - init
- {
- [super init];
- cur=data=NXZoneMalloc([self zone],START);
- *cur='\0';
- return self;
- }
-
- - free
- {
- free(data);
- return [super free];
- }
-
- - grow:(int)by
- {
- int pos = cur-data;
- int size = malloc_size(data);
-
- do { size *= 2; } while (pos+by >= size);
- data=NXZoneRealloc([self zone],data,size);
- cur=data+pos;
- return self;
- }
-
- - grow
- {
- return [self grow:0];
- }
-
- - (char *)string
- {
- return data;
- }
-
- - (int)length
- {
- return BYTE_LENGTH(self);
- }
-
- #define iskanji(c) (c & 0x80)
-
- - (int)textLength
- {
- if (EnhanceUseKanji())
- {
- char *c=data;
- int length=0;
- const int byte_per_mbchar=2;
-
- while (c<cur)
- {
- if (iskanji(*c)) c+=byte_per_mbchar; else c++;
- length++;
- }
- return length;
- }
- return BYTE_LENGTH(self);
- }
-
- - empty
- {
- cur=data;
- *cur='\0';
- return self;
- }
-
- - (int)appendChar:(char)c
- {
- if (MUSTGROW(self,1)) [self grow:1];
- *cur++=c;
- *cur='\0';
- return cur-data;
- }
-
- - (int)appendString:(const char *)str
- {
- return [self appendString:str length:strlen(str)];
- }
-
- - (int)appendString:(const char *)str length:(int)len
- {
- if (MUSTGROW(self,len)) [self grow:len];
- while(len>0) { *cur++=*str++; len--; }
- *cur='\0';
- return cur-data;
- }
-
- - (int)appendStream:(NXStream *)s
- {
- int c;
-
- while ((c=NXRead(s,cur,data+malloc_size(data)-cur))>0)
- {
- cur+=c;
- if (MUSTGROW(self,0)) [self grow];
- }
-
- *cur='\0';
- return cur-data;
- }
-
- - (int)appendFile:(int)fd
- {
- int c;
-
- while ((c=read(fd,cur,data+malloc_size(data)-cur))>0)
- {
- cur+=c;
- if (MUSTGROW(self,0)) [self grow];
- }
-
- *cur='\0';
- return cur-data;
- }
-
- - (int)writeFile:(int)fd
- {
- char *pos;
- int c;
-
- for(pos=data;pos<cur;)
- {
- c=write(fd,pos,cur-pos);
- if (c<0) return c;
- pos+=c;
- }
-
- return cur-data;
- }
-
- - (int)appendSimpleString:(id)sstr
- {
- return [self appendString:[sstr string] length:[sstr length]];
- }
-
- - (int)appendAndFreeSimpleString:(id)sstr
- {
- int ret = [self appendSimpleString:sstr];
- [sstr free];
- return ret;
- }
-
- - (int)insertString:(const char *)str
- {
- return [self insertString:str length:strlen(str) at:0];
- }
-
- - (int)insertString:(const char *)str length:(int)len
- {
- return [self insertString:str length:len at:0];
- }
-
- - (int)insertString:(const char *)str length:(int)len at:(int)pos
- {
- char *p, *d;
- const char *s;
-
- if (MUSTGROW(self,len)) [self grow:len];
- if (pos < 0) p = data;
- else if (pos > cur-data) p = cur;
- else p = data + pos;
- cur += len;
- // shift tail (including terminating '\0'):
- for (d = cur + 1, s = d - len; s > p; ) *--d = *--s;
- // insert string:
- for (s = str, d = p; --len >= 0; ) *d++ = *s++;
- return cur-data;
- }
-
- - (int)lastChar
- {
- return (cur>data) ? *(cur-1) : -1;
- }
-
- @end // SimpleString
-