1/*
2 * Copyright 2023, Andrew Lindesay <apl@lindesay.co.nz>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5#include "FakeJsonDataGenerator.h"
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <strings.h>
10#include <string.h>
11
12
13static const char* kTextData = "abcdefghijklmnopqrstuvwxyz!@#$"
14	"ABCDEFGHIJKLMNOPQRSTUVWXYZ)(*&"
15	"0123456789{}[]|:;'<>,.?/~`_+-="
16	"abcdefghijklmnopqrstuvwxyz!@#$"
17	"ABCDEFGHIJKLMNOPQRSTUVWXYZ)(*&"
18	"0123456789{}[]|:;'<>,.?/~`_+-=";
19static const int kTextDataLength = 180;
20
21
22FakeJsonStreamDataIO::FakeJsonStreamDataIO(int count, uint32 checksumLimit)
23	:
24	fFeedOutState(OPEN_ARRAY),
25	fItemCount(count),
26	fItemUpto(0),
27	fChecksum(0),
28	fChecksumLimit(checksumLimit)
29{
30}
31
32
33FakeJsonStreamDataIO::~FakeJsonStreamDataIO()
34{
35}
36
37
38ssize_t
39FakeJsonStreamDataIO::Read(void* buffer, size_t size)
40{
41	char* buffer_c = static_cast<char*>(buffer);
42	status_t result = B_OK;
43	size_t i = 0;
44
45	while (i < size && result == B_OK) {
46		result = NextChar(&buffer_c[i]);
47		if (result == B_OK)
48			i++;
49	}
50
51	if(0 != i)
52		return i;
53
54	return result;
55}
56
57
58ssize_t
59FakeJsonStreamDataIO::Write(const void* buffer, size_t size)
60{
61	return B_NOT_SUPPORTED;
62}
63
64
65status_t
66FakeJsonStreamDataIO::Flush()
67{
68	return B_OK;
69}
70
71
72uint32
73FakeJsonStreamDataIO::Checksum() const
74{
75	return fChecksum;
76}
77
78
79void
80FakeJsonStreamDataIO::_ChecksumProcessCharacter(const char c)
81{
82	fChecksum = (fChecksum + static_cast<int32>(c)) % fChecksumLimit;
83}
84
85
86// #pragma mark - FakeJsonStringStreamDataIO
87
88
89FakeJsonStringStreamDataIO::FakeJsonStringStreamDataIO(int count, uint32 checksumLimit)
90	:
91	FakeJsonStreamDataIO(count, checksumLimit),
92	fItemBufferSize(0),
93	fItemBufferUpto(0)
94{
95	FillBuffer();
96}
97
98
99FakeJsonStringStreamDataIO::~FakeJsonStringStreamDataIO()
100{
101}
102
103
104status_t
105FakeJsonStringStreamDataIO::NextChar(char* c)
106{
107	switch (fFeedOutState) {
108		case OPEN_ARRAY:
109			c[0] = '[';
110			fFeedOutState = OPEN_QUOTE;
111			return B_OK;
112		case OPEN_QUOTE:
113			c[0] = '"';
114			fFeedOutState = ITEM;
115			return B_OK;
116		case ITEM:
117			c[0] = kTextData[fItemBufferUpto];
118			_ChecksumProcessCharacter(kTextData[fItemBufferUpto]);
119			fItemBufferUpto++;
120			if (fItemBufferUpto >= fItemBufferSize) {
121				fFeedOutState = CLOSE_QUOTE;
122				FillBuffer();
123			}
124			return B_OK;
125		case CLOSE_QUOTE:
126			c[0] = '"';
127			fItemUpto++;
128			if (fItemUpto >= fItemCount)
129				fFeedOutState = CLOSE_ARRAY;
130			else
131				fFeedOutState = SEPARATOR;
132			return B_OK;
133		case SEPARATOR:
134			c[0] = ',';
135			fFeedOutState = OPEN_QUOTE;
136			return B_OK;
137		case CLOSE_ARRAY:
138			c[0] = ']';
139			fFeedOutState = END;
140			return B_OK;
141		default:
142			return -1; // end of file
143	}
144}
145
146
147void
148FakeJsonStringStreamDataIO::FillBuffer()
149{
150	fItemBufferSize = random() % kTextDataLength;
151	fItemBufferUpto = 0;
152}
153
154
155// #pragma mark - FakeJsonStringStreamDataIO
156
157
158FakeJsonNumberStreamDataIO::FakeJsonNumberStreamDataIO(int count, uint32 checksumLimit)
159	:
160	FakeJsonStreamDataIO(count, checksumLimit),
161	fItemBufferSize(0),
162	fItemBufferUpto(0)
163{
164	bzero(fBuffer, 32);
165	FillBuffer();
166}
167
168
169FakeJsonNumberStreamDataIO::~FakeJsonNumberStreamDataIO()
170{
171}
172
173
174status_t
175FakeJsonNumberStreamDataIO::NextChar(char* c)
176{
177	switch (fFeedOutState) {
178		case OPEN_ARRAY:
179			c[0] = '[';
180			fFeedOutState = ITEM;
181			return B_OK;
182		case ITEM:
183			c[0] = fBuffer[fItemBufferUpto];
184			_ChecksumProcessCharacter(fBuffer[fItemBufferUpto]);
185			fItemBufferUpto++;
186			if (fItemBufferUpto >= fItemBufferSize) {
187				fItemUpto++;
188				if (fItemUpto >= fItemCount)
189					fFeedOutState = CLOSE_ARRAY;
190				else
191					fFeedOutState = SEPARATOR;
192				FillBuffer();
193			}
194			return B_OK;
195		case SEPARATOR:
196			c[0] = ',';
197			fFeedOutState = ITEM;
198			return B_OK;
199		case CLOSE_ARRAY:
200			c[0] = ']';
201			fFeedOutState = END;
202			return B_OK;
203		default:
204			return -1; // end of file
205	}
206}
207
208
209void
210FakeJsonNumberStreamDataIO::FillBuffer()
211{
212	int32 value = static_cast<int32>(random());
213	fItemBufferSize = snprintf(fBuffer, 32, "%" B_PRIu32, value);
214	fItemBufferUpto = 0;
215}