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