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 }