1e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk/* 2e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Copyright (C) 2017 The Android Open Source Project 3e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 4e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * you may not use this file except in compliance with the License. 6e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * You may obtain a copy of the License at 7e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 8e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 9e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 10e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Unless required by applicable law or agreed to in writing, software 11e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * See the License for the specific language governing permissions and 14e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * limitations under the License. 15e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk */ 16e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 17e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <stdint.h> 18e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <memory.h> 19e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 20e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "FixedBlockAdapter.h" 21e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 22e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "FixedBlockReader.h" 23e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 24e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 25e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil BurkFixedBlockReader::FixedBlockReader(FixedBlockProcessor &fixedBlockProcessor) 26e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk : FixedBlockAdapter(fixedBlockProcessor) { 27e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mPosition = mSize; 28e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 29e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 30e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkint32_t FixedBlockReader::open(int32_t bytesPerFixedBlock) { 31e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int32_t result = FixedBlockAdapter::open(bytesPerFixedBlock); 32e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mPosition = mSize; // Indicate no data in storage. 33e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return result; 34e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 35e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 36e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkint32_t FixedBlockReader::readFromStorage(uint8_t *buffer, int32_t numBytes) { 37e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int32_t bytesToRead = numBytes; 38e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int32_t dataAvailable = mSize - mPosition; 39e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (bytesToRead > dataAvailable) { 40e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk bytesToRead = dataAvailable; 41e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 42e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk memcpy(buffer, mStorage + mPosition, bytesToRead); 43e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mPosition += bytesToRead; 44e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return bytesToRead; 45e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 46e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 47e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkint32_t FixedBlockReader::processVariableBlock(uint8_t *buffer, int32_t numBytes) { 48e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int32_t result = 0; 49e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int32_t bytesLeft = numBytes; 50e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk while(bytesLeft > 0 && result == 0) { 51e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (mPosition < mSize) { 52e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Use up bytes currently in storage. 53e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int32_t bytesRead = readFromStorage(buffer, bytesLeft); 54e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk buffer += bytesRead; 55e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk bytesLeft -= bytesRead; 56e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } else if (bytesLeft >= mSize) { 57e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Read through if enough for a complete block. 58e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = mFixedBlockProcessor.onProcessFixedBlock(buffer, mSize); 59e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk buffer += mSize; 60e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk bytesLeft -= mSize; 61e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } else { 62e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Just need a partial block so we have to use storage. 63e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk result = mFixedBlockProcessor.onProcessFixedBlock(mStorage, mSize); 64e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mPosition = 0; 65e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 66e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 67e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return result; 68e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 69e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 70