1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10// TODO: add unittests for all these operations
11
12#ifndef SkOSFile_DEFINED
13#define SkOSFile_DEFINED
14
15#include "SkString.h"
16
17#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
18    #include <dirent.h>
19#endif
20
21#include <stddef.h> // ptrdiff_t
22
23struct SkFILE;
24
25enum SkFILE_Flags {
26    kRead_SkFILE_Flag   = 0x01,
27    kWrite_SkFILE_Flag  = 0x02
28};
29
30#ifdef _WIN32
31const static char SkPATH_SEPARATOR = '\\';
32#else
33const static char SkPATH_SEPARATOR = '/';
34#endif
35
36SkFILE* sk_fopen(const char path[], SkFILE_Flags);
37void    sk_fclose(SkFILE*);
38
39size_t  sk_fgetsize(SkFILE*);
40/** Return true if the file could seek back to the beginning
41*/
42bool    sk_frewind(SkFILE*);
43
44size_t  sk_fread(void* buffer, size_t byteCount, SkFILE*);
45size_t  sk_fwrite(const void* buffer, size_t byteCount, SkFILE*);
46
47char*   sk_fgets(char* str, int size, SkFILE* f);
48
49void    sk_fflush(SkFILE*);
50
51bool    sk_fseek(SkFILE*, size_t);
52bool    sk_fmove(SkFILE*, long);
53size_t  sk_ftell(SkFILE*);
54
55/** Maps a file into memory. Returns the address and length on success, NULL otherwise.
56 *  The mapping is read only.
57 *  When finished with the mapping, free the returned pointer with sk_fmunmap.
58 */
59void*   sk_fmmap(SkFILE* f, size_t* length);
60
61/** Maps a file descriptor into memory. Returns the address and length on success, NULL otherwise.
62 *  The mapping is read only.
63 *  When finished with the mapping, free the returned pointer with sk_fmunmap.
64 */
65void*   sk_fdmmap(int fd, size_t* length);
66
67/** Unmaps a file previously mapped by sk_fmmap or sk_fdmmap.
68 *  The length parameter must be the same as returned from sk_fmmap.
69 */
70void    sk_fmunmap(const void* addr, size_t length);
71
72/** Returns true if the two point at the exact same filesystem object. */
73bool    sk_fidentical(SkFILE* a, SkFILE* b);
74
75/** Returns the underlying file descriptor for the given file.
76 *  The return value will be < 0 on failure.
77 */
78int     sk_fileno(SkFILE* f);
79
80// Returns true if something (file, directory, ???) exists at this path.
81bool    sk_exists(const char *path);
82
83// Returns true if a directory exists at this path.
84bool    sk_isdir(const char *path);
85
86// Have we reached the end of the file?
87int sk_feof(SkFILE *);
88
89
90// Create a new directory at this path; returns true if successful.
91// If the directory already existed, this will return true.
92// Description of the error, if any, will be written to stderr.
93bool    sk_mkdir(const char* path);
94
95class SkOSFile {
96public:
97    class Iter {
98    public:
99        Iter();
100        Iter(const char path[], const char suffix[] = NULL);
101        ~Iter();
102
103        void reset(const char path[], const char suffix[] = NULL);
104        /** If getDir is true, only returns directories.
105            Results are undefined if true and false calls are
106            interleaved on a single iterator.
107        */
108        bool next(SkString* name, bool getDir = false);
109
110    private:
111#ifdef SK_BUILD_FOR_WIN
112        HANDLE      fHandle;
113        uint16_t*   fPath16;
114#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
115        DIR*        fDIR;
116        SkString    fPath, fSuffix;
117#endif
118    };
119};
120
121class SkUTF16_Str {
122public:
123    SkUTF16_Str(const char src[]);
124    ~SkUTF16_Str()
125    {
126        sk_free(fStr);
127    }
128    const uint16_t* get() const { return fStr; }
129
130private:
131    uint16_t*   fStr;
132};
133
134/**
135 *  Functions for modifying SkStrings which represent paths on the filesystem.
136 */
137class SkOSPath {
138public:
139    /**
140     * Assembles rootPath and relativePath into a single path, like this:
141     * rootPath/relativePath.
142     * It is okay to call with a NULL rootPath and/or relativePath. A path
143     * separator will still be inserted.
144     *
145     * Uses SkPATH_SEPARATOR, to work on all platforms.
146     */
147    static SkString SkPathJoin(const char *rootPath, const char *relativePath);
148
149    /**
150     *  Return the name of the file, ignoring the directory structure.
151     *  Behaves like python's os.path.basename. If the fullPath is
152     *  /dir/subdir/, an empty string is returned.
153     *  @param fullPath Full path to the file.
154     *  @return SkString The basename of the file - anything beyond the
155     *      final slash, or the full name if there is no slash.
156     */
157    static SkString SkBasename(const char* fullPath);
158};
159#endif
160