#include "Vec_ZZ_p.h"

Vec_ZZ_p::Vec_ZZ_p(int len)
{           
	if(len <= 0)//初始化长度非法。
	{
		length = 0;
		v = nullptr; 
		std::cerr<<"bad Vector size."<<std::endl;
		exit(1);
	}
	length = len;
	v = new unsigned char[length];//内存分配。
	memset(v,0,len * sizeof(unsigned char));

}

Vec_ZZ_p::~Vec_ZZ_p(void)
{
	length = 0;
	if(this->v != nullptr)
		delete []this->v;
}
int Vec_ZZ_p::getlength()const
{
	return length;
}

void Vec_ZZ_p::put(int index,unsigned char num)
{
	v[index] = num % THREE;
}
unsigned char& Vec_ZZ_p::operator[](unsigned int index)
{
	return v[index];
}
unsigned char& Vec_ZZ_p::operator[](unsigned int index)const
{
	return v[index];
}
Vec_ZZ_p::Vec_ZZ_p(const Vec_ZZ_p& vec)
{
	this->length = vec.getlength();
	if(this->length != 0)
	{
		v = new unsigned char[length];
		memcpy((void*)v,(void*)vec.v, length * sizeof(unsigned char));
	}
	else 
		v = NULL;
	
	
}
Vec_ZZ_p& Vec_ZZ_p::operator=(const Vec_ZZ_p& vec)
{
	if(this == &vec)
		return *this;
	length = vec.length;
	v = new unsigned char[length];	
	memcpy((void*)v,(void*)vec.v,length * sizeof(unsigned char));
	return *this;
}

Vec_ZZ_p& Vec_ZZ_p::operator+=(const Vec_ZZ_p &a)
{
	if(!a.v) return *this;
	if(a.length != length)
	{
		std::cerr << "error vector add equal due to dim different！"<< std::endl;
		std::abort();
	}
	for (int i = 0;i < length;i++)
		this->v[i] = (this->v[i] + a.v[i]) % THREE;
	return *this;

}
Vec_ZZ_p& Vec_ZZ_p::operator-=(const Vec_ZZ_p &a)
{
	if(!a.v) return *this;
	if(a.length != length)
	{
		std::cerr << "error vector sub equal due to dim different！"<< std::endl;
		std::abort();
	}
	for (int i = 0;i < length;i++)
		this->v[i] = (THREE + this->v[i] - a.v[i]) % THREE;
	return *this;
}
Vec_ZZ_p operator+(const Vec_ZZ_p &a,const Vec_ZZ_p& b)
{
	Vec_ZZ_p tmp = a;
    tmp += b;
    return tmp;
}
Vec_ZZ_p operator-(const Vec_ZZ_p &a,const Vec_ZZ_p& b)
{
	Vec_ZZ_p tmp = a;
    tmp -= b;
    return tmp;
}

Vec_ZZ_p operator*(int a,const Vec_ZZ_p& b)
{
	Vec_ZZ_p tmp(b.length);
	if(a == 0)
		return tmp;
	else if(a == 1)
		return b;
	for (int i = 0;i < b.length;i++)
		tmp.v[i] = (a * b.v[i]) % 3;
	return tmp;
}
Vec_ZZ_p operator*(const Vec_ZZ_p& b,int a)
{
	Vec_ZZ_p tmp(b.length);
	if(a == 0)
		return tmp;
	else if(a == 1)
		return b;
	for (int i = 0;i < b.length;i++)
		tmp.v[i] = (a * b.v[i]) % 3;
	return tmp;
}
Vec_ZZ_p operator%(const Vec_ZZ_p& b,int a)
{
	Vec_ZZ_p tmp(b.length);
	for (int i = 0;i < b.length;i++)
		tmp[i] = b[i] % a;
	return tmp;
}


//std::ofstream &operator<<(std::ofstream &os,const Vec_ZZ_p &a)
//{
//	os << "[";
//	for(int i = 0;i < a.getlength() - 1;i++)
//	{
//		//os << a[i] << " ";
//		os.write((char*)&a[i],sizeof(a[i])) ;
//		os<< " ";
//	}		
//	//os.write((char*)&a[a.getlength() - 1],sizeof(a[a.getlength() - 1]));
//	os << "]";
//	return os;
//}
//std::ifstream &operator>>(std::ifstream &is,Vec_ZZ_p &a)
//{
//	for(int i = 0;i < a.getlength();i++)
//		is.read((char*)(&a.v[i]),sizeof(a[i]));
//	//is >> "]";
//	return is;
//}
std::ostream &operator<<(std::ostream &os,const Vec_ZZ_p &a)
{
	os << "[";
	for(int i = 0;i < a.getlength() - 1;i++)
		os <<(int)a[i] << " ";
	os << (int)(a[a.getlength() - 1]);
	os << "]";
	return os;
}

void Vec_ZZ_p:: print()
{
	std::cout << "[";
	for(int i = 0;i < length - 1;i++)
		std::cout <<(int)v[i] << " ";
	std::cout << (int)v[length - 1];
	std::cout << "]";
}

bool Vec_ZZ_p::SaveToTxt(const char *filename)//保存为文件
{
	std::ofstream file(filename,std::ios::app);
    if(!file)
        return false;
    for(int i = 0;i < length;i++)
        file << (int)(*(v + i));
    file.close();
    return true;
}
bool Vec_ZZ_p::LoadFromTxt(const char *filename)
{
	std::ifstream file(filename,std::ios::in);
	assert(file);
	if(!file)
		return false;
	for(int i = 0;i < length;i++)
	{
		char ch;
		file >> ch;
		v[i] = ch - '0';
	}		
	file.close();
    return true;
}
