⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 ST5518机顶盒系统文件系统源代码!绝对超值!
💻 C
📖 第 1 页 / 共 5 页
字号:
            Error = STAVFS_ERROR_OUT_OF_RANGE;        }        else if (WritePosition)        {            stavfs_SetPos(Device_p, DirEntry_p, &CurrentPos, &(FileHandle_p->Write));        }        else        {            stavfs_SetPos(Device_p, DirEntry_p, &CurrentPos, &(FileHandle_p->Read));        }    }        return (Error);}/******************************************************************************Function Name : stavfs_SeekCyclicFile  Description :   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_SeekCyclicFile (STAVFS_FileHandle_t Handle, S64 Position, STAVFS_TypePosition_t Mode, BOOL WritePosition){    ST_ErrorCode_t           Error        = ST_NO_ERROR;    int                      FileId       = (int)Handle;    stavfs_OpenFileHandle_t *FileHandle_p = FileHandleTable+FileId;    stavfs_Device_t         *Device_p     = FileHandle_p->Device_p;    stavfs_DirEntry_t       *DirEntry_p   = FileHandle_p->DirEntry_p;     U64 CurrentPos;    U64 BuffSize;   /* Size of the cyclic buffer in bytes */    U64 Offset;     /* Offset into the buffer */        assert (FileHandle_p->Device_p   != NULL);    assert (FileHandle_p->DirEntry_p != NULL);        /* Set the offset */        I64_SetValue(DirEntry_p->Size.Cyclic.TopOffset, 0, Offset);        /* Get the file size in bytes */        INT_I64_MulLit(DirEntry_p->AllocSize, Device_p->ClusterSize, BuffSize);     /* Multiply by sector size */     I64_ShiftLeft(9, BuffSize);        /* Move relative to a given position */        if (Error == ST_NO_ERROR)    {        switch (Mode)        {            case STAVFS_START :                {                    /*                     * We have a lot of wrapping issues. So we calculate an unwrapped                     * and wrapped base and check for a valid offset against both.                     */                                        U64 Base;                    U64 Diff;                    U64 One   = {1, 0};                     /* Calculate the unwrapped base */                     INT_I64_MulLit(DirEntry_p->AllocSize, DirEntry_p->Size.Cyclic.LoopCount-1, Base);                    INT_I64_MulLit(Base, Device_p->ClusterSize, Base);                     /* Multiply by the sector size */                     I64_ShiftLeft(9, Base);                     /* Get the offset */                     I64_Sub(Position, Base, CurrentPos);                     /* Check it is in range */                     I64_Sub(CurrentPos, Offset, Diff);                     /*                     * We can go to the last byte but not the first                     * So zero diff is not valid.                     */                     I64_Sub(Diff, One, Diff);                     /* Because this is an unsigned comparison    */                    /* negative values will also be out of range */                     if (I64_IsLessThan(Diff, BuffSize))                    {                        /* We are in range */                    }                    else                    {                        /* We could be out of range */                         /* Calculate the wrapped base */                         INT_I64_MulLit(DirEntry_p->AllocSize, DirEntry_p->Size.Cyclic.LoopCount, Base);                        INT_I64_MulLit(Base, Device_p->ClusterSize, Base);                         /* Multiply by the sector size */                         I64_ShiftLeft(9, Base);                         /* Get the offset */                         I64_Sub(Position,   Base,     CurrentPos);                        I64_Add(CurrentPos, BuffSize, CurrentPos);                         /* Check it is in range */                         I64_Sub(CurrentPos, Offset, Diff);                         /*                         * We can go to the last byte but not the first                         * So zero diff is not valid.                         */                         I64_Sub(Diff, One, Diff);                         /* Because this is an unsigned comparison    */                        /* negative values will also be out of range */                         if (I64_IsLessThan(Diff, BuffSize))                        {                            /* We are in range */                        }                        else                        {                            /* We are out of range */                             Error = STAVFS_ERROR_OUT_OF_RANGE;                        }                    }                }                 break;             case STAVFS_END :                                if (I64_IsLessThan(Position, BuffSize))                {                    /* Get the position relative to the offset */                                        I64_Add(Position, Offset, CurrentPos);                }                else                {                    Error = STAVFS_ERROR_OUT_OF_RANGE;                }                 I64_Sub(Offset, Position, CurrentPos);                 break;             case STAVFS_CURRENT :                {                    U64 Diff;                                        if (WritePosition)                    {                        /* Get the write offset */                                                Error = stavfs_GetPos(Device_p, &(FileHandle_p->Write), &CurrentPos);                    }                    else                    {                        /* Get the read offset */                                                Error = stavfs_GetPos(Device_p, &(FileHandle_p->Read), &CurrentPos);                    }                                        /* Are we going backwards */                                        if (I64_IsNegative(Position))                    {                        /* Going backwards (We are working with negative numbers) */                        /* Get the position relative to the offset */                                                I64_Sub(Offset, CurrentPos, Diff);                                                if (!I64_IsNegative(Diff))                        {                            I64_Sub(Diff, BuffSize, Diff);                        }                                                /* Check for any wrapping */                         if (I64_IsLessThan(Diff, Position))                        {                            /* In range */                                                        I64_Add(CurrentPos, Position, CurrentPos);                        }                        else                        {                            Error = STAVFS_ERROR_OUT_OF_RANGE;                        }                    }                    else                    {                        /* Going forwards */                        /* Get the position relative to the offset */                                                I64_Sub(Offset, CurrentPos, Diff);                                                if (I64_IsNegative(Diff))                        {                            I64_Add(Diff, BuffSize, Diff);                        }                                                /* Check for any wrapping */                         if (I64_IsGreaterOrEqual(Diff, Position))                        {                            /* In range */                                                        I64_Add(CurrentPos, Position, CurrentPos);                        }                        else                        {                            Error = STAVFS_ERROR_OUT_OF_RANGE;                        }                    }                }                 break;             default :                Error = ST_ERROR_BAD_PARAMETER;                break;        }    }        /* Set the position */        if (Error == ST_NO_ERROR)    {        /* Check for wrapping */         if (I64_IsNegative(CurrentPos))        {            I64_Add(CurrentPos, BuffSize, CurrentPos);        }        else if (I64_IsGreaterOrEqual(CurrentPos, BuffSize))        {            I64_Sub(CurrentPos, BuffSize, CurrentPos);        }         /* Set the loop count */         if (WritePosition)        {            if (I64_IsLessThan(Offset, CurrentPos))            {                FileHandle_p->LoopCount = DirEntry_p->Size.Cyclic.LoopCount -1;            }            else            {                FileHandle_p->LoopCount = DirEntry_p->Size.Cyclic.LoopCount;            }        }                /* Set the file position */                if (WritePosition)        {            stavfs_SetPos(Device_p, DirEntry_p, &CurrentPos, &(FileHandle_p->Write));        }        else        {            stavfs_SetPos(Device_p, DirEntry_p, &CurrentPos, &(FileHandle_p->Read));        }    }        return (Error);}/******************************************************************************Function Name : stavfs_AllocDiskSpace  Description : Allocate more space to the file.   Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_AllocDiskSpace(stavfs_Device_t *Device_p, stavfs_DirEntry_t *DirEntry_p, U64 Size){    ST_ErrorCode_t Error = ST_NO_ERROR;    int AllocationUnits  = 1;    U64 PrevLBA;    U64 FreeLBA;        assert(Device_p   != NULL);    assert(DirEntry_p != NULL);    if (DirEntry_p->Flags & FILE_FLAG_STREAM_MODE)    {        /* Allocate Cluster Blocks */                AllocationUnits = CLUSTERS_PER_BLOCK(Device_p);    }    else    {        /* Allocate Clusters */                AllocationUnits = 1;    }        /* Find the end of the File allocation chain */        PrevLBA = DirEntry_p->EndLBA;    if (ST_NO_ERROR != (Error = stavfs_WalkTheChain(Device_p, FALSE, &PrevLBA, NULL)))    {    }        else if (0 == stavfs_GetFreeClusters(Device_p, AllocationUnits, &(PrevLBA), &(FreeLBA)))    {        /* No space available */        STTBX_Print(("Failed to find free disk space\n"));        Error = STAVFS_ERROR_DISK_FULL;    }    else     {        /* Are we appending */                if (INT_I64_AreEqual(NullLBA, DirEntry_p->StartLBA))        {            /* First allocation to file. We must link the on-disk directory entry              to the chain before we allocate any cluster, in order that things              can be recovered in the event of a crash */                                    stavfs_ModifyDirEntry(Device_p, DirEntry_p);                        DirEntry_p->StartLBA = FreeLBA;            DirEntry_p->EndLBA   = FreeLBA;            PrevLBA              = NullLBA;                        Error = stavfs_FlushDir(Device_p, NULL);        }                if (Error == ST_NO_ERROR)        {            U32 RequiredSize   = 0;            U32 AllocatedSize  = 0;            U32 Round          = 0;                        /* Rescale Size to Sectors */                        if (Size.LSW & 0X000001FF)            {                Round = 1;            }            else            {                Round = 0;            }                        /* Divide by the sector size */                        I64_ShiftRight(9, Size);                        RequiredSize += Size.LSW +Round;                        /* Rescale to Allocation units */                        if (RequiredSize % (AllocationUnits * Device_p->ClusterSize))            {                Round = 1;            }            else            {                Round = 0;            }                        RequiredSize = RequiredSize/(AllocationUnits * Device_p->ClusterSize) + Round;                        /* Allocate the required space */             /* Impose a minimum size */             if (0 == RequiredSize)            {                RequiredSize = 1;            }             /* In Clusters */             RequiredSize *= AllocationUnits;             AllocatedSize = stavfs_AllocFreeClusters (Device_p, RequiredSize, AllocationUnits, &(PrevLBA), &(FreeLBA));            RequiredSize -= AllocatedSize;                        if (AllocatedSize != 0)            {                /* We allocated something */                                stavfs_ModifyDirEntry(Device_p, DirEntry_p);                DirEntry_p->EndLBA = PrevLBA;                                INT_I64_AddLit(DirEntry_p->AllocSize, AllocatedSize, DirEntry_p->AllocSize);            }                        if (RequiredSize != 0)            {                /* Not all space allocated */                 Error = STAVFS_ERROR_DISK_FULL;            }        }    }        return (Error);}/***********************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -