Arquivos
hhvm/hphp/runtime/base/mem_file.cpp
T
Kyle Delong a8e3321fbd HPHP/XHP: 'mixed' type in attribute declarations
We'd like to start using ##mixed## instead of ##var## for attribute types to be consistent with Hack. As a followup to this (once released), we would codemod all ##var## to ##mixed##.
2013-07-18 17:28:37 -07:00

200 linhas
5.4 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/runtime/base/mem_file.h"
#include "hphp/runtime/base/complex_types.h"
#include "hphp/runtime/base/http_client.h"
#include "hphp/runtime/server/static_content_cache.h"
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/util/compression.h"
#include "hphp/util/logger.h"
namespace HPHP {
IMPLEMENT_OBJECT_ALLOCATION(MemFile)
///////////////////////////////////////////////////////////////////////////////
StaticString MemFile::s_class_name("MemFile");
///////////////////////////////////////////////////////////////////////////////
MemFile::MemFile()
: File(false), m_data(nullptr), m_len(-1), m_cursor(0), m_malloced(false) {
}
MemFile::MemFile(const char *data, int64_t len)
: File(false), m_data(nullptr), m_len(len), m_cursor(0), m_malloced(true) {
m_data = (char*)malloc(len + 1);
if (m_data && len) {
memcpy(m_data, data, len);
}
m_data[len] = '\0';
}
MemFile::~MemFile() {
closeImpl();
}
bool MemFile::open(CStrRef filename, CStrRef mode) {
assert(m_len == -1);
// mem files are read-only
const char* mode_str = mode.c_str();
if (strchr(mode_str, '+') || strchr(mode_str, 'a') || strchr(mode_str, 'w')) {
return false;
}
int len = INT_MIN;
bool compressed = false;
char *data =
StaticContentCache::TheFileCache->read(filename.c_str(), len, compressed);
// -1: PHP file; -2: directory
if (len != INT_MIN && len != -1 && len != -2) {
assert(len >= 0);
if (compressed) {
assert(RuntimeOption::EnableOnDemandUncompress);
data = gzdecode(data, len);
if (data == nullptr) {
throw FatalErrorException("cannot unzip compressed data");
}
m_data = data;
m_malloced = true;
m_len = len;
return true;
}
m_name = (std::string) filename;
m_data = data;
m_len = len;
return true;
}
if (len != INT_MIN) {
Logger::Error("Cannot open a PHP file or a directory as MemFile: %s",
filename.c_str());
}
return false;
}
bool MemFile::close() {
return closeImpl();
}
bool MemFile::closeImpl() {
s_file_data->m_pcloseRet = 0;
m_closed = true;
if (m_malloced && m_data) {
free(m_data);
m_data = nullptr;
}
File::closeImpl();
return true;
}
///////////////////////////////////////////////////////////////////////////////
int64_t MemFile::readImpl(char *buffer, int64_t length) {
assert(m_len != -1);
assert(length > 0);
int64_t remaining = m_len - m_cursor;
if (remaining < length) length = remaining;
if (length > 0) {
memcpy(buffer, (const void *)(m_data + m_cursor), length);
}
m_cursor += length;
return length;
}
int MemFile::getc() {
assert(m_len != -1);
return File::getc();
}
bool MemFile::seek(int64_t offset, int whence /* = SEEK_SET */) {
assert(m_len != -1);
if (whence == SEEK_CUR) {
if (offset > 0 && offset < m_writepos - m_readpos) {
m_readpos += offset;
m_position += offset;
return true;
}
offset += m_position;
whence = SEEK_SET;
}
// invalidate the current buffer
m_writepos = 0;
m_readpos = 0;
if (whence == SEEK_SET) {
m_cursor = offset;
} else {
assert(whence == SEEK_END);
m_cursor = m_len + offset;
}
m_position = m_cursor;
return true;
}
int64_t MemFile::tell() {
assert(m_len != -1);
return m_position;
}
bool MemFile::eof() {
assert(m_len != -1);
int64_t avail = m_writepos - m_readpos;
if (avail > 0) {
return false;
}
return m_cursor == m_len;
}
bool MemFile::rewind() {
assert(m_len != -1);
m_cursor = 0;
m_writepos = 0;
m_readpos = 0;
m_position = 0;
return true;
}
int64_t MemFile::writeImpl(const char *buffer, int64_t length) {
throw FatalErrorException((string("cannot write a mem stream: ") +
m_name).c_str());
}
bool MemFile::flush() {
throw FatalErrorException((string("cannot flush a mem stream: ") +
m_name).c_str());
}
///////////////////////////////////////////////////////////////////////////////
void MemFile::unzip() {
assert(m_len != -1);
assert(!m_malloced);
assert(m_cursor == 0);
int len = m_len;
char *data = gzdecode(m_data, len);
if (data == nullptr) {
throw FatalErrorException((string("cannot unzip mem stream: ") +
m_name).c_str());
}
m_data = data;
m_malloced = true;
m_len = len;
}
///////////////////////////////////////////////////////////////////////////////
}