Пример #1
0
FileEntitySchemeInputStream::FileEntitySchemeInputStream(ptr<Entity> entity)
: entity(entity), currentBlockIndex(0), currentBlockOffset(0), ended(false)
{
	BEGIN_TRY();

	// read descriptor
	ptr<File> descriptorFile = entity->ReadData(nullptr);
	if(!descriptorFile)
		THROW("No descriptor");

	descriptorReader = NEW(StreamReader(NEW(FileInputStream(descriptorFile))));

	// read & check the version
	size_t version = descriptorReader->ReadShortly();
	// for now only version 1 is supported
	if(version != 1)
		THROW("Invalid descriptor version");
	totalSize = descriptorReader->ReadShortlyBig();
	remainingSize = totalSize;

	hashStream = NEW(Crypto::WhirlpoolStream());
	totalHashStream = NEW(Crypto::WhirlpoolStream());

	// read total hash
	totalHashFromDescriptor = descriptorReader->Read(totalHashStream->GetHashSize());

	END_TRY("Can't create input stream for file entity");
}
Пример #2
0
BEGIN_INANITY_MONO

BaseAssemblyGenerator::BaseAssemblyGenerator(ptr<State> state, const char* libgenPath)
: state(state), currentClassFullName(nullptr)
{
	BEGIN_TRY();

	domain = NEW(DotNetDomain(state->GetDomain()));

	// load libgen assembly
	ptr<DotNetImage> libgenImage = domain->LoadAssembly(libgenPath);

	// get string class
	cString = DotNetImage::GetCorlibImage()->GetClass("System", "String");

	// get AssemblyMeta class
	ptr<DotNetClass> cAssemblyMeta = libgenImage->GetClass("Inanity.Script.Mono", "AssemblyMeta");

	// get some methods
	mAddClass = cAssemblyMeta->GetMethod("AddClass", 1);
	mSetClassParent = cAssemblyMeta->GetMethod("SetClassParent", 2);
	mSetClassConstructor = cAssemblyMeta->GetMethod("SetClassConstructor", 2);
	mAddClassMethod = cAssemblyMeta->GetMethod("AddClassMethod", 4);
	mAddClassStaticMethod = cAssemblyMeta->GetMethod("AddClassStaticMethod", 4);
	mResolve = cAssemblyMeta->GetMethod("Resolve", 2);

	// create instance of assembly meta
	oAssemblyMeta = cAssemblyMeta->GetConstructor(0)->Construct(domain);

	END_TRY("Can't create base assembly generator");
}
Пример #3
0
void FileEntitySchemeOutputStream::Write(const void* data, size_t size)
{
	BEGIN_TRY();

	const char* dataPtr = (const char*)data;

	while(size)
	{
		// if there's no current block stream, create it
		if(!currentBlockStream)
			currentBlockStream = NEW(MemoryStream(blockSize));

		// write data
		size_t sizeToWrite = blockSize - currentBlockSize;
		if(sizeToWrite > size)
			sizeToWrite = size;
		currentBlockStream->Write(dataPtr, sizeToWrite);
		// write it also to total hash stream
		totalHashStream->Write(dataPtr, sizeToWrite);
		// move pointers and counters
		dataPtr += sizeToWrite;
		size -= sizeToWrite;
		currentBlockSize += sizeToWrite;


		// if block is over, finish it
		if(currentBlockSize >= blockSize)
			FinishCurrentBlock();
	}

	END_TRY("Can't write data to file entity");
}
Пример #4
0
char __cdecl JavaToFunctionCallHandler(DCCallback* callback, DCArgs* args, DCValue* result, void* userdata)
{
	FunctionCallInfo* info = (FunctionCallInfo*)userdata;
	CallTempStruct* call;
	JNIEnv* env;
	LastError lastError = { 0, 0 };
	jboolean setsLastError = info->fInfo.fSetsLastError;
	initCallHandler(args, &call, NULL, &info->fInfo);
	env = call->env;
	
	call->pCallIOs = info->fInfo.fCallIOs;
	
	BEGIN_TRY(env, call);
	
	if (setsLastError) {
		clearLastError(info->fInfo.fEnv);
	}

	JavaToFunctionCallHandler_Sub(call, info, args, result, setsLastError);

	if (setsLastError) {
	  lastError = call->lastError;
	  //memcpy(&lastError, &call->lastError, sizeof(LastError));
	}
	
	END_TRY(info->fInfo.fEnv, call);

	cleanupCallHandler(call);

  if (setsLastError) {
    setLastError(env, lastError, info->fInfo.fThrowsLastError);
  }
	return info->fInfo.fDCReturnType;
}
Пример #5
0
void AsioTcpSocket::Send(ptr<File> file, ptr<SendHandler> sendHandler)
{
	BEGIN_TRY();

	CriticalCode cc(cs);

	// если запланировано закрытие передачи, то больше в очередь добавлять ничего нельзя
	if(sendClosed)
		THROW("Sending closed");

	bool queueWasEmpty = sendQueue.empty();

	// добавить элемент в очередь
	sendQueue.push_back(SendItem(file, sendHandler));

	// сбросить количество переданных данных в первом элементе,
	// если очередь была пуста (то есть первый элемент как раз
	// был добавлен)
	// также, если очередь была пуста, начать отправку
	if(queueWasEmpty)
	{
		firstItemSent = 0;
		StartSending();
	}

	END_TRY("Can't send data to Asio TCP socket");
}
Пример #6
0
char __cdecl CToJavaCallHandler(DCCallback* callback, DCArgs* args, DCValue* result, void* userdata)
{
	CallTempStruct* call;
	jthrowable exc;
	NativeToJavaCallbackCallInfo* info = (NativeToJavaCallbackCallInfo*)userdata;
	JNIEnv *env = GetEnv();
	initCallHandler(NULL, &call, env, &info->fInfo);
	
	call->pCallIOs = info->fInfo.fCallIOs;
	
	BEGIN_TRY(env, call);
	
	CToJavaCallHandler_Sub(call, info, args, result);
	
	END_TRY(info->fInfo.fEnv, call);

	exc = (*env)->ExceptionOccurred(env);
	if (exc) {
		(*env)->ExceptionDescribe(env);
        printStackTrace(env, exc);
		//(*env)->ExceptionClear(env);
	}
	
	cleanupCallHandler(call);
	
	return info->fInfo.fDCReturnType;
	
}
Пример #7
0
long long ServerRepo::GetUserId(const String& userName)
{
	BEGIN_TRY();

	// try to find user id
	{
		Data::SqliteQuery query(stmtGetUserId);
		stmtGetUserId->Bind(1, userName);
		switch(stmtGetUserId->Step())
		{
		case SQLITE_ROW:
			return stmtGetUserId->ColumnInt64(0);
		case SQLITE_DONE:
			// no such user
			break;
		default:
			THROW_SECONDARY("Can't find user id", db->Error());
		}
	}

	// add new user
	{
		Data::SqliteQuery query(stmtAddUser);
		stmtAddUser->Bind(1, userName);
		if(stmtAddUser->Step() != SQLITE_DONE)
			THROW("Can't add new user");

		return db->LastInsertRowId();
	}

	END_TRY("Can't get user id");
}
Пример #8
0
void ServerRepo::RespondWatch(StreamWriter* writer)
{
	BEGIN_TRY();

	writer->WriteShortlyBig(GetMaxRevision());

	END_TRY("Can't respond to watch request");
}
Пример #9
0
ptr<Win32Window> Win32Window::CreateForOpenGL(const String& title, int left, int top, int width, int height, bool visible)
{
	BEGIN_TRY();

	static ATOM windowClass = NULL;
	//зарегистрировать класс окна, если еще не сделано
	if(!windowClass)
	{
		WNDCLASS wndClass;
		ZeroMemory(&wndClass, sizeof(wndClass));
		wndClass.style = CS_OWNDC;
		wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
		wndClass.lpszClassName = TEXT("Win32OpenGLWindow");
		wndClass.hInstance = GetModuleHandle(NULL);
		wndClass.lpfnWndProc = StaticWndProc;
		windowClass = RegisterClass(&wndClass);
		if(!windowClass)
			THROW("Can't register window class");
	}

	ptr<Win32Window> window = Create(windowClass, title, left, top, width, height, visible);

	// get window's persistent HDC
	HDC hdc = GetDC(window->GetHWND());
	if(!hdc)
		THROW_SECONDARY("Can't get window's HDC", Exception::SystemError());
	// store it to window
	window->hdc = hdc;

	// choose & set pixel format
	PIXELFORMATDESCRIPTOR pfd;
	ZeroMemory(&pfd, sizeof(pfd));
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 24;
	pfd.cDepthBits = 0;
	pfd.iLayerType = PFD_MAIN_PLANE;
	int pixelFormat = ChoosePixelFormat(hdc, &pfd);
	if(!pixelFormat)
		THROW("Can't choose pixel format");
	if(!SetPixelFormat(hdc, pixelFormat, &pfd))
		THROW("Can't set pixel format");

	return window;

	END_TRY("Can't create window for OpenGL");
}
Пример #10
0
ptr<Window::Cursor> Win32Window::CreateCursor(ptr<Graphics::RawTextureData> texture, int hotX, int hotY)
{
	BEGIN_TRY();

	if(!(texture->GetFormat() == Graphics::PixelFormats::uintRGBA32S))
		THROW("Win32 window cursor must be RGB");

	HCURSOR cursor = CreateIconFromTexture(texture, FALSE, hotX, hotY);

	if(!cursor) THROW("Can't create cursor");

	return NEW(Win32Cursor(cursor));

	END_TRY("Can't create Win32 cursor");
}
Пример #11
0
ptr<Window::Icon> Win32Window::CreateIcon(ptr<Graphics::RawTextureData> texture)
{
	BEGIN_TRY();

	if(!(texture->GetFormat() == Graphics::PixelFormats::uintRGBA32S))
		THROW("Win32 window icon must be RGBA");

	HCURSOR icon = CreateIconFromTexture(texture, TRUE, 0, 0);

	if(!icon) THROW("Can't create icon");

	return NEW(Win32Icon(icon));

	END_TRY("Can't create Win32 icon");
}
Пример #12
0
BEGIN_INANITY_GRAPHICS

