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
2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <cutils/log.h>
2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stddef.h>
2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdint.h>
2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <binder/Parcel.h>
2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/String8.h>
2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#if LOG_NDEBUG
2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define IF_LOG_WINDOW() if (false)
3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_WINDOW(...)
3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#else
3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, "CursorWindow")
3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_WINDOW(...) ALOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/**
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * This class stores a set of rows from a database in a buffer. The begining of the
4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * window has first chunk of RowSlots, which are offsets to the row directory, followed by
4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case
4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * FieldSlot per column, which has the size, offset, and type of the data for that field.
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Note that the data types come from sqlite3.h.
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Strings are stored in UTF-8.
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinskiclass CursorWindow {
5216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    CursorWindow(const String8& name, int ashmemFd,
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            void* data, size_t size, bool readOnly);
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinskipublic:
5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /* Field types. */
5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    enum {
5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_NULL = 0,
5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_INTEGER = 1,
6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_FLOAT = 2,
6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_STRING = 3,
6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        FIELD_TYPE_BLOB = 4,
6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /* Opaque type that describes a field slot. */
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct FieldSlot {
6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    private:
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        int32_t type;
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        union {
7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski            double d;
7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski            int64_t l;
7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski            struct {
7316c4d154dca43c662571129af31b27433b919a32Adam Lesinski                uint32_t offset;
7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski                uint32_t size;
7516c4d154dca43c662571129af31b27433b919a32Adam Lesinski            } buffer;
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        } data;
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        friend class CursorWindow;
7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    } __attribute((packed));
8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ~CursorWindow();
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);
8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t writeToParcel(Parcel* parcel);
8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline String8 name() { return mName; }
8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline size_t size() { return mSize; }
9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline size_t freeSpace() { return mSize - mHeader->freeOffset; }
9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline uint32_t getNumRows() { return mHeader->numRows; }
9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline uint32_t getNumColumns() { return mHeader->numColumns; }
9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t clear();
9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t setNumColumns(uint32_t numColumns);
9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /**
9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Allocate a row slot and its directory.
9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * The row is initialized will null entries for each field.
10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t allocRow();
10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t freeLastRow();
10316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);
10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);
10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putLong(uint32_t row, uint32_t column, int64_t value);
10716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putDouble(uint32_t row, uint32_t column, double value);
10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putNull(uint32_t row, uint32_t column);
10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /**
11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Gets the field slot at the specified row and column.
11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Returns null if the requested row or column is not in the window.
11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    FieldSlot* getFieldSlot(uint32_t row, uint32_t column);
11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {
11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return fieldSlot->type;
11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {
12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return fieldSlot->data.l;
12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {
12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return fieldSlot->data.d;
12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,
12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            size_t* outSizeIncludingNull) {
13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        *outSizeIncludingNull = fieldSlot->data.buffer.size;
13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return static_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));
13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {
13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        *outSize = fieldSlot->data.buffer.size;
13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return offsetToPtr(fieldSlot->data.buffer.offset);
13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13916c4d154dca43c662571129af31b27433b919a32Adam Lesinskiprivate:
14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;
14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct Header {
14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        // Offset of the lowest unused byte in the window.
14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t freeOffset;
14516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        // Offset of the first row slot chunk.
14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t firstChunkOffset;
14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t numRows;
15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t numColumns;
15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct RowSlot {
15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t offset;
15516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    struct RowSlotChunk {
15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];
15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t nextChunkOffset;
16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    };
16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    String8 mName;
16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int mAshmemFd;
16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    void* mData;
16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t mSize;
16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool mReadOnly;
16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    Header* mHeader;
16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline void* offsetToPtr(uint32_t offset) {
17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return static_cast<uint8_t*>(mData) + offset;
17116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
17216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    inline uint32_t offsetFromPtr(void* ptr) {
17416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);
17516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
17616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    /**
17816c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * Allocate a portion of the window. Returns the offset
17916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * of the allocation, or 0 if there isn't enough space.
18016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     * If aligned is true, the allocation gets 4 byte alignment.
18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     */
18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    uint32_t alloc(size_t size, bool aligned = false);
18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
18416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    RowSlot* getRowSlot(uint32_t row);
18516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    RowSlot* allocRowSlot();
18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    status_t putBlobOrString(uint32_t row, uint32_t column,
18816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            const void* value, size_t size, int32_t type);
18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski};
19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski}; // namespace android
19216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
194