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 12DataIOUtils::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 36ConstraintedDataIO::ConstraintedDataIO(BDataIO* delegate, size_t limit) 37 : 38 fDelegate(delegate), 39 fLimit(limit) 40{ 41} 42 43 44ConstraintedDataIO::~ConstraintedDataIO() 45{ 46} 47 48 49ssize_t 50ConstraintedDataIO::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 64ssize_t 65ConstraintedDataIO::Write(const void* buffer, size_t size) 66{ 67 return B_NOT_SUPPORTED; 68} 69 70 71status_t 72ConstraintedDataIO::Flush() 73{ 74 return B_OK; 75} 76 77 78// #pragma mark - Base64DecodingDataIO 79 80Base64DecodingDataIO::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 91Base64DecodingDataIO::~Base64DecodingDataIO() 92{ 93} 94 95 96status_t 97Base64DecodingDataIO::_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 133status_t 134Base64DecodingDataIO::_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 164ssize_t 165Base64DecodingDataIO::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 181ssize_t 182Base64DecodingDataIO::Write(const void* buffer, size_t size) 183{ 184 return B_NOT_SUPPORTED; 185} 186 187 188status_t 189Base64DecodingDataIO::Flush() 190{ 191 return B_OK; 192}