xref: /haiku/src/apps/haikudepot/util/DataIOUtils.cpp (revision 7eab6b486ebadb54ca3c306601f4b04dd92359fa)
1 /*
2  * Copyright 2018-2023, Andrew Lindesay <apl@lindesay.co.nz>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 #include "DataIOUtils.h"
6 
7 
8 #define BUFFER_SIZE 1024
9 
10 
11 /*static*/ status_t
12 DataIOUtils::CopyAll(BDataIO* target, BDataIO* source)
13 {
14 	status_t result = B_OK;
15 	uint8 buffer[BUFFER_SIZE];
16 	size_t sizeRead = 0;
17 
18 	do {
19 		result = source->ReadExactly(buffer, BUFFER_SIZE, &sizeRead);
20 
21 		switch (result)
22 		{
23 			case B_OK:
24 			case B_PARTIAL_READ:
25 				result = target->WriteExactly(buffer, sizeRead);
26 				break;
27 		}
28 	} while(result == B_OK && sizeRead > 0);
29 
30 	return result;
31 }
32 
33 
34 // #pragma mark - ConstraintedDataIO
35 
36 ConstraintedDataIO::ConstraintedDataIO(BDataIO* delegate, size_t limit)
37 	:
38 	fDelegate(delegate),
39 	fLimit(limit)
40 {
41 }
42 
43 
44 ConstraintedDataIO::~ConstraintedDataIO()
45 {
46 }
47 
48 
49 ssize_t
50 ConstraintedDataIO::Read(void* buffer, size_t size)
51 {
52 	if (size > fLimit)
53 		size = fLimit;
54 
55 	ssize_t actualRead = fDelegate->Read(buffer, size);
56 
57 	if (actualRead > 0)
58 		fLimit -= actualRead;
59 
60 	return actualRead;
61 }
62 
63 
64 ssize_t
65 ConstraintedDataIO::Write(const void* buffer, size_t size)
66 {
67 	return B_NOT_SUPPORTED;
68 }
69 
70 
71 status_t
72 ConstraintedDataIO::Flush()
73 {
74 	return B_OK;
75 }
76 
77 
78 // #pragma mark - Base64DecodingDataIO
79 
80 Base64DecodingDataIO::Base64DecodingDataIO(BDataIO* delegate, char char62, char char63)
81 	:
82 	fDelegate(delegate),
83 	fChar62(char62),
84 	fChar63(char63),
85 	fNextByteAssembly(0),
86     fNextByteAssemblyBits(0)
87 {
88 }
89 
90 
91 Base64DecodingDataIO::~Base64DecodingDataIO()
92 {
93 }
94 
95 
96 status_t
97 Base64DecodingDataIO::_CharToInt(uint8 ch, uint8* value)
98 {
99 	if (ch >= 0x41 && ch <= 0x5A) {
100 		*value = (ch - 0x41);
101 		return B_OK;
102 	}
103 
104 	if (ch >= 0x61 && ch <= 0x7a) {
105 		*value = (ch - 0x61) + 26;
106 		return B_OK;
107 	}
108 
109 	if (ch >= 0x30 && ch <= 0x39) {
110 		*value = (ch - 0x30) + 52;
111 		return B_OK;
112 	}
113 
114 	if (ch == fChar62) {
115 		*value = 62;
116 		return B_OK;
117 	}
118 
119 	if (ch == fChar63) {
120 		*value = 63;
121 		return B_OK;
122 	}
123 
124 	if (ch == '=') {
125 		*value = 0;
126 		return B_OK;
127 	}
128 
129 	return B_BAD_DATA;
130 }
131 
132 
133 status_t
134 Base64DecodingDataIO::_ReadSingleByte(void* buffer)
135 {
136 	uint8 delegateRead;
137 	uint8 delegateReadInt;
138 	status_t result = B_OK;
139 
140 	if (result == B_OK)
141 		result = fDelegate->ReadExactly(&delegateRead, 1);
142 
143 	if (result == B_OK)
144 		result = _CharToInt(delegateRead, &delegateReadInt);
145 
146 	if (result == B_OK && 0 == fNextByteAssemblyBits) {
147 		fNextByteAssembly = delegateReadInt;
148 		fNextByteAssemblyBits = 6;
149 		return _ReadSingleByte(buffer);
150 	}
151 
152 	if (result == B_OK) {
153 		uint8 followingNextByteAssemblyBits = (6 - (8 - fNextByteAssemblyBits));
154 		*((uint8 *) buffer) = fNextByteAssembly << (8 - fNextByteAssemblyBits)
155 			| (delegateReadInt >> followingNextByteAssemblyBits);
156 		fNextByteAssembly = delegateReadInt & (0x3f >> (6 - followingNextByteAssemblyBits));
157 		fNextByteAssemblyBits = followingNextByteAssemblyBits;
158 	}
159 
160 	return result;
161 }
162 
163 
164 ssize_t
165 Base64DecodingDataIO::Read(void* buffer, size_t size)
166 {
167 	size_t readSize = 0;
168 	status_t result = B_OK;
169 
170 	while (result == B_OK && readSize < size) {
171 		result = _ReadSingleByte(&((uint8_t*) buffer)[readSize]);
172 
173 		if (result == B_OK)
174 			readSize++;
175 	}
176 
177 	return readSize++;
178 }
179 
180 
181 ssize_t
182 Base64DecodingDataIO::Write(const void* buffer, size_t size)
183 {
184 	return B_NOT_SUPPORTED;
185 }
186 
187 
188 status_t
189 Base64DecodingDataIO::Flush()
190 {
191 	return B_OK;
192 }