Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 12-11-2011, 09:58 AM   #1 (permalink)
Registered Member
 
Join Date: Dec 2011
Posts: 3
ateam007 is on a distinguished road
Exclamation CSV parsing issue, Simulator works - App store missing data

Hi Guys



Code:
/*
 * cCSVParse, a small CVS file parser
 
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdbool.h>

#import "parseCSV.h"
#define EOL(x) ((*(x) == '\r' || *(x) == '\n') && *(x) != '\0')
#define NOT_EOL(x) (*(x) != '\0' && *(x) != '\r' && *(x) != '\n')
static char *cstrstr(const char *haystack, const char needle) {
	char *it = (char*)haystack;
	while (*it != '\0') {
		if (*it == needle)
			return it;
		it++;
	}
	return NULL;
}
@implementation CSVParser
-(NSString*)parseString:(char*)textp withLastStop:(char*)laststop {
	int stringSize = (int)(textp - laststop);
	if (*laststop == '\"' && *(laststop+1) != '\0' && *(laststop + stringSize - 1) == '\"') {
		laststop++;
		stringSize -= 2;
	}
	char *retval = (char*)malloc(stringSize + 1);
	if (retval == NULL)
		return NULL;
	strncpy(retval, laststop, (size_t)(stringSize));
	retval[stringSize] = '\0';
	NSMutableString *tempString = [NSMutableString stringWithCString: retval encoding:encoding];
	free(retval);
	retval = NULL;
	[tempString replaceOccurrencesOfString:@"\"\"" 
				    withString:@"\"" 
				       options:0
				         range:NSMakeRange(0, [tempString length])];
	return [NSString stringWithString: tempString];
}
-(id)init {
	self = [super init];
	if (self) {
		// Set default bufferSize
		bufferSize = 8192;
		// Set fileHandle to an invalid value
		fileHandle = 0;
		// Set delimiter to 0
		delimiter = '\0';
		// Set default encoding
		encoding = NSISOLatin1StringEncoding;
	}
	return self;
}

-(char)autodetectDelimiter {
	if (YES) {
		delimiter = ',';
		return delimiter;
	}
	
	char possibleDelimiters[4] = ",;\t\0";

	char buffer[bufferSize+1];
	// Seek to the beginning of the file
	lseek(fileHandle, 0, SEEK_SET);

	// Fill the buffer
	if (read(fileHandle, buffer, bufferSize) > 0) {
		char *textp = buffer;
		// ...we assume that this is the header which also contains the separation character
		while (NOT_EOL(textp) && cstrstr(possibleDelimiters, *textp) == NULL)
			textp++;

		// Check if a delimiter was found and set it
		if (NOT_EOL(textp)) {
			delimiter = *cstrstr((const char*)possibleDelimiters, *textp);
			return delimiter;
		}
	}

	return 0;
}


/*
 * Parses the CSV-file with the given filename and stores the result in a
 * NSMutableArray.
 *
 */
-(NSMutableArray*)parseString:(NSString *)csvString {
	NSMutableArray *csvLine = [NSMutableArray array];
	NSMutableArray *csvContent = [NSMutableArray array];
	if (fileHandle <= 0)
		return csvContent;
	char possibleDelimiters[4] = ",;\t\0";
	int n = 1, diff;
	unsigned int quoteCount = 0;
	bool firstLine = true;
	char *buffer = malloc(sizeof(char) * (bufferSize + 1));
	char *textp, *laststop, *lineBeginning, *lastLineBuffer = NULL;
	lseek(fileHandle, 0, SEEK_SET);
	while (n > 0) {
		if (lastLineBuffer != NULL) {
			if (strlen(lastLineBuffer) == bufferSize) {
				[csvContent removeAllObjects];
				[csvContent addObject: [NSArray arrayWithObject: @"ERROR: Buffer too small"]];
				return csvContent;
			}
			
			// Care for the quotes in lastLineBuffer!
			textp = lastLineBuffer;
			while (*textp != '\0') {
				if (*textp == '\"')
					quoteCount++;
				textp++;
			}
			strcpy(buffer, lastLineBuffer);
			diff = strlen(lastLineBuffer);
			// Make the buffer bigger
			buffer = realloc(buffer, diff + bufferSize);
			if (buffer == NULL) {
				[csvContent removeAllObjects];
				[csvContent addObject: [NSArray arrayWithObject: @"ERROR: Could not allocate bytes for buffer"]];
				return csvContent;
			}
			lastLineBuffer = NULL;
		} else diff = 0;
		n = read(fileHandle, (buffer + diff), bufferSize);
		if (n <= 0)
			break;
		// Terminate buffer correctly
		if ((diff+n) <= (bufferSize + diff))
			buffer[diff+n] = '\0';
		
		textp = (char*)buffer;
		
		while (*textp != '\0') {
			// If we don't have a delimiter yet and this is the first line...
			if (firstLine && delimiter == '\0') {
				firstLine = false;
				// ...we assume that this is the header which also contains the separation character
				while (NOT_EOL(textp) && cstrstr(possibleDelimiters, *textp) == NULL)
					textp++;
				
				// Check if a delimiter was found and set it
				if (NOT_EOL(textp)) {
					delimiter = *cstrstr((const char*)possibleDelimiters, *textp);
					printf("delim is %c / %d :-)\n", delimiter, delimiter);
					while (NOT_EOL(textp))
						textp++;
				}
				
				textp = (char*)buffer;
			} 
			
			if (strlen(textp) > 0) {
				// This is data
				laststop = textp;
				lineBeginning = textp;
				
				// Parsing is splitted in parts till EOL
				while (NOT_EOL(textp) || (*textp != '\0' && (quoteCount % 2) != 0)) {
					// If we got two quotes and a delimiter before and after, this is an empty value
					if (	*textp == '\"' && 
						*(textp+1) == '\"') {
						// we'll just skip this, but firstly check if it's an empty value
						if (	(textp > (const char*)buffer) && 
							*(textp-1) == delimiter && 
							*(textp+2) == delimiter) {
							[csvLine addObject: @""];
						}
						textp++;
					} else if (*textp == '\"')
						quoteCount++;
					else if (*textp == delimiter && (quoteCount % 2) == 0) {
						// There is a delimiter which is not between an unmachted pair of quotes?
						[csvLine addObject: [self parseString:textp withLastStop:laststop]];
						laststop = textp + 1;
					}
					
					// Go to the next character
					textp++;
				}
				
				if (laststop == textp && *(textp-1) == delimiter) {
					[csvLine addObject:@""];
					if ((int)(buffer + bufferSize + diff - textp) > 0) {
						lineBeginning = textp + 1;
						[csvContent addObject: csvLine];
					}
					csvLine = [NSMutableArray new];
					[csvLine autorelease];
				}
				if (laststop != textp && (quoteCount % 2) == 0) {
					[csvLine addObject: [self parseString:textp withLastStop:laststop]];
					
					if ((int)(buffer + bufferSize + diff - textp) > 0) {
						lineBeginning = textp + 1;
						[csvContent addObject: csvLine];
					}
					csvLine = [NSMutableArray new];
					[csvLine autorelease];
				} 
				if ((*textp == '\0' || (quoteCount % 2) != 0) && lineBeginning != textp) {
					lastLineBuffer = lineBeginning;
					csvLine = [NSMutableArray new];
					[csvLine autorelease];
				}
			}
			
			while (EOL(textp))
				textp++;
		}
	}
	
	free(buffer);
	buffer = NULL;
	
	return csvContent;
}


/*
 * Parses the CSV-file with the given filename and stores the result in a
 * NSMutableArray.
 *
 */
-(NSMutableArray*)parseFile {
	NSMutableArray *csvLine = [NSMutableArray array];
	NSMutableArray *csvContent = [NSMutableArray array];
	if (fileHandle <= 0)
		return csvContent;
	char possibleDelimiters[4] = ",;\t\0";
	int n = 1, diff;
	unsigned int quoteCount = 0;
	bool firstLine = true;
	char *buffer = malloc(sizeof(char) * (bufferSize + 1));
	char *textp, *laststop, *lineBeginning, *lastLineBuffer = NULL;
	lseek(fileHandle, 0, SEEK_SET);
	while (n > 0) {
		if (lastLineBuffer != NULL) {
			if (strlen(lastLineBuffer) == bufferSize) {
				[csvContent removeAllObjects];
				[csvContent addObject: [NSArray arrayWithObject: @"ERROR: Buffer too small"]];
				return csvContent;
			}

			// Care for the quotes in lastLineBuffer!
			textp = lastLineBuffer;
			while (*textp != '\0') {
				if (*textp == '\"')
					quoteCount++;
				textp++;
			}
			strcpy(buffer, lastLineBuffer);
			diff = strlen(lastLineBuffer);
			// Make the buffer bigger
			buffer = realloc(buffer, diff + bufferSize);
			if (buffer == NULL) {
				[csvContent removeAllObjects];
				[csvContent addObject: [NSArray arrayWithObject: @"ERROR: Could not allocate bytes for buffer"]];
				return csvContent;
			}
			lastLineBuffer = NULL;
		} else diff = 0;
		n = read(fileHandle, (buffer + diff), bufferSize);
		if (n <= 0)
			break;
		// Terminate buffer correctly
		if ((diff+n) <= (bufferSize + diff))
			buffer[diff+n] = '\0';
		
		textp = (char*)buffer;

		while (*textp != '\0') {
			// If we don't have a delimiter yet and this is the first line...
			if (firstLine && delimiter == '\0') {
				firstLine = false;
				// ...we assume that this is the header which also contains the separation character
				while (NOT_EOL(textp) && cstrstr(possibleDelimiters, *textp) == NULL)
					textp++;

				// Check if a delimiter was found and set it
				if (NOT_EOL(textp)) {
					delimiter = *cstrstr((const char*)possibleDelimiters, *textp);
					printf("delim is %c / %d :-)\n", delimiter, delimiter);
					while (NOT_EOL(textp))
						textp++;
				}

				textp = (char*)buffer;
			} 

			if (strlen(textp) > 0) {
				// This is data
				laststop = textp;
				lineBeginning = textp;

				// Parsing is splitted in parts till EOL
				while (NOT_EOL(textp) || (*textp != '\0' && (quoteCount % 2) != 0)) {
					// If we got two quotes and a delimiter before and after, this is an empty

Last edited by ateam007; 04-22-2012 at 09:04 AM.
ateam007 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 397
12 members and 385 guests
7twenty7, AppsBlogger, David-T, Duncan C, HemiMG, heshiming, LunarMoon, Murphy, sacha1996, Sami Gh, teebee74, Tomsky
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,676
Threads: 94,127
Posts: 402,915
Top Poster: BrianSlick (7,990)
Welcome to our newest member, jleannex55
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 06:46 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0