12fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* 22fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Copyright (C) 2013, The Android Open Source Project 32fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * 42fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Licensed under the Apache License, Version 2.0 (the "License"); 52fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * you may not use this file except in compliance with the License. 62fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * You may obtain a copy of the License at 72fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * 82fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * http://www.apache.org/licenses/LICENSE-2.0 92fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * 102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Unless required by applicable law or agreed to in writing, software 112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * distributed under the License is distributed on an "AS IS" BASIS, 122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * See the License for the specific language governing permissions and 142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * limitations under the License. 152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa */ 162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/mmapped_buffer.h" 182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <cerrno> 202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <climits> 212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <cstdio> 222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <fcntl.h> 232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <sys/mman.h> 242fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <unistd.h> 252fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 2688bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/file_utils.h" 272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime { 292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 302fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ MmappedBuffer::MmappedBufferPtr MmappedBuffer::openBuffer( 312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const char *const path, const int bufferOffset, const int bufferSize, 322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const bool isUpdatable) { 332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int mmapFd = open(path, O_RDONLY); 342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (mmapFd < 0) { 352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: Can't open the source. path=%s errno=%d", path, errno); 362dc8e36f8eaa598371a67dc58757a096a75374a3Keisuke Kuroyanagi return nullptr; 372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int pagesize = sysconf(_SC_PAGESIZE); 392fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int offset = bufferOffset % pagesize; 402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa int alignedOffset = bufferOffset - offset; 412fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa int alignedSize = bufferSize + offset; 422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int protMode = isUpdatable ? PROT_READ | PROT_WRITE : PROT_READ; 432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa void *const mmappedBuffer = mmap(0, alignedSize, protMode, MAP_PRIVATE, mmapFd, 442fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa alignedOffset); 452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (mmappedBuffer == MAP_FAILED) { 462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno); 472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa close(mmapFd); 482dc8e36f8eaa598371a67dc58757a096a75374a3Keisuke Kuroyanagi return nullptr; 492fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa uint8_t *const buffer = static_cast<uint8_t *>(mmappedBuffer) + offset; 512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (!buffer) { 522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: buffer is null"); 532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa close(mmapFd); 542dc8e36f8eaa598371a67dc58757a096a75374a3Keisuke Kuroyanagi return nullptr; 552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 562fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return MmappedBufferPtr(new MmappedBuffer(buffer, bufferSize, mmappedBuffer, alignedSize, 572fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mmapFd, isUpdatable)); 582fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 592fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 602fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ MmappedBuffer::MmappedBufferPtr MmappedBuffer::openBuffer( 612fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const char *const path, const bool isUpdatable) { 622fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int fileSize = FileUtils::getFileSize(path); 632fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (fileSize == -1) { 642dc8e36f8eaa598371a67dc58757a096a75374a3Keisuke Kuroyanagi return nullptr; 652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else if (fileSize == 0) { 662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return MmappedBufferPtr(new MmappedBuffer(isUpdatable)); 672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } else { 682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return openBuffer(path, 0 /* bufferOffset */, fileSize, isUpdatable); 692fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ MmappedBuffer::MmappedBufferPtr MmappedBuffer::openBuffer( 732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const char *const dirPath, const char *const fileName, const bool isUpdatable) { 742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int filePathBufferSize = PATH_MAX + 1 /* terminator */; 752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa char filePath[filePathBufferSize]; 762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa const int filePathLength = snprintf(filePath, filePathBufferSize, "%s%s", dirPath, 772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa fileName); 782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (filePathLength >= filePathBufferSize) { 792dc8e36f8eaa598371a67dc58757a096a75374a3Keisuke Kuroyanagi return nullptr; 802fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 812fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return openBuffer(filePath, isUpdatable); 822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen WakasaMmappedBuffer::~MmappedBuffer() { 852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (mAlignedSize == 0) { 862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return; 872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa int ret = munmap(mMmappedBuffer, mAlignedSize); 892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (ret != 0) { 902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno); 912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa ret = close(mMmapFd); 932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (ret != 0) { 942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa AKLOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno); 952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} 972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} // namespace latinime 99