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
22c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk#include "FixedBlockReader.h"
23c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk
24c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk
25c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil BurkFixedBlockReader::FixedBlockReader(FixedBlockProcessor &fixedBlockProcessor)
26c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    : FixedBlockAdapter(fixedBlockProcessor) {
27c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    mPosition = mSize;
28c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk}
29c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk
30c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burkint32_t FixedBlockReader::open(int32_t bytesPerFixedBlock) {
31c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    int32_t result = FixedBlockAdapter::open(bytesPerFixedBlock);
32c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    mPosition = mSize; // Indicate no data in storage.
33c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    return result;
34c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk}
35c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk
36c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burkint32_t FixedBlockReader::readFromStorage(uint8_t *buffer, int32_t numBytes) {
37c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    int32_t bytesToRead = numBytes;
38c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    int32_t dataAvailable = mSize - mPosition;
39c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    if (bytesToRead > dataAvailable) {
40c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk        bytesToRead = dataAvailable;
41c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    }
42c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    memcpy(buffer, mStorage + mPosition, bytesToRead);
43c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    mPosition += bytesToRead;
44c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    return bytesToRead;
45c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk}
46c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk
47c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burkint32_t FixedBlockReader::processVariableBlock(uint8_t *buffer, int32_t numBytes) {
48c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    int32_t result = 0;
49c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    int32_t bytesLeft = numBytes;
50c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    while(bytesLeft > 0 && result == 0) {
51c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk        if (mPosition < mSize) {
52c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            // Use up bytes currently in storage.
53c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            int32_t bytesRead = readFromStorage(buffer, bytesLeft);
54c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            buffer += bytesRead;
55c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            bytesLeft -= bytesRead;
56c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk        } else if (bytesLeft >= mSize) {
57c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            // Read through if enough for a complete block.
58c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            result = mFixedBlockProcessor.onProcessFixedBlock(buffer, mSize);
59c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            buffer += mSize;
60c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            bytesLeft -= mSize;
61c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk        } else {
62c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            // Just need a partial block so we have to use storage.
63c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            result = mFixedBlockProcessor.onProcessFixedBlock(mStorage, mSize);
64c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk            mPosition = 0;
65c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk        }
66c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    }
67c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk    return result;
68c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk}
69c8f372c22a0e4c667a3ad3c1ec569032574c1d64Phil Burk
70