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"); }
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"); }
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"); }
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; }
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"); }
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; }
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"); }
void ServerRepo::RespondWatch(StreamWriter* writer) { BEGIN_TRY(); writer->WriteShortlyBig(GetMaxRevision()); END_TRY("Can't respond to watch request"); }
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"); }
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"); }
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"); }
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"); }
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"); }
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; }
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; }
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"); }
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"); }
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"); }
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"); }
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; }
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"); }
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"); }
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"); }
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, ¶m ); _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; }