116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2006 The Android Open Source Project
316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License.
616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at
716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
816c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software
1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and
1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License.
1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef _ANDROID__DATABASE_WINDOW_H
1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define _ANDROID__DATABASE_WINDOW_H
1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2045e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov#include <inttypes.h>
2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stddef.h>
2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdint.h>
2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <binder/Parcel.h>
2552eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h>
2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/String8.h>
2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if LOG_NDEBUG
2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define IF_LOG_WINDOW() if (false)
3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_WINDOW(...)
3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#else
3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, "CursorWindow")
3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_WINDOW(...) ALOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski/**
4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This class stores a set of rows from a database in a buffer. The begining of the
4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * window has first chunk of RowSlots, which are offsets to the row directory, followed by
4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * FieldSlot per column, which has the size, offset, and type of the data for that field.
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Note that the data types come from sqlite3.h.
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Strings are stored in UTF-8.
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
5216c4d154dca43c662571129af31b27433b919a32Adam Lesinskiclass CursorWindow {
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    CursorWindow(const String8& name, int ashmemFd,
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski            void* data, size_t size, bool readOnly);
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5616c4d154dca43c662571129af31b27433b919a32Adam Lesinskipublic:
5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /* Field types. */
5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    enum {
5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_NULL = 0,
6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_INTEGER = 1,
6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_FLOAT = 2,
6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_STRING = 3,
6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_BLOB = 4,
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /* Opaque type that describes a field slot. */
6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct FieldSlot {
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    private:
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        int32_t type;
7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        union {
7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski            double d;
7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski            int64_t l;
7316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            struct {
7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski                uint32_t offset;
7516c4d154dca43c662571129af31b27433b919a32Adam Lesinski                uint32_t size;
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski            } buffer;
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        } data;
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        friend class CursorWindow;
8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    } __attribute((packed));
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ~CursorWindow();
8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);
8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);
8616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t writeToParcel(Parcel* parcel);
8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline String8 name() { return mName; }
9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline size_t size() { return mSize; }
9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline size_t freeSpace() { return mSize - mHeader->freeOffset; }
9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline uint32_t getNumRows() { return mHeader->numRows; }
9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline uint32_t getNumColumns() { return mHeader->numColumns; }
9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t clear();
9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t setNumColumns(uint32_t numColumns);
9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /**
9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Allocate a row slot and its directory.
10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * The row is initialized will null entries for each field.
10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t allocRow();
10316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t freeLastRow();
10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);
10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);
10716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putLong(uint32_t row, uint32_t column, int64_t value);
10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putDouble(uint32_t row, uint32_t column, double value);
10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putNull(uint32_t row, uint32_t column);
11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /**
11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Gets the field slot at the specified row and column.
11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Returns null if the requested row or column is not in the window.
11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    FieldSlot* getFieldSlot(uint32_t row, uint32_t column);
11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {
11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return fieldSlot->type;
11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {
12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return fieldSlot->data.l;
12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {
12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return fieldSlot->data.d;
12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,
13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski            size_t* outSizeIncludingNull) {
13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        *outSizeIncludingNull = fieldSlot->data.buffer.size;
13245e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov        return static_cast<char*>(offsetToPtr(
13345e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov                fieldSlot->data.buffer.offset, fieldSlot->data.buffer.size));
13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {
13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        *outSize = fieldSlot->data.buffer.size;
13845e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov        return offsetToPtr(fieldSlot->data.buffer.offset, fieldSlot->data.buffer.size);
13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14116c4d154dca43c662571129af31b27433b919a32Adam Lesinskiprivate:
14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;
14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct Header {
14516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        // Offset of the lowest unused byte in the window.
14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t freeOffset;
14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        // Offset of the first row slot chunk.
14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t firstChunkOffset;
15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t numRows;
15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t numColumns;
15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct RowSlot {
15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t offset;
15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct RowSlotChunk {
16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];
16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t nextChunkOffset;
16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    String8 mName;
16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int mAshmemFd;
16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    void* mData;
16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mSize;
16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool mReadOnly;
16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    Header* mHeader;
17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17145e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov    inline void* offsetToPtr(uint32_t offset, uint32_t bufferSize = 0) {
17245e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov        if (offset >= mSize) {
17345e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov            ALOGE("Offset %" PRIu32 " out of bounds, max value %zu", offset, mSize);
17445e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov            return NULL;
17545e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov        }
17645e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov        if (offset + bufferSize > mSize) {
17745e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov            ALOGE("End offset %" PRIu32 " out of bounds, max value %zu",
17845e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov                    offset + bufferSize, mSize);
17945e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov            return NULL;
18045e2e95c2ffeb2d978e2cce80b729ef6ada3b8d2Fyodor Kupolov        }
18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return static_cast<uint8_t*>(mData) + offset;
18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
18416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline uint32_t offsetFromPtr(void* ptr) {
18516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);
18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
18816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /**
18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Allocate a portion of the window. Returns the offset
19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * of the allocation, or 0 if there isn't enough space.
19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * If aligned is true, the allocation gets 4 byte alignment.
19216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
19316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    uint32_t alloc(size_t size, bool aligned = false);
19416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    RowSlot* getRowSlot(uint32_t row);
19616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    RowSlot* allocRowSlot();
19716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putBlobOrString(uint32_t row, uint32_t column,
19916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            const void* value, size_t size, int32_t type);
20016c4d154dca43c662571129af31b27433b919a32Adam Lesinski};
20116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
20216c4d154dca43c662571129af31b27433b919a32Adam Lesinski}; // namespace android
20316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
20416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
205