Example #1
0
//TODO: remove return int, make bool
int BinTreeNodeReader::readStreamStart()
{
    bool result = getOneToplevelStream();
    //TODO: count real bytes;
    int bytes = getOneToplevelStreamSize();

    if (decodedStream.bytesAvailable() < 3) {
        //TODO: make bool result. remove int.
        //return false;
        return bytes;
    }

    quint8 tag = 0, size;
    //TODO: check for bool result
    readInt8(tag);
    readInt8(size);
    readInt8(tag);
    if (tag != 1) {
        throw ProtocolException("Expecting STREAM_START in readStreamStart.");
    }

    int attribCount = (size - 2 + size % 2) / 2;

    AttributeList attribs;
    if (!readAttributes(attribs,attribCount)) {
        //TODO: make bool result. remove int.
        //return false;
        qDebug() << "readStreamStart: failed to read attributes" << attribCount;
        return bytes;
    }

    //TODO: make bool result. remove int.
    return bytes;
}
Example #2
0
bool BinTreeNodeReader::readString(int token, QByteArray& s)
{
    if (token == -1) {
        throw ProtocolException("-1 token in readString.");
    }

    if (token > 2 && token < 0xf5)
        return getToken(token, s);

    //no default value.
    switch (token)
    {
        case 0:
            return false;

        case 0xfc:
            quint8 size8;
            if (!readInt8(size8))
                return false;
            return fillArray(s,size8);

        case 0xfd:
            qint32 size24;
            if (!readInt24(size24))
                return false;
            return fillArray(s,size24);

        case 0xfe:
            quint8 token8;
            if (!readInt8(token8))
                return false;
            return getToken(0xf5 + token8, s);

        case 0xfa:
            QByteArray user,server;
            bool usr = readString(user);
            bool srv = readString(server);
            if (usr & srv)
            {
                s = user + "@" + server;
                return true;
            }
            if (srv)
            {
                s = server;
                return true;
            }
            throw ProtocolException("readString couldn't reconstruct jid.");
    }
    throw ProtocolException("readString invalid token " + QString::number(token));

}
Example #3
0
bool BinTreeNodeReader::readInt16(qint16 &val)
{
    quint8 r1;
    quint8 r2;

    if (!readInt8(r1)
            || !readInt8(r2)) {
        return false;
    }

    val = (r1 << 8) + r2;
    return true;
}
Example #4
0
bool BinTreeNodeReader::nextTreeInternal(ProtocolTreeNode& node)
{
    quint8 b;

    if (!readInt8(b))
        return false;

    int size = -1;
    if (!readListSize(b, size))
        return false;
    if (size < 0)
        return false;

    if (!readInt8(b))
        return false;

    if (b == 2)
        return false;

    QByteArray tag;
    if (!readString(b, tag))
        return false;

    int attribCount = (size - 2 + size % 2) / 2;

    AttributeList attribs;
    if (!readAttributes(attribs,attribCount))
        return false;

    node.setTag(tag);
    node.setAttributes(attribs);

    if ((size % 2) == 1)
        return true;

    if (!readInt8(b))
        return false;

    if (isListTag(b))
    {
        return readList(b,node);
    }

    QByteArray data;
    if (!readString(b,data))
        return false;

    node.setData(data);
    return true;
}
Example #5
0
bool BinTreeNodeReader::readInt24(qint32 &val)
{
    quint8 r1;
    quint8 r2;
    quint8 r3;

    if (!readInt8(r1)
            || !readInt8(r2)
            || !readInt8(r3)) {
        return false;
    }

    val = (r1 << 16) + (r2 << 8) + r3;
    return true;
}
Example #6
0
void UnitSpec_ReadVer1(UnitSpec* inUnitSpec, char*& buffer)
{
	int32 name[kSCNameLen];
	ReadName(buffer, name);

	inUnitSpec->mUnitDef = GetUnitDef(name);
	if (!inUnitSpec->mUnitDef) {
		char str[256];
		sprintf(str, "UGen '%s' not installed.", (char*)name);
		throw std::runtime_error(str);
		return;
	}
	inUnitSpec->mCalcRate = readInt8(buffer);

	inUnitSpec->mNumInputs = readInt16_be(buffer);
	inUnitSpec->mNumOutputs = readInt16_be(buffer);
	inUnitSpec->mSpecialIndex = readInt16_be(buffer);
	inUnitSpec->mInputSpec = (InputSpec*)malloc(sizeof(InputSpec) * inUnitSpec->mNumInputs);
	inUnitSpec->mOutputSpec = (OutputSpec*)malloc(sizeof(OutputSpec) * inUnitSpec->mNumOutputs);
	for (uint32 i=0; i<inUnitSpec->mNumInputs; ++i) {
		InputSpec_ReadVer1(inUnitSpec->mInputSpec + i, buffer);
	}
	for (uint32 i=0; i<inUnitSpec->mNumOutputs; ++i) {
		OutputSpec_Read(inUnitSpec->mOutputSpec + i, buffer);
	}
	uint64 numPorts = inUnitSpec->mNumInputs + inUnitSpec->mNumOutputs;
	inUnitSpec->mAllocSize = inUnitSpec->mUnitDef->mAllocSize + numPorts * (sizeof(Wire*) +  sizeof(float*));
}
Example #7
0
void OutputSpec_Read(OutputSpec* inOutputSpec, char*& buffer)
{
	inOutputSpec->mCalcRate = readInt8(buffer);
	inOutputSpec->mWireIndex = -1;
	inOutputSpec->mBufferIndex = -1;
	inOutputSpec->mNumConsumers = 0;
}
Example #8
0
bool BinTreeNodeReader::readString(QByteArray& s)
{
    quint8 token;
    if (!readInt8(token)) {
        qDebug() << "failed to read string token";
        return false;
    }
    return readString(token,s);
}
Example #9
0
bool BinTreeNodeReader::readString(int token, QByteArray& s, QDataStream& in)
{
    int size;

    if (token == -1) {
        qDebug() << "-1 token in readString";
        //socket->disconnectFromHost();
        Q_EMIT socketBroken();
    }

    if (token > 2 && token < 0xf5)
        return getToken(token, s, in);

    switch (token)
    {
        case 0:
            return false;

        case 0xfc:
            size = readInt8(in);
            fillArray(s,size,in);
            return true;

        case 0xfd:
            size = readInt24(in);
            fillArray(s,size,in);
            return true;

        case 0xfe:
            in >> token;
            return getToken(0xf5 + token, s, in);

        case 0xfa:
            QByteArray user,server;
            bool usr = readString(user,in);
            bool srv = readString(server,in);
            if (usr & srv)
            {
                s = user + "@" + server;
                return true;
            }
            if (srv)
            {
                s = server;
                return true;
            }
            qDebug() << "readString couldn't reconstruct jid.";
            //socket->disconnectFromHost();
            Q_EMIT socketBroken();
    }
    qDebug() << "readString invalid token" << QString::number(token);
    //socket->disconnectFromHost();
    Q_EMIT socketBroken();
    return false;
}
Example #10
0
int BinTreeNodeReader::readListSize(int token)
{
	switch (token) {
	case 0:   return 0;
	case 248: return readInt8(this->in);
	case 249: return readInt16(this->in);
	default:
		throw new WAException("invalid list size in readListSize: token " + token, WAException::CORRUPT_STREAM_EX, 0);
	}
	return 0;
}
Example #11
0
int WaveReader::readSample(int bytes) {
	switch (bytes) {
		case 1:
			return readInt8();
		case 2:
			return readInt16();
		case 4:
			return readInt32();
	}

	return 0;
}
Example #12
0
double MessageIn::readDouble()
{
    double value;
#ifdef USE_NATIVE_DOUBLE
    if (mPos + sizeof(double) <= mLength)
        memcpy(&value, mData + mPos, sizeof(double));
    mPos += sizeof(double);
#else
    int length = readInt8();
    std::istringstream i (readString(length));
    i >> value;
#endif
    return value;
}
Example #13
0
quint32 BinTreeNodeReader::readListSize(qint32 token, QDataStream& in)
{
    int size;
    if (token == 0)
        size = 0;
    else if (token == 0xf8)
        size = readInt8(in);
    else if (token == 0xf9)
        size = readInt16(in);
    else
        throw ProtocolException("Invalid list size in readListSize: token 0x" + QString::number(token,16));

    return size;
}
Example #14
0
static bool patchApplyPPF3(FILE *f, u8 **rom, int *size)
{
  fseek(f, 0, SEEK_END);
  int count = ftell(f);
  if (count < 56+4+1024)
    return false;
  count -= 56+4;

  fseek(f, 56, SEEK_SET);

  int imagetype = fgetc(f);
  int blockcheck = fgetc(f);
  int undo = fgetc(f);
  fgetc(f);

  u8 *mem = *rom;

  if (blockcheck) {
    u8 block[1024];
    fread(&block, 1, 1024, f);
    if (memcmp(&mem[(imagetype == 0) ? 0x9320 : 0x80A0], &block, 1024) != 0)
      return false;
    count -= 1024;
  }

  int idlen = ppfFileIdLen(f, 2);
  if (idlen > 0)
    count -= 16 + 16 + idlen;

  fseek(f, 56+4+(blockcheck ? 1024 : 0), SEEK_SET);

  while (count > 0) {
    __off64_t offset = readInt8(f);
    if (offset == -1)
      break;
    int len = fgetc(f);
    if (len == EOF)
      break;
    if (offset+len > *size)
      break;
    if (fread(&mem[offset], 1, len, f) != (size_t)len)
      break;
    if (undo) fseeko64(f, len, SEEK_CUR);
    count -= 8 + 1 + len;
    if (undo) count -= len;
  }

  return (count == 0);
}
Example #15
0
bool BinTreeNodeReader::readString(int token, QByteArray& s, QDataStream& in)
{
    int size;

    if (token == -1)
        throw ProtocolException("-1 token in readString.");

    if (token > 4 && token < 0xf5)
        return getToken(token,s);

    switch (token)
    {
        case 0:
            return false;

        case 0xfc:
            size = readInt8(in);
            fillArray(s,size,in);
            return true;

        case 0xfd:
            size = readInt24(in);
            fillArray(s,size,in);
            return true;

        case 0xfe:
            in >> token;
            return getToken(245 + token,s);

        case 0xfa:
            QByteArray user,server;
            bool usr = readString(user,in);
            bool srv = readString(server,in);
            if (usr & srv)
            {
                s = user + "@" + server;
                return true;
            }
            if (srv)
            {
                s = server;
                return true;
            }
            throw ProtocolException("readString couldn't reconstruct jid.");
    }
    throw ProtocolException("readString invalid token " + QString::number(token));
}
Example #16
0
quint32 BinTreeNodeReader::readListSize(qint32 token, QDataStream& in)
{
    int size;
    if (token == 0)
        size = 0;
    else if (token == 0xf8)
        size = readInt8(in);
    else if (token == 0xf9)
        size = readInt16(in);
    else {
        qDebug() << "Invalid list size in readListSize: token 0x" << QString::number(token,16);
        //socket->disconnectFromHost();
        Q_EMIT socketBroken();
    }

    return size;
}
Example #17
0
bool BinTreeNodeReader::getToken(int token, QByteArray &s)
{
    //qDebug() << "getToken:" << QString::number(token, 16);
    if (token >= 0 && token < dictionary.length())
    {
        if (token == 236) {
            quint8 ext;
            if (!readInt8(ext))
                return false;
            token += ext + 1;
            //qDebug() << "extToken:" << QString::number(token, 16);
        }
        s = dictionary.at(token).toUtf8();
        return true;
    }

    throw ProtocolException("Invalid token/length in getToken.");
}
Example #18
0
bool BinTreeNodeReader::getToken(int token, QByteArray &s)
{
    //qDebug() << "getToken:" << QString::number(token, 16);
    bool subdict = false;
    QString string;
    dict->getToken(string, subdict, token);
    if (string.isEmpty()) {
        quint8 ext;
        if (!readInt8(ext))
            return false;
        dict->getToken(string, subdict, ext);
        if (!string.isEmpty()) {
            s = string.toUtf8();
            return true;
        }
    }
    else {
        s = string.toUtf8();
        return true;
    }

    throw ProtocolException("Invalid token/length in getToken.");
}
Example #19
0
bool BinTreeNodeReader::readListSize(qint32 token, int& size)
{
    size = -1;
    if (token == 0) {
        size = 0;
    } else if (token == 0xf8) {
        quint8 b;
        if (!readInt8(b)) {
            qDebug() << "failed to read 8bit size";
            return false;
        }
        size = b;
    } else if (token == 0xf9) {
        qint16 b; //TODO: changed from quint16 to qint16. check if valid
        if (!readInt16(b)) {
            qDebug() << "failed to read 16bit size";
            return false;
        }
        size = b;
    } else {
        throw ProtocolException("Invalid list size in readListSize: token 0x" + QString::number(token,16));
    }
    return true;
}
Example #20
0
qint8 U2Bits::readInt32(const uchar* bits, int pos) {
    int res = (readInt8(bits, pos) << 24) + (readInt8(bits, pos + 8) << 16) + (readInt8(bits, pos + 16) << 8) + readInt8(bits, pos + 24);
    return qint16(res);
}
Example #21
0
size_t Buffer::readBool(bool& _dst, size_t _offset)
{
	return readInt8(reinterpret_cast<int8_t&>(_dst), _offset);
}
Example #22
0
qint8 U2Bits::readInt16(const uchar* bits, int pos) {
    int res = (readInt8(bits, pos) << 8) + readInt8(bits, pos + 8);
    return qint16(res);
}
Example #23
0
bool BinTreeNodeReader::readString(int token, QByteArray& s)
{
    if (token == -1) {
        throw ProtocolException("-1 token in readString.");
    }

    if (token > 0 && token < 0xf5)
        return getToken(token, s);

    QByteArray user,server;
    bool usr, srv;

    //no default value.
    switch (token)
    {
        case 0:
            return false;

        case 0xfc:
            quint8 size8;
            if (!readInt8(size8))
                return false;
            return fillArray(s,size8);

        case 0xfd:
            qint32 size24;
            if (!readInt24(size24))
                return false;
            return fillArray(s,size24);

        case 0xfe:
            quint8 token8;
            if (!readInt8(token8))
                return false;
            return getToken(0xf5 + token8, s);

        case 0xfa:
            usr = readString(user);
            srv = readString(server);
            if (usr & srv)
            {
                s = user + "@" + server;
                return true;
            }
            if (srv)
            {
                s = server;
                return true;
            }
            throw ProtocolException("readString couldn't reconstruct jid.");
            
        case 0xff: {
            quint8 nbyte;
            if (!readInt8(nbyte))
                return false;
            int size = nbyte & 0x7f;
            int numnibbles = size * 2 - ((nbyte & 0x80) ? 1 : 0);

            QByteArray res;
            if (!fillArray(res, size))
                return false;
            res = res.toHex().left(numnibbles);
            res = res.replace('a', '-').replace('b', '.');
            s = res;
            return true;
        }
    }
    throw ProtocolException("readString invalid token " + QString::number(token));

}
Example #24
0
ReadData* BinTreeNodeReader::readString(int token)
{
	if (token == -1)
		throw WAException("-1 token in readString", WAException::CORRUPT_STREAM_EX, -1);

	int bSize;
	ReadData *ret = new ReadData();

	if (token > 2 && token <= 236) {
		if (token != 236)
			ret->data = new std::string(dictionary[token]);
		else {
			token = readInt8(this->in);
			ret->data = new std::string(extended_dict[token]);
		}

		ret->type = STRING;
		return ret;
	}

	switch (token) {
	case 0:
		delete ret;
		return NULL;

	case 252:
		bSize = readInt8(this->in);
		{
			std::vector<unsigned char>* buf8 = new std::vector<unsigned char>(bSize);
			fillArray(*buf8, bSize, this->in);
			ret->type = ARRAY;
			ret->data = buf8;
		}
		return ret;

	case 253:
		bSize = readInt24(this->in);
		{
			std::vector<unsigned char>* buf24 = new std::vector<unsigned char>(bSize);
			fillArray(*buf24, bSize, this->in);
			ret->type = ARRAY;
			ret->data = buf24;
		}
		return ret;

	case 255:
		bSize = readInt8(this->in);
		{
			int size = bSize & 0x7f;
			int numnibbles = size * 2 - ((bSize & 0x80) ? 1 : 0);

			std::vector<unsigned char> tmp(size);
			fillArray(tmp, size, this->in);
			std::string s;
			for (int i = 0; i < numnibbles; i++) {
				char c = (tmp[i / 2] >> (4 - ((i & 1) << 2))) & 0xF;
				if (c < 10) s += (c + '0');
				else s += (c - 10 + '-');
			}

			ret->type = STRING;
			ret->data = new std::string(s);
		}
		return ret;

	case 250:
		std::string* user = readStringAsString();
		std::string* server = readStringAsString();
		if ((user != NULL) && (server != NULL)) {
			std::string* result = new std::string(*user + "@" + *server);
			delete user;
			delete server;
			ret->type = STRING;
			ret->data = result;
			return ret;
		}
		if (server != NULL) {
			ret->type = STRING;
			ret->data = server;
			return ret;
		}
		throw WAException("readString couldn't reconstruct jid", WAException::CORRUPT_STREAM_EX, -1);
	}
	throw WAException("readString couldn't match token" + (int)token, WAException::CORRUPT_STREAM_EX, -1);
}
Example #25
0
string psoCat::odbcFieldToStr( uint32_t length )
{
   psoFieldDefinition * fieldODBC;
   int numFields, i;
   string outStr;
   
   fieldODBC = (psoFieldDefinition *) fieldDef;
   numFields = fieldDefLength / sizeof(psoFieldDefinition);
   
   psoaGetFieldOffsets( fieldODBC, numFields, fieldOffsets );

   for ( i = 0; i < numFields; ++i ) {
      string s;
      
      switch( fieldODBC[i].type ) {

      case PSO_TINYINT:
         s = readInt8( &buffer[fieldOffsets[i]] );
         break;

      case PSO_SMALLINT:
         s = readInt16( &buffer[fieldOffsets[i]] );
         break;

      case PSO_INTEGER:
         s = readInt32( &buffer[fieldOffsets[i]] );
         break;

      case PSO_BIGINT:
         s = readInt64( &buffer[fieldOffsets[i]] );
         break;

      case PSO_BINARY:
         readBinary( s,
                     fieldODBC[i].vals.length,
                     &buffer[fieldOffsets[i]] );
         break;

      case PSO_CHAR:
         readString( s,
                     fieldODBC[i].vals.length,
                     &buffer[fieldOffsets[i]] );
         break;

      case PSO_NUMERIC:
         s = readDecimal( fieldODBC[i].vals.decimal.precision,
                          fieldODBC[i].vals.decimal.scale,
                          &buffer[fieldOffsets[i]] );
         break;

      case PSO_VARCHAR:
      case PSO_LONGVARCHAR:
         readString( s,
                     length - fieldOffsets[i],
                     &buffer[fieldOffsets[i]] );
         break;
      case PSO_VARBINARY:
      case PSO_LONGVARBINARY:
         readBinary( s,
                     length - fieldOffsets[i],
                     &buffer[fieldOffsets[i]] );
         break;

      case PSO_REAL:
         s = readFloat32( &buffer[fieldOffsets[i]] );
         break;

      case PSO_DOUBLE:
         s = readFloat64( &buffer[fieldOffsets[i]] );
         break;
      
      case PSO_DATE:
         s = readDate( &buffer[fieldOffsets[i]] );
         break;

      case PSO_TIME:
         s = readTime( &buffer[fieldOffsets[i]] );
         break;

      case PSO_TIMESTAMP:
         s = readTimeStamp( &buffer[fieldOffsets[i]] );
         break;
      }
      outStr += s;
      if ( i < numFields-1) outStr += ", ";
   }
   
   return outStr;
}
Example #26
0
        void initFileObject(lua_State* L)
        {
            luaL_newmetatable(L, meta<File>());
            // Duplicate the metatable on the stack.
            lua_pushvalue(L, -1);
            // metatable.__index = metatable
            lua_setfield(L, -2, "__index");

            // Put the members into the metatable.
            const luaL_Reg functions[] = {
                {"__gc", [](lua_State* L) { return script::wrapped<File>(L, 1)->gc(L); }},
                {"__index", [](lua_State* L) { return script::wrapped<File>(L, 1)->index(L); }},
                {"__newindex", [](lua_State* L) { return script::wrapped<File>(L, 1)->newindex(L); }},
                {"__tostring", [](lua_State* L) { return script::wrapped<File>(L, 1)->tostring(L); }},
                {"__pairs", [](lua_State* L) { return script::wrapped<File>(L, 1)->pairs(L); }},
                {"close", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    file->close();
                    return 0;
                }},
                {"readUnsigned8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    uint8_t value;
                    if(file->readUnsigned8(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readUnsigned16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    uint16_t value;
                    if(file->readUnsigned16(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readUnsigned32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    uint32_t value;
                    if(file->readUnsigned32(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readInt8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    int8_t value;
                    if(file->readInt8(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readInt16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    int16_t value;
                    if(file->readInt16(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readInt32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    int32_t value;
                    if(file->readInt32(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readFloat", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    float value;
                    if(file->readFloat(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readDouble", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    double value;
                    if(file->readDouble(value))
                    {
                        script::push(L, value);
                        return 1;
                    }
                    return 0;
                }},
                {"readString", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto blockSize = script::get<int>(L, 2);

                    std::string buffer(blockSize, 0);
                    if(file->readString(buffer))
                    {
                        lua_pushlstring(L, buffer.data(), buffer.size());
                        return 1;
                    }
                    return 0;
                }},
                {"readLine", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    std::string value;
                    if(file->readLine(value))
                    {
                        script::push(L, value.c_str());
                        return 1;
                    }
                    return 0;
                }},
                {"readFully", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);

                    // Get current position.
                    auto pos = file->tell();
                    if(pos == -1)
                    {
                        return 0;
                    }

                    // Length to read = position of end - current.
                    auto length = 0;
                    if(!file->seek(pos, FileSeekMode::End))
                    {
                        return 0;
                    }
                    length = file->tell() - pos;
                    if(!file->seek(pos, FileSeekMode::Start))
                    {
                        return 0;
                    }

                    // Read the entire file into a string.
                    std::string buf(length, 0);
                    if(file->readString(buf))
                    {
                        lua_pushlstring(L, buf.data(), buf.size());
                        return 1;
                    }
                    return 0;
                }},
                {"writeUnsigned8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeUnsigned8(value));
                    return 1;
                }},
                {"writeUnsigned16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeUnsigned16(value));
                    return 1;
                }},
                {"writeUnsigned32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeUnsigned32(value));
                    return 1;
                }},
                {"writeInt8", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeInt8(value));
                    return 1;
                }},
                {"writeInt16", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeInt16(value));
                    return 1;
                }},
                {"writeInt32", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<int>(L, 2);

                    script::push(L, file->writeInt32(value));
                    return 1;
                }},
                {"writeFloat", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<double>(L, 2);

                    script::push(L, file->writeFloat((float) value));
                    return 1;
                }},
                {"writeDouble", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto value = script::get<double>(L, 2);

                    script::push(L, file->writeDouble(value));
                    return 1;
                }},
                {"writeString", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    size_t length = 0;
                    const char* buffer = luaL_checklstring(L, 2, &length);
                    std::string value(buffer, buffer + length);
                    script::push(L, file->writeString(value));
                    return 1;
                }},
                {"writeLine", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    size_t length = 0;
                    const char* buffer = luaL_checklstring(L, 2, &length);
                    std::string value(buffer, buffer + length);
                    script::push(L, file->writeLine(value));
                    return 1;
                }},
                {"tell", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    script::push(L, int(file->tell()));
                    return 1;
                }},
                {"seek", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    auto position = script::get<int>(L, 2);
                    auto mode = FileSeekMode(script::get<int>(L, 3));
                    script::push(L, file->seek(position, mode));
                    return 1;
                }},
                {"flush", [](lua_State* L)
                {
                    auto file = script::ptr<File>(L, 1);
                    file->flush();
                    return 0;
                }},
                {nullptr, nullptr},
            };
            luaL_setfuncs(L, functions, 0);

            lua_pop(L, 1);
                
            // Push plum namespace.
            lua_getglobal(L, "plum");

            // plum.File = <function create>
            script::push(L, "File");
            lua_pushcfunction(L, [](lua_State* L)
            {
                auto filename = script::get<const char*>(L, 1);
                auto mode = FileOpenMode(script::get<int>(L, 2));
                auto f = new File(filename, mode);
                // Failure.
                if(!f->isActive())
                {    
                    delete f;
                    return 0;
                }

                script::push(L, f, LUA_NOREF);
                return 1;
            });
            lua_settable(L, -3);

            // Pop plum namespace.
            lua_pop(L, 1);
        }