SdlAdapter::SdlAdapter(int videoDriverIndex) :
	sdl(Platform::Sdl::Get(SDL_INIT_VIDEO)),
	monitorsInitialized(false)
{
	BEGIN_TRY();

	const char* videoDriverName = SDL_GetVideoDriver(videoDriverIndex);
	if(!videoDriverName)
		THROW_SECONDARY("Can't get video driver name", Platform::Sdl::Error());
	name = videoDriverName;

	END_TRY("Can't create SDL adapter");
}
Пример #13
0
ptr<Shape> BtWorld::CreateCompoundShape(const std::vector<std::pair<mat4x4, ptr<Shape> > >& shapes)
{
	BEGIN_TRY();

	btCompoundShape* compoundShape = new btCompoundShape(false);
	for(size_t i = 0; i < shapes.size(); ++i)
	{
		const auto& p = shapes[i];
		compoundShape->addChildShape(toBt(p.first), p.second.FastCast<BtShape>()->GetInternalObject());
	}

	return NEW(BtShape(this, compoundShape));

	END_TRY("Can't create bullet compound shape");
}
Пример #14
0
char __cdecl JavaToCPPMethodCallHandler(DCCallback* callback, DCArgs* args, DCValue* result, void* userdata)
{
	FunctionCallInfo* info = (FunctionCallInfo*)userdata;
	CallTempStruct* call;
	jobject instance = initCallHandler(args, &call, NULL, &info->fInfo);
	
	call->pCallIOs = info->fInfo.fCallIOs;
	
	BEGIN_TRY(call->env, call);

	JavaToCPPMethodCallHandler_Sub(call, info, instance, args, result);

	END_TRY(info->fInfo.fEnv, call);
	cleanupCallHandler(call);
	
	return info->fInfo.fDCReturnType;
}
Пример #15
0
char __cdecl JavaToCCallHandler(DCCallback* callback, DCArgs* args, DCValue* result, void* userdata)
{
	CallTempStruct* call;
	JavaToNativeCallbackCallInfo* info = (JavaToNativeCallbackCallInfo*)userdata;
	jobject instance = initCallHandler(args, &call, NULL, &info->fInfo);
	
	// printf("JavaToCCallHandler !!!\n");
	call->pCallIOs = info->fInfo.fCallIOs;
	
	BEGIN_TRY(env, call);
	
	JavaToCCallHandler_Sub(call, info, instance, args, result);

	END_TRY(info->fInfo.fEnv, call);
	cleanupCallHandler(call);
	
	return info->fInfo.fDCReturnType;
}
Пример #16
0
ptr<Win32Window> Win32Window::Create(ATOM windowClass, const String& title,
	int left, int top, int width, int height, bool visible)
{
	BEGIN_TRY();

	//создать окно
	HWND hWnd = CreateWindow(
		(LPCTSTR)windowClass, Strings::UTF82Unicode(title).c_str(),
		WS_OVERLAPPEDWINDOW | (visible ? WS_VISIBLE : 0),
		left, top, width, height,
		NULL, NULL, GetModuleHandle(NULL), NULL);
	if(!hWnd)
		THROW("Can't create window");

	return NEW(Win32Window(hWnd));

	END_TRY("Can't create game window");
}
Пример #17
0
void ServerRepo::WriteManifest(StreamWriter* writer)
{
	BEGIN_TRY();

	// write protocol magic
	writer->Write(protocolMagic, sizeof(protocolMagic));
	// write protocol version
	writer->WriteShortly(protocolVersion);
	// write constraints
	writer->WriteShortly(maxKeySize);
	writer->WriteShortly(maxValueSize);
	writer->WriteShortly(maxPushKeysCount);
	writer->WriteShortly(maxPushTotalSize);
	writer->WriteShortly(maxPullKeysCount);
	writer->WriteShortly(maxPullTotalSize);

	END_TRY("Can't write server repo manifest");
}
Пример #18
0
bool ServerRepo::Watch(StreamReader* reader, StreamWriter* writer)
{
	BEGIN_TRY();

	long long clientRevision = reader->ReadShortlyBig();
	reader->ReadEnd();

	long long maxRevision = GetMaxRevision();

	if(clientRevision < maxRevision)
	{
		writer->WriteShortlyBig(maxRevision);
		return true;
	}

	return false;

	END_TRY("Can't process watch request");
}
Пример #19
0
const Adapter::Monitors& SdlAdapter::GetMonitors()
{
	BEGIN_TRY();

	if(!monitorsInitialized)
	{
		int monitorsCount = SDL_GetNumVideoDisplays();
		if(monitorsCount <= 0)
			THROW_SECONDARY("Can't get number of video displays", Platform::Sdl::Error());
		monitors.resize(monitorsCount);
		for(int i = 0; i < monitorsCount; ++i)
			monitors[i] = NEW(SdlMonitor(i));

		monitorsInitialized = true;
	}

	return monitors;

	END_TRY("Can't get SDL monitors");
}
Пример #20
0
char __cdecl JavaToObjCCallHandler(DCCallback* callback, DCArgs* args, DCValue* result, void* userdata)
{
    JavaToObjCCallInfo* info = (JavaToObjCCallInfo*)userdata;
    CallTempStruct* call;
    jobject instance = initCallHandler(args, &call, NULL, &info->fInfo);
    JNIEnv* env = call->env;
    BEGIN_TRY(env, call);

    call->pCallIOs = info->fInfo.fCallIOs;

    void* targetId = info->fNativeClass ? JLONG_TO_PTR(info->fNativeClass) : getNativeObjectPointer(env, instance, NULL);
    void* callback = //objc_msgSend_stret;//
        objc_msgSend;

#if defined(DC__Arch_Intel_x86)
    switch (info->fInfo.fReturnType) {
    case eDoubleValue:
    case eFloatValue:
        callback = objc_msgSend_fpret;
        break;
    }
#endif

    dcMode(call->vm, info->fInfo.fDCMode);
    //dcReset(call->vm);

    dcArgPointer(call->vm, targetId);
    dcArgPointer(call->vm, info->fSelector);

    followArgs(call, args, info->fInfo.nParams, info->fInfo.fParamTypes, JNI_FALSE, JNI_TRUE)// TODO isVarArgs ??
    &&
    followCall(call, info->fInfo.fReturnType, result, callback, JNI_FALSE, JNI_FALSE);

    END_TRY(info->fInfo.fEnv, call);
    cleanupCallHandler(call);

    return info->fInfo.fDCReturnType;
}
Пример #21
0
size_t FileEntitySchemeInputStream::Read(void* data, size_t size)
{
	BEGIN_TRY();

	if(ended)
		return 0;

	char* dataPtr = (char*)data;

	// don't allow to read more than remaining size
	if((bigsize_t)size > remainingSize)
		size = (size_t)remainingSize;

	while(size)
	{
		if(!currentBlockFile || currentBlockOffset >= currentBlockFile->GetSize())
		{
			// read next block

			// reset offset
			currentBlockOffset = 0;

			// get the block
			currentBlockFile = entity->ReadData(GetBlockName(currentBlockIndex));
			if(!currentBlockFile)
				THROW("Can't read next block");

			// increment index for next block
			++currentBlockIndex;

			// write it into total hash stream
			totalHashStream->Write(currentBlockFile);

			// read and check the hash
			size_t hashSize = hashStream->GetHashSize();
			ptr<File> hashFromDescriptor = descriptorReader->Read(hashSize);

			hashStream->Reset();
			hashStream->Write(currentBlockFile);
			hashStream->End();
			ptr<File> hashFromBlock = NEW(MemoryFile(hashSize));
			hashStream->GetHash(hashFromBlock->GetData());

			if(memcmp(hashFromDescriptor->GetData(), hashFromBlock->GetData(), hashSize) != 0)
				THROW("Wrong hash");
		}

		size_t sizeToCopy = currentBlockFile->GetSize() - currentBlockOffset;
		if(sizeToCopy > size)
			sizeToCopy = size;
		memcpy(dataPtr, (const char*)currentBlockFile->GetData() + currentBlockOffset, sizeToCopy);
		dataPtr += sizeToCopy;
		size -= sizeToCopy;
		currentBlockOffset += sizeToCopy;
		remainingSize -= sizeToCopy;
	}

	// if there is no more data, check that data is actually ends
	if(remainingSize <= 0)
	{
		ended = true;

		// check total hash
		totalHashStream->End();
		size_t hashSize = totalHashStream->GetHashSize();
		ptr<File> totalHash = NEW(MemoryFile(hashSize));
		totalHashStream->GetHash(totalHash->GetData());
		if(memcmp(totalHash->GetData(), totalHashFromDescriptor->GetData(), hashSize) != 0)
			THROW("Wrong total hash");

		// check that last block is over
		if(currentBlockFile && currentBlockOffset < currentBlockFile->GetSize())
			THROW("Last block is not over");

		// check that last block is last
		descriptorReader->ReadEnd();
	}

	return dataPtr - (char*)data;

	END_TRY("Can't read data from file entity");
}
Пример #22
0
BEGIN_INANITY_OIL

