| // Copyright 2017 Google Inc. |
| // |
| // 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 "filesystem_for_testing.h" |
| |
| #include <cassert> |
| #include <climits> |
| #include <cstdio> |
| #include <cstring> |
| #include <utility> |
| |
| namespace cpu_features { |
| |
| FakeFile::FakeFile(int file_descriptor, const char* content) |
| : file_descriptor_(file_descriptor), content_(content) {} |
| |
| FakeFile::~FakeFile() { assert(!opened_); } |
| |
| void FakeFile::Open() { |
| assert(!opened_); |
| opened_ = true; |
| } |
| |
| void FakeFile::Close() { |
| assert(opened_); |
| opened_ = false; |
| } |
| |
| int FakeFile::Read(int fd, void* buf, size_t count) { |
| assert(count < INT_MAX); |
| assert(fd == file_descriptor_); |
| const size_t remainder = content_.size() - head_index_; |
| const size_t read = count > remainder ? remainder : count; |
| memcpy(buf, content_.data() + head_index_, read); |
| head_index_ += read; |
| assert(read < INT_MAX); |
| return (int)read; |
| } |
| |
| void FakeFilesystem::Reset() { files_.clear(); } |
| |
| FakeFile* FakeFilesystem::CreateFile(const std::string& filename, |
| const char* content) { |
| auto& file = files_[filename]; |
| file = |
| std::unique_ptr<FakeFile>(new FakeFile(next_file_descriptor_++, content)); |
| return file.get(); |
| } |
| |
| FakeFile* FakeFilesystem::FindFileOrNull(const std::string& filename) const { |
| const auto itr = files_.find(filename); |
| return itr == files_.end() ? nullptr : itr->second.get(); |
| } |
| |
| FakeFile* FakeFilesystem::FindFileOrDie(const int file_descriptor) const { |
| for (const auto& filename_file_pair : files_) { |
| FakeFile* const file_ptr = filename_file_pair.second.get(); |
| if (file_ptr->GetFileDescriptor() == file_descriptor) { |
| return file_ptr; |
| } |
| } |
| assert(false); |
| return nullptr; |
| } |
| |
| static FakeFilesystem* kFilesystem = new FakeFilesystem(); |
| |
| FakeFilesystem& GetEmptyFilesystem() { |
| kFilesystem->Reset(); |
| return *kFilesystem; |
| } |
| |
| extern "C" int CpuFeatures_OpenFile(const char* filename) { |
| auto* const file = kFilesystem->FindFileOrNull(filename); |
| if (file) { |
| file->Open(); |
| return file->GetFileDescriptor(); |
| } |
| return -1; |
| } |
| |
| extern "C" void CpuFeatures_CloseFile(int file_descriptor) { |
| kFilesystem->FindFileOrDie(file_descriptor)->Close(); |
| } |
| |
| extern "C" int CpuFeatures_ReadFile(int file_descriptor, void* buffer, |
| size_t buffer_size) { |
| return kFilesystem->FindFileOrDie(file_descriptor) |
| ->Read(file_descriptor, buffer, buffer_size); |
| } |
| |
| } // namespace cpu_features |