Пример #1
0
        protected override Result DoSetSize(long size)
        {
            using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock();

            Result rc = AccessCheck(isWriteAccess: true);

            if (rc.IsFailure())
            {
                return(rc);
            }

            return(_baseStorage.Target.SetSize(size));
        }
Пример #2
0
        protected override Result DoWrite(long offset, ReadOnlySpan <byte> source)
        {
            using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock();

            Result rc = AccessCheck(isWriteAccess: true);

            if (rc.IsFailure())
            {
                return(rc);
            }

            return(_baseStorage.Target.Write(offset, source));
        }
Пример #3
0
        protected override Result DoRead(long offset, Span <byte> destination)
        {
            using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock();

            Result rc = AccessCheck(isWriteAccess: false);

            if (rc.IsFailure())
            {
                return(rc);
            }

            return(_baseStorage.Target.Read(offset, destination));
        }
Пример #4
0
        protected override Result DoOperateRange(Span <byte> outBuffer, OperationId operationId, long offset, long size,
                                                 ReadOnlySpan <byte> inBuffer)
        {
            using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock();

            Result rc = AccessCheck(isWriteAccess: true);

            if (rc.IsFailure())
            {
                return(rc);
            }

            return(_baseStorage.Target.OperateRange(outBuffer, operationId, offset, size, inBuffer));
        }
Пример #5
0
        protected override Result DoGetSize(out long size)
        {
            Unsafe.SkipInit(out size);

            using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock();

            Result rc = AccessCheck(isWriteAccess: false);

            if (rc.IsFailure())
            {
                return(rc);
            }

            return(_baseStorage.Target.GetSize(out size));
        }
Пример #6
0
        /// <summary>
        /// Opens a <see cref="SaveDataIndexerAccessor"/> for the specified save data space.
        /// </summary>
        /// <remarks>
        /// The returned <see cref="SaveDataIndexerAccessor"/> will have exclusive access to the requested indexer.
        /// The accessor must be disposed after use.
        /// </remarks>
        /// <param name="accessor">If the method returns successfully, contains the created accessor.</param>
        /// <param name="neededInit">If the method returns successfully, contains <see langword="true"/>
        /// if the indexer needed to be initialized.</param>
        /// <param name="spaceId">The <see cref="SaveDataSpaceId"/> of the indexer to open.</param>
        /// <returns>The <see cref="Result"/> of the operation.</returns>
        public Result OpenSaveDataIndexerAccessor(out SaveDataIndexerAccessor accessor, out bool neededInit,
                                                  SaveDataSpaceId spaceId)
        {
            UnsafeHelpers.SkipParamInit(out neededInit);

            if (IsBisUserRedirectionEnabled && spaceId == SaveDataSpaceId.User)
            {
                spaceId = SaveDataSpaceId.ProperSystem;
            }

            UniqueLock indexerLock = default;

            try
            {
                ISaveDataIndexer indexer;
                switch (spaceId)
                {
                case SaveDataSpaceId.System:
                case SaveDataSpaceId.User:
                    indexerLock = new UniqueLock(_bisIndexer.Locker);

                    if (!_bisIndexer.IsInitialized)
                    {
                        _bisIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(SystemIndexerMountName),
                                                                  SaveDataSpaceId.System, SaveDataId, MemoryResource);

                        neededInit = true;
                    }

                    indexer = _bisIndexer.Indexer;
                    break;

                case SaveDataSpaceId.SdSystem:
                case SaveDataSpaceId.SdCache:
                    // ReSharper doesn't realize that UniqueLock locks the indexer's lock object
                    // ReSharper disable InconsistentlySynchronizedField
                    indexerLock = new UniqueLock(_sdCardIndexer.Locker);

                    // We need to reinitialize the indexer if the SD card has changed
                    if (!_sdCardHandleManager.IsValid(in _sdCardHandle) && _sdCardIndexer.IsInitialized)
                    {
                        _sdCardIndexer.Indexer.Dispose();
                        _sdCardIndexer.Indexer = null;
                    }

                    if (!_sdCardIndexer.IsInitialized)
                    {
                        _sdCardIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(SdCardIndexerMountName),
                                                                     SaveDataSpaceId.SdSystem, SaveDataId, MemoryResource);

                        _sdCardHandleManager.GetHandle(out _sdCardHandle).IgnoreResult();

                        neededInit = true;
                    }

                    indexer = _sdCardIndexer.Indexer;
                    // ReSharper restore InconsistentlySynchronizedField

                    break;

                case SaveDataSpaceId.Temporary:
                    indexerLock = new UniqueLock(_tempIndexer.Locker);

                    indexer = _tempIndexer.Indexer;
                    break;

                case SaveDataSpaceId.ProperSystem:
                    indexerLock = new UniqueLock(_properSystemIndexer.Locker);

                    if (!_properSystemIndexer.IsInitialized)
                    {
                        _properSystemIndexer.Indexer = new SaveDataIndexer(FsClient,
                                                                           new U8Span(ProperSystemIndexerMountName),
                                                                           SaveDataSpaceId.ProperSystem, SaveDataId, MemoryResource);

                        neededInit = true;
                    }

                    indexer = _properSystemIndexer.Indexer;
                    break;

                case SaveDataSpaceId.SafeMode:
                    indexerLock = new UniqueLock(_safeIndexer.Locker);

                    if (!_safeIndexer.IsInitialized)
                    {
                        _safeIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(SafeModeIndexerMountName),
                                                                   SaveDataSpaceId.SafeMode, SaveDataId, MemoryResource);

                        neededInit = true;
                    }

                    indexer = _safeIndexer.Indexer;
                    break;

                default:
                    accessor = default;
                    return(ResultFs.InvalidArgument.Log());
                }


                accessor = new SaveDataIndexerAccessor(indexer, ref indexerLock);
                return(Result.Success);
            }
            finally
            {
                indexerLock.Dispose();
            }
        }
Пример #7
0
 public SaveDataIndexerAccessor(ISaveDataIndexer indexer, ref UniqueLock locker)
 {
     Indexer = indexer;
     _locker = new UniqueLock(ref locker);
 }