/* Copyright (C) 2014 InfiniDB, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; version 2 of
   the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301, USA. */

/*
 * $Id: elementtype.cpp 9655 2013-06-25 23:08:13Z xlou $
 */

#include <iostream>
#include <utility>
#include <string>
#include <sstream>
using namespace std;

#include "elementtype.h"
using namespace joblist;

namespace joblist
{

StringElementType::StringElementType() { };

StringElementType::StringElementType(uint64_t f, const std::string& s) : first(f), second(s) { };

DoubleElementType::DoubleElementType() { };

DoubleElementType::DoubleElementType(uint64_t f, double s) : first(f), second(s) { };

RIDElementType::RIDElementType()
{
    first = static_cast<uint64_t>(-1);
};

RIDElementType::RIDElementType(uint64_t f) : first(f) { };

const string ElementType::toString() const
{
    ostringstream oss;
    oss << first << '/' << second;
    return oss.str();
}

istream& operator>>(istream& in, ElementType& rhs)
{
    in.read((char*) &rhs, sizeof(ElementType));
    return in;
}

ostream& operator<<(ostream& out, const ElementType& rhs)
{
    out.write((char*) &rhs, sizeof(ElementType));
    return out;
}

ostream& operator<<(std::ostream& out, const StringElementType& rhs)
{
    uint64_t r = rhs.first;
    int16_t dlen = rhs.second.length();

    out.write((char*)&r, sizeof(r));
    out.write( (char*)&dlen, sizeof(dlen));
    out.write( rhs.second.c_str(), dlen);

    return out;
}

istream& operator>>(std::istream& out, StringElementType& rhs)
{
    uint64_t r;
    int16_t dlen;
    char d[32768];   // atm 32k is the largest possible val for the length of strings stored

    out.read((char*)&r, sizeof(r));
    out.read( (char*)&dlen, sizeof(dlen));
    out.read( (char*)&d, dlen);

    rhs.first = r;
    rhs.second = string(d, dlen);

    return out;
}

istream& operator>>(istream& in, DoubleElementType& rhs)
{
    in.read((char*) &rhs, sizeof(DoubleElementType));
    return in;
}

ostream& operator<<(ostream& out, const DoubleElementType& rhs)
{
    out.write((char*) &rhs, sizeof(DoubleElementType));
    return out;
}

istream& operator>>(istream& is, RIDElementType& dl)
{
    is.read((char*)&dl, sizeof(RIDElementType));
    return is;
}

ostream& operator<<(ostream& os, const RIDElementType& dl)
{
    os.write((char*)&dl, sizeof(RIDElementType));
    return os;
}

istream& operator>>(istream& is, TupleType& dl)
{
    throw std::logic_error("TupleType >> not implemented");
}

ostream& operator<<(ostream& os, const TupleType& dl)
{
    throw std::logic_error("TupleType << not implemented");
}

} // namespace joblist

