16f2c2defSopenharmony_ci/*
26f2c2defSopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
36f2c2defSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
46f2c2defSopenharmony_ci * you may not use this file except in compliance with the License.
56f2c2defSopenharmony_ci * You may obtain a copy of the License at
66f2c2defSopenharmony_ci *
76f2c2defSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
86f2c2defSopenharmony_ci *
96f2c2defSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
106f2c2defSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
116f2c2defSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126f2c2defSopenharmony_ci * See the License for the specific language governing permissions and
136f2c2defSopenharmony_ci * limitations under the License.
146f2c2defSopenharmony_ci */
156f2c2defSopenharmony_ci
166f2c2defSopenharmony_ci#include "hiview_cache.h"
176f2c2defSopenharmony_ci#include "securec.h"
186f2c2defSopenharmony_ci#include "ohos_types.h"
196f2c2defSopenharmony_ci#include "hiview_util.h"
206f2c2defSopenharmony_ci
216f2c2defSopenharmony_cistatic uint16 GetReadCursor(HiviewCache *cache);
226f2c2defSopenharmony_ci
236f2c2defSopenharmony_ciboolean InitHiviewStaticCache(HiviewCache *cache, HiviewCacheType type, uint8 *buffer, uint16 size)
246f2c2defSopenharmony_ci{
256f2c2defSopenharmony_ci    if (cache == NULL) {
266f2c2defSopenharmony_ci        return FALSE;
276f2c2defSopenharmony_ci    }
286f2c2defSopenharmony_ci
296f2c2defSopenharmony_ci    cache->usedSize = 0;
306f2c2defSopenharmony_ci    cache->wCursor = 0;
316f2c2defSopenharmony_ci    cache->buffer = buffer;
326f2c2defSopenharmony_ci    cache->size = size;
336f2c2defSopenharmony_ci    cache->type = type;
346f2c2defSopenharmony_ci
356f2c2defSopenharmony_ci    return TRUE;
366f2c2defSopenharmony_ci}
376f2c2defSopenharmony_ci
386f2c2defSopenharmony_ciboolean InitHiviewCache(HiviewCache *cache, HiviewCacheType type, uint16 size)
396f2c2defSopenharmony_ci{
406f2c2defSopenharmony_ci    if (cache == NULL) {
416f2c2defSopenharmony_ci        return FALSE;
426f2c2defSopenharmony_ci    }
436f2c2defSopenharmony_ci
446f2c2defSopenharmony_ci    uint8 *buffer = (uint8 *)HIVIEW_MemAlloc(MEM_POOL_HIVIEW_ID, size);
456f2c2defSopenharmony_ci    if (buffer == NULL) {
466f2c2defSopenharmony_ci        return FALSE;
476f2c2defSopenharmony_ci    }
486f2c2defSopenharmony_ci
496f2c2defSopenharmony_ci    cache->usedSize = 0;
506f2c2defSopenharmony_ci    cache->wCursor = 0;
516f2c2defSopenharmony_ci    cache->buffer = buffer;
526f2c2defSopenharmony_ci    cache->size = size;
536f2c2defSopenharmony_ci    cache->type = type;
546f2c2defSopenharmony_ci
556f2c2defSopenharmony_ci    return TRUE;
566f2c2defSopenharmony_ci}
576f2c2defSopenharmony_ci
586f2c2defSopenharmony_ciint32 WriteToCache(HiviewCache *cache, const uint8 *data, uint16 wLen)
596f2c2defSopenharmony_ci{
606f2c2defSopenharmony_ci    if (cache == NULL || data == NULL || cache->buffer == NULL) {
616f2c2defSopenharmony_ci        return -1;
626f2c2defSopenharmony_ci    }
636f2c2defSopenharmony_ci
646f2c2defSopenharmony_ci    uint16 firstLen;
656f2c2defSopenharmony_ci    uint16 secondLen;
666f2c2defSopenharmony_ci    uint32 intSave = HIVIEW_IntLock();
676f2c2defSopenharmony_ci    // cast to uint32 for prevent uint16 overflow
686f2c2defSopenharmony_ci    if ((uint32)cache->size < (uint32)wLen + (uint32)cache->usedSize) {
696f2c2defSopenharmony_ci        HIVIEW_IntRestore(intSave);
706f2c2defSopenharmony_ci        return -1;
716f2c2defSopenharmony_ci    }
726f2c2defSopenharmony_ci    // overflow, cast to uint32 for prevent uint16 overflow
736f2c2defSopenharmony_ci    if ((uint32)cache->wCursor + (uint32)wLen > (uint32)cache->size) {
746f2c2defSopenharmony_ci        firstLen = cache->size - cache->wCursor;
756f2c2defSopenharmony_ci        if (firstLen > 0) {
766f2c2defSopenharmony_ci            if (memcpy_s(cache->buffer + cache->wCursor, firstLen, data, firstLen) == EOK) {
776f2c2defSopenharmony_ci                cache->wCursor += firstLen;
786f2c2defSopenharmony_ci                cache->usedSize += firstLen;
796f2c2defSopenharmony_ci            } else {
806f2c2defSopenharmony_ci                HIVIEW_IntRestore(intSave);
816f2c2defSopenharmony_ci                return -1;
826f2c2defSopenharmony_ci            }
836f2c2defSopenharmony_ci        }
846f2c2defSopenharmony_ci        cache->wCursor = 0;
856f2c2defSopenharmony_ci        secondLen = wLen - firstLen;
866f2c2defSopenharmony_ci        if (secondLen > 0) {
876f2c2defSopenharmony_ci            if (memcpy_s(cache->buffer + cache->wCursor, secondLen, data + firstLen, secondLen) == EOK) {
886f2c2defSopenharmony_ci                cache->wCursor += secondLen;
896f2c2defSopenharmony_ci                cache->usedSize += secondLen;
906f2c2defSopenharmony_ci            } else {
916f2c2defSopenharmony_ci                HIVIEW_IntRestore(intSave);
926f2c2defSopenharmony_ci                return firstLen;
936f2c2defSopenharmony_ci            }
946f2c2defSopenharmony_ci        }
956f2c2defSopenharmony_ci    } else {
966f2c2defSopenharmony_ci        if (memcpy_s(cache->buffer + cache->wCursor, wLen, data, wLen) == EOK) {
976f2c2defSopenharmony_ci            cache->wCursor += wLen;
986f2c2defSopenharmony_ci            cache->usedSize += wLen;
996f2c2defSopenharmony_ci        } else {
1006f2c2defSopenharmony_ci            HIVIEW_IntRestore(intSave);
1016f2c2defSopenharmony_ci            return -1;
1026f2c2defSopenharmony_ci        }
1036f2c2defSopenharmony_ci    }
1046f2c2defSopenharmony_ci    HIVIEW_IntRestore(intSave);
1056f2c2defSopenharmony_ci
1066f2c2defSopenharmony_ci    return wLen;
1076f2c2defSopenharmony_ci}
1086f2c2defSopenharmony_ci
1096f2c2defSopenharmony_ciint32 ReadFromCache(HiviewCache *cache, uint8 *data, uint16 rLen)
1106f2c2defSopenharmony_ci{
1116f2c2defSopenharmony_ci    if (cache == NULL || data == NULL || cache->buffer == NULL) {
1126f2c2defSopenharmony_ci        return -1;
1136f2c2defSopenharmony_ci    }
1146f2c2defSopenharmony_ci
1156f2c2defSopenharmony_ci    uint16 firstLen;
1166f2c2defSopenharmony_ci    uint16 secondLen;
1176f2c2defSopenharmony_ci    uint16 rCursor;
1186f2c2defSopenharmony_ci    // This function is the only read operation, so there is no need to lock
1196f2c2defSopenharmony_ci    if (cache->usedSize < rLen) {
1206f2c2defSopenharmony_ci        return -1;
1216f2c2defSopenharmony_ci    }
1226f2c2defSopenharmony_ci    rCursor = GetReadCursor(cache);
1236f2c2defSopenharmony_ci    // overflow, cast to uint32 for prevent uint16 overflow
1246f2c2defSopenharmony_ci    if ((uint32)rCursor + (uint32)rLen > (uint32)cache->size) {
1256f2c2defSopenharmony_ci        firstLen = cache->size - rCursor;
1266f2c2defSopenharmony_ci        if (firstLen > 0) {
1276f2c2defSopenharmony_ci            if (memcpy_s(data, firstLen, cache->buffer + rCursor, firstLen) != EOK) {
1286f2c2defSopenharmony_ci                return -1;
1296f2c2defSopenharmony_ci            }
1306f2c2defSopenharmony_ci        }
1316f2c2defSopenharmony_ci        secondLen = rLen - firstLen;
1326f2c2defSopenharmony_ci        if (secondLen > 0) {
1336f2c2defSopenharmony_ci            if (memcpy_s(data + firstLen, secondLen, cache->buffer, secondLen) != EOK) {
1346f2c2defSopenharmony_ci                return firstLen;
1356f2c2defSopenharmony_ci            }
1366f2c2defSopenharmony_ci        }
1376f2c2defSopenharmony_ci    } else {
1386f2c2defSopenharmony_ci        if (memcpy_s(data, rLen, cache->buffer + rCursor, rLen) != EOK) {
1396f2c2defSopenharmony_ci            return -1;
1406f2c2defSopenharmony_ci        }
1416f2c2defSopenharmony_ci    }
1426f2c2defSopenharmony_ci    uint32 intSave = HIVIEW_IntLock();
1436f2c2defSopenharmony_ci    cache->usedSize -= rLen;
1446f2c2defSopenharmony_ci    HIVIEW_IntRestore(intSave);
1456f2c2defSopenharmony_ci
1466f2c2defSopenharmony_ci    return rLen;
1476f2c2defSopenharmony_ci}
1486f2c2defSopenharmony_ci
1496f2c2defSopenharmony_ciint32 PrereadFromCache(HiviewCache *cache, uint8 *data, uint16 rLen)
1506f2c2defSopenharmony_ci{
1516f2c2defSopenharmony_ci    if (cache == NULL || data == NULL || cache->buffer == NULL) {
1526f2c2defSopenharmony_ci        return -1;
1536f2c2defSopenharmony_ci    }
1546f2c2defSopenharmony_ci    if (cache->usedSize < rLen) {
1556f2c2defSopenharmony_ci        return -1;
1566f2c2defSopenharmony_ci    }
1576f2c2defSopenharmony_ci
1586f2c2defSopenharmony_ci    uint16 firstLen;
1596f2c2defSopenharmony_ci    uint16 secondLen;
1606f2c2defSopenharmony_ci    uint16 rCursor = GetReadCursor(cache);
1616f2c2defSopenharmony_ci    // overflow, cast to uint32 for prevent uint16 overflow
1626f2c2defSopenharmony_ci    if ((uint32)rCursor + (uint32)rLen > (uint32)cache->size) {
1636f2c2defSopenharmony_ci        firstLen = cache->size - rCursor;
1646f2c2defSopenharmony_ci        if (firstLen > 0) {
1656f2c2defSopenharmony_ci            if (memcpy_s(data, firstLen, cache->buffer + rCursor, firstLen) != EOK) {
1666f2c2defSopenharmony_ci                return -1;
1676f2c2defSopenharmony_ci            }
1686f2c2defSopenharmony_ci        }
1696f2c2defSopenharmony_ci        secondLen = rLen - firstLen;
1706f2c2defSopenharmony_ci        if (secondLen > 0) {
1716f2c2defSopenharmony_ci            if (memcpy_s(data + firstLen, secondLen, cache->buffer, secondLen) != EOK) {
1726f2c2defSopenharmony_ci                return firstLen;
1736f2c2defSopenharmony_ci            }
1746f2c2defSopenharmony_ci        }
1756f2c2defSopenharmony_ci    } else {
1766f2c2defSopenharmony_ci        if (memcpy_s(data, rLen, cache->buffer + rCursor, rLen) != EOK) {
1776f2c2defSopenharmony_ci            return -1;
1786f2c2defSopenharmony_ci        }
1796f2c2defSopenharmony_ci    }
1806f2c2defSopenharmony_ci
1816f2c2defSopenharmony_ci    return rLen;
1826f2c2defSopenharmony_ci}
1836f2c2defSopenharmony_ci
1846f2c2defSopenharmony_civoid DiscardCacheData(HiviewCache *cache)
1856f2c2defSopenharmony_ci{
1866f2c2defSopenharmony_ci    if (cache == NULL) {
1876f2c2defSopenharmony_ci        return;
1886f2c2defSopenharmony_ci    }
1896f2c2defSopenharmony_ci    cache->wCursor = 0;
1906f2c2defSopenharmony_ci    cache->usedSize = 0;
1916f2c2defSopenharmony_ci}
1926f2c2defSopenharmony_ci
1936f2c2defSopenharmony_civoid DestroyCache(HiviewCache *cache)
1946f2c2defSopenharmony_ci{
1956f2c2defSopenharmony_ci    if (cache == NULL) {
1966f2c2defSopenharmony_ci        return;
1976f2c2defSopenharmony_ci    }
1986f2c2defSopenharmony_ci    if (cache->buffer != NULL) {
1996f2c2defSopenharmony_ci        HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, cache->buffer);
2006f2c2defSopenharmony_ci        cache->buffer = NULL;
2016f2c2defSopenharmony_ci    }
2026f2c2defSopenharmony_ci    cache->wCursor = 0;
2036f2c2defSopenharmony_ci    cache->usedSize = 0;
2046f2c2defSopenharmony_ci    cache->size = 0;
2056f2c2defSopenharmony_ci}
2066f2c2defSopenharmony_ci
2076f2c2defSopenharmony_cistatic uint16 GetReadCursor(HiviewCache *cache)
2086f2c2defSopenharmony_ci{
2096f2c2defSopenharmony_ci    if (cache == NULL || cache->buffer == NULL) {
2106f2c2defSopenharmony_ci        return 0;
2116f2c2defSopenharmony_ci    }
2126f2c2defSopenharmony_ci
2136f2c2defSopenharmony_ci    uint16 readCursor;
2146f2c2defSopenharmony_ci    uint32 intSave = HIVIEW_IntLock();
2156f2c2defSopenharmony_ci    if (cache->wCursor >= cache->usedSize) {
2166f2c2defSopenharmony_ci        readCursor = cache->wCursor - cache->usedSize;
2176f2c2defSopenharmony_ci    } else {
2186f2c2defSopenharmony_ci        readCursor = cache->size - (cache->usedSize - cache->wCursor);
2196f2c2defSopenharmony_ci    }
2206f2c2defSopenharmony_ci    HIVIEW_IntRestore(intSave);
2216f2c2defSopenharmony_ci    return readCursor;
2226f2c2defSopenharmony_ci}
223