/* Copyright (c) 1998, 1999, 2000, 2001, 2003, 2004 Benhur Stein This file is part of Pajé. Pajé is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Pajé 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Pajé; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "DataScanner.h" #include @implementation DataScanner + (DataScanner *)scannerWithData:(NSData *)_data { return [[[self alloc] initWithData:_data] autorelease]; } - (id)initWithData:(NSData *)_data { if ((self = [super init])) { Assign(data, _data); position = 0; // FIXME: find a cleaner way of reading numbers independently of locale setlocale(LC_NUMERIC, "C"); } return self; } - (void)dealloc { Assign(data, nil); [super dealloc]; } - (NSData *)data { return data; } - (unsigned)position { return position; } - (void)setPosition:(unsigned)_position { if (_position <= [data length]) position = _position; } #define DECLS char *bytes = (char *)[data bytes]; \ unsigned length = [data length]; \ int c; #define NEXTCHAR ((position < length) ? bytes[position++] : -1) #define SKIPWHITE do { c = NEXTCHAR; } while (c==' ' /*|| c=='\n'*/ || c=='\t' || c=='\r') #define SKIPNONWHITE do { c = NEXTCHAR; } while (c!=' ' && c!='\n' && c!='\t' && c!=-1) - (int)readChar { DECLS; SKIPWHITE; if (c == '\\') { c = NEXTCHAR; if (c == 'n') { c = '\n'; } } return c; } - (NSNumber *)readIntNumber { int value = 0; int signal = 1; DECLS; SKIPWHITE; if (c == '-') { signal = -1; c = NEXTCHAR; } if (c<'0' || c>'9') { if (c != -1) position--; return nil; } while (c >= '0' && c <= '9') { value = value * 10 + c - '0'; c = NEXTCHAR; } if (c != -1) position--; return [NSNumber numberWithInt:value*signal]; } - (NSNumber *)readDoubleNumber { double value=0; int signal = 1; DECLS; return [NSNumber numberWithDouble:[self readDouble]]; SKIPWHITE; if (c == '-') { signal = -1; c = NEXTCHAR; } if (c < '0' || c > '9') { if (c != -1) position--; return nil; } while (c >= '0' && c <= '9') { value = value * 10 + c - '0'; c = NEXTCHAR; } if (c == '.') { double m=.1; c = NEXTCHAR; while (c >= '0' && c <= '9') { value = value + (c - '0') * m; m /= 10; c = NEXTCHAR; } } if (c != -1) position--; return [NSNumber numberWithDouble:value*signal]; } - (double)readDouble { double value=0; int signal = 1; DECLS; SKIPWHITE; value = atof(&bytes[position-1]); SKIPNONWHITE; if (c != -1) position--; return value; if (c == '-') { signal = -1; c = NEXTCHAR; } if (c < '0' || c > '9') { if (c != -1) position--; return 0; } while (c >= '0' && c <= '9') { value = value * 10 + c - '0'; c = NEXTCHAR; } if (c == '.') { double m=.1; c = NEXTCHAR; while (c >= '0' && c <= '9') { value = value + (c - '0') * m; m /= 10; c = NEXTCHAR; } } if (c != -1) position--; return value*signal; } - (NSString *)readString { char value[500]; int bi=0; BOOL f=NO; DECLS; SKIPWHITE; if (c=='"') { f=YES; c = NEXTCHAR; } do { if (c == '\\') { c = NEXTCHAR; if (c == 'n') { c = '\n'; } } value[bi++] = c; c = NEXTCHAR; } while ((c != -1) && ((f && c!='"') || (!f && !(c==' ' || c=='\n' || c=='\t')))); if (f && (c == '"')) position++; if (c != -1) position--; return [NSString stringWithCString:value length:bi]; } - (BOOL)isAtEnd { DECLS; SKIPWHITE; if (c == -1) return YES; position--; return NO; } @end