blob: b249694c6c3cdcacddf64c40261d1ee4542556d5 [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/files/file_path.h"
#include "base/files/file_starboard.h"
#include "base/files/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 {
SbFile ToSbFile(SkFile* sk_file) {
// PlatformFile is a pointer type in Starboard, so we cannot use static_cast
// from intptr_t.
return reinterpret_cast<SbFile>(sk_file);
}
SkFile* ToFILE(SbFile starboard_file) {
return reinterpret_cast<SkFile*>(starboard_file);
}
int ToSbFileFlags(SkFILE_Flags sk_flags) {
int flags = 0;
if (sk_flags & kRead_SkFILE_Flag) {
if (sk_flags & kWrite_SkFILE_Flag) {
flags |= kSbFileWrite;
}
flags |= kSbFileOpenOnly | kSbFileRead;
} else if (sk_flags & kWrite_SkFILE_Flag) {
flags |= kSbFileOpenAlways | kSbFileWrite;
}
return flags;
}
} // namespace
SkFile* sk_fopen(const char path[], SkFILE_Flags sk_flags) {
SbFile starboard_file = SbFileOpen(path, ToSbFileFlags(sk_flags), NULL, NULL);
if (starboard_file == base::kInvalidPlatformFile) {
return nullptr;
}
return ToFILE(starboard_file);
}
void sk_fclose(SkFile* sk_file) {
SkASSERT(sk_file);
SbFileClose(ToSbFile(sk_file));
}
size_t sk_fgetsize(SkFile* sk_file) {
SkASSERT(sk_file);
SbFile file = ToSbFile(sk_file);
// Save current position so we can restore it.
int64_t current_position = SbFileSeek(file, kSbFileFromCurrent, 0);
if (current_position < 0) {
return 0;
}
// Find the file size by seeking to the end.
int64_t size = SbFileSeek(file, kSbFileFromEnd, 0);
if (size < 0) {
size = 0;
}
// Restore original file position.
SbFileSeek(file, kSbFileFromBegin, current_position);
return size;
}
size_t sk_fwrite(const void* buffer, size_t byteCount, SkFile* sk_file) {
SkASSERT(sk_file);
SbFile file = ToSbFile(sk_file);
int result =
SbFileWrite(file, reinterpret_cast<const char*>(buffer), byteCount);
base::RecordFileWriteStat(result);
return result;
}
void sk_fflush(SkFile* sk_file) {
SkASSERT(sk_file);
SbFile file = ToSbFile(sk_file);
SbFileFlush(file);
}
bool sk_fseek(SkFile* sk_file, size_t position) {
SkASSERT(sk_file);
SbFile file = ToSbFile(sk_file);
int64_t new_position = SbFileSeek(file, kSbFileFromBegin, position);
return new_position == position;
}
size_t sk_ftell(SkFile* sk_file) {
SkASSERT(sk_file);
SbFile file = ToSbFile(sk_file);
return SbFileSeek(file, kSbFileFromCurrent, 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 base::PathExists(base::FilePath(path));
}
bool sk_isdir(const char* path) {
return base::DirectoryExists(base::FilePath(path));
}
bool sk_mkdir(const char* path) {
// Strange linking error on windows when calling base::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);
SbFile file = ToSbFile(f);
// Technically, flush doesn't have to call sync... but this is the best
// effort we can make.
SbFileFlush(file);
}
size_t sk_qread(SkFile* file, void* buffer, size_t count, size_t offset) {
SkASSERT(file);
SbFile starboard_file = ToSbFile(file);
int original_position = SbFileSeek(starboard_file, kSbFileFromCurrent, 0);
if (original_position < 0) {
return SIZE_MAX;
}
int position = SbFileSeek(starboard_file, kSbFileFromBegin, offset);
int result = 0;
if (position == offset) {
result = SbFileReadAll(starboard_file, reinterpret_cast<char*>(buffer),
static_cast<int>(count));
}
position = SbFileSeek(starboard_file, kSbFileFromBegin, original_position);
if (result < 0 || position < 0) {
return SIZE_MAX;
} else {
return result;
}
}
size_t sk_fread(void* buffer, size_t byteCount, SkFile* file) {
SkASSERT(file);
SbFile starboard_file = ToSbFile(file);
return SbFileReadAll(starboard_file, reinterpret_cast<char*>(buffer),
byteCount);
}