EvalEmitDVArray: varray
[hiphop-php.git] / hphp / runtime / base / file.h
blobaf933d23da769f46b88f0b4e0d72488304621d4e
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_FILE_H_
18 #define incl_HPHP_FILE_H_
20 #include "hphp/runtime/base/execution-context.h"
21 #include "hphp/runtime/base/req-list.h"
22 #include "hphp/runtime/base/request-event-handler.h"
23 #include "hphp/runtime/base/req-ptr.h"
24 #include "hphp/runtime/base/type-array.h"
25 #include "hphp/runtime/base/type-resource.h"
26 #include "hphp/runtime/base/type-string.h"
27 #include "hphp/runtime/base/type-variant.h"
29 #include "hphp/util/rds-local.h"
31 struct stat;
33 namespace HPHP {
34 ///////////////////////////////////////////////////////////////////////////////
36 struct StreamContext;
38 extern RDS_LOCAL(int, s_pcloseRet);
40 // This structure holds the request allocated data members of File. The
41 // purpose of the class is to allow File (and subclasses) to be managed by
42 // the request heap while also allowing their underlying OS handles to be
43 // persisted beyond the lifetime of a request.
45 // The FileData is stored in a shared_ptr and managed by new/delete, so it is
46 // safe to store in an object whose lifetime is longer than a request.
47 // A File (or subclass) can be reconstructed using a shared_ptr to a FileData.
48 // Note that subclasses of File that need to be persisted must subclass
49 // FileData to add any persistent data members, e.g. see Socket.
50 // Classes in the FileData hierarchy may not contain request-allocated data.
51 struct FileData {
52 static const int DEFAULT_CHUNK_SIZE;
54 FileData() { }
55 explicit FileData(bool nonblocking);
56 virtual bool closeImpl();
57 virtual ~FileData();
59 protected:
60 bool valid() const { return m_fd >= 0;}
61 bool isClosed() const { return m_closed; }
62 void setIsClosed(bool closed) { m_closed = closed; }
63 void setFd(int fd) { m_fd = fd; }
64 int getFd() { return m_fd; }
66 private:
67 friend struct File;
68 friend struct PhpStreamWrapper;
69 int m_fd{-1}; // file descriptor
70 bool m_isLocal{false}; // is this on the local disk?
71 bool m_closed{false}; // whether close() was called
72 const bool m_nonblocking{true};
74 // fields useful for both reads and writes
75 bool m_eof{false};
76 int64_t m_position{0}; // the current cursor position
78 // fields only useful for buffered reads
79 int64_t m_writepos{0}; // where we have read from lower level
80 int64_t m_readpos{0}; // where we have given to upper level
82 std::string m_name;
83 std::string m_mode;
85 char *m_buffer{nullptr};
86 int64_t m_bufferSize{0};
87 int64_t m_chunkSize{DEFAULT_CHUNK_SIZE};
90 /**
91 * This is PHP's "stream", base class of plain file, gzipped file, directory
92 * and sockets. We are not going to structure directories this way at all,
93 * but we will have PlainFile, ZipFile and Socket derive from this base class,
94 * so they can share some minimal functionalities.
96 struct File : SweepableResourceData {
97 static String TranslatePath(const String& filename);
98 // Same as TranslatePath except doesn't make paths absolute
99 static String TranslatePathKeepRelative(const char* fn, uint32_t len);
100 static String TranslatePathKeepRelative(const String& filename) {
101 return TranslatePathKeepRelative(filename.c_str(), filename.size());
103 static String TranslatePathKeepRelative(const std::string& filename) {
104 return TranslatePathKeepRelative(filename.c_str(), filename.size());
106 // Same as TranslatePath except checks the file cache on miss
107 static String TranslatePathWithFileCache(const String& filename);
108 static String TranslateCommand(const String& cmd);
109 static req::ptr<File> Open(
110 const String& filename, const String& mode,
111 int options = 0, const req::ptr<StreamContext>& context = nullptr);
113 static bool IsVirtualDirectory(const String& filename);
114 static bool IsVirtualFile(const String& filename);
115 static bool IsPlainFilePath(const String& filename) {
116 return filename.find("://") == String::npos;
119 static const int USE_INCLUDE_PATH;
121 explicit File(bool nonblocking = true,
122 const String& wrapper_type = null_string,
123 const String& stream_type = empty_string_ref);
124 ~File() override;
126 static StaticString& classnameof() {
127 static StaticString result("File");
128 return result;
130 static StaticString s_resource_name;
132 // overriding ResourceData
133 const String& o_getClassNameHook() const override { return classnameof(); }
134 const String& o_getResourceName() const override;
135 bool isInvalid() const override { return m_data->m_closed; }
137 virtual int fd() const { return m_data->m_fd;}
138 bool valid() const { return m_data && m_data->m_fd >= 0; }
139 std::string getName() const { return m_data->m_name;}
141 virtual bool setBlocking(bool mode);
142 virtual bool setTimeout(uint64_t usecs);
145 * How to open this type of file.
147 virtual bool open(const String& filename, const String& mode) = 0;
149 virtual bool close() = 0;
150 virtual bool isClosed() const { return !m_data || m_data->m_closed; }
152 /* Use:
153 * - read() when fetching data to return to PHP
154 * - readImpl() when you want raw unbuffered data; for example, if you use
155 * the Socket class to implement a network-based extension, use readImpl
156 * to avoid the internal buffer, and so on
160 * Read one chunk of input. Returns a null string on failure or eof.
162 virtual int64_t readImpl(char *buffer, int64_t length) = 0;
163 virtual int getc();
164 virtual String read(int64_t length);
165 virtual String read();
167 /* Use:
168 * - write() in response to a PHP code that is documented as writing to a
169 * stream
170 * - writeImpl() if you want C-like behavior, instead of PHP-like behavior;
171 * for example, if you write a network-based extension using Socket
175 * Write one chunk of output. Returns bytes written.
177 virtual int64_t writeImpl(const char *buffer, int64_t length) = 0;
178 virtual int64_t write(const String& str, int64_t length = 0);
179 int putc(char c);
182 * Optional virtual functions to implement.
184 virtual bool seekable() { return false;}
185 virtual bool seek(int64_t offset, int whence = SEEK_SET);
186 virtual int64_t tell();
187 virtual bool eof();
188 virtual bool rewind();
189 virtual bool flush();
190 virtual bool truncate(int64_t size);
191 virtual bool lock(int operation);
192 virtual bool lock(int operation, bool &wouldblock);
193 virtual bool stat(struct stat *sb);
195 virtual Object await(uint16_t events, double timeout);
197 virtual Array getMetaData();
198 virtual Variant getWrapperMetaData() { return Variant(); }
199 String getWrapperType() const;
200 String getStreamType() const { return String{m_streamType}; }
201 const req::ptr<StreamContext>& getStreamContext() { return m_streamContext; }
202 void setStreamContext(const req::ptr<StreamContext>& context) {
203 m_streamContext = context;
205 int64_t bufferedLen() { return m_data->m_writepos - m_data->m_readpos; }
207 std::string getMode() { return m_data->m_mode; }
210 * Read one line a time. Returns a null string on failure or eof.
212 String readLine(int64_t maxlen = 0);
215 * Read one record a time. Returns a false on failure or eof.
217 Variant readRecord(const String& delimiter, int64_t maxlen = 0);
220 * Read entire file and print it out.
222 int64_t print();
225 * Write to file with specified format and arguments.
227 int64_t printf(const String& format, const Array& args);
230 * Get the Chunk Size.
232 int64_t getChunkSize() const;
235 * Set the Chunk Size.
237 void setChunkSize(int64_t chunk_size);
240 * Write one line of csv record.
242 int64_t writeCSV(const Array& fields, char delimiter = ',',
243 char enclosure = '"', char escape_char = '\\');
246 * Read one line of csv record.
248 Array readCSV(int64_t length = 0, char delimiter = ',', char enclosure = '"',
249 char escape = '\\', const String* initial = nullptr);
252 * Return the last error we know about
254 String getLastError();
256 bool isLocal() const { return m_data->m_isLocal; }
258 std::shared_ptr<FileData> getData() const { return m_data; }
260 protected:
261 bool closeImpl();
262 void sweep() override;
264 void setIsLocal(bool isLocal) { m_data->m_isLocal = isLocal; }
265 void setIsClosed(bool closed) { m_data->m_closed = closed; }
267 bool getEof() const { return m_data->m_eof; }
268 void setEof(bool eof) { m_data->m_eof = eof; }
270 int64_t getPosition() const { return m_data->m_position; }
271 void setPosition(int64_t pos) { m_data->m_position = pos; }
273 int64_t getWritePosition() const { return m_data->m_writepos; }
274 void setWritePosition(int64_t wpos) { m_data->m_writepos = wpos; }
276 int64_t getReadPosition() const { return m_data->m_readpos; }
277 void setReadPosition(int64_t rpos) { m_data->m_readpos = rpos; }
279 int getFd() const { return m_data->m_fd; }
280 void setFd(int fd) { m_data->m_fd = fd; }
282 void setName(std::string name) { m_data->m_name = name; }
284 void setStreamType(const StaticString& streamType) {
285 m_streamType = streamType.get();
288 FileData* getFileData() { return m_data.get(); }
289 const FileData* getFileData() const { return m_data.get(); }
291 protected:
292 explicit File(std::shared_ptr<FileData> data,
293 const String& wrapper_type = null_string,
294 const String& stream_type = empty_string_ref);
296 private:
297 std::shared_ptr<FileData> m_data;
298 StringData* m_wrapperType;
299 StringData* m_streamType;
300 req::ptr<StreamContext> m_streamContext;
303 ///////////////////////////////////////////////////////////////////////////////
306 #endif // incl_HPHP_FILE_H_