// Read(u32 fd) -> (i32 ret, u32 bsd_errno, buffer<i8, 0x22, 0> message) public ResultCode Read(ServiceCtx context) { int fd = context.RequestData.ReadInt32(); (ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22(); WritableRegion receiveRegion = context.Memory.GetWritableRegion(receivePosition, (int)receiveLength); LinuxError errno = LinuxError.EBADF; IFileDescriptor file = _context.RetrieveFileDescriptor(fd); int result = -1; if (file != null) { errno = file.Read(out result, receiveRegion.Memory.Span); if (errno == LinuxError.SUCCESS) { SetResultErrno(file, result); receiveRegion.Dispose(); } } return(WriteBsdResult(context, result, errno)); }
/// <summary> /// Asynchronously query synchronizing records. /// </summary> /// <param name="files"></param> /// <param name="page"></param> /// <param name="onOk"></param> /// <param name="onErr"></param> /// <returns>this</returns> public AlbumClientier asyncQuerySyncs(IList <IFileDescriptor> files, SyncingPage page, OnOk onOk, OnError onErr) { Task.Run(() => { DocsResp resp = null; try { AnsonHeader header = client.Header().act("album.c#", "query", "r/states", "query sync"); List <DocsResp> reslts = new List <DocsResp>(files.Count); AlbumReq req = (AlbumReq) new AlbumReq().Syncing(page).A(A.selectSyncs); for (int i = page.start; i < page.end & i < files.Count; i++) { IFileDescriptor p = files[i]; req.querySync(p); } AnsonMsg q = client.UserReq(uri, new AlbumPort(AlbumPort.album), req) .Header(header); resp = (DocsResp)client.Commit(q, errCtx); reslts.Add(resp); onOk.ok(resp); } catch (Exception e) { onErr.err(new MsgCode(MsgCode.exIo), uri, new string[] { e.GetType().Name, e.Message }); } }); return(this); }
/// <summary> /// Запись элемента в низкоуровневое хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток-источник</param> public IFile Set(IFileDescriptor file, Stream stream) { return(new FileDirtyVersionBased( DirtyVersionStorage, DirtyVersionStorage.Save(file.Path, stream) )); }
public override async Task <string> Store(IFileDescriptor definition, Stream source) { var targetPath = _location; if (definition.StoragePath != null) { targetPath = Path.Combine(_location, definition.StoragePath); } Directory.CreateDirectory(targetPath); targetPath = Path.Combine(targetPath, definition.StorageName); try { using (Stream file = File.Create(targetPath)) { source.CopyStreamTo(file); } } catch (Exception e) { Log.Add(e); } return(definition.Locator); }
public override Task <Stream> Fetch(IFileDescriptor definition) { var fullPath = Path.Combine(definition.StoragePath, definition.StorageName); var fileStream = new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); Stream castBuffer = fileStream; return(Task.FromResult(castBuffer)); }
public DocsReq querySync(IFileDescriptor p) { if (syncQueries == null) { syncQueries = new ArrayList(); } syncQueries.Add(new SyncRec(p)); return(this); }
/// <summary> /// Дескриптор файла, основанный на хранилище DirtyVersion /// </summary> public FileDirtyVersionBased(IDirtyVersionStorage storage, Commit commit) { _dirtyVersionStorage = storage; Commit = commit; Descriptor = new FileDescriptor { Path = commit.MappingInfo.Name, Owner = (commit.Author != null) ? (commit.Author.Commiter) : (null), Version = commit.Hash }; }
void MapFiles(IFileDescriptor afile) { afile.data = _files.Count; _files.Add(afile); foreach (var file in afile.children) { MapFiles(file); } }
/// <summary> /// Чтение элемента из низкоуровневого хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return new FileDirtyVersionBased( DirtyVersionStorage, new Commit { MappingInfo = new MappingInfo {Name = file.Path}, Hash = file.Version } ); }
/// <summary> /// Запись файла в хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток-источник</param> /// <returns></returns> public IFile Set(IFileDescriptor file, Stream stream) { return(new FileVcsStorageBased( VcsStoragePersister.Commit(new VcsCommit { File = file }, stream).File, VcsStoragePersister )); }
public ISocket RetrieveSocket(int socketFd) { IFileDescriptor file = RetrieveFileDescriptor(socketFd); if (file is ISocket socket) { return(socket); } return(null); }
/// <summary> /// Сохранение файла в хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток-источник</param> /// <returns>Дескриптор файла</returns> public IFile Set(IFileDescriptor file, Stream stream) { var record = _hashedDirectoryStorage.Write(file.Path, stream); return new FileHashedDirectoryBased( _hashedDirectoryStorage, new FileDescriptor { Path = file.Path, Filename = record.NameHash, DateTime = record.LastWriteTime, Version = record.DataHash } ); }
/// <summary> /// Чтение элемента из низкоуровневого хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return(new FileDirtyVersionBased( DirtyVersionStorage, new Commit { MappingInfo = new MappingInfo { Name = file.Path }, Hash = file.Version } )); }
public override async Task <string> Store(IFileDescriptor definition, Stream source) { var fullPath = Path.Combine(LocalStoragePath, definition.StoragePath.Replace("/", "\\"), definition.StorageName); await using var fs = File.OpenWrite(fullPath); source.Seek(0, SeekOrigin.Begin); await source.CopyToAsync(fs); fs.Close(); return(fullPath); }
/// <summary> /// Сохранение файла в хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток-источник</param> /// <returns>Дескриптор файла</returns> public IFile Set(IFileDescriptor file, Stream stream) { var record = _hashedDirectoryStorage.Write(file.Path, stream); return(new FileHashedDirectoryBased( _hashedDirectoryStorage, new FileDescriptor { Path = file.Path, Filename = record.NameHash, DateTime = record.LastWriteTime, Version = record.DataHash } )); }
private string TargetPath(IFileDescriptor definition) { var targetPath = _location; if (definition.StoragePath != null) { targetPath = Path.Combine(_location, definition.StoragePath); } targetPath = Path.Combine(targetPath, definition.StorageName); return(targetPath); }
/// <summary> /// Прокатака цикла реальной записи на диск /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток до файла</param> private IFile RollRealWriting(IFileDescriptor file, Stream stream) { VcsStorageUtils.CreateDirectoryIfNotExists( GenerateElementDirectory(file) ); VcsStorageUtils.WriteAllTextFromStream( GeneratePath(file), stream ); return(new FileFsBased(FileAccess.Read, new FileDescriptor { Path = GeneratePath(file) })); }
public DocsReq blockStart(IFileDescriptor file, SessionInf usr) { this.device = usr.device; if (LangExt.isblank(this.device, new string[] { ".", "/" })) { throw new SemanticException("File to be uploaded must come with user's device id - for distinguish files. {0}", file.fullpath()); } this.clientpath = file.fullpath(); this.docName = file.clientname(); this.createDate = file.Cdate(); this.blockSeq = 0; this.a = A.blockStart; return(this); }
public int DuplicateFileDescriptor(int fd) { IFileDescriptor oldFile = RetrieveFileDescriptor(fd); if (oldFile != null) { lock (_lock) { oldFile.Refcount++; return(RegisterFileDescriptor(oldFile)); } } return(-1); }
public int RegisterFileDescriptor(IFileDescriptor file) { lock (_lock) { for (int fd = 0; fd < _fds.Count; fd++) { if (_fds[fd] == null) { _fds[fd] = file; return(fd); } } _fds.Add(file); return(_fds.Count - 1); } }
public bool CloseFileDescriptor(int fd) { IFileDescriptor file = RetrieveFileDescriptor(fd); if (file != null) { file.Refcount--; if (file.Refcount <= 0) { file.Dispose(); } lock (_lock) { _fds[fd] = null; } return(true); } return(false); }
// Write(u32 fd, buffer<i8, 0x21, 0> message) -> (i32 ret, u32 bsd_errno) public ResultCode Write(ServiceCtx context) { int fd = context.RequestData.ReadInt32(); (ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21(); ReadOnlySpan <byte> sendBuffer = context.Memory.GetSpan(sendPosition, (int)sendSize); LinuxError errno = LinuxError.EBADF; IFileDescriptor file = _context.RetrieveFileDescriptor(fd); int result = -1; if (file != null) { errno = file.Write(out result, sendBuffer); if (errno == LinuxError.SUCCESS) { SetResultErrno(file, result); } } return(WriteBsdResult(context, result, errno)); }
public static void Open(this IFileDescriptor fileDescriptor, int fd) { fileDescriptor.Open((IntPtr)fd); }
/// <summary> /// проверяет существование файла в хранилище /// </summary> /// <returns></returns> public bool Exists(IFileDescriptor file) { return _mapper.Exists(new VcsCommit {File = file}); }
/// <summary> /// Получение файла из хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return new FileDescriptorMongoDbBased(file, MongoDbConnector); }
public override async Task <bool> Exists(IFileDescriptor definition) { return(File.Exists(TargetPath(definition))); }
/// <summary> /// Удаление (реальное) файла из хранилища /// </summary> /// <param name="file">Представление файла</param> public void Del(IFileDescriptor file) { MongoDbConnector.GridFs.Delete(file.Path); }
/// <summary> /// Удалить элемент из хранилища /// </summary> /// <param name="file">Целевой элемент</param> public void Remove(IFileDescriptor file) { Remove(new VcsCommit {File = file}, EnumerateCommits(file)); }
/// <summary> /// Прокатака цикла реальной записи на диск /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток до файла</param> private IFile RollRealWriting(IFileDescriptor file, Stream stream) { VcsStorageUtils.CreateDirectoryIfNotExists( GenerateElementDirectory(file) ); VcsStorageUtils.WriteAllTextFromStream( GeneratePath(file), stream ); return new FileFsBased(FileAccess.Read, new FileDescriptor { Path = GeneratePath(file) }); }
/// <summary> /// Перечисляет идентификаторы коммитов файла /// </summary> /// <param name="file">Представление элемента</param> /// <returns>Перечисление идентификаторов коммитов</returns> public IEnumerable<string> EnumerateCommits(IFileDescriptor file) { return _mapper.Find(new VcsCommit {File = file}).Select(el => el.Code); }
/// <summary> /// Подсчитывает количество версий элемента в хранилище /// </summary> /// <param name="file"></param> /// <returns></returns> public int Count(IFileDescriptor file) { return _mapper.Count(file); }
/// <summary> /// Генерирует путь до файла /// </summary> /// <param name="file">Представление элемента</param> /// <returns>Полный путь</returns> private string GeneratePath(IFileDescriptor file) { return System.IO.Path.Combine(GenerateElementDirectory(file), System.IO.Path.GetFileName(file.Path)); }
/// <summary> /// Генерирует полный путь к директории, в которой располагается /// описываемый дескриптором элемент /// </summary> /// <param name="file">Дескриптор</param> /// <returns></returns> private string GenerateElementDirectory(IFileDescriptor file) { return System.IO.Path.Combine(WorkingDirectory.FullName, System.IO.Path.GetDirectoryName(file.Path)); }
/// <summary> /// Производит прокат реального удаления файла из хранилища /// </summary> /// <param name="file">Представление файла</param> private void RollRealDeleting(IFileDescriptor file) { File.Delete(GeneratePath(file)); }
/// <summary> /// Реальное чтение элемента из низкоуровневого хранилища /// </summary> /// <param name="file">Дескриптор элемента</param> /// <returns>Дескриптор файла</returns> private IFile RollRealReading(IFileDescriptor file) { return new FileFsBased(FileAccess.Read, new FileDescriptor { Path = GeneratePath(file) }); }
// Poll(u32 nfds, u32 timeout, buffer<unknown, 0x21, 0> fds) -> (i32 ret, u32 bsd_errno, buffer<unknown, 0x22, 0>) public ResultCode Poll(ServiceCtx context) { int fdsCount = context.RequestData.ReadInt32(); int timeout = context.RequestData.ReadInt32(); (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(); if (timeout < -1 || fdsCount < 0 || (ulong)(fdsCount * 8) > bufferSize) { return(WriteBsdResult(context, -1, LinuxError.EINVAL)); } PollEvent[] events = new PollEvent[fdsCount]; for (int i = 0; i < fdsCount; i++) { PollEventData pollEventData = context.Memory.Read <PollEventData>(bufferPosition + (ulong)(i * Unsafe.SizeOf <PollEventData>())); IFileDescriptor fileDescriptor = _context.RetrieveFileDescriptor(pollEventData.SocketFd); if (fileDescriptor == null) { return(WriteBsdResult(context, -1, LinuxError.EBADF)); } events[i] = new PollEvent(pollEventData, fileDescriptor); } List <PollEvent> discoveredEvents = new List <PollEvent>(); List <PollEvent>[] eventsByPollManager = new List <PollEvent> [_pollManagers.Count]; for (int i = 0; i < eventsByPollManager.Length; i++) { eventsByPollManager[i] = new List <PollEvent>(); foreach (PollEvent evnt in events) { if (_pollManagers[i].IsCompatible(evnt)) { eventsByPollManager[i].Add(evnt); discoveredEvents.Add(evnt); } } } foreach (PollEvent evnt in events) { if (!discoveredEvents.Contains(evnt)) { Logger.Error?.Print(LogClass.ServiceBsd, $"Poll operation is not supported for {evnt.FileDescriptor.GetType().Name}!"); return(WriteBsdResult(context, -1, LinuxError.EBADF)); } } int updateCount = 0; LinuxError errno = LinuxError.SUCCESS; if (fdsCount != 0) { bool IsUnexpectedLinuxError(LinuxError error) { return(errno != LinuxError.SUCCESS && errno != LinuxError.ETIMEDOUT); } // Hybrid approach long budgetLeftMilliseconds; if (timeout == -1) { budgetLeftMilliseconds = PerformanceCounter.ElapsedMilliseconds + uint.MaxValue; } else { budgetLeftMilliseconds = PerformanceCounter.ElapsedMilliseconds + timeout; } do { for (int i = 0; i < eventsByPollManager.Length; i++) { if (eventsByPollManager[i].Count == 0) { continue; } errno = _pollManagers[i].Poll(eventsByPollManager[i], 0, out updateCount); if (IsUnexpectedLinuxError(errno)) { break; } if (updateCount > 0) { break; } } // If we are here, that mean nothing was availaible, sleep for 50ms context.Device.System.KernelContext.Syscall.SleepThread(50 * 1000000); }while (PerformanceCounter.ElapsedMilliseconds < budgetLeftMilliseconds); } else if (timeout == -1) { // FIXME: If we get a timeout of -1 and there is no fds to wait on, this should kill the KProces. (need to check that with re) throw new InvalidOperationException(); } else { context.Device.System.KernelContext.Syscall.SleepThread(timeout); } // TODO: Spanify for (int i = 0; i < fdsCount; i++) { context.Memory.Write(bufferPosition + (ulong)(i * Unsafe.SizeOf <PollEventData>()), events[i].Data); } return(WriteBsdResult(context, updateCount, errno)); }
/// <summary> /// Подсчитывает количество версий файла /// </summary> /// <param name="file"></param> /// <returns></returns> public int Count(IFileDescriptor file) { return Find(new VcsCommit {File = file}).Count(); }
/// <summary> /// Получение файла из хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return new FileHashedDirectoryBased(_hashedDirectoryStorage, file); }
/// <summary> /// Чтение элемента из низкоуровневого хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return RollRealReading(file); }
public SyncRec(IFileDescriptor p) { this.clientpath = p.fullpath(); this.filename = p.clientname(); this.cdate = p.Cdate(); }
/// <summary> /// Производит удаление файла из хранилища /// </summary> /// <param name="file">Представление файла</param> public void Del(IFileDescriptor file) { RollRealDeleting(file); }
private LinuxError SetResultErrno(IFileDescriptor socket, int result) { return(result == 0 && !socket.Blocking ? LinuxError.EWOULDBLOCK : LinuxError.SUCCESS); }
/// <summary> /// Запись элемента в низкоуровневое хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток-источник</param> public IFile Set(IFileDescriptor file, Stream stream) { return new FileDirtyVersionBased( DirtyVersionStorage, DirtyVersionStorage.Save(file.Path, stream) ); }
/// <summary> /// Дескриптор файла, базированный на MongoDB /// </summary> /// <param name="fileDescriptor">Представление файла</param> /// <param name="mongoDbConnector">Настроенный коннектор к базе</param> public FileDescriptorMongoDbBased(IFileDescriptor fileDescriptor, IMongoDbConnector mongoDbConnector) { Descriptor = fileDescriptor; _mongoDbConnector = mongoDbConnector; }
/// <summary> /// Генерирует путь до файла /// </summary> /// <param name="file">Представление элемента</param> /// <returns>Полный путь</returns> private string GeneratePath(IFileDescriptor file) { return(System.IO.Path.Combine(GenerateElementDirectory(file), System.IO.Path.GetFileName(file.Path))); }
/// <summary> /// Получение файла из хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return(new FileHashedDirectoryBased(_hashedDirectoryStorage, file)); }
/// <summary> /// Запись элемента в низкоуровневое хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток до файла</param> public IFile Set(IFileDescriptor file, Stream stream) { return(RollRealWriting(file, stream)); }
public override async Task <Stream> Fetch(IFileDescriptor definition) { return(new FileStream(TargetPath(definition), FileMode.Open)); }
/// <summary> /// Чтение элемента из низкоуровневого хранилища /// </summary> /// <param name="file">Представление файла</param> /// <returns>Дескриптор файла</returns> public IFile Get(IFileDescriptor file) { return(RollRealReading(file)); }
/// <summary> /// Запись элемента в низкоуровневое хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream">Поток до файла</param> public IFile Set(IFileDescriptor file, Stream stream) { return RollRealWriting(file, stream); }
/// <summary> /// Сохранение файла в хранилище /// </summary> /// <param name="file">Представление файла</param> /// <param name="stream"></param> /// <returns></returns> public IFile Set(IFileDescriptor file, Stream stream) { MongoDbConnector.GridFs.Upload(stream, file.Path); return new FileDescriptorMongoDbBased(file, MongoDbConnector); }