/*

Push:

-> client revision (shortly big)
-> client upper revision (shortly big)
->{
    key size (shortly)
    key data[key size]
    value size (shortly)
    value data[value size]
  }
  0 (shortly)

<- total number of changed unique keys since client revision (shortly big)
<- pre-push revision (shortly big)
<- post-push revision (shortly big)
<-{
    key size (shortly)
    key data[key size]
    value size (shortly)
    value data[value size]
    revision (shortly big)
  }
  0 (shortly)
<- new client revision (shortly big)

*/

ServerRepo::ServerRepo(const char* fileName)
: Repo(fileName)
{
	BEGIN_TRY();

	// check format version
	CheckAppVersion(serverRepoAppVersion);

	// create table revs
	if(sqlite3_exec(*db,
		"CREATE TABLE IF NOT EXISTS revs ("
		"rev INTEGER PRIMARY KEY AUTOINCREMENT, "
		"date INTEGER NOT NULL, "
		"user INTEGER NOT NULL, "
		"latest INTEGER NOT NULL, "
		"key BLOB NOT NULL, "
		"value BLOB NOT NULL)",
		0, 0, 0) != SQLITE_OK)
		THROW_SECONDARY("Can't create table revs", db->Error());
	// create index revs_rev__latest_1
	if(sqlite3_exec(*db,
		"CREATE UNIQUE INDEX IF NOT EXISTS revs_rev__latest_1 ON revs (rev) WHERE latest = 1",
		0, 0, 0) != SQLITE_OK)
		THROW_SECONDARY("Can't create index revs_rev__latest_1", db->Error());
	// create index revs_key__latest_1
	if(sqlite3_exec(*db,
		"CREATE UNIQUE INDEX IF NOT EXISTS revs_key__latest_1 ON revs (key) WHERE latest = 1",
		0, 0, 0) != SQLITE_OK)
		THROW_SECONDARY("Can't create index revs_key__latest_1", db->Error());

	// create table users
	if(sqlite3_exec(*db,
		"CREATE TABLE IF NOT EXISTS users ("
		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
		"name TEXT NOT NULL)",
		0, 0, 0) != SQLITE_OK)
		THROW_SECONDARY("Can't create table users", db->Error());
	// create index users_name
	if(sqlite3_exec(*db,
		"CREATE INDEX IF NOT EXISTS users_name ON users (name)",
		0, 0, 0) != SQLITE_OK)
		THROW_SECONDARY("Can't create index users_name", db->Error());

	// create statements
	stmtGetMaxRevision = db->CreateStatement("SELECT MAX(rev) FROM revs");
	stmtClearLatest = db->CreateStatement("UPDATE revs SET latest = 0 WHERE key = ?1 AND latest = 1");
	stmtWrite = db->CreateStatement("INSERT INTO revs (date, user, latest, key, value) VALUES (strftime('%s','now'), ?1, 1, ?2, ?3)");
	stmtPull = db->CreateStatement("SELECT rev, key, value FROM revs WHERE rev > ?1 AND rev <= ?2 AND latest = 1 ORDER BY rev LIMIT ?3");
	stmtGetWeakRevision = db->CreateStatement("SELECT rev FROM revs WHERE rev > ?1 AND rev <= ?2 AND latest = 1 ORDER BY rev LIMIT 1");
	stmtPullTotalSize = db->CreateStatement("SELECT COUNT(rev) FROM revs WHERE rev > ?1 AND latest = 1");
	stmtGetUserId = db->CreateStatement("SELECT id FROM users WHERE name = ?1");
	stmtAddUser = db->CreateStatement("INSERT INTO users (name) VALUES (?1)");

	END_TRY("Can't create server repo");
}
Пример #23
0
bool ServerRepo::Sync(StreamReader* reader, StreamWriter* writer, const String& userName, bool writeAccess)
{
	BEGIN_TRY();

	// push & pull should be in a one transaction
	Data::SqliteTransaction transaction(db);

	// get user id
	long long userId = GetUserId(userName);

	// get initial revision
	long long prePushRevision = GetMaxRevision();

	// read client revision
	long long clientRevision = reader->ReadShortlyBig();
	// read client upper revision
	long long clientUpperRevision = reader->ReadShortlyBig();
	// correct upper revision
	if(clientUpperRevision == 0 || clientUpperRevision > prePushRevision)
		clientUpperRevision = prePushRevision;

	// determine total size of the pull
	{
		Data::SqliteQuery queryPullTotalSize(stmtPullTotalSize);

		stmtPullTotalSize->Bind(1, clientRevision);
		if(stmtPullTotalSize->Step() != SQLITE_ROW)
			THROW("Can't determine total pull size");

		// output total size of pull
		long long pullTotalSize = stmtPullTotalSize->ColumnInt64(0);
		writer->WriteShortlyBig(pullTotalSize);
	}

	//*** push

	void* key = keyBufferFile->GetData();
	void* value = valueBufferFile->GetData();

	size_t totalPushSize = 0;

	// output pre-push revision
	writer->WriteShortlyBig(prePushRevision);

	bool pushedSomething = false;

	// loop for push keys
	for(size_t i = 0; ; ++i)
	{
		// read key size
		size_t keySize = reader->ReadShortly();
		// if it's 0, it's signal of end
		if(!keySize)
			break;

		// if there is no write access right, stop
		if(!writeAccess)
			THROW("Write access denied");

		// check number of keys
		if(i >= (size_t)maxPushKeysCount)
			THROW("Too many keys");

		// check key size
		if(keySize > maxKeySize)
			THROW("Too big key");

		// read key value
		reader->Read(key, keySize);

		// read value
		size_t valueSize = reader->ReadShortly();
		if(valueSize > maxValueSize)
			THROW("Too big value");
		if(valueSize)
			reader->Read(value, valueSize);

		// check total push size
		totalPushSize += valueSize;
		if(totalPushSize > maxPushTotalSize)
			THROW("Too big push total size");

		ptr<File> keyFile = NEW(PartFile(keyBufferFile, key, keySize));

		// clear latest flag for that key
		Data::SqliteQuery queryClearLatest(stmtClearLatest);
		stmtClearLatest->Bind(1, keyFile);
		if(stmtClearLatest->Step() != SQLITE_DONE)
			THROW_SECONDARY("Can't clear latest flag", db->Error());
		// do write
		Data::SqliteQuery queryWrite(stmtWrite);
		stmtWrite->Bind(1, userId);
		stmtWrite->Bind(2, keyFile);
		stmtWrite->Bind(3, NEW(PartFile(valueBufferFile, value, valueSize)));
		if(stmtWrite->Step() != SQLITE_DONE)
			THROW_SECONDARY("Can't do write", db->Error());

		pushedSomething = true;
	}

	// ensure request is over
	reader->ReadEnd();

	// output post-push revision
	writer->WriteShortlyBig(GetMaxRevision());

	//*** pull
	Data::SqliteQuery queryPull(stmtPull);

	stmtPull->Bind(1, clientRevision);
	stmtPull->Bind(2, clientUpperRevision);
	stmtPull->Bind(3, maxPullKeysCount);

	long long lastKnownClientRevision = clientRevision;

	size_t totalPullSize = 0;
	bool done = false;
	while(!done)
	{
		switch(stmtPull->Step())
		{
		case SQLITE_ROW:
			// check total pull size
			totalPullSize += stmtPull->ColumnBlobSize(2);
			if(totalPullSize > maxPullTotalSize)
			{
				// stop pull, that's enough
				done = true;
				break;
			}

			// output key
			{
				ptr<File> key = stmtPull->ColumnBlob(1);
				size_t keySize = key->GetSize();
				writer->WriteShortly(keySize);
				writer->Write(key->GetData(), keySize);
			}
			// output value
			{
				ptr<File> value = stmtPull->ColumnBlob(2);
				size_t valueSize = value->GetSize();
				writer->WriteShortly(valueSize);
				writer->Write(value->GetData(), valueSize);
			}
			{
				// output revision
				long long revision = stmtPull->ColumnInt64(0);
				writer->WriteShortlyBig(revision);

				// remember last revision
				lastKnownClientRevision = revision;
			}

			break;

		case SQLITE_DONE:
			// end, no more keys
			done = true;
			break;

		default:
			// some error
			THROW_SECONDARY("Error pulling changes", db->Error());
		}
	}

	// write final zero
	writer->WriteShortly(0);

	// write new client revision
	{
		Data::SqliteQuery query(stmtGetWeakRevision);

		stmtGetWeakRevision->Bind(1, lastKnownClientRevision);
		stmtGetWeakRevision->Bind(2, clientUpperRevision);

		long long newClientRevision;
		switch(stmtGetWeakRevision->Step())
		{
		case SQLITE_ROW:
			newClientRevision = stmtGetWeakRevision->ColumnInt64(0) - 1;
			break;
		case SQLITE_DONE:
			newClientRevision = clientUpperRevision;
			break;
		default:
			THROW_SECONDARY("Error getting new client revision", db->Error());
		}

		writer->WriteShortlyBig(newClientRevision);
	}

	// commit transaction
	transaction.Commit();

	return pushedSomething;

	END_TRY("Can't sync server repo");
}
Пример #24
0
int processXMsg( int streamId, char *readmsg,
                 RuleEngineEventParam *param, Node *node,
                 Env *env, ruleExecInfo_t *rei ) {

    char myhdr[HEADER_TYPE_LEN];
    char mymsg[MAX_NAME_LEN];
    char *outStr = NULL;
    int i, n;
    int iLevel, wCnt;
    int  ruleInx = 0;
    Region *r;
    Res *res;
    rError_t errmsg;
    errmsg.len = 0;
    errmsg.errMsg = NULL;
    r = make_region( 0, NULL );
    ParserContext *context = newParserContext( &errmsg, r );
    Pointer *e = newPointer2( readmsg );
    int rulegen = 1;
    int found;
    int grdf[2];
    int cmd = 0;
    int smallW;

    snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug:%s", param->actionName );
    memset( mymsg, 0, sizeof( mymsg ) );

    PARSER_BEGIN( DbgCmd )
    TRY( DbgCmd )
    TTEXT2( "n", "next" );
    cmd = REDEBUG_STEP_OVER;
    OR( DbgCmd )
    TTEXT2( "s", "step" );
    cmd = REDEBUG_NEXT;
    OR( DbgCmd )
    TTEXT2( "f", "finish" );
    cmd = REDEBUG_STEP_OUT;
    OR( DbgCmd )
    TTEXT2( "b", "break" );
    TRY( Param )
    TTYPE( TK_TEXT );
    int breakPointsInx2;
    for ( breakPointsInx2 = 0; breakPointsInx2 < 100; breakPointsInx2++ ) {
        if ( breakPoints[breakPointsInx2].actionName == NULL ) {
            break;
        }
    }
    if ( breakPointsInx2 == 100 ) {
        _writeXMsg( streamId, myhdr, "Maximum breakpoint count reached. Breakpoint not set.\n" );
        cmd = REDEBUG_WAIT;
    }
    else {
        breakPoints[breakPointsInx2].actionName = strdup( token->text );
        char * base_ptr = NULL;
        TRY( loc )
        TTYPE( TK_TEXT );
        base_ptr = ( char * ) malloc( sizeof( token->text ) + 2 );
        base_ptr[0] = 'f';
        strcpy( base_ptr + 1, token->text );
        TTEXT( ":" );
        TTYPE( TK_INT );
        breakPoints[breakPointsInx2].base = strdup( base_ptr );
        breakPoints[breakPointsInx2].line = atoi( token->text );
        rodsLong_t range[2];
        char rulesFileName[MAX_NAME_LEN];
        getRuleBasePath( base_ptr, rulesFileName );

        FILE *file;
        /* char errbuf[ERR_MSG_LEN]; */
        file = fopen( rulesFileName, "r" );
        if ( file == NULL ) {
            free( context );
            deletePointer( e );
            free( base_ptr );
            return RULES_FILE_READ_ERROR;
        }
        Pointer *p = newPointer( file, base_ptr );


        if ( getLineRange( p, breakPoints[breakPointsInx2].line, range ) == 0 ) {
            breakPoints[breakPointsInx2].start = range[0];
            breakPoints[breakPointsInx2].finish = range[1];
        }
        else {
            breakPoints[breakPointsInx2].actionName = NULL;
        }
        deletePointer( p );
        OR( loc )
        TTYPE( TK_INT );
        if ( node != NULL ) {
            breakPoints[breakPointsInx2].base = strdup( node->base );
            breakPoints[breakPointsInx2].line = atoi( token->text );
            rodsLong_t range[2];
            Pointer *p = newPointer2( breakPoints[breakPointsInx2].base );
            if ( getLineRange( p, breakPoints[breakPointsInx2].line, range ) == 0 ) {
                breakPoints[breakPointsInx2].start = range[0];
                breakPoints[breakPointsInx2].finish = range[1];
            }
            else {
                breakPoints[breakPointsInx2].actionName = NULL;
            }
            deletePointer( p );
        }
        else {
            breakPoints[breakPointsInx2].actionName = NULL;
        }
        OR( loc )
        /* breakPoints[breakPointsInx].base = NULL; */
        END_TRY( loc )

        free( base_ptr );
        if ( breakPoints[breakPointsInx2].actionName != NULL )
            snprintf( mymsg, MAX_NAME_LEN, "Breakpoint %i  set at %s\n", breakPointsInx2,
                      breakPoints[breakPointsInx2].actionName );
        else {
            snprintf( mymsg, MAX_NAME_LEN, "Cannot set breakpoint, source not available\n" );
        }
        _writeXMsg( streamId, myhdr, mymsg );
        if ( breakPointsInx <= breakPointsInx2 ) {
            breakPointsInx = breakPointsInx2 + 1;
        }
        cmd = REDEBUG_WAIT;
    }
    OR( Param )
    NEXT_TOKEN_BASIC;
    _writeXMsg( streamId, myhdr, "Unknown parameter type.\n" );
    cmd = REDEBUG_WAIT;
    OR( Param )
    _writeXMsg( streamId, myhdr, "Debugger command \'break\' requires at least one argument.\n" );
    cmd = REDEBUG_WAIT;
    END_TRY( Param )

    OR( DbgCmd )
    TRY( Where )
    TTEXT2( "w", "where" );
    smallW = 1;
    OR( Where )
    TTEXT2( "W", "Where" );
    smallW = 0;
    END_TRY( Where )
    wCnt = 20;
    OPTIONAL_BEGIN( Param )
    TTYPE( TK_INT );
    wCnt = atoi( token->text );
    OPTIONAL_END( Param )
    iLevel = 0;

    i = reDebugStackCurrPtr - 1;
    while ( i >= 0 && wCnt > 0 ) {
        if ( !smallW || ( reDebugPCType( ( RuleEngineEvent ) reDebugStackCurr[i].label ) & 1 ) != 0 ) {
            snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug: Level %3i", iLevel );
            char msg[HEADER_TYPE_LEN - 1];
            RuleEngineEventParam param;
            param.ruleIndex = 0;
            param.actionName = reDebugStackCurr[i].step;
            printRuleEngineEventLabel( msg, HEADER_TYPE_LEN - 1, ( RuleEngineEvent ) reDebugStackCurr[i].label, &param );
            _writeXMsg( streamId,  myhdr, msg );
            if ( reDebugStackCurr[i].label != EXEC_ACTION_BEGIN ) {
                iLevel++;
            }
            wCnt--;
        }
        i--;
    }
    OR( DbgCmd )
    TTEXT2( "l", "list" );
    TRY( Param )
    TTEXT2( "r", "rule" );
    TRY( ParamParam )
    TTYPE( TK_TEXT );

    mymsg[0] = '\n';
    mymsg[1] = '\0';
    snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug: Listing %s", token->text );
    RuleIndexListNode *node;
    found = 0;
    while ( findNextRule2( token->text, ruleInx, &node ) != NO_MORE_RULES_ERR ) {
        found = 1;
        if ( node->secondaryIndex ) {
            n = node->condIndex->valIndex->len;
            int i;
            for ( i = 0; i < n; i++ ) {
                Bucket *b = node->condIndex->valIndex->buckets[i];
                while ( b != NULL ) {
                    RuleDesc *rd = getRuleDesc( *( int * )b->value );
                    char buf[MAX_RULE_LEN];
                    ruleToString( buf, MAX_RULE_LEN, rd );
                    snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "%i: %s\n%s\n", node->ruleIndex, rd->node->base[0] == 's' ? "<source>" : rd->node->base + 1, buf );
                    b = b->next;
                }
            }
        }
        else {
            RuleDesc *rd = getRuleDesc( node->ruleIndex );
            char buf[MAX_RULE_LEN];
            ruleToString( buf, MAX_RULE_LEN, rd );
            snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "\n  %i: %s\n%s\n", node->ruleIndex, rd->node->base[0] == 's' ? "<source>" : rd->node->base + 1, buf );
        }
        ruleInx ++;
    }
    if ( !found ) {
        snprintf( mymsg, MAX_NAME_LEN, "Rule %s not found\n", token->text );
    }
    _writeXMsg( streamId, myhdr, mymsg );
    cmd = REDEBUG_WAIT;
    OR( ParamParam )
    _writeXMsg( streamId, myhdr, "Debugger command \'list rule\' requires one argument.\n" );
    cmd = REDEBUG_WAIT;
    END_TRY( ParamParam )
    OR( Param )
    TTEXT2( "b", "breakpoints" );
    snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug: Listing %s", token->text );
    mymsg[0] = '\n';
    mymsg[1] = '\0';
    for ( i = 0; i < breakPointsInx; i++ ) {
        if ( breakPoints[i].actionName != NULL ) {
            if ( breakPoints[i].base != NULL ) {
                snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "Breaking at BreakPoint %i:%s %s:%d\n", i , breakPoints[i].actionName, breakPoints[i].base[0] == 's' ? "<source>" : breakPoints[i].base + 1, breakPoints[i].line );
            }
            else {
                snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "Breaking at BreakPoint %i:%s\n", i , breakPoints[i].actionName );
            }
        }
    }
    _writeXMsg( streamId, myhdr, mymsg );
    cmd = REDEBUG_WAIT;
    OR( Param )
    TTEXT( "*" );
    snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug: Listing %s", token->text );
    Env *cenv = env;
    mymsg[0] = '\n';
    mymsg[1] = '\0';
    found = 0;
    while ( cenv != NULL ) {
        n = cenv->current->size;
        for ( i = 0; i < n; i++ ) {
            Bucket *b = cenv->current->buckets[i];
            while ( b != NULL ) {
                if ( b->key[0] == '*' ) { /* skip none * variables */
                    found = 1;
                    char typeString[128];
                    typeToString( ( ( Res * )b->value )->exprType, NULL, typeString, 128 );
                    snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "%s of type %s\n", b->key, typeString );
                }
                b = b->next;
            }
        }
        cenv = cenv->previous;
    }
    if ( !found ) {
        snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "<empty>\n" );
    }
    _writeXMsg( streamId, myhdr, mymsg );
    cmd = REDEBUG_WAIT;
    OR( Param )
    syncTokenQueue( e, context );
    skipWhitespace( e );
    ABORT( lookAhead( e, 0 ) != '$' );
    snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug: Listing %s", token->text );
    mymsg[0] = '\n';
    mymsg[1] = '\0';
    Hashtable *vars = newHashTable( 100 );
    for ( i = 0; i < coreRuleVarDef .MaxNumOfDVars; i++ ) {
        if ( lookupFromHashTable( vars, coreRuleVarDef.varName[i] ) == NULL ) {
            snprintf( &mymsg[strlen( mymsg )], MAX_NAME_LEN - strlen( mymsg ), "$%s\n", coreRuleVarDef.varName[i] );
            insertIntoHashTable( vars, coreRuleVarDef.varName[i], coreRuleVarDef.varName[i] );
        }
    }
    deleteHashTable( vars, NULL );
    _writeXMsg( streamId, myhdr, mymsg );
    cmd = REDEBUG_WAIT;
    OR( Param )
    NEXT_TOKEN_BASIC;
    _writeXMsg( streamId, myhdr, "Unknown parameter type.\n" );
    cmd = REDEBUG_WAIT;
    OR( Param )
    _writeXMsg( streamId, myhdr, "Debugger command \'list\' requires at least one argument.\n" );
    cmd = REDEBUG_WAIT;
    END_TRY( Param )
    OR( DbgCmd )
    TTEXT2( "c", "continue" );
    cmd = REDEBUG_STEP_CONTINUE;
    OR( DbgCmd )
    TTEXT2( "C", "Continue" );
    cmd = REDEBUG_CONTINUE_VERBOSE;
    OR( DbgCmd )
    TTEXT2( "del", "delete" );
    TRY( Param )
    TTYPE( TK_INT );
    n = atoi( token->text );
    if ( breakPoints[n].actionName != NULL ) {
        free( breakPoints[n].actionName );
        if ( breakPoints[n].base != NULL ) {
            free( breakPoints[n].base );
        }
        breakPoints[n].actionName = NULL;
        breakPoints[n].base = NULL;
        snprintf( mymsg, MAX_NAME_LEN, "Breakpoint %i  deleted\n", n );
    }
    else {
        snprintf( mymsg, MAX_NAME_LEN, "Breakpoint %i  has not been defined\n", n );
    }
    _writeXMsg( streamId, myhdr, mymsg );
    cmd = REDEBUG_WAIT;
    OR( Param )
    _writeXMsg( streamId, myhdr, "Debugger command \'delete\' requires one argument.\n" );
    cmd = REDEBUG_WAIT;
    END_TRY( Param )
    OR( DbgCmd )
    TTEXT2( "p", "print" );
    Node *n = parseTermRuleGen( e, 1, context );
    if ( getNodeType( n ) == N_ERROR ) {
        errMsgToString( context->errmsg, mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ) );
    }
    else {
        snprintf( myhdr, HEADER_TYPE_LEN - 1,   "idbug: Printing " );
        char * ptr = myhdr + strlen( myhdr );
        i = HEADER_TYPE_LEN - 1 - strlen( myhdr );
        termToString( &ptr, &i, 0, MIN_PREC, n, 0 );
        snprintf( ptr, i, "\n" );
        if ( env != NULL ) {
            disableReDebugger( grdf );
            res = computeNode( n, NULL, regionRegionCpEnv( env, r, ( RegionRegionCopyFuncType * ) regionRegionCpNode ), rei, 0, &errmsg, r );
            enableReDebugger( grdf );
            outStr = convertResToString( res );
            snprintf( mymsg, MAX_NAME_LEN, "%s\n", outStr );
            free( outStr );
            if ( getNodeType( res ) == N_ERROR ) {
                errMsgToString( &errmsg, mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ) );
            }
        }
        else {
            snprintf( mymsg, MAX_NAME_LEN, "Runtime environment: <empty>\n" );
        }
    }
    _writeXMsg( streamId, myhdr, mymsg );

    cmd = REDEBUG_WAIT;
    OR( DbgCmd )
    TTEXT2( "d", "discontinue" );
    cmd = REDEBUG_WAIT;
    OR( DbgCmd )
    snprintf( mymsg, MAX_NAME_LEN, "Unknown Action: %s", readmsg );
    _writeXMsg( streamId, myhdr, mymsg );
    cmd = REDEBUG_WAIT;
    END_TRY( DbgCmd )
    PARSER_END( DbgCmd )
    freeRErrorContent( &errmsg );
    region_free( r );
    deletePointer( e );
    free( context );
    return cmd;
}