/* * Copyright (c) 2023 Fancy Code. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "SharedDataImpl.h" #include "ILog.h" #include "SharedDataCode.h" #include static const char *SHARED_DATA_NAME = "shared_data"; constexpr short THERE_TWO_USER_DATA_HEADER = 2; SharedDataCpp::SharedDataCpp(const SHARER_NAME &sharerName, const char *path, const int &projectId) : SharedMemory(path, projectId), mSharerName(sharerName) { mPrimaryReadSize = 0; mMinorReadSize = 0; mSharedMemeory = nullptr; } void SharedDataCpp::MakeSharedMemory(const unsigned int readableSize, const unsigned int writableSize) { if (SHARER_NAME_PRIMARY == mSharerName) { mPrimaryReadSize = readableSize; mMinorReadSize = writableSize; } else if (SHARER_NAME_MINOR == mSharerName) { mPrimaryReadSize = writableSize; mMinorReadSize = readableSize; } else { LogError("Make shared memory failed.\n"); return; } const int SHARED_MEMORY_SIZE = readableSize + writableSize + sizeof(UserDataHeader) * THERE_TWO_USER_DATA_HEADER; SharedMemory::MakeSharedMemory(SHARED_MEMORY_SIZE); mSharedMemeory = SharedMemory::GetMemory(); WritableDataInit(); } void SharedDataCpp::WritableDataInit(void) { if (nullptr == mSharedMemeory) { LogError("mSharedMemeory is nullptr, failed.\n"); return; } if (SHARER_NAME_PRIMARY == mSharerName) { UserDataHeader *writableHeader = (UserDataHeader *)((char *)mSharedMemeory + sizeof(UserDataHeader) + mPrimaryReadSize); memcpy(writableHeader->mUserName, USER_NAME_INIT_NAME, USER_NAME_BUF_LENGTH); writableHeader->mDataLength = mMinorReadSize; } else if (SHARER_NAME_MINOR == mSharerName) { UserDataHeader *writableHeader = (UserDataHeader *)((char *)mSharedMemeory); memcpy(writableHeader->mUserName, USER_NAME_INIT_NAME, USER_NAME_BUF_LENGTH); writableHeader->mDataLength = mPrimaryReadSize; } else { LogError("Make shared memory failed.\n"); return; } } const StatusCode SharedDataCpp::GetReadableMemory(void *buf, const unsigned int &bufLength) { if (nullptr == mSharedMemeory) { LogError("mSharedMemeory is nullptr, failed.\n"); return CreateStatusCode(STATUS_CODE_NOT_OK); } if (SHARER_NAME_PRIMARY == mSharerName && bufLength == mPrimaryReadSize) { UserDataHeader *readableHeader = (UserDataHeader *)((char *)mSharedMemeory); LogInfo("Want to read %d and can be read %d\n", bufLength, readableHeader->mDataLength); if (memcmp(readableHeader->mUserName, USER_NAME_INIT_NAME, USER_NAME_BUF_LENGTH) == 0 && bufLength == readableHeader->mDataLength) { memcpy(buf, (char *)mSharedMemeory + sizeof(UserDataHeader), bufLength); } else { LogError("Readable memory didn't init yet or init error.\n"); return CreateSharedDataCode(SHARED_DATA_CODE_WRONG_PEER_PARAMETERS); } } else if (SHARER_NAME_MINOR == mSharerName && bufLength == mMinorReadSize) { UserDataHeader *readableHeader = (UserDataHeader *)((char *)mSharedMemeory + sizeof(UserDataHeader) + mPrimaryReadSize); LogInfo("Want to read %d and can be read %d\n", bufLength, readableHeader->mDataLength); if (memcmp(readableHeader->mUserName, USER_NAME_INIT_NAME, USER_NAME_BUF_LENGTH) == 0 && bufLength == readableHeader->mDataLength) { memcpy(buf, (char *)mSharedMemeory + sizeof(UserDataHeader) * THERE_TWO_USER_DATA_HEADER + mPrimaryReadSize, bufLength); } else { LogError("Readable memory didn't init yet or init error.\n"); return CreateSharedDataCode(SHARED_DATA_CODE_WRONG_PEER_PARAMETERS); } } else { LogError("Get readable memory failed.\n"); return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER); } return CreateStatusCode(STATUS_CODE_OK); } void SharedDataCpp::SetWritableMemory(void *buf, const unsigned int &bufLength) { if (nullptr == mSharedMemeory) { LogError("mSharedMemeory is nullptr, failed.\n"); return; } if (SHARER_NAME_PRIMARY == mSharerName && bufLength == mMinorReadSize) { UserDataHeader *readableHeader = (UserDataHeader *)((char *)mSharedMemeory); if (memcmp(readableHeader->mUserName, USER_NAME_INIT_NAME, USER_NAME_BUF_LENGTH) == 0) { if (mPrimaryReadSize == readableHeader->mDataLength) { memcpy((char *)mSharedMemeory + sizeof(UserDataHeader) * THERE_TWO_USER_DATA_HEADER + mPrimaryReadSize, buf, bufLength); } else { LogError("Peer not match.\n"); } } else { memcpy((char *)mSharedMemeory + sizeof(UserDataHeader) * THERE_TWO_USER_DATA_HEADER + mPrimaryReadSize, buf, bufLength); } } else if (SHARER_NAME_MINOR == mSharerName && bufLength == mPrimaryReadSize) { memcpy((char *)mSharedMemeory + sizeof(UserDataHeader), buf, bufLength); } else { LogError("Set writable memory failed.\n"); } } static const StatusCode MakeSharedData(SharedData *object, const unsigned int readableSize, const unsigned int writableSize) { SharedDataImpl *impl = ((SharedDataImpl *)(((char *)object) - sizeof(SharedDataHeader))); impl->mSharedData->MakeSharedMemory(readableSize, writableSize); return CreateStatusCode(STATUS_CODE_OK); } static const StatusCode GetSharedReadableMemory(SharedData *object, void *buf, const unsigned int bufLength) { SharedDataImpl *impl = ((SharedDataImpl *)(((char *)object) - sizeof(SharedDataHeader))); return impl->mSharedData->GetReadableMemory(buf, bufLength); } static void SetSharedWritableMemory(SharedData *object, void *buf, const unsigned int bufLength) { SharedDataImpl *impl = ((SharedDataImpl *)(((char *)object) - sizeof(SharedDataHeader))); impl->mSharedData->SetWritableMemory(buf, bufLength); } static void SharedDataImplFree(void *ptr) { SharedDataImpl *object = ((SharedDataImpl *)(((char *)ptr) - sizeof(SharedDataHeader))); if (SHARED_DATA_NAME == object->mHeader.mCheckName) { object->mSharedData->CleanSharedMemory(); object->mSharedData = nullptr; free(((char *)ptr) - sizeof(SharedDataHeader)); } else { LogError("Unknow ptr.\n"); } } SharedData *NewSharedDataImpl(const SHARER_NAME &name, const char *path, const int &projectId) { SharedDataImpl *impl = (SharedDataImpl *)malloc(sizeof(SharedDataImpl)); SharedDataImpl tmp; memcpy((void *)impl, (void *)&tmp, sizeof(SharedDataImpl)); impl->mHeader.mCheckName = SHARED_DATA_NAME; impl->mBase.mMakeSharedData = MakeSharedData; impl->mBase.mGetReadableData = GetSharedReadableMemory; impl->mBase.mSetWritableData = SetSharedWritableMemory; impl->mBase.mFree = SharedDataImplFree; impl->mSharedData = std::make_shared(name, path, projectId); return (SharedData *)(((char *)impl) + sizeof(SharedDataHeader)); }