/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SYSTEM_KEYMASTER_SERIALIZABLE_H_
#define SYSTEM_KEYMASTER_SERIALIZABLE_H_

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <stddef.h>
#include <keymaster/new>
// #include <new>

#include <keymaster/UniquePtr.h>

namespace keymaster {

class Serializable {
  public:
    Serializable() {}
    virtual ~Serializable() {}

    /**
     * Return the size of the serialized representation of this object.
     */
    virtual size_t SerializedSize() const = 0;

    /**
     * Serialize this object into the provided buffer.  Returns a pointer to the byte after the last
     * written.  Will not write past \p end, which should point to \p buf + size of the buffer
     * (i.e. one past the end of the buffer).
     */
    virtual uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const = 0;

    /**
     * Deserialize from the provided buffer, copying the data into newly-allocated storage.  Returns
     * true if successful, and advances *buf past the bytes read.
     */
    virtual bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) = 0;

    // Disallow copying and assignment.
    Serializable(const Serializable&) = delete;
    Serializable& operator=(const Serializable&) = delete;

    // Move only.
    Serializable(Serializable&&) = default;
    Serializable& operator=(Serializable&&) = default;
};

/*
 * Utility functions for writing Serialize() methods
 */

/**
 * Convert a pointer into a value.  This is used to make sure compiler won't optimize away pointer
 * overflow checks. (See http://www.kb.cert.org/vuls/id/162289)
 */
template <typename T> inline uintptr_t __pval(const T *p) {
    return reinterpret_cast<uintptr_t>(p);
}

/**
 * Append a byte array to a buffer.  Note that by itself this function isn't very useful, because it
 * provides no indication in the serialized buffer of what the array size is.  For writing arrays,
 * see \p append_size_and_data_to_buf().
 *
 * Returns a pointer to the first byte after the data written.
 */
uint8_t* append_to_buf(uint8_t* buf, const uint8_t* end, const void* data, size_t data_len);

/**
 * Append some type of value convertible to a uint32_t to a buffer.  This is primarily used for
 * writing enumerated values, and uint32_ts.
 *
 * Returns a pointer to the first byte after the data written.
 */
template <typename T>
inline uint8_t* append_uint32_to_buf(uint8_t* buf, const uint8_t* end, T value) {
    uint32_t val = static_cast<uint32_t>(value);
    return append_to_buf(buf, end, &val, sizeof(val));
}

/**
 * Append a uint64_t to a buffer.  Returns a pointer to the first byte after the data written.
 */
inline uint8_t* append_uint64_to_buf(uint8_t* buf, const uint8_t* end, uint64_t value) {
    return append_to_buf(buf, end, &value, sizeof(value));
}

/**
 * Appends a byte array to a buffer, prefixing it with a 32-bit size field.  Returns a pointer to
 * the first byte after the data written.
 *
 * See copy_size_and_data_from_buf().
 */
inline uint8_t* append_size_and_data_to_buf(uint8_t* buf, const uint8_t* end, const void* data,
                                            size_t data_len) {
    buf = append_uint32_to_buf(buf, end, data_len);
    return append_to_buf(buf, end, data, data_len);
}

/**
 * Appends an array of values that are convertible to uint32_t as uint32ts to a buffer, prefixing a
 * count so deserialization knows how many values to read.
 *
 * See copy_uint32_array_from_buf().
 */
template <typename T>
inline uint8_t* append_uint32_array_to_buf(uint8_t* buf, const uint8_t* end, const T* data,
                                           size_t count) {
    // Check for overflow
    if (count >= (UINT32_MAX / sizeof(uint32_t)) ||
        __pval(buf) + count * sizeof(uint32_t) < __pval(buf))
        return buf;
    buf = append_uint32_to_buf(buf, end, count);
    for (size_t i = 0; i < count; ++i)
        buf = append_uint32_to_buf(buf, end, static_cast<uint32_t>(data[i]));
    return buf;
}

/*
 * Utility functions for writing Deserialize() methods.
 */

/**
 * Copy \p size bytes from \p *buf_ptr into \p dest.  If there are fewer than \p size bytes to read,
 * returns false.  Advances *buf_ptr to the next byte to be read.
 */
bool copy_from_buf(const uint8_t** buf_ptr, const uint8_t* end, void* dest, size_t size);

/**
 * Extracts a uint32_t size from *buf_ptr, placing it in \p *size, and then reads *size bytes from
 * *buf_ptr, placing them in newly-allocated storage in *dest.  If there aren't enough bytes in
 * *buf_ptr, returns false.  Advances \p *buf_ptr to the next byte to be read.
 *
 * See \p append_size_and_data_to_buf().
 */
bool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, size_t* size,
                                 UniquePtr<uint8_t[]>* dest);

/**
 * Copies a value convertible from uint32_t from \p *buf_ptr.  Returns false if there are less than
 * four bytes remaining in \p *buf_ptr.  Advances \p *buf_ptr to the next byte to be read.
 */
template <typename T>
inline bool copy_uint32_from_buf(const uint8_t** buf_ptr, const uint8_t* end, T* value) {
    uint32_t val;
    if (!copy_from_buf(buf_ptr, end, &val, sizeof(val)))
        return false;
    *value = static_cast<T>(val);
    return true;
}

/**
 * Copies a uint64_t from \p *buf_ptr.  Returns false if there are less than eight bytes remaining
 * in \p *buf_ptr.  Advances \p *buf_ptr to the next byte to be read.
 */
inline bool copy_uint64_from_buf(const uint8_t** buf_ptr, const uint8_t* end, uint64_t* value) {
    return copy_from_buf(buf_ptr, end, value, sizeof(*value));
}

/**
 * Copies an array of values convertible to uint32_t from \p *buf_ptr, first reading a count of
 * values to read. The count is returned in \p *count and the values returned in newly-allocated
 * storage at *data.  Returns false if there are insufficient bytes at \p *buf_ptr.  Advances \p
 * *buf_ptr to the next byte to be read.
 */
template <typename T>
inline bool copy_uint32_array_from_buf(const uint8_t** buf_ptr, const uint8_t* end,
                                       UniquePtr<T[]>* data, size_t* count) {
    if (!copy_uint32_from_buf(buf_ptr, end, count))
        return false;

    uintptr_t array_end = __pval(*buf_ptr) + *count * sizeof(uint32_t);
    if (*count >= UINT32_MAX / sizeof(uint32_t) ||
        array_end < __pval(*buf_ptr) || array_end > __pval(end))
        return false;

    data->reset(new (std::nothrow) T[*count]);
    if (!data->get())
        return false;
    for (size_t i = 0; i < *count; ++i)
        if (!copy_uint32_from_buf(buf_ptr, end, &(*data)[i]))
            return false;
    return true;
}

/**
 * A simple buffer that supports reading and writing.  Manages its own memory.
 */
class Buffer : public Serializable {
  public:
    Buffer() : buffer_(nullptr), buffer_size_(0), read_position_(0), write_position_(0) {}
    explicit Buffer(size_t size) : buffer_(nullptr) { Reinitialize(size); }
    Buffer(const void* buf, size_t size) : buffer_(nullptr) { Reinitialize(buf, size); }

    // Grow the buffer so that at least \p size bytes can be written.
    bool reserve(size_t size);

    bool Reinitialize(size_t size);
    bool Reinitialize(const void* buf, size_t size);

    // Reinitialize with a copy of the provided buffer's readable data.
    bool Reinitialize(const Buffer& buffer) {
        return Reinitialize(buffer.peek_read(), buffer.available_read());
    }

    const uint8_t* begin() const { return peek_read(); }
    const uint8_t* end() const { return peek_read() + available_read(); }

    void Clear();

    size_t available_write() const;
    size_t available_read() const;
    size_t buffer_size() const { return buffer_size_; }

    bool write(const uint8_t* src, size_t write_length);
    bool read(uint8_t* dest, size_t read_length);
    const uint8_t* peek_read() const { return buffer_.get() + read_position_; }
    bool advance_read(int distance) {
        if (static_cast<size_t>(read_position_ + distance) <= write_position_) {
            read_position_ += distance;
            return true;
        }
        return false;
    }
    uint8_t* peek_write() { return buffer_.get() + write_position_; }
    bool advance_write(int distance) {
        if (static_cast<size_t>(write_position_ + distance) <= buffer_size_) {
            write_position_ += distance;
            return true;
        }
        return false;
    }

    size_t SerializedSize() const;
    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const;
    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);

  private:
    // Disallow copy construction and assignment.
    void operator=(const Buffer& other);
    Buffer(const Buffer&);

    UniquePtr<uint8_t[]> buffer_;
    size_t buffer_size_;
    size_t read_position_;
    size_t write_position_;
};

}  // namespace keymaster

#endif  // SYSTEM_KEYMASTER_SERIALIZABLE_H_
