<commit_before>/**
 * @file commands.cpp
 * @brief Implementation of various commands
 *
 * (c) 2013 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega/types.h"
#include "mega/command.h"
#include "mega/megaapp.h"
#include "mega/fileattributefetch.h"
#include "mega/base64.h"
#include "mega/transferslot.h"
#include "mega/transfer.h"
#include "mega/utils.h"
#include "mega/user.h"

namespace mega {

HttpReqCommandPutFA::HttpReqCommandPutFA(MegaClient* client, handle cth, fatype ctype, byte* cdata, unsigned clen)
{
	cmd("ufa");
	arg("s",clen);

	persistent = true;	// object will be recycled either for retry or for posting to the file attribute server

	th = cth;
	type = ctype;
	data = cdata;
	len = clen;

	binary = true;

	tag = client->reqtag;
}

HttpReqCommandPutFA::~HttpReqCommandPutFA()
{
	delete[] data;
}

void HttpReqCommandPutFA::procresult()
{
	if (client->json.isnumeric()) status = REQ_FAILURE;
	else
	{
		const char* p = NULL;

		for (;;)
		{
			switch (client->json.getnameid())
			{
				case 'p':
					p = client->json.getvalue();
					break;

				case EOO:
					if (!p) status = REQ_FAILURE;
					else
					{
						Node::copystring(&posturl,p);
						post(client,(char*)data,len);
					}
					return;

				default:
					if (!client->json.storeobject()) return client->app->putfa_result(th,type,API_EINTERNAL);
			}
		}
	}
}

CommandGetFA::CommandGetFA(int p, handle fahref)
{
	part = p;

	cmd("ufa");
	arg("fah",(byte*)&fahref,sizeof fahref);
}

void CommandGetFA::procresult()
{
	fafc_map::iterator it = client->fafcs.find(part);

	// (can never happen)
	if (it == client->fafcs.end()) return;

	if (client->json.isnumeric())
	{
		it->second->req.status = REQ_FAILURE;
		return;
	}

	const char* p = NULL;

	for (;;)
	{
		switch (client->json.getnameid())
		{
			case 'p':
				p = client->json.getvalue();
				break;

			case EOO:
				if (p)
				{
					string url;

					Node::copystring(&url,p);
					it->second->dispatch(client,part,url.c_str());
				}
				else it->second->req.status = REQ_FAILURE;
				return;

			default:
				if (!client->json.storeobject())
				{
					it->second->req.status = REQ_FAILURE;
					return;
				}
		}
	}
}

CommandAttachFA::CommandAttachFA(handle nh, fatype t, handle ah, int ctag)
{
	cmd("pfa");
	arg("n",(byte*)&nh,MegaClient::NODEHANDLE);

	char buf[64];

	sprintf(buf,"%u*",t);
	Base64::btoa((byte*)&ah,sizeof(ah),strchr(buf+2,0));
	arg("fa",buf);

	h = nh;
	type = t;
	tag = ctag;
}

void CommandAttachFA::procresult()
{
	client->app->putfa_result(h,type,client->json.isnumeric() ? (error)client->json.getint() : API_EINTERNAL);
}

// request upload target URL
CommandPutFile::CommandPutFile(TransferSlot* ctslot, int ms)
{
	tslot = ctslot;

	cmd("u");
	arg("s",tslot->file->size);
	arg("ms",ms);
}

void CommandPutFile::cancel()
{
	Command::cancel();
	tslot = NULL;
}

// set up file transfer with returned target URL
void CommandPutFile::procresult()
{
	if (tslot) tslot->pendingcmd = NULL;
	if (canceled) return;

	if (client->json.isnumeric()) return tslot->transfer->failed((error)client->json.getint());

	for (;;)
	{
		switch (client->json.getnameid())
		{
			case 'p':
				client->json.storeobject(&tslot->tempurl);
				break;

			case EOO:
				if (tslot->tempurl.size())
				{
					tslot->starttime = tslot->lastdata = client->waiter->ds;
					return tslot->progress();
				}
				else return tslot->transfer->failed(API_EINTERNAL);

			default:
				if (!client->json.storeobject()) return tslot->transfer->failed(API_EINTERNAL);
		}
	}
}

// request temporary source URL
// p == private node
CommandGetFile::CommandGetFile(TransferSlot* ctslot, byte* key, handle h, bool p)
{
	cmd("g");
	arg(p ? "n" : "p",(byte*)&h,MegaClient::NODEHANDLE);
	arg("g",1);

	tslot = ctslot;

	if (!tslot)
	{
		ph = h;
		memcpy(filekey,key,FILENODEKEYLENGTH);
	}
}

void CommandGetFile::cancel()
{
	Command::cancel();
	tslot = NULL;
}

// process file credentials
void CommandGetFile::procresult()
{
	if (tslot) tslot->pendingcmd = NULL;
	if (canceled) return;

	if (client->json.isnumeric())
	{
		if (tslot) return tslot->transfer->failed((error)client->json.getint());
		return client->app->checkfile_result(ph,(error)client->json.getint());
	}

	const char* at = NULL;
	error e = API_EINTERNAL;
	m_off_t s = -1;
	int d = 0;
	byte* buf;
	time_t ts = 0, tm = 0;

	// credentials relevant to a non-TransferSlot scenario (node query)
	string fileattrstring;
	string filenamestring;
	string filefingerprint;
debug = 1;
	for (;;)<commit_msg>Transfers: Removed debug = 1<commit_after>/**
 * @file commands.cpp
 * @brief Implementation of various commands
 *
 * (c) 2013 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega/types.h"
#include "mega/command.h"
#include "mega/megaapp.h"
#include "mega/fileattributefetch.h"
#include "mega/base64.h"
#include "mega/transferslot.h"
#include "mega/transfer.h"
#include "mega/utils.h"
#include "mega/user.h"

namespace mega {

HttpReqCommandPutFA::HttpReqCommandPutFA(MegaClient* client, handle cth, fatype ctype, byte* cdata, unsigned clen)
{
	cmd("ufa");
	arg("s",clen);

	persistent = true;	// object will be recycled either for retry or for posting to the file attribute server

	th = cth;
	type = ctype;
	data = cdata;
	len = clen;

	binary = true;

	tag = client->reqtag;
}

HttpReqCommandPutFA::~HttpReqCommandPutFA()
{
	delete[] data;
}

void HttpReqCommandPutFA::procresult()
{
	if (client->json.isnumeric()) status = REQ_FAILURE;
	else
	{
		const char* p = NULL;

		for (;;)
		{
			switch (client->json.getnameid())
			{
				case 'p':
					p = client->json.getvalue();
					break;

				case EOO:
					if (!p) status = REQ_FAILURE;
					else
					{
						Node::copystring(&posturl,p);
						post(client,(char*)data,len);
					}
					return;

				default:
					if (!client->json.storeobject()) return client->app->putfa_result(th,type,API_EINTERNAL);
			}
		}
	}
}

CommandGetFA::CommandGetFA(int p, handle fahref)
{
	part = p;

	cmd("ufa");
	arg("fah",(byte*)&fahref,sizeof fahref);
}

void CommandGetFA::procresult()
{
	fafc_map::iterator it = client->fafcs.find(part);

	// (can never happen)
	if (it == client->fafcs.end()) return;

	if (client->json.isnumeric())
	{
		it->second->req.status = REQ_FAILURE;
		return;
	}

	const char* p = NULL;

	for (;;)
	{
		switch (client->json.getnameid())
		{
			case 'p':
				p = client->json.getvalue();
				break;

			case EOO:
				if (p)
				{
					string url;

					Node::copystring(&url,p);
					it->second->dispatch(client,part,url.c_str());
				}
				else it->second->req.status = REQ_FAILURE;
				return;

			default:
				if (!client->json.storeobject())
				{
					it->second->req.status = REQ_FAILURE;
					return;
				}
		}
	}
}

CommandAttachFA::CommandAttachFA(handle nh, fatype t, handle ah, int ctag)
{
	cmd("pfa");
	arg("n",(byte*)&nh,MegaClient::NODEHANDLE);

	char buf[64];

	sprintf(buf,"%u*",t);
	Base64::btoa((byte*)&ah,sizeof(ah),strchr(buf+2,0));
	arg("fa",buf);

	h = nh;
	type = t;
	tag = ctag;
}

void CommandAttachFA::procresult()
{
	client->app->putfa_result(h,type,client->json.isnumeric() ? (error)client->json.getint() : API_EINTERNAL);
}

// request upload target URL
CommandPutFile::CommandPutFile(TransferSlot* ctslot, int ms)
{
	tslot = ctslot;

	cmd("u");
	arg("s",tslot->file->size);
	arg("ms",ms);
}

void CommandPutFile::cancel()
{
	Command::cancel();
	tslot = NULL;
}

// set up file transfer with returned target URL
void CommandPutFile::procresult()
{
	if (tslot) tslot->pendingcmd = NULL;
	if (canceled) return;

	if (client->json.isnumeric()) return tslot->transfer->failed((error)client->json.getint());

	for (;;)
	{
		switch (client->json.getnameid())
		{
			case 'p':
				client->json.storeobject(&tslot->tempurl);
				break;

			case EOO:
				if (tslot->tempurl.size())
				{
					tslot->starttime = tslot->lastdata = client->waiter->ds;
					return tslot->progress();
				}
				else return tslot->transfer->failed(API_EINTERNAL);

			default:
				if (!client->json.storeobject()) return tslot->transfer->failed(API_EINTERNAL);
		}
	}
}

// request temporary source URL
// p == private node
CommandGetFile::CommandGetFile(TransferSlot* ctslot, byte* key, handle h, bool p)
{
	cmd("g");
	arg(p ? "n" : "p",(byte*)&h,MegaClient::NODEHANDLE);
	arg("g",1);

	tslot = ctslot;

	if (!tslot)
	{
		ph = h;
		memcpy(filekey,key,FILENODEKEYLENGTH);
	}
}

void CommandGetFile::cancel()
{
	Command::cancel();
	tslot = NULL;
}

// process file credentials
void CommandGetFile::procresult()
{
	if (tslot) tslot->pendingcmd = NULL;
	if (canceled) return;

	if (client->json.isnumeric())
	{
		if (tslot) return tslot->transfer->failed((error)client->json.getint());
		return client->app->checkfile_result(ph,(error)client->json.getint());
	}

	const char* at = NULL;
	error e = API_EINTERNAL;
	m_off_t s = -1;
	int d = 0;
	byte* buf;
	time_t ts = 0, tm = 0;

	// credentials relevant to a non-TransferSlot scenario (node query)
	string fileattrstring;
	string filenamestring;
	string filefingerprint;

	for (;;)
{'fraction_non_alphanumeric': 0.1585692995529061, 'fraction_numerical': 0.003775459513164431, 'mean_word_length': 3.8047732696897376, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 111, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1628797', 'n_tokens_mistral': 4080, 'n_tokens_neox': 3647, 'n_words': 863}