michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: // TODO: add unittests for all these operations michael@0: michael@0: #ifndef SkOSFile_DEFINED michael@0: #define SkOSFile_DEFINED michael@0: michael@0: #include "SkString.h" michael@0: michael@0: #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) michael@0: #include michael@0: #endif michael@0: michael@0: #include // ptrdiff_t michael@0: michael@0: struct SkFILE; michael@0: michael@0: enum SkFILE_Flags { michael@0: kRead_SkFILE_Flag = 0x01, michael@0: kWrite_SkFILE_Flag = 0x02 michael@0: }; michael@0: michael@0: #ifdef _WIN32 michael@0: const static char SkPATH_SEPARATOR = '\\'; michael@0: #else michael@0: const static char SkPATH_SEPARATOR = '/'; michael@0: #endif michael@0: michael@0: SkFILE* sk_fopen(const char path[], SkFILE_Flags); michael@0: void sk_fclose(SkFILE*); michael@0: michael@0: size_t sk_fgetsize(SkFILE*); michael@0: /** Return true if the file could seek back to the beginning michael@0: */ michael@0: bool sk_frewind(SkFILE*); michael@0: michael@0: size_t sk_fread(void* buffer, size_t byteCount, SkFILE*); michael@0: size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE*); michael@0: michael@0: char* sk_fgets(char* str, int size, SkFILE* f); michael@0: michael@0: void sk_fflush(SkFILE*); michael@0: michael@0: bool sk_fseek(SkFILE*, size_t); michael@0: bool sk_fmove(SkFILE*, long); michael@0: size_t sk_ftell(SkFILE*); michael@0: michael@0: /** Maps a file into memory. Returns the address and length on success, NULL otherwise. michael@0: * The mapping is read only. michael@0: * When finished with the mapping, free the returned pointer with sk_fmunmap. michael@0: */ michael@0: void* sk_fmmap(SkFILE* f, size_t* length); michael@0: michael@0: /** Maps a file descriptor into memory. Returns the address and length on success, NULL otherwise. michael@0: * The mapping is read only. michael@0: * When finished with the mapping, free the returned pointer with sk_fmunmap. michael@0: */ michael@0: void* sk_fdmmap(int fd, size_t* length); michael@0: michael@0: /** Unmaps a file previously mapped by sk_fmmap or sk_fdmmap. michael@0: * The length parameter must be the same as returned from sk_fmmap. michael@0: */ michael@0: void sk_fmunmap(const void* addr, size_t length); michael@0: michael@0: /** Returns true if the two point at the exact same filesystem object. */ michael@0: bool sk_fidentical(SkFILE* a, SkFILE* b); michael@0: michael@0: /** Returns the underlying file descriptor for the given file. michael@0: * The return value will be < 0 on failure. michael@0: */ michael@0: int sk_fileno(SkFILE* f); michael@0: michael@0: // Returns true if something (file, directory, ???) exists at this path. michael@0: bool sk_exists(const char *path); michael@0: michael@0: // Returns true if a directory exists at this path. michael@0: bool sk_isdir(const char *path); michael@0: michael@0: // Have we reached the end of the file? michael@0: int sk_feof(SkFILE *); michael@0: michael@0: michael@0: // Create a new directory at this path; returns true if successful. michael@0: // If the directory already existed, this will return true. michael@0: // Description of the error, if any, will be written to stderr. michael@0: bool sk_mkdir(const char* path); michael@0: michael@0: class SkOSFile { michael@0: public: michael@0: class Iter { michael@0: public: michael@0: Iter(); michael@0: Iter(const char path[], const char suffix[] = NULL); michael@0: ~Iter(); michael@0: michael@0: void reset(const char path[], const char suffix[] = NULL); michael@0: /** If getDir is true, only returns directories. michael@0: Results are undefined if true and false calls are michael@0: interleaved on a single iterator. michael@0: */ michael@0: bool next(SkString* name, bool getDir = false); michael@0: michael@0: private: michael@0: #ifdef SK_BUILD_FOR_WIN michael@0: HANDLE fHandle; michael@0: uint16_t* fPath16; michael@0: #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) michael@0: DIR* fDIR; michael@0: SkString fPath, fSuffix; michael@0: #endif michael@0: }; michael@0: }; michael@0: michael@0: class SkUTF16_Str { michael@0: public: michael@0: SkUTF16_Str(const char src[]); michael@0: ~SkUTF16_Str() michael@0: { michael@0: sk_free(fStr); michael@0: } michael@0: const uint16_t* get() const { return fStr; } michael@0: michael@0: private: michael@0: uint16_t* fStr; michael@0: }; michael@0: michael@0: /** michael@0: * Functions for modifying SkStrings which represent paths on the filesystem. michael@0: */ michael@0: class SkOSPath { michael@0: public: michael@0: /** michael@0: * Assembles rootPath and relativePath into a single path, like this: michael@0: * rootPath/relativePath. michael@0: * It is okay to call with a NULL rootPath and/or relativePath. A path michael@0: * separator will still be inserted. michael@0: * michael@0: * Uses SkPATH_SEPARATOR, to work on all platforms. michael@0: */ michael@0: static SkString SkPathJoin(const char *rootPath, const char *relativePath); michael@0: michael@0: /** michael@0: * Return the name of the file, ignoring the directory structure. michael@0: * Behaves like python's os.path.basename. If the fullPath is michael@0: * /dir/subdir/, an empty string is returned. michael@0: * @param fullPath Full path to the file. michael@0: * @return SkString The basename of the file - anything beyond the michael@0: * final slash, or the full name if there is no slash. michael@0: */ michael@0: static SkString SkBasename(const char* fullPath); michael@0: }; michael@0: #endif