blob: ff304cdee752555f2e5e63960ae8afe92fca2cde [file] [log] [blame]
/*
* Copyright 2013 The Cobalt Authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkOSFile_cobalt.h"
#include "SkString.h"
#include "SkTFitsIn.h"
#include "SkTemplates.h"
#include "SkTypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/optional.h"
#include "base/path_service.h"
// Implement functionality declared in SkOSFile.h via primitives provided
// by Chromium. In doing this, we need only ensure that support for Chromium
// file utilities is working and then Skia file utilities will also work.
namespace {
base::PlatformFile ToPlatformFile(SkFile* sk_file) {
// PlatformFile is a pointer type in Starboard, so we cannot use static_cast
// from intptr_t.
return reinterpret_cast<base::PlatformFile>(sk_file);
}
SkFile* ToFILE(base::PlatformFile platform_file) {
return reinterpret_cast<SkFile*>(platform_file);
}
int ToPlatformFlags(SkFILE_Flags sk_flags) {
int flags = 0;
if (sk_flags & kRead_SkFILE_Flag) {
if (sk_flags & kWrite_SkFILE_Flag) {
flags |= base::PLATFORM_FILE_WRITE;
}
flags |= base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ;
} else if (sk_flags & kWrite_SkFILE_Flag) {
flags |= base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
}
return flags;
}
} // namespace
SkFile* sk_fopen(const char path[], SkFILE_Flags sk_flags) {
base::PlatformFile platform_file = base::CreatePlatformFile(
FilePath(path), ToPlatformFlags(sk_flags), NULL, NULL);
if (platform_file == base::kInvalidPlatformFileValue) {
return nullptr;
}
return ToFILE(platform_file);
}
void sk_fclose(SkFile* sk_file) {
SkASSERT(sk_file);
base::ClosePlatformFile(ToPlatformFile(sk_file));
}
size_t sk_fgetsize(SkFile* sk_file) {
SkASSERT(sk_file);
base::PlatformFile file = ToPlatformFile(sk_file);
// Save current position so we can restore it.
int64_t current_position =
SeekPlatformFile(file, base::PLATFORM_FILE_FROM_CURRENT, 0);
if (current_position < 0) {
return 0;
}
// Find the file size by seeking to the end.
int64_t size = base::SeekPlatformFile(file, base::PLATFORM_FILE_FROM_END, 0);
if (size < 0) {
size = 0;
}
// Restore original file position.
SeekPlatformFile(file, base::PLATFORM_FILE_FROM_BEGIN, current_position);
return size;
}
size_t sk_fwrite(const void* buffer, size_t byteCount, SkFile* sk_file) {
SkASSERT(sk_file);
base::PlatformFile file = ToPlatformFile(sk_file);
return base::WritePlatformFileAtCurrentPos(
file, reinterpret_cast<const char*>(buffer), byteCount);
}
void sk_fflush(SkFile* sk_file) {
SkASSERT(sk_file);
base::PlatformFile file = ToPlatformFile(sk_file);
base::FlushPlatformFile(file);
}
bool sk_fseek(SkFile* sk_file, size_t position) {
SkASSERT(sk_file);
base::PlatformFile file = ToPlatformFile(sk_file);
int64_t new_position =
SeekPlatformFile(file, base::PLATFORM_FILE_FROM_BEGIN, position);
return new_position == position;
}
size_t sk_ftell(SkFile* sk_file) {
SkASSERT(sk_file);
base::PlatformFile file = ToPlatformFile(sk_file);
return SeekPlatformFile(file, base::PLATFORM_FILE_FROM_CURRENT, 0);
}
void* sk_fmmap(SkFile* sk_file, size_t* length) {
// Not supported, but clients may try to call to see if it is supported.
return NULL;
}
void* sk_fdmmap(int fd, size_t* length) {
NOTREACHED() << __FUNCTION__;
return NULL;
}
void sk_fmunmap(const void* addr, size_t length) {
NOTREACHED() << __FUNCTION__;
}
bool sk_fidentical(SkFile* sk_file_a, SkFile* sk_file_b) {
NOTREACHED() << __FUNCTION__;
return false;
}
int sk_fileno(SkFile* sk_file_a) {
NOTREACHED() << __FUNCTION__;
return -1;
}
bool sk_exists(const char* path, SkFILE_Flags) {
return file_util::PathExists(FilePath(path));
}
bool sk_isdir(const char* path) {
return file_util::DirectoryExists(FilePath(path));
}
bool sk_mkdir(const char* path) {
// Strange linking error on windows when calling file_util::CreateDirectory,
// having something to do with a system #define. This isn't used, anyway.
NOTREACHED() << __FUNCTION__;
return false;
}
void sk_fsync(SkFile* f) {
SkASSERT(f);
base::PlatformFile file = ToPlatformFile(f);
// Technically, flush doesn't have to call sync... but this is the best
// effort we can make.
base::FlushPlatformFile(file);
}
size_t sk_qread(SkFile* file, void* buffer, size_t count, size_t offset) {
SkASSERT(file);
base::PlatformFile platform_file = ToPlatformFile(file);
return base::ReadPlatformFile(platform_file, offset,
reinterpret_cast<char*>(buffer), count);
}
size_t sk_fread(void* buffer, size_t byteCount, SkFile* file) {
SkASSERT(file);
base::PlatformFile platform_file = ToPlatformFile(file);
return base::ReadPlatformFileAtCurrentPos(
platform_file, reinterpret_cast<char*>(buffer), byteCount);
}