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