summaryrefslogtreecommitdiffstats
path: root/libconfig/ArrayData.m
blob: 646c7640757c220295bf8d04d5c9a209dd7f17cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "ArrayData.h"
#include "Parser.h"
#include "String.h"

#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

@implementation ArrayData
-init
{
	self = [super init];

	numChildren = 0;
	curObj = 0;
	data = malloc(MALLOC_GRANULARITY * sizeof(DictEntry *));
	if (!data) {
		fprintf(stderr, "ERROR: couldn't allocate memory: %s.\n",
			strerror(errno));
		return nil;
	}

	return self;
}

-free
{
	int i;

	fprintf(stderr, "DEBUG: freeing array\n");
	for (i = 0; i < numChildren; i++)
		[data[i] free];
	free(data);
	[super free];

	return nil;
}

-addChild: child
{
	/* Allocate additional space for children pointers, if required. */
	if (numChildren % MALLOC_GRANULARITY == 0) {
		/* TODO: fail gracefully. */
		data = realloc(data, (numChildren+MALLOC_GRANULARITY) *
				     sizeof(DataObject *));
		if (!data) {
			fprintf(stderr,
				"ERROR: couldn't allocate memory: %s.\n",
				strerror(errno));
			return nil;
		}
	}

	data[numChildren] = child;

	numChildren++;
	return self;
}

-setFromBuffer: (const char *)buffer withLength: (int)len
{
	Parser *parser;
	String *string;
	const char *offset;

	self = [super init];
	parser = [Parser new];
	string = [[String new] init];
	if (parser == nil || string == nil)
		return nil;

	if (buffer[len] == '\0')
		len--;

	/* Skip any leading white space. */
	for (offset = buffer; offset <= buffer+len && isspace((int)*offset);
	     offset++);
	/* Kill any ending white space. */
	for (; len >= 0 && isspace((int)buffer[len]); len--);

	/* If there's a leading brace, kill it and the ending one. */
	if (offset[0] == '[') {
		if (buffer[len] != ']') {
			fprintf(stderr, "ERROR: Unbalanced braces.\n");
			[parser free]; [string free];
			return nil;
		}
		offset++; len--;

		/* Do the whitespace shuffle again. */
		for (; len >= 0 && isspace((int)buffer[len]); len--);
	}

	while (offset < buffer+len) {
		DataObject *dataObj;
		int strLen;

		/* Do the whitespace shuffle. */
		for (; offset <= buffer+len && isspace((int)*offset); offset++);

		strLen = [parser getLineLenFrom: offset to: buffer+len];
		[string setStr: offset withLength: strLen];
		offset += strLen + 1;

		/* Parse the data element, then add it to our list. */
		dataObj = [parser getDataFrom: string];
		if (dataObj == nil) {
			[parser free]; [string free];
			return nil;
		}
		[self addChild: dataObj];
	}

	[parser free]; [string free];
	return self;
}

-(int)
numObjects
{
	return numChildren;
}

-objectAt: (int)index
{
	if (index >= numChildren)
		return nil;
	return data[index];
}
@end