xref: /haiku/src/tests/kits/shared/FakeJsonDataGenerator.cpp (revision 35c4600e215ec42e39fe5fbaeda10a9f4e2d8884)
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 
13 static const char* kTextData = "abcdefghijklmnopqrstuvwxyz!@#$"
14 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ)(*&"
15 	"0123456789{}[]|:;'<>,.?/~`_+-="
16 	"abcdefghijklmnopqrstuvwxyz!@#$"
17 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ)(*&"
18 	"0123456789{}[]|:;'<>,.?/~`_+-=";
19 static const int kTextDataLength = 180;
20 
21 
FakeJsonStreamDataIO(int count,uint32 checksumLimit)22 FakeJsonStreamDataIO::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 
~FakeJsonStreamDataIO()33 FakeJsonStreamDataIO::~FakeJsonStreamDataIO()
34 {
35 }
36 
37 
38 ssize_t
Read(void * buffer,size_t size)39 FakeJsonStreamDataIO::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 
58 ssize_t
Write(const void * buffer,size_t size)59 FakeJsonStreamDataIO::Write(const void* buffer, size_t size)
60 {
61 	return B_NOT_SUPPORTED;
62 }
63 
64 
65 status_t
Flush()66 FakeJsonStreamDataIO::Flush()
67 {
68 	return B_OK;
69 }
70 
71 
72 uint32
Checksum() const73 FakeJsonStreamDataIO::Checksum() const
74 {
75 	return fChecksum;
76 }
77 
78 
79 void
_ChecksumProcessCharacter(const char c)80 FakeJsonStreamDataIO::_ChecksumProcessCharacter(const char c)
81 {
82 	fChecksum = (fChecksum + static_cast<int32>(c)) % fChecksumLimit;
83 }
84 
85 
86 // #pragma mark - FakeJsonStringStreamDataIO
87 
88 
FakeJsonStringStreamDataIO(int count,uint32 checksumLimit)89 FakeJsonStringStreamDataIO::FakeJsonStringStreamDataIO(int count, uint32 checksumLimit)
90 	:
91 	FakeJsonStreamDataIO(count, checksumLimit),
92 	fItemBufferSize(0),
93 	fItemBufferUpto(0)
94 {
95 	FillBuffer();
96 }
97 
98 
~FakeJsonStringStreamDataIO()99 FakeJsonStringStreamDataIO::~FakeJsonStringStreamDataIO()
100 {
101 }
102 
103 
104 status_t
NextChar(char * c)105 FakeJsonStringStreamDataIO::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 
147 void
FillBuffer()148 FakeJsonStringStreamDataIO::FillBuffer()
149 {
150 	fItemBufferSize = random() % kTextDataLength;
151 	fItemBufferUpto = 0;
152 }
153 
154 
155 // #pragma mark - FakeJsonStringStreamDataIO
156 
157 
FakeJsonNumberStreamDataIO(int count,uint32 checksumLimit)158 FakeJsonNumberStreamDataIO::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 
~FakeJsonNumberStreamDataIO()169 FakeJsonNumberStreamDataIO::~FakeJsonNumberStreamDataIO()
170 {
171 }
172 
173 
174 status_t
NextChar(char * c)175 FakeJsonNumberStreamDataIO::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 
209 void
FillBuffer()210 FakeJsonNumberStreamDataIO::FillBuffer()
211 {
212 	int32 value = static_cast<int32>(random());
213 	fItemBufferSize = snprintf(fBuffer, 32, "%" B_PRIu32, value);
214 	fItemBufferUpto = 0;
215 }