<commit_before>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTextureDomainEffect.h"
#include "gl/GrGLProgramStage.h"
#include "GrProgramStageFactory.h"

class GrGLTextureDomainEffect : public GrGLProgramStage {
public:
    GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
                            const GrCustomStage& stage);

    virtual void setupVariables(GrGLShaderBuilder* state,
                                int stage) SK_OVERRIDE;
    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE { }
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;

    virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;

    virtual void setData(const GrGLInterface*,
                         const GrCustomStage&,
                         const GrRenderTarget*,
                         int stageNum) SK_OVERRIDE;

    static inline StageKey GenKey(const GrCustomStage&) { return 0; }

private:
    const GrGLShaderVar* fNameVar;
    int                  fNameLocation;

    typedef GrGLProgramStage INHERITED;
};

GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
                                                 const GrCustomStage& stage)
    : GrGLProgramStage(factory)
    , fNameVar(NULL)
    , fNameLocation(0) {
}

void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* state,
                                             int stage) {
    fNameVar = &state->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                  kVec4f_GrSLType, "uTexDom", stage);
    fNameLocation = kUseUniform;
};

void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* state,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const char* samplerName) {
    SkString coordVar("clampCoord");
    state->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
                           GrGLShaderVar::TypeString(GrSLFloatVectorType(state->fCoordDims)),
                           coordVar.c_str(),
                           state->fSampleCoords.c_str(),
                           fNameVar->getName().c_str(),
                           fNameVar->getName().c_str());
    state->fSampleCoords = coordVar;

    state->emitDefaultFetch(outputColor, samplerName);
}

void GrGLTextureDomainEffect::initUniforms(const GrGLInterface* gl, int programID) {
    GR_GL_CALL_RET(gl, fNameLocation,
                   GetUniformLocation(programID, fNameVar->getName().c_str()));
    GrAssert(kUnusedUniform != fNameLocation);
}

void GrGLTextureDomainEffect::setData(const GrGLInterface* gl,
                         const GrCustomStage& data,
                         const GrRenderTarget*,
                         int stageNum) {
    const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
    const GrRect& domain = effect.domain();

    float values[4] = {
        GrScalarToFloat(domain.left()),
        GrScalarToFloat(domain.top()),
        GrScalarToFloat(domain.right()),
        GrScalarToFloat(domain.bottom())
    };
    // vertical flip if necessary
    const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
    if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
        values[1] = 1.0f - values[1];
        values[3] = 1.0f - values[3];
        // The top and bottom were just flipped, so correct the ordering
        // of elements so that values = (l, t, r, b).
        SkTSwap(values[1], values[3]);
    }

    GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values));
}

///////////////////////////////////////////////////////////////////////////////

GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
    : GrSingleTextureEffect(texture)
    , fTextureDomain(domain) {

}

GrTextureDomainEffect::~GrTextureDomainEffect() {

}

const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
    return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
}

bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
    const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
    return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
}

<commit_msg>Fix build breakage in r4641. Unreviewed.<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTextureDomainEffect.h"
#include "gl/GrGLProgramStage.h"
#include "GrProgramStageFactory.h"

// For brevity, and these definitions are likely to move to a different class soon.
typedef GrGLShaderBuilder::UniformHandle UniformHandle;
static const UniformHandle kInvalidUniformHandle = GrGLShaderBuilder::kInvalidUniformHandle;

class GrGLTextureDomainEffect : public GrGLProgramStage {
public:
    GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
                            const GrCustomStage& stage);

    virtual void setupVariables(GrGLShaderBuilder* builder,
                                int stage) SK_OVERRIDE;
    virtual void emitVS(GrGLShaderBuilder* builder,
                        const char* vertexCoords) SK_OVERRIDE { }
    virtual void emitFS(GrGLShaderBuilder* builder,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;

    virtual void initUniforms(const GrGLShaderBuilder* builder,
                              const GrGLInterface*,
                              int programID) SK_OVERRIDE;

    virtual void setData(const GrGLInterface*,
                         const GrCustomStage&,
                         const GrRenderTarget*,
                         int stageNum) SK_OVERRIDE;

    static inline StageKey GenKey(const GrCustomStage&) { return 0; }

private:
    UniformHandle fNameUni;
    int           fNameLocation;

    typedef GrGLProgramStage INHERITED;
};

GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrProgramStageFactory& factory,
                                                 const GrCustomStage& stage)
    : GrGLProgramStage(factory)
    , fNameUni(kInvalidUniformHandle)
    , fNameLocation(0) {
}

void GrGLTextureDomainEffect::setupVariables(GrGLShaderBuilder* builder,
                                             int stage) {
    fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                   kVec4f_GrSLType, "uTexDom", stage);
    fNameLocation = kUseUniform;
};

void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const char* samplerName) {
    SkString coordVar("clampCoord");
    builder->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
                           GrGLShaderVar::TypeString(GrSLFloatVectorType(builder->fCoordDims)),
                           coordVar.c_str(),
                           builder->fSampleCoords.c_str(),
                           builder->getUniformCStr(fNameUni),
                           builder->getUniformCStr(fNameUni));
    builder->fSampleCoords = coordVar;

    builder->emitDefaultFetch(outputColor, samplerName);
}

void GrGLTextureDomainEffect::initUniforms(const GrGLShaderBuilder* builder,
                                           const GrGLInterface* gl, int programID) {
    GR_GL_CALL_RET(gl, fNameLocation,
                   GetUniformLocation(programID, builder->getUniformCStr(fNameUni)));
    GrAssert(kUnusedUniform != fNameLocation);
}

void GrGLTextureDomainEffect::setData(const GrGLInterface* gl,
                         const GrCustomStage& data,
                         const GrRenderTarget*,
                         int stageNum) {
    const GrTextureDomainEffect& effect = static_cast<const GrTextureDomainEffect&>(data);
    const GrRect& domain = effect.domain();

    float values[4] = {
        GrScalarToFloat(domain.left()),
        GrScalarToFloat(domain.top()),
        GrScalarToFloat(domain.right()),
        GrScalarToFloat(domain.bottom())
    };
    // vertical flip if necessary
    const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
    if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
        values[1] = 1.0f - values[1];
        values[3] = 1.0f - values[3];
        // The top and bottom were just flipped, so correct the ordering
        // of elements so that values = (l, t, r, b).
        SkTSwap(values[1], values[3]);
    }

    GR_GL_CALL(gl, Uniform4fv(fNameLocation, 1, values));
}

///////////////////////////////////////////////////////////////////////////////

GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, GrRect domain)
    : GrSingleTextureEffect(texture)
    , fTextureDomain(domain) {

}

GrTextureDomainEffect::~GrTextureDomainEffect() {

}

const GrProgramStageFactory& GrTextureDomainEffect::getFactory() const {
    return GrTProgramStageFactory<GrTextureDomainEffect>::getInstance();
}

bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
    const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
    return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
}

<|endoftext|>


<commit_before>/////////////////////////////////////////
//
//   OpenLieroX
//
//   Auxiliary Software class library
//
//   based on the work of JasonB
//   enhanced by Dark Charlie and Albert Zeyer
//
//   code under LGPL
//
/////////////////////////////////////////

// Byte stream class
// Created 13/10/01
// Jason Boettcher

#include <stdarg.h>
#include <iostream>
#include <iomanip>
#include "CBytestream.h"
#include "EndianSwap.h"
#include "StringUtils.h"

using namespace std;

void CBytestream::Test()
{
	std::cout << std::endl;
	std::cout << "Running a Bytestream debug test:" << std::endl;
	std::cout << "Tested function / Original / Write / Read / Warning" << std::endl;

	// Byte
	uchar b = 125;
	std::cout << "Byte: (" << b << ") ";
	writeByte(b);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	uchar b2 = readByte();
	std::cout << "(" << b2 << ") ";
	if (b2 != b)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// Bool
	bool boo = true;
	std::cout << "Bool: (" << boo << ") ";
	writeByte(boo);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	bool boo2 = readBool();
	std::cout << "(" << boo2 << ") ";
	if (boo2 != boo)
		std::cout << "NOT SAME!";
	std::cout << std::endl;
	Clear();

	// Integer
	int i = 125;
	std::cout << "Int: (" << i << ") ";
	writeInt(i, 4);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	int i2 = readInt(4);
	std::cout << "(" << itoa(i2) << ") ";
	if (i2 != i)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// Short
	short s = 125;
	std::cout << "Short: (" << s << ") ";
	writeInt16(s);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	short s2 = readInt16();
	std::cout << "(" << s2 << ") ";
	if (s2 != s)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// Float
	float f = 125.125f;
	std::cout << "Float: (" << f << ") ";
	writeFloat(f);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	float f2 = readFloat();
	std::cout << "(" << f2 << ") ";
	if (f2 != f)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// String
	std::string str = "Test";
	std::cout << "String: (" << str << ") ";
	writeString(str);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	std::string str2 = readString();
	std::cout << "(" << str2 << ") ";
	if (str2 != str)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// 2Int12
	short x = 125;
	short y = 521;
	std::cout << "2Int12: (" << x << "/" << y << ") ";
	write2Int12(x, y);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	short x2, y2;
	read2Int12(x2, y2);
	std::cout << "(" << x2 << "/" << y2 << ") ";
	if (x2 != x || y2 != y)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// 2Int4
	short u = 10;
	short v = 12;
	std::cout << "2Int4: (" << u << "/" << v << ") ";
	write2Int4(u, v);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	short u2, v2;
	read2Int4(u2, v2);
	std::cout << "(" << u2 + "/" << v2 << ") ";
	if (u2 != u || v2 != v)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

}

///////////////////
// Append another bytestream onto this one
void CBytestream::Append(CBytestream *bs)
{
	Data << bs->Data.str();
}

///////////////////
// Dump the data out
void CBytestream::Dump(void)
{
	std::cout << std::endl << "Dumping stream:" << std::endl;

	size_t i = 0;
	for(string::const_iterator it = Data.str().begin(); it != Data.str().end(); it++, i++) {
		if((uchar)*it <= 127 && (uchar)*it >= 32) {
			// Write out the byte and its ascii representation
			if(*it != '\\')
				cout << *it;
			else
				cout << "\\\\";
		} else
			cout << "\\" << hex << (uint)(uchar)*it << dec;

		// Linebreak after 16 dumped bytes
		if((i % 16) == 15)
			cout << endl;
	}

	cout << endl;
}

// Writes

///////////////////
// Writes a single byte
bool CBytestream::writeByte(uchar byte)
{
	Data << byte;
	return true;
}

///////////////////
// Writes a boolean value to the stream
bool CBytestream::writeBool(bool value)
{
	return writeByte((uchar)value);
}

///////////////////
// Writes an integer to the stream
bool CBytestream::writeInt(int value, uchar numbytes)
{
	// Numbytes cannot be more then 4
	if(numbytes <= 0 || numbytes >= 5)
		return false;

	// Copy the interger into individual bytes
	// HINT: this is endian independent code; it uses little endian
	uchar bytes[4];
	bytes[0] = (uint)value & 0xff;
	bytes[1] = ((uint)value & 0xff00) >> 8;
	bytes[2] = ((uint)value & 0xff0000) >> 16;
	bytes[3] = ((uint)value & 0xff000000) >> 24;

	for(short n=0; n<numbytes; n++)
		if(!writeByte(bytes[n]))
			return false;

	return true;
}

///////////////////
// Write a short to the stream
bool CBytestream::writeInt16(Sint16 value)
{
	// HINT: this time, the value is stored in big endian
	uchar dat[2];
	dat[1] = (Uint16)value & 0xff;
	dat[0] = ((Uint16)value & 0xff00) >> 8;

	if (!writeByte(dat[0]))
		return false;

	if (!writeByte(dat[1]))
		return false;

	return true;
}

///////////////////
// Writes a float to the stream
bool CBytestream::writeFloat(float value)
{
	union {
		uchar bin[4];
		float val;
	} tmp;
	tmp.val = value;

	// HINT: original LX uses little endian floats over network
	EndianSwap(tmp.bin);

	for(short i = 0; i < 4; i++)
		if(!writeByte(tmp.bin[i]))
			return false;

	return true;
}

bool CBytestream::writeString(const std::string& value) {
	Data << value.c_str(); // convert it to a C-string because we don't want null-bytes in it
	Data << (char)'\0';
	return true;
}

// cast 2 int12 to 3 bytes
bool CBytestream::write2Int12(short x, short y) {
	if(!writeByte((ushort)x & 0xff)) return false;
	if(!writeByte((((ushort)x & 0xf00) >> 8) + (((ushort)y & 0xf) << 4))) return false;
	if(!writeByte(((ushort)y & 0xff0) >> 4)) return false;
	return true;
}

// cast 2 int4 to 1 byte
bool CBytestream::write2Int4(short x, short y) {
	return writeByte(((ushort)x & 0xf) + (((ushort)y & 0xf) << 4));
}

// Reads

///////////////////
// Reads a single byte
uchar CBytestream::readByte(void) {
	if(Data.good())
		return Data.get();
	else
		return 0;
}

///////////////////
// Reads a boolean value from the stream
bool CBytestream::readBool(void)
{
	return readByte() != 0;
}

///////////////////
// Reads an interger value from the stream
int CBytestream::readInt(uchar numbytes)
{
	// Numbytes cannot be more than 4
	if(numbytes <= 0 || numbytes >= 5)
		return 0;

	uchar bytes[4];
	for(short n=0; n<numbytes; n++)
		bytes[n] = readByte();

	// HINT: this is endian independent; value is stored in little endian
	uint ret = 0;
	if(numbytes>0)
		ret = (uint)bytes[0];
	if(numbytes>1)
		ret += (uint)bytes[1] << 8;
	if(numbytes>2)
		ret += (uint)bytes[2] << 16;
	if(numbytes>3)
		ret += (uint)bytes[3] << 24;

	return (int)ret;
}

///////////////////
// Read a short from the stream
Sint16 CBytestream::readInt16(void)
{
	// HINT: this time, the value is stored in big endian
	uchar dat[2];
	dat[1] = readByte();
	dat[0] = readByte();

	Uint16 value;
	value = (Uint16)dat[0];
	value += (Uint16)dat[1] << 8;

	return (Sint16)value;
}

///////////////////
// Read a float value from the stream
float CBytestream::readFloat(void)
{
	union {
		uchar bin[4];
		float val;
	} tmp;

	tmp.val = 0;

	for(short i = 0; i < 4; i++)
		tmp.bin[i] = readByte();

	// HINT: original LX uses little endian floats over network
	EndianSwap(tmp.bin);

	return tmp.val;
}

std::string CBytestream::readString() {
	static std::string result; result = "";
	uchar b;
	while((b = readByte()) != 0) result += b;
	return result;
}

std::string CBytestream::readString(size_t maxlen) {
	static std::string result; result = "";
	size_t i = 0;
	uchar b;
	while(i < maxlen && (b = readByte()) != 0) {
		result += b;
		i++;
	}
	return result;
}

// cast 3 bytes to 2 int12
void CBytestream::read2Int12(short& x, short& y) {
	static ushort dat[3];
	dat[0] = readByte();
	dat[1] = readByte();
	dat[2] = readByte();

	x = dat[0] + ((dat[1] & 0xf) << 8);
	y = (short)(((dat[1] & 0xf0) >> 4) + (dat[2] << 4));
}

// cast 1 byte to 2 int4
void CBytestream::read2Int4(short& x, short& y) {
	uchar tmp = readByte();
	x = tmp & 0xf;
	y = (short)((tmp & 0xf0) >> 4);
}

// Skips a string, including the terminating character
// Returns true if we're at the end of the stream after the skip
bool CBytestream::SkipString()  {
	readString();
	return isPosAtEnd();
}

bool CBytestream::Skip(size_t num) {
	Data.seekg(num, ios::cur);
	if(Data.fail()) {
		Data.clear();
		Data.seekg(0, ios::end);
	}
	return isPosAtEnd();
}

size_t CBytestream::Read(NetworkSocket sock) {
	Clear();
	#define BUFSIZE 1024
	static char buf[BUFSIZE];
	size_t len = 0, res;
	while(true) {
		res = ReadSocket(sock, buf, BUFSIZE);
		if(res <= 0) break;
		Data.write(buf, res);
		len += res;
		if(res < BUFSIZE) break;
	}
	Data.sync();
	Data.seekg(0, ios::beg);
	return len;
}

void CBytestream::Send(NetworkSocket sock) {
	Data.sync();
	WriteSocket(sock, Data.str().data(), Data.str().size());
}
<commit_msg>Updated Dump (looks like hexa editor now)<commit_after>/////////////////////////////////////////
//
//   OpenLieroX
//
//   Auxiliary Software class library
//
//   based on the work of JasonB
//   enhanced by Dark Charlie and Albert Zeyer
//
//   code under LGPL
//
/////////////////////////////////////////

// Byte stream class
// Created 13/10/01
// Jason Boettcher

#include <stdarg.h>
#include <iostream>
#include <iomanip>
#include "CBytestream.h"
#include "EndianSwap.h"
#include "StringUtils.h"

using namespace std;

void CBytestream::Test()
{
	std::cout << std::endl;
	std::cout << "Running a Bytestream debug test:" << std::endl;
	std::cout << "Tested function / Original / Write / Read / Warning" << std::endl;

	// Byte
	uchar b = 125;
	std::cout << "Byte: (" << b << ") ";
	writeByte(b);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	uchar b2 = readByte();
	std::cout << "(" << b2 << ") ";
	if (b2 != b)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// Bool
	bool boo = true;
	std::cout << "Bool: (" << boo << ") ";
	writeByte(boo);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	bool boo2 = readBool();
	std::cout << "(" << boo2 << ") ";
	if (boo2 != boo)
		std::cout << "NOT SAME!";
	std::cout << std::endl;
	Clear();

	// Integer
	int i = 125;
	std::cout << "Int: (" << i << ") ";
	writeInt(i, 4);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	int i2 = readInt(4);
	std::cout << "(" << itoa(i2) << ") ";
	if (i2 != i)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// Short
	short s = 125;
	std::cout << "Short: (" << s << ") ";
	writeInt16(s);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	short s2 = readInt16();
	std::cout << "(" << s2 << ") ";
	if (s2 != s)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// Float
	float f = 125.125f;
	std::cout << "Float: (" << f << ") ";
	writeFloat(f);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	float f2 = readFloat();
	std::cout << "(" << f2 << ") ";
	if (f2 != f)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// String
	std::string str = "Test";
	std::cout << "String: (" << str << ") ";
	writeString(str);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	std::string str2 = readString();
	std::cout << "(" << str2 << ") ";
	if (str2 != str)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// 2Int12
	short x = 125;
	short y = 521;
	std::cout << "2Int12: (" << x << "/" << y << ") ";
	write2Int12(x, y);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	short x2, y2;
	read2Int12(x2, y2);
	std::cout << "(" << x2 << "/" << y2 << ") ";
	if (x2 != x || y2 != y)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

	// 2Int4
	short u = 10;
	short v = 12;
	std::cout << "2Int4: (" << u << "/" << v << ") ";
	write2Int4(u, v);
	ResetPosToBegin();
	std::cout << "(" << Data.str() << ") ";
	short u2, v2;
	read2Int4(u2, v2);
	std::cout << "(" << u2 + "/" << v2 << ") ";
	if (u2 != u || v2 != v)
		std::cout << "NOT SAME!";
	std::cout <<std::endl;
	Clear();

}

///////////////////
// Append another bytestream onto this one
void CBytestream::Append(CBytestream *bs)
{
	Data << bs->Data.str();
}

///////////////////
// Dump the data out
void CBytestream::Dump(void)
{
#define BYTESPERLINE 8

	std::cout << std::endl << "Dumping stream:" << std::endl;

	std::string::const_iterator ascii_it = Data.str().begin();

	size_t i = 0;
	size_t j = 0;
	uchar c;
	for(string::const_iterator it = Data.str().begin(); it != Data.str().end(); it++, i++) {
		c = *it;

		if (c <= 0xF)
			cout << "0" << hex << (uint)c << dec << ' ';
		else
			cout << hex << (uint)c << dec << ' ';

		// 8 dumped bytes, dump the ascii
		if((i % BYTESPERLINE) == BYTESPERLINE - 1)  {
			cout << "    ";
			for (j = 0; j < 8; j++)  {
				c = *ascii_it;
				if (c <= 127 && c >= 32)
					cout << (char)c << " ";
				else
					cout << ". ";

				ascii_it++;
			}
			cout << endl;
		}
	}

	// Last unfinished line
	if (ascii_it != Data.str().end())  {
		int numspaces = (BYTESPERLINE - i % BYTESPERLINE) * 3 + 4;
		for (j = 0; j < numspaces; j++)
			cout << ' ';

		while (ascii_it != Data.str().end()) {
				c = *ascii_it;
				if (c <= 127 && c >= 32)
					cout << (char)c << " ";
				else
					cout << ". ";

				ascii_it++;
		}
	}

	cout << endl;
}

// Writes

///////////////////
// Writes a single byte
bool CBytestream::writeByte(uchar byte)
{
	Data << byte;
	return true;
}

///////////////////
// Writes a boolean value to the stream
bool CBytestream::writeBool(bool value)
{
	return writeByte((uchar)value);
}

///////////////////
// Writes an integer to the stream
bool CBytestream::writeInt(int value, uchar numbytes)
{
	// Numbytes cannot be more then 4
	if(numbytes <= 0 || numbytes >= 5)
		return false;

	// Copy the interger into individual bytes
	// HINT: this is endian independent code; it uses little endian
	uchar bytes[4];
	bytes[0] = (uint)value & 0xff;
	bytes[1] = ((uint)value & 0xff00) >> 8;
	bytes[2] = ((uint)value & 0xff0000) >> 16;
	bytes[3] = ((uint)value & 0xff000000) >> 24;

	for(short n=0; n<numbytes; n++)
		if(!writeByte(bytes[n]))
			return false;

	return true;
}

///////////////////
// Write a short to the stream
bool CBytestream::writeInt16(Sint16 value)
{
	// HINT: this time, the value is stored in big endian
	uchar dat[2];
	dat[1] = (Uint16)value & 0xff;
	dat[0] = ((Uint16)value & 0xff00) >> 8;

	if (!writeByte(dat[0]))
		return false;

	if (!writeByte(dat[1]))
		return false;

	return true;
}

///////////////////
// Writes a float to the stream
bool CBytestream::writeFloat(float value)
{
	union {
		uchar bin[4];
		float val;
	} tmp;
	tmp.val = value;

	// HINT: original LX uses little endian floats over network
	EndianSwap(tmp.bin);

	for(short i = 0; i < 4; i++)
		if(!writeByte(tmp.bin[i]))
			return false;

	return true;
}

bool CBytestream::writeString(const std::string& value) {
	Data << value.c_str(); // convert it to a C-string because we don't want null-bytes in it
	Data << (char)'\0';
	return true;
}

// cast 2 int12 to 3 bytes
bool CBytestream::write2Int12(short x, short y) {
	if(!writeByte((ushort)x & 0xff)) return false;
	if(!writeByte((((ushort)x & 0xf00) >> 8) + (((ushort)y & 0xf) << 4))) return false;
	if(!writeByte(((ushort)y & 0xff0) >> 4)) return false;
	return true;
}

// cast 2 int4 to 1 byte
bool CBytestream::write2Int4(short x, short y) {
	return writeByte(((ushort)x & 0xf) + (((ushort)y & 0xf) << 4));
}

// Reads

///////////////////
// Reads a single byte
uchar CBytestream::readByte(void) {
	if(Data.good())
		return Data.get();
	else
		return 0;
}

///////////////////
// Reads a boolean value from the stream
bool CBytestream::readBool(void)
{
	return readByte() != 0;
}

///////////////////
// Reads an interger value from the stream
int CBytestream::readInt(uchar numbytes)
{
	// Numbytes cannot be more than 4
	if(numbytes <= 0 || numbytes >= 5)
		return 0;

	uchar bytes[4];
	for(short n=0; n<numbytes; n++)
		bytes[n] = readByte();

	// HINT: this is endian independent; value is stored in little endian
	uint ret = 0;
	if(numbytes>0)
		ret = (uint)bytes[0];
	if(numbytes>1)
		ret += (uint)bytes[1] << 8;
	if(numbytes>2)
		ret += (uint)bytes[2] << 16;
	if(numbytes>3)
		ret += (uint)bytes[3] << 24;

	return (int)ret;
}

///////////////////
// Read a short from the stream
Sint16 CBytestream::readInt16(void)
{
	// HINT: this time, the value is stored in big endian
	uchar dat[2];
	dat[1] = readByte();
	dat[0] = readByte();

	Uint16 value;
	value = (Uint16)dat[0];
	value += (Uint16)dat[1] << 8;

	return (Sint16)value;
}

///////////////////
// Read a float value from the stream
float CBytestream::readFloat(void)
{
	union {
		uchar bin[4];
		float val;
	} tmp;

	tmp.val = 0;

	for(short i = 0; i < 4; i++)
		tmp.bin[i] = readByte();

	// HINT: original LX uses little endian floats over network
	EndianSwap(tmp.bin);

	return tmp.val;
}

std::string CBytestream::readString() {
	static std::string result; result = "";
	uchar b;
	while((b = readByte()) != 0) result += b;
	return result;
}

std::string CBytestream::readString(size_t maxlen) {
	static std::string result; result = "";
	size_t i = 0;
	uchar b;
	while(i < maxlen && (b = readByte()) != 0) {
		result += b;
		i++;
	}
	return result;
}

// cast 3 bytes to 2 int12
void CBytestream::read2Int12(short& x, short& y) {
	static ushort dat[3];
	dat[0] = readByte();
	dat[1] = readByte();
	dat[2] = readByte();

	x = dat[0] + ((dat[1] & 0xf) << 8);
	y = (short)(((dat[1] & 0xf0) >> 4) + (dat[2] << 4));
}

// cast 1 byte to 2 int4
void CBytestream::read2Int4(short& x, short& y) {
	uchar tmp = readByte();
	x = tmp & 0xf;
	y = (short)((tmp & 0xf0) >> 4);
}

// Skips a string, including the terminating character
// Returns true if we're at the end of the stream after the skip
bool CBytestream::SkipString()  {
	readString();
	return isPosAtEnd();
}

bool CBytestream::Skip(size_t num) {
	Data.seekg(num, ios::cur);
	if(Data.fail()) {
		Data.clear();
		Data.seekg(0, ios::end);
	}
	return isPosAtEnd();
}

size_t CBytestream::Read(NetworkSocket sock) {
	Clear();
	#define BUFSIZE 1024
	static char buf[BUFSIZE];
	size_t len = 0, res;
	while(true) {
		res = ReadSocket(sock, buf, BUFSIZE);
		if(res <= 0) break;
		Data.write(buf, res);
		len += res;
		if(res < BUFSIZE) break;
	}
	Data.sync();
	Data.seekg(0, ios::beg);
	return len;
}

void CBytestream::Send(NetworkSocket sock) {
	Data.sync();
	WriteSocket(sock, Data.str().data(), Data.str().size());
}
<|endoftext|>


<commit_before>
#include "include/types.h"
#include "msg/Message.h"
#include "osd/OSD.h"
#include "messages/MClass.h"
#include "ClassHandler.h"
#include "common/arch.h"

#include <dlfcn.h>

#include <map>

#include "config.h"

#define DOUT_SUBSYS osd
#undef dout_prefix
#define dout_prefix *_dout << dbeginl

static ClassHandler::ClassData null_cls_data;

void ClassHandler::_load_class(ClassData &cls)
{
  dout(10) << "load_class " << cls.name << dendl;

  char *fname=strdup("/tmp/class-XXXXXX");
  int fd = mkstemp(fname);
  cls_deps_t *(*cls_deps)();

  for (list<bufferptr>::const_iterator it = cls.impl.binary.buffers().begin();
       it != cls.impl.binary.buffers().end(); it++)
    write(fd, it->c_str(), it->length());

  close(fd);

  cls.handle = dlopen(fname, RTLD_NOW);

  if (!cls.handle) {
    dout(0) << "could not open class (dlopen failed)" << dendl;
    goto done;
  }
  cls_deps = (cls_deps_t *(*)())dlsym(cls.handle, "class_deps");
  if (cls_deps) {
    cls_deps_t *deps = cls_deps();
    while (deps) {
      if (!deps->name)
        break;
      cls._add_dependency(deps);
      deps++;
    }
  }
  cls.load();
done:
  unlink(fname);
  free(fname);

  return;
}

void ClassHandler::load_class(const nstring& cname)
{
  ClassData& cls = get_obj(cname);
  if (&cls == &null_cls_data) {
    dout(0) << "ERROR: can't load null class data" << dendl;
    return;
  }
  cls.mutex->Lock();
  _load_class(cls);
  cls.mutex->Unlock();
}

ClassHandler::ClassData& ClassHandler::get_obj(const nstring& cname)
{
  Mutex::Locker locker(mutex);
  map<nstring, ClassData>::iterator iter = classes.find(cname);
  if (iter == classes.end()) {
    ClassData& cls = classes[cname];
    cls.mutex = new Mutex("ClassData");
    if (!cls.mutex) {
      classes[cname] = null_cls_data;
      return null_cls_data;
    }
    dout(0) << "get_obj: adding new class name=" << cname << " ptr=" << &cls << dendl;
    cls.name = cname;
    cls.osd = osd;
    cls.handler = this;
    return cls;
  }

  return iter->second;
}

ClassHandler::ClassData *ClassHandler::get_class(const nstring& cname, ClassVersion& version)
{
  ClassHandler::ClassData *ret = NULL;
  ClassData *class_data = &get_obj(cname);
  if (class_data == &null_cls_data)
    return NULL;

  Mutex::Locker lock(*class_data->mutex);

  switch (class_data->status) {
  case ClassData::CLASS_INVALID:
  case ClassData::CLASS_LOADED:
    if (class_data->cache_timed_out()) {
      dout(0) << "class timed out going to send request for " << cname.c_str() << " v" << version << dendl;
      ret = class_data;
      goto send;
    }
    return class_data;
  case ClassData::CLASS_REQUESTED:
    return NULL;
    break;

  case ClassData::CLASS_UNKNOWN:
    class_data->set_status(ClassData::CLASS_REQUESTED);
    break;

  default:
    assert(0);
  }

  class_data->version = version;
send:
  osd->send_class_request(cname.c_str(), version);
  return ret;
}

void ClassHandler::handle_class(MClass *m)
{
  deque<ClassInfo>::iterator info_iter;
  deque<ClassImpl>::iterator impl_iter;
  deque<bool>::iterator add_iter;

  for (info_iter = m->info.begin(), add_iter = m->add.begin(), impl_iter = m->impl.begin();
       info_iter != m->info.end();
       ++info_iter, ++add_iter) {
    ClassData& data = get_obj(info_iter->name);
    if (&data == &null_cls_data) {
      dout(0) << "couldn't get class, out of memory? continuing" << dendl;
      continue;
    }
    dout(0) << "handle_class " << info_iter->name << dendl;
    data.mutex->Lock();

    if (*add_iter) {
        data.set_status(ClassData::CLASS_REQUESTED);
	dout(10) << "added class '" << info_iter->name << "'" << dendl;
	data.impl = *impl_iter;
	++impl_iter;
	_load_class(data);
    } else {
	dout(10) << "response of an invalid class '" << info_iter->name << "'" << dendl;
        data.set_status(ClassData::CLASS_INVALID);
        osd->got_class(info_iter->name);
    }
    data.mutex->Unlock();
  }
}

void ClassHandler::resend_class_requests()
{
  for (map<nstring,ClassData>::iterator p = classes.begin(); p != classes.end(); p++) {
    dout(20) << "resending class request "<< p->first.c_str() << " v" << p->second.version << dendl;
    osd->send_class_request(p->first.c_str(), p->second.version);
  }
}

ClassHandler::ClassData *ClassHandler::register_class(const char *cname)
{
  ClassData& class_data = get_obj(cname);

  if (&class_data == &null_cls_data) {
    dout(0) << "couldn't get class object, out of memory?" << dendl;
    return NULL;
  }

  dout(0) << "&class_data=" << (void *)&class_data << " status=" << class_data.status << dendl;

  if (class_data.status != ClassData::CLASS_LOADED) {
    dout(0) << "class " << cname << " can't be loaded" << dendl;
    return NULL;
  }

  if (class_data.registered) {
    dout(0) << "class " << cname << " already registered" << dendl;
  }

  class_data.registered = true;

  return &class_data;
}

void ClassHandler::unregister_class(ClassHandler::ClassData *cls)
{
  /* FIXME: do we really need this one? */
}

void ClassHandler::ClassData::load()
{
  if (status == CLASS_INVALID) {
    /* if we're invalid, we should just notify osd */
    osd->got_class(name);
    return;
  }

  if (!has_missing_deps()) {
    set_status(CLASS_LOADED);
    dout(0) << "setting class " << name << " status to CLASS_LOADED" << dendl;
    init();
    osd->got_class(name);
  }

  list<ClassData *>::iterator iter;
  for (iter = dependents.begin(); iter != dependents.end(); ++iter) {
    ClassData *cls = *iter;
    cls->satisfy_dependency(this);
  }
}

void ClassHandler::ClassData::init()
{
  void (*cls_init)() = (void (*)())dlsym(handle, "class_init");

  if (cls_init)
    cls_init();
}

bool ClassHandler::ClassData::_add_dependency(cls_deps_t *dep)
{
  if (!dep->name)
    return false;

  ClassData& cls_dep = handler->get_obj(dep->name);
  if (&cls_dep == &null_cls_data) {
    dout(0) << "couldn't get class dep object, out of memory?" << dendl;
    return false;
  }
  map<nstring, ClassData *>::iterator iter = missing_dependencies.find(dep->name);
  dependencies[dep->name] = &cls_dep;
  dout(0) << "adding dependency " << dep->name << dendl;

  if (cls_dep.status != CLASS_LOADED) {
    missing_dependencies[dep->name] = &cls_dep;

    if(cls_dep.status == CLASS_UNKNOWN) {
      ClassVersion version;
      version.set_arch(get_arch());
      handler->get_class(dep->name, version);
    }
    dout(0) << "adding missing dependency " << dep->name << dendl;
  }
  cls_dep._add_dependent(*this);

  if (cls_dep.status == CLASS_INVALID) {
    dout(0) << "ouch! depending on invalid class" << dendl;
    set_status(CLASS_INVALID); /* we have an invalid dependency, we're invalid */
  }

  return true;
}

void ClassHandler::ClassData::satisfy_dependency(ClassData *cls)
{
  Mutex::Locker lock(*mutex);
  map<nstring, ClassData *>::iterator iter = missing_dependencies.find(cls->name);

  if (iter != missing_dependencies.end()) {
    dout(0) << "satisfied dependency name=" << name << " dep=" << cls->name << dendl;
    missing_dependencies.erase(iter);
    if (missing_dependencies.size() == 0) {
      dout(0) << "all dependencies are satisfied! initializing, notifying osd" << dendl;
      set_status(CLASS_LOADED);
  dout(0) << "this=" << (void *)this << " status=" << status << dendl;
      init();
      osd->got_class(name);
    }
  }
}

void ClassHandler::ClassData::_add_dependent(ClassData& dependent)
{
  Mutex::Locker lock(*mutex);
  dout(0) << "class " << name << " has dependet: " << dependent.name << dendl;
  dependents.push_back(&dependent);
}

ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *mname,
                                                                    int flags,
								    cls_method_call_t func)
{
  /* no need for locking, called under the class_init mutex */
  ClassMethod& method = methods_map[mname];
  method.func = func;
  method.name = mname;
  method.cls = this;

  return &method;
}

ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const char *mname,
                                                                        int flags,
									cls_method_cxx_call_t func)
{
  /* no need for locking, called under the class_init mutex */
  ClassMethod& method = methods_map[mname];
  method.cxx_func = func;
  method.name = mname;
  method.cls = this;

  return &method;
}

ClassHandler::ClassMethod *ClassHandler::ClassData::get_method(const char *mname)
{
  Mutex::Locker lock(*mutex);
  map<nstring, ClassHandler::ClassMethod>::iterator iter = methods_map.find(mname);

  if (iter == methods_map.end())
    return NULL;

  return &(iter->second);
}

void ClassHandler::ClassData::unregister_method(ClassHandler::ClassMethod *method)
{
 /* no need for locking, called under the class_init mutex */
   map<nstring, ClassMethod>::iterator iter;

   iter = methods_map.find(method->name);
   if (iter == methods_map.end())
     return;

   methods_map.erase(iter);
}

void ClassHandler::ClassData::set_status(ClassHandler::ClassData::Status _status)
{
  status = _status;

  switch (status) {
    case CLASS_INVALID:
    case CLASS_LOADED:
      set_timeout();
      break;
    default:
      break;
  }
}

void ClassHandler::ClassData::set_timeout()
{
  timeout = g_clock.now();
  timeout += g_conf.osd_class_timeout;
}

bool ClassHandler::ClassData::cache_timed_out()
{
  dout(0) << "timeout=" << timeout << " g_clock.now()=" << g_clock.now() << dendl;
  return (timeout && g_clock.now() >= timeout);
}

void ClassHandler::ClassMethod::unregister()
{
  cls->unregister_method(this);
}

int ClassHandler::ClassMethod::exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata)
{
  int ret;
  if (cxx_func) {
    // C++ call version
    ret = cxx_func(ctx, &indata, &outdata);
  } else {
    // C version
    char *out = NULL;
    int olen = 0;
    ret = func(ctx, indata.c_str(), indata.length(), &out, &olen);
    if (out) {
      // assume *out was allocated via cls_alloc (which calls malloc!)
      buffer::ptr bp = buffer::claim_malloc(olen, out);
      outdata.push_back(bp);
    }
  }
  return ret;
}

int ClassHandler::get_method_flags(const nstring& cname, const nstring& mname)
{
  ClassData& cls = get_obj(cname);
  if (&cls == &null_cls_data)
    return 0;

  ClassMethod *method = cls.get_method(mname.c_str());
  if (!method)
    return 0;

  return method->flags;
}
<commit_msg>class: set method flags on registration<commit_after>
#include "include/types.h"
#include "msg/Message.h"
#include "osd/OSD.h"
#include "messages/MClass.h"
#include "ClassHandler.h"
#include "common/arch.h"

#include <dlfcn.h>

#include <map>

#include "config.h"

#define DOUT_SUBSYS osd
#undef dout_prefix
#define dout_prefix *_dout << dbeginl

static ClassHandler::ClassData null_cls_data;

void ClassHandler::_load_class(ClassData &cls)
{
  dout(10) << "load_class " << cls.name << dendl;

  char *fname=strdup("/tmp/class-XXXXXX");
  int fd = mkstemp(fname);
  cls_deps_t *(*cls_deps)();

  for (list<bufferptr>::const_iterator it = cls.impl.binary.buffers().begin();
       it != cls.impl.binary.buffers().end(); it++)
    write(fd, it->c_str(), it->length());

  close(fd);

  cls.handle = dlopen(fname, RTLD_NOW);

  if (!cls.handle) {
    dout(0) << "could not open class (dlopen failed)" << dendl;
    goto done;
  }
  cls_deps = (cls_deps_t *(*)())dlsym(cls.handle, "class_deps");
  if (cls_deps) {
    cls_deps_t *deps = cls_deps();
    while (deps) {
      if (!deps->name)
        break;
      cls._add_dependency(deps);
      deps++;
    }
  }
  cls.load();
done:
  unlink(fname);
  free(fname);

  return;
}

void ClassHandler::load_class(const nstring& cname)
{
  ClassData& cls = get_obj(cname);
  if (&cls == &null_cls_data) {
    dout(0) << "ERROR: can't load null class data" << dendl;
    return;
  }
  cls.mutex->Lock();
  _load_class(cls);
  cls.mutex->Unlock();
}

ClassHandler::ClassData& ClassHandler::get_obj(const nstring& cname)
{
  Mutex::Locker locker(mutex);
  map<nstring, ClassData>::iterator iter = classes.find(cname);
  if (iter == classes.end()) {
    ClassData& cls = classes[cname];
    cls.mutex = new Mutex("ClassData");
    if (!cls.mutex) {
      classes[cname] = null_cls_data;
      return null_cls_data;
    }
    dout(0) << "get_obj: adding new class name=" << cname << " ptr=" << &cls << dendl;
    cls.name = cname;
    cls.osd = osd;
    cls.handler = this;
    return cls;
  }

  return iter->second;
}

ClassHandler::ClassData *ClassHandler::get_class(const nstring& cname, ClassVersion& version)
{
  ClassHandler::ClassData *ret = NULL;
  ClassData *class_data = &get_obj(cname);
  if (class_data == &null_cls_data)
    return NULL;

  Mutex::Locker lock(*class_data->mutex);

  switch (class_data->status) {
  case ClassData::CLASS_INVALID:
  case ClassData::CLASS_LOADED:
    if (class_data->cache_timed_out()) {
      dout(0) << "class timed out going to send request for " << cname.c_str() << " v" << version << dendl;
      ret = class_data;
      goto send;
    }
    return class_data;
  case ClassData::CLASS_REQUESTED:
    return NULL;
    break;

  case ClassData::CLASS_UNKNOWN:
    class_data->set_status(ClassData::CLASS_REQUESTED);
    break;

  default:
    assert(0);
  }

  class_data->version = version;
send:
  osd->send_class_request(cname.c_str(), version);
  return ret;
}

void ClassHandler::handle_class(MClass *m)
{
  deque<ClassInfo>::iterator info_iter;
  deque<ClassImpl>::iterator impl_iter;
  deque<bool>::iterator add_iter;

  for (info_iter = m->info.begin(), add_iter = m->add.begin(), impl_iter = m->impl.begin();
       info_iter != m->info.end();
       ++info_iter, ++add_iter) {
    ClassData& data = get_obj(info_iter->name);
    if (&data == &null_cls_data) {
      dout(0) << "couldn't get class, out of memory? continuing" << dendl;
      continue;
    }
    dout(0) << "handle_class " << info_iter->name << dendl;
    data.mutex->Lock();

    if (*add_iter) {
        data.set_status(ClassData::CLASS_REQUESTED);
	dout(10) << "added class '" << info_iter->name << "'" << dendl;
	data.impl = *impl_iter;
	++impl_iter;
	_load_class(data);
    } else {
	dout(10) << "response of an invalid class '" << info_iter->name << "'" << dendl;
        data.set_status(ClassData::CLASS_INVALID);
        osd->got_class(info_iter->name);
    }
    data.mutex->Unlock();
  }
}

void ClassHandler::resend_class_requests()
{
  for (map<nstring,ClassData>::iterator p = classes.begin(); p != classes.end(); p++) {
    dout(20) << "resending class request "<< p->first.c_str() << " v" << p->second.version << dendl;
    osd->send_class_request(p->first.c_str(), p->second.version);
  }
}

ClassHandler::ClassData *ClassHandler::register_class(const char *cname)
{
  ClassData& class_data = get_obj(cname);

  if (&class_data == &null_cls_data) {
    dout(0) << "couldn't get class object, out of memory?" << dendl;
    return NULL;
  }

  dout(0) << "&class_data=" << (void *)&class_data << " status=" << class_data.status << dendl;

  if (class_data.status != ClassData::CLASS_LOADED) {
    dout(0) << "class " << cname << " can't be loaded" << dendl;
    return NULL;
  }

  if (class_data.registered) {
    dout(0) << "class " << cname << " already registered" << dendl;
  }

  class_data.registered = true;

  return &class_data;
}

void ClassHandler::unregister_class(ClassHandler::ClassData *cls)
{
  /* FIXME: do we really need this one? */
}

void ClassHandler::ClassData::load()
{
  if (status == CLASS_INVALID) {
    /* if we're invalid, we should just notify osd */
    osd->got_class(name);
    return;
  }

  if (!has_missing_deps()) {
    set_status(CLASS_LOADED);
    dout(0) << "setting class " << name << " status to CLASS_LOADED" << dendl;
    init();
    osd->got_class(name);
  }

  list<ClassData *>::iterator iter;
  for (iter = dependents.begin(); iter != dependents.end(); ++iter) {
    ClassData *cls = *iter;
    cls->satisfy_dependency(this);
  }
}

void ClassHandler::ClassData::init()
{
  void (*cls_init)() = (void (*)())dlsym(handle, "class_init");

  if (cls_init)
    cls_init();
}

bool ClassHandler::ClassData::_add_dependency(cls_deps_t *dep)
{
  if (!dep->name)
    return false;

  ClassData& cls_dep = handler->get_obj(dep->name);
  if (&cls_dep == &null_cls_data) {
    dout(0) << "couldn't get class dep object, out of memory?" << dendl;
    return false;
  }
  map<nstring, ClassData *>::iterator iter = missing_dependencies.find(dep->name);
  dependencies[dep->name] = &cls_dep;
  dout(0) << "adding dependency " << dep->name << dendl;

  if (cls_dep.status != CLASS_LOADED) {
    missing_dependencies[dep->name] = &cls_dep;

    if(cls_dep.status == CLASS_UNKNOWN) {
      ClassVersion version;
      version.set_arch(get_arch());
      handler->get_class(dep->name, version);
    }
    dout(0) << "adding missing dependency " << dep->name << dendl;
  }
  cls_dep._add_dependent(*this);

  if (cls_dep.status == CLASS_INVALID) {
    dout(0) << "ouch! depending on invalid class" << dendl;
    set_status(CLASS_INVALID); /* we have an invalid dependency, we're invalid */
  }

  return true;
}

void ClassHandler::ClassData::satisfy_dependency(ClassData *cls)
{
  Mutex::Locker lock(*mutex);
  map<nstring, ClassData *>::iterator iter = missing_dependencies.find(cls->name);

  if (iter != missing_dependencies.end()) {
    dout(0) << "satisfied dependency name=" << name << " dep=" << cls->name << dendl;
    missing_dependencies.erase(iter);
    if (missing_dependencies.size() == 0) {
      dout(0) << "all dependencies are satisfied! initializing, notifying osd" << dendl;
      set_status(CLASS_LOADED);
  dout(0) << "this=" << (void *)this << " status=" << status << dendl;
      init();
      osd->got_class(name);
    }
  }
}

void ClassHandler::ClassData::_add_dependent(ClassData& dependent)
{
  Mutex::Locker lock(*mutex);
  dout(0) << "class " << name << " has dependet: " << dependent.name << dendl;
  dependents.push_back(&dependent);
}

ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *mname,
                                                                    int flags,
								    cls_method_call_t func)
{
  /* no need for locking, called under the class_init mutex */
  ClassMethod& method = methods_map[mname];
  method.func = func;
  method.name = mname;
  method.flags = flags;
  method.cls = this;

  return &method;
}

ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const char *mname,
                                                                        int flags,
									cls_method_cxx_call_t func)
{
  /* no need for locking, called under the class_init mutex */
  ClassMethod& method = methods_map[mname];
  method.cxx_func = func;
  method.name = mname;
  method.flags = flags;
  method.cls = this;

  return &method;
}

ClassHandler::ClassMethod *ClassHandler::ClassData::get_method(const char *mname)
{
  Mutex::Locker lock(*mutex);
  map<nstring, ClassHandler::ClassMethod>::iterator iter = methods_map.find(mname);

  if (iter == methods_map.end())
    return NULL;

  return &(iter->second);
}

void ClassHandler::ClassData::unregister_method(ClassHandler::ClassMethod *method)
{
 /* no need for locking, called under the class_init mutex */
   map<nstring, ClassMethod>::iterator iter;

   iter = methods_map.find(method->name);
   if (iter == methods_map.end())
     return;

   methods_map.erase(iter);
}

void ClassHandler::ClassData::set_status(ClassHandler::ClassData::Status _status)
{
  status = _status;

  switch (status) {
    case CLASS_INVALID:
    case CLASS_LOADED:
      set_timeout();
      break;
    default:
      break;
  }
}

void ClassHandler::ClassData::set_timeout()
{
  timeout = g_clock.now();
  timeout += g_conf.osd_class_timeout;
}

bool ClassHandler::ClassData::cache_timed_out()
{
  dout(0) << "timeout=" << timeout << " g_clock.now()=" << g_clock.now() << dendl;
  return (timeout && g_clock.now() >= timeout);
}

void ClassHandler::ClassMethod::unregister()
{
  cls->unregister_method(this);
}

int ClassHandler::ClassMethod::exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata)
{
  int ret;
  if (cxx_func) {
    // C++ call version
    ret = cxx_func(ctx, &indata, &outdata);
  } else {
    // C version
    char *out = NULL;
    int olen = 0;
    ret = func(ctx, indata.c_str(), indata.length(), &out, &olen);
    if (out) {
      // assume *out was allocated via cls_alloc (which calls malloc!)
      buffer::ptr bp = buffer::claim_malloc(olen, out);
      outdata.push_back(bp);
    }
  }
  return ret;
}

int ClassHandler::get_method_flags(const nstring& cname, const nstring& mname)
{
  ClassData& cls = get_obj(cname);
  if (&cls == &null_cls_data)
    return 0;

  ClassMethod *method = cls.get_method(mname.c_str());
  if (!method)
    return 0;

  return method->flags;
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "math.h"
#include <iostream>
#include "trida.h"
using namespace std;

void Complex::set_real(double r)
{
	real = r;
}
void Complex::set_imag(double i)
{
	imag = i;
}
<commit_msg>Update cviko_3_trida.cpp<commit_after>#include "stdafx.h"
#define _USE_MATH_DEFINES
#include "math.h"
#include <iostream>
#include "trida.h"

using namespace std;

void Complex::set_real(double r)
{
	real = r;
}
void Complex::set_imag(double i)
{
	imag = i;
}
double Complex::get_real(void)
{
	return real;
}

double Complex::get_imag(void)
{
	return imag;
}

double Complex::modul(void)
{
	return sqrt(real*real + imag*imag);
}
double Complex::faze(void)
{
	return acos(imag / sqrt(real*real + imag*imag))*(180/M_PI);
}

void Complex::tisk(void)
{
	cout << "vase cislo je" << get_real() << "+j" << get_imag() << endl;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// macho_id.cc: Functions to gather identifying information from a macho file
//
// See macho_id.h for documentation
//
// Author: Dan Waylonis

#include <fcntl.h>
#include <mach-o/loader.h>
#include <mach-o/swap.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include "common/mac/macho_id.h"
#include "common/mac/macho_walker.h"

namespace MacFileUtilities {

MachoID::MachoID(const char *path) {
  strlcpy(path_, path, sizeof(path_));
  file_ = open(path, O_RDONLY);
}

MachoID::~MachoID() {
  if (file_ != -1)
    close(file_);
}

// The CRC info is from http://en.wikipedia.org/wiki/Adler-32
// With optimizations from http://www.zlib.net/

// The largest prime smaller than 65536
#define MOD_ADLER 65521
// MAX_BLOCK is the largest n such that 255n(n+1)/2 + (n+1)(MAX_BLOCK-1) <= 2^32-1
#define MAX_BLOCK 5552

void MachoID::UpdateCRC(unsigned char *bytes, size_t size) {
// Unrolled loops for summing
#define DO1(buf,i)  {sum1 += (buf)[i]; sum2 += sum1;}
#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
#define DO16(buf)   DO8(buf,0); DO8(buf,8);
  // Split up the crc
  uint32_t sum1 = crc_ & 0xFFFF;
  uint32_t sum2 = (crc_ >> 16) & 0xFFFF;

  // Do large blocks
  while (size >= MAX_BLOCK) {
    size -= MAX_BLOCK;
    int block_count = MAX_BLOCK / 16;
    do {
      DO16(bytes);
      bytes += 16;
    } while (--block_count);
    sum1 %= MOD_ADLER;
    sum2 %= MOD_ADLER;
  }

  // Do remaining bytes
  if (size) {
    while (size >= 16) {
      size -= 16;
      DO16(bytes);
      bytes += 16;
    }
    while (size--) {
      sum1 += *bytes++;
      sum2 += sum1;
    }
    sum1 %= MOD_ADLER;
    sum2 %= MOD_ADLER;
    crc_ = (sum2 << 16) | sum1;
  }
}

void MachoID::UpdateMD5(unsigned char *bytes, size_t size) {
  MD5_Update(&md5_context_, bytes, size);
}

void MachoID::UpdateSHA1(unsigned char *bytes, size_t size) {
  SHA_Update(&sha1_context_, bytes, size);
}

void MachoID::Update(MachoWalker *walker, unsigned long offset, size_t size) {
  if (!update_function_ || !size)
    return;

  // Read up to 4k bytes at a time
  unsigned char buffer[4096];
  size_t buffer_size;
  off_t file_offset = offset;
  while (size > 0) {
    if (size > sizeof(buffer)) {
      buffer_size = sizeof(buffer);
      size -= buffer_size;
    } else {
      buffer_size = size;
      size = 0;
    }

    if (!walker->ReadBytes(buffer, buffer_size, file_offset))
      return;

    (this->*update_function_)(buffer, buffer_size);
    file_offset += buffer_size;
  }
}

bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) {
  struct uuid_command uuid_cmd;
  MachoWalker walker(path_, UUIDWalkerCB, &uuid_cmd);

  uuid_cmd.cmd = 0;
  if (!walker.WalkHeader(cpu_type))
    return false;

  // If we found the command, we'll have initialized the uuid_command
  // structure
  if (uuid_cmd.cmd == LC_UUID) {
    memcpy(bytes, uuid_cmd.uuid, sizeof(uuid_cmd.uuid));
    return true;
  }

  return false;
}

bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) {
  struct dylib_command dylib_cmd;
  MachoWalker walker(path_, IDWalkerCB, &dylib_cmd);

  dylib_cmd.cmd = 0;
  if (!walker.WalkHeader(cpu_type))
    return false;

  // If we found the command, we'll have initialized the dylib_command
  // structure
  if (dylib_cmd.cmd == LC_ID_DYLIB) {
    // Take the hashed filename, version, and compatability version bytes
    // to form the first 12 bytes, pad the rest with zeros

    // create a crude hash of the filename to generate the first 4 bytes
    identifier[0] = 0;
    identifier[1] = 0;
    identifier[2] = 0;
    identifier[3] = 0;

    for (int j = 0, i = strlen(path_)-1; i >= 0 && path_[i]!='/'; ++j, --i) {
      identifier[j%4] += path_[i];
    }

    identifier[4] = (dylib_cmd.dylib.current_version >> 24) & 0xFF;
    identifier[5] = (dylib_cmd.dylib.current_version >> 16) & 0xFF;
    identifier[6] = (dylib_cmd.dylib.current_version >> 8) & 0xFF;
    identifier[7] = dylib_cmd.dylib.current_version & 0xFF;
    identifier[8] = (dylib_cmd.dylib.compatibility_version >> 24) & 0xFF;
    identifier[9] = (dylib_cmd.dylib.compatibility_version >> 16) & 0xFF;
    identifier[10] = (dylib_cmd.dylib.compatibility_version >> 8) & 0xFF;
    identifier[11] = dylib_cmd.dylib.compatibility_version & 0xFF;
    identifier[12] = identifier[13] = identifier[14] = identifier[15] = 0;

    return true;
  }

  return false;
}

uint32_t MachoID::Adler32(int cpu_type) {
  MachoWalker walker(path_, WalkerCB, this);
  update_function_ = &MachoID::UpdateCRC;
  crc_ = 0;

  if (!walker.WalkHeader(cpu_type))
    return 0;

  return crc_;
}

bool MachoID::MD5(int cpu_type, unsigned char identifier[16]) {
  MachoWalker walker(path_, WalkerCB, this);
  update_function_ = &MachoID::UpdateMD5;

  if (MD5_Init(&md5_context_)) {
    if (!walker.WalkHeader(cpu_type))
      return false;

    MD5_Final(identifier, &md5_context_);
    return true;
  }

  return false;
}

bool MachoID::SHA1(int cpu_type, unsigned char identifier[16]) {
  MachoWalker walker(path_, WalkerCB, this);
  update_function_ = &MachoID::UpdateSHA1;

  if (SHA_Init(&sha1_context_)) {
    if (!walker.WalkHeader(cpu_type))
      return false;

    SHA_Final(identifier, &sha1_context_);
    return true;
  }

  return false;
}

// static
bool MachoID::WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                       bool swap, void *context) {
  MachoID *macho_id = (MachoID *)context;

  if (cmd->cmd == LC_SEGMENT) {
    struct segment_command seg;

    if (!walker->ReadBytes(&seg, sizeof(seg), offset))
      return false;

    if (swap)
      swap_segment_command(&seg, NXHostByteOrder());

    struct mach_header_64 header;
    off_t header_offset;

    if (!walker->CurrentHeader(&header, &header_offset))
      return false;

    // Process segments that have sections:
    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
    offset += sizeof(struct segment_command);
    struct section sec;
    for (unsigned long i = 0; i < seg.nsects; ++i) {
      if (!walker->ReadBytes(&sec, sizeof(sec), offset))
        return false;

      if (swap)
        swap_section(&sec, 1, NXHostByteOrder());

      macho_id->Update(walker, header_offset + sec.offset, sec.size);
      offset += sizeof(struct section);
    }
  } else if (cmd->cmd == LC_SEGMENT_64) {
    struct segment_command_64 seg64;

    if (!walker->ReadBytes(&seg64, sizeof(seg64), offset))
      return false;

    if (swap)
      swap_segment_command_64(&seg64, NXHostByteOrder());

    struct mach_header_64 header;
    off_t header_offset;

    if (!walker->CurrentHeader(&header, &header_offset))
      return false;

    // Process segments that have sections:
    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
    offset += sizeof(struct segment_command_64);
    struct section_64 sec64;
    for (unsigned long i = 0; i < seg64.nsects; ++i) {
      if (!walker->ReadBytes(&sec64, sizeof(sec64), offset))
        return false;

      if (swap)
        swap_section_64(&sec64, 1, NXHostByteOrder());

      macho_id->Update(walker, header_offset + sec64.offset, sec64.size);
      offset += sizeof(struct section_64);
    }
  }

  // Continue processing
  return true;
}

// static
bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                           bool swap, void *context) {
  if (cmd->cmd == LC_UUID) {
    struct uuid_command *uuid_cmd = (struct uuid_command *)context;

    if (!walker->ReadBytes(uuid_cmd, sizeof(struct uuid_command), offset))
      return false;

    if (swap)
      swap_uuid_command(uuid_cmd, NXHostByteOrder());

    return false;
  }

  // Continue processing
  return true;
}

// static
bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                         bool swap, void *context) {
  if (cmd->cmd == LC_ID_DYLIB) {
    struct dylib_command *dylib_cmd = (struct dylib_command *)context;

    if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset))
      return false;

    if (swap)
      swap_dylib_command(dylib_cmd, NXHostByteOrder());

    return false;
  }

  // Continue processing
  return true;
}

}  // namespace MacFileUtilities
<commit_msg>issue141: reviewer Waylonis<commit_after>// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// macho_id.cc: Functions to gather identifying information from a macho file
//
// See macho_id.h for documentation
//
// Author: Dan Waylonis

#include <fcntl.h>
#include <mach-o/loader.h>
#include <mach-o/swap.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include "common/mac/macho_id.h"
#include "common/mac/macho_walker.h"

namespace MacFileUtilities {

MachoID::MachoID(const char *path) {
  strlcpy(path_, path, sizeof(path_));
  file_ = open(path, O_RDONLY);
}

MachoID::~MachoID() {
  if (file_ != -1)
    close(file_);
}

// The CRC info is from http://en.wikipedia.org/wiki/Adler-32
// With optimizations from http://www.zlib.net/

// The largest prime smaller than 65536
#define MOD_ADLER 65521
// MAX_BLOCK is the largest n such that 255n(n+1)/2 + (n+1)(MAX_BLOCK-1) <= 2^32-1
#define MAX_BLOCK 5552

void MachoID::UpdateCRC(unsigned char *bytes, size_t size) {
// Unrolled loops for summing
#define DO1(buf,i)  {sum1 += (buf)[i]; sum2 += sum1;}
#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
#define DO16(buf)   DO8(buf,0); DO8(buf,8);
  // Split up the crc
  uint32_t sum1 = crc_ & 0xFFFF;
  uint32_t sum2 = (crc_ >> 16) & 0xFFFF;

  // Do large blocks
  while (size >= MAX_BLOCK) {
    size -= MAX_BLOCK;
    int block_count = MAX_BLOCK / 16;
    do {
      DO16(bytes);
      bytes += 16;
    } while (--block_count);
    sum1 %= MOD_ADLER;
    sum2 %= MOD_ADLER;
  }

  // Do remaining bytes
  if (size) {
    while (size >= 16) {
      size -= 16;
      DO16(bytes);
      bytes += 16;
    }
    while (size--) {
      sum1 += *bytes++;
      sum2 += sum1;
    }
    sum1 %= MOD_ADLER;
    sum2 %= MOD_ADLER;
    crc_ = (sum2 << 16) | sum1;
  }
}

void MachoID::UpdateMD5(unsigned char *bytes, size_t size) {
  MD5_Update(&md5_context_, bytes, size);
}

void MachoID::UpdateSHA1(unsigned char *bytes, size_t size) {
  SHA_Update(&sha1_context_, bytes, size);
}

void MachoID::Update(MachoWalker *walker, unsigned long offset, size_t size) {
  if (!update_function_ || !size)
    return;

  // Read up to 4k bytes at a time
  unsigned char buffer[4096];
  size_t buffer_size;
  off_t file_offset = offset;
  while (size > 0) {
    if (size > sizeof(buffer)) {
      buffer_size = sizeof(buffer);
      size -= buffer_size;
    } else {
      buffer_size = size;
      size = 0;
    }

    if (!walker->ReadBytes(buffer, buffer_size, file_offset))
      return;

    (this->*update_function_)(buffer, buffer_size);
    file_offset += buffer_size;
  }
}

bool MachoID::UUIDCommand(int cpu_type, unsigned char bytes[16]) {
  struct uuid_command uuid_cmd;
  MachoWalker walker(path_, UUIDWalkerCB, &uuid_cmd);

  uuid_cmd.cmd = 0;
  if (!walker.WalkHeader(cpu_type))
    return false;

  // If we found the command, we'll have initialized the uuid_command
  // structure
  if (uuid_cmd.cmd == LC_UUID) {
    memcpy(bytes, uuid_cmd.uuid, sizeof(uuid_cmd.uuid));
    return true;
  }

  return false;
}

bool MachoID::IDCommand(int cpu_type, unsigned char identifier[16]) {
  struct dylib_command dylib_cmd;
  MachoWalker walker(path_, IDWalkerCB, &dylib_cmd);

  dylib_cmd.cmd = 0;
  if (!walker.WalkHeader(cpu_type))
    return false;

  // If we found the command, we'll have initialized the dylib_command
  // structure
  if (dylib_cmd.cmd == LC_ID_DYLIB) {
    // Take the hashed filename, version, and compatability version bytes
    // to form the first 12 bytes, pad the rest with zeros

    // create a crude hash of the filename to generate the first 4 bytes
    identifier[0] = 0;
    identifier[1] = 0;
    identifier[2] = 0;
    identifier[3] = 0;

    for (int j = 0, i = strlen(path_)-1; i >= 0 && path_[i]!='/'; ++j, --i) {
      identifier[j%4] += path_[i];
    }

    identifier[4] = (dylib_cmd.dylib.current_version >> 24) & 0xFF;
    identifier[5] = (dylib_cmd.dylib.current_version >> 16) & 0xFF;
    identifier[6] = (dylib_cmd.dylib.current_version >> 8) & 0xFF;
    identifier[7] = dylib_cmd.dylib.current_version & 0xFF;
    identifier[8] = (dylib_cmd.dylib.compatibility_version >> 24) & 0xFF;
    identifier[9] = (dylib_cmd.dylib.compatibility_version >> 16) & 0xFF;
    identifier[10] = (dylib_cmd.dylib.compatibility_version >> 8) & 0xFF;
    identifier[11] = dylib_cmd.dylib.compatibility_version & 0xFF;
    identifier[12] = (cpu_type >> 24) & 0xFF;
    identifier[13] = (cpu_type >> 16) & 0xFF;
    identifier[14] = (cpu_type >> 8) & 0xFF;
    identifier[15] = cpu_type & 0xFF;

    return true;
  }

  return false;
}

uint32_t MachoID::Adler32(int cpu_type) {
  MachoWalker walker(path_, WalkerCB, this);
  update_function_ = &MachoID::UpdateCRC;
  crc_ = 0;

  if (!walker.WalkHeader(cpu_type))
    return 0;

  return crc_;
}

bool MachoID::MD5(int cpu_type, unsigned char identifier[16]) {
  MachoWalker walker(path_, WalkerCB, this);
  update_function_ = &MachoID::UpdateMD5;

  if (MD5_Init(&md5_context_)) {
    if (!walker.WalkHeader(cpu_type))
      return false;

    MD5_Final(identifier, &md5_context_);
    return true;
  }

  return false;
}

bool MachoID::SHA1(int cpu_type, unsigned char identifier[16]) {
  MachoWalker walker(path_, WalkerCB, this);
  update_function_ = &MachoID::UpdateSHA1;

  if (SHA_Init(&sha1_context_)) {
    if (!walker.WalkHeader(cpu_type))
      return false;

    SHA_Final(identifier, &sha1_context_);
    return true;
  }

  return false;
}

// static
bool MachoID::WalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                       bool swap, void *context) {
  MachoID *macho_id = (MachoID *)context;

  if (cmd->cmd == LC_SEGMENT) {
    struct segment_command seg;

    if (!walker->ReadBytes(&seg, sizeof(seg), offset))
      return false;

    if (swap)
      swap_segment_command(&seg, NXHostByteOrder());

    struct mach_header_64 header;
    off_t header_offset;

    if (!walker->CurrentHeader(&header, &header_offset))
      return false;

    // Process segments that have sections:
    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
    offset += sizeof(struct segment_command);
    struct section sec;
    for (unsigned long i = 0; i < seg.nsects; ++i) {
      if (!walker->ReadBytes(&sec, sizeof(sec), offset))
        return false;

      if (swap)
        swap_section(&sec, 1, NXHostByteOrder());

      macho_id->Update(walker, header_offset + sec.offset, sec.size);
      offset += sizeof(struct section);
    }
  } else if (cmd->cmd == LC_SEGMENT_64) {
    struct segment_command_64 seg64;

    if (!walker->ReadBytes(&seg64, sizeof(seg64), offset))
      return false;

    if (swap)
      swap_segment_command_64(&seg64, NXHostByteOrder());

    struct mach_header_64 header;
    off_t header_offset;

    if (!walker->CurrentHeader(&header, &header_offset))
      return false;

    // Process segments that have sections:
    // (e.g., __TEXT, __DATA, __IMPORT, __OBJC)
    offset += sizeof(struct segment_command_64);
    struct section_64 sec64;
    for (unsigned long i = 0; i < seg64.nsects; ++i) {
      if (!walker->ReadBytes(&sec64, sizeof(sec64), offset))
        return false;

      if (swap)
        swap_section_64(&sec64, 1, NXHostByteOrder());

      macho_id->Update(walker, header_offset + sec64.offset, sec64.size);
      offset += sizeof(struct section_64);
    }
  }

  // Continue processing
  return true;
}

// static
bool MachoID::UUIDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                           bool swap, void *context) {
  if (cmd->cmd == LC_UUID) {
    struct uuid_command *uuid_cmd = (struct uuid_command *)context;

    if (!walker->ReadBytes(uuid_cmd, sizeof(struct uuid_command), offset))
      return false;

    if (swap)
      swap_uuid_command(uuid_cmd, NXHostByteOrder());

    return false;
  }

  // Continue processing
  return true;
}

// static
bool MachoID::IDWalkerCB(MachoWalker *walker, load_command *cmd, off_t offset,
                         bool swap, void *context) {
  if (cmd->cmd == LC_ID_DYLIB) {
    struct dylib_command *dylib_cmd = (struct dylib_command *)context;

    if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset))
      return false;

    if (swap)
      swap_dylib_command(dylib_cmd, NXHostByteOrder());

    return false;
  }

  // Continue processing
  return true;
}

}  // namespace MacFileUtilities
<|endoftext|>


<commit_before>#pragma once

#include "common/Histogram.hpp"

#include <cstddef>
#include <iostream>
#include <stdint.h>

struct BufferProcessor {
    typedef vector<Read> ReadVector;
    typedef boost::unordered_map<Signature, ReadVector> SignatureMap;

    Histogram<uint64_t> dup_insert_sizes;
    Histogram<uint64_t> nondup_insert_sizes;
    Histogram<uint64_t> distances;
    Histogram<uint64_t> number_of_dups;
    std::size_t total_dups;
    std::size_t total_fragments;
    std::size_t total_intertile;

    BufferProcessor()
        : total_dups(0)
        , total_fragments(0)
        , total_intertile(0)
    {}

    void update_distances(ReadVector const& reads) {
        std::size_t n = reads.size();
        for (std::size_t i = 0; i < n; ++i) {
            ++dup_insert_sizes[abs(reads[i].insert_size)];
            nondup_insert_sizes[abs(reads[i].insert_size)] += 0;
            for (std::size_t j = i + 1; j < n; ++j) {
                if (is_on_same_tile(reads[i], reads[j])) {
                    uint64_t flow_cell_distance = euclidean_distance(reads[i], reads[j]);
                    ++distances[flow_cell_distance];
                }
                else {
                    ++total_intertile;
                }
            }
        }
    }

    void operator()(ReadVector const& reads) {
        total_fragments += reads.size();
        if (reads.size() > 1) {
            total_dups += reads.size();
            ++number_of_dups[reads.size()];
            update_distances(reads);
        }
        else {
            dup_insert_sizes[abs(reads[0].insert_size)] += 0;
            ++nondup_insert_sizes[abs(reads[0].insert_size)];
        }
    }

    void merge(BufferProcessor& x) {
        dup_insert_sizes.merge(x.dup_insert_sizes);
        nondup_insert_sizes.merge(x.nondup_insert_sizes);
        distances.merge(x.distances);
        number_of_dups.merge(x.number_of_dups);
        total_dups += x.total_dups;
    }

    //XXX This is terrible and should abstracted out
    void write_output(std::ostream& os) {
        os << "{\n"; //start json
        os << " \"summary\": [\n";
        os << "    { "
           << "\"total_fragments\": " << total_fragments
           << ", "
           << "\"total_duplicate_fragments\": " << total_dups
           << ", "
           << "\"total_intertile_duplicates\": " << total_intertile
           << " }\n ],\n";
        typedef Histogram<uint64_t>::VectorType HVec;
        HVec dist = distances.as_sorted_vector();
        os << " \"distance\": [\n";
        for (HVec::const_iterator i = dist.begin(); i != dist.end(); ++i) {
            os << "    { "
               << "\"intertile_distance\": " << i->name
               << ", "
               << "\"count\": " << i->count
               << " }";
            if (i + 1 != dist.end()) {
                os << ",\n";
            }
        }
        os << "\n ],\n";

        os << " \"num_times_duplicated\": [\n";
        HVec ndup = number_of_dups.as_sorted_vector();
        for (HVec::const_iterator i = ndup.begin(); i != ndup.end(); ++i) {
            os << "    { "
               << "\"num_duplicates\": " << i->name
               << ", "
               << "\"count\": " << i->count
               << " }";
            if (i + 1 != ndup.end()) {
                os << ",\n";
            }
        }
        os << "\n ],\n";

        os << " \"insert_size\": [\n";
        HVec isizes = nondup_insert_sizes.as_sorted_vector();
        for (HVec::const_iterator i = isizes.begin(); i != isizes.end(); ++i) {
            os << "    { "
               << "\"insert_size\": " << i->name
               << ", "
               << "\"unique_count\": " << i->count
               << ", "
               << "\"duplicate_count\": " << dup_insert_sizes[i->name]
               << " }";
            if (i + 1 != isizes.end()) {
                os << ",\n";
            }
        }
        os << "\n ]\n}\n";

        std::cerr << total_dups << " duplicates found out of " << total_fragments << ".\n";
    }
};
<commit_msg>properly label intratile distances<commit_after>#pragma once

#include "common/Histogram.hpp"

#include <cstddef>
#include <iostream>
#include <stdint.h>

struct BufferProcessor {
    typedef vector<Read> ReadVector;
    typedef boost::unordered_map<Signature, ReadVector> SignatureMap;

    Histogram<uint64_t> dup_insert_sizes;
    Histogram<uint64_t> nondup_insert_sizes;
    Histogram<uint64_t> distances;
    Histogram<uint64_t> number_of_dups;
    std::size_t total_dups;
    std::size_t total_fragments;
    std::size_t total_intertile;

    BufferProcessor()
        : total_dups(0)
        , total_fragments(0)
        , total_intertile(0)
    {}

    void update_distances(ReadVector const& reads) {
        std::size_t n = reads.size();
        for (std::size_t i = 0; i < n; ++i) {
            ++dup_insert_sizes[abs(reads[i].insert_size)];
            nondup_insert_sizes[abs(reads[i].insert_size)] += 0;
            for (std::size_t j = i + 1; j < n; ++j) {
                if (is_on_same_tile(reads[i], reads[j])) {
                    uint64_t flow_cell_distance = euclidean_distance(reads[i], reads[j]);
                    ++distances[flow_cell_distance];
                }
                else {
                    ++total_intertile;
                }
            }
        }
    }

    void operator()(ReadVector const& reads) {
        total_fragments += reads.size();
        if (reads.size() > 1) {
            total_dups += reads.size();
            ++number_of_dups[reads.size()];
            update_distances(reads);
        }
        else {
            dup_insert_sizes[abs(reads[0].insert_size)] += 0;
            ++nondup_insert_sizes[abs(reads[0].insert_size)];
        }
    }

    void merge(BufferProcessor& x) {
        dup_insert_sizes.merge(x.dup_insert_sizes);
        nondup_insert_sizes.merge(x.nondup_insert_sizes);
        distances.merge(x.distances);
        number_of_dups.merge(x.number_of_dups);
        total_dups += x.total_dups;
    }

    //XXX This is terrible and should abstracted out
    void write_output(std::ostream& os) {
        os << "{\n"; //start json
        os << " \"summary\": [\n";
        os << "    { "
           << "\"total_fragments\": " << total_fragments
           << ", "
           << "\"total_duplicate_fragments\": " << total_dups
           << ", "
           << "\"total_intertile_duplicates\": " << total_intertile
           << " }\n ],\n";
        typedef Histogram<uint64_t>::VectorType HVec;
        HVec dist = distances.as_sorted_vector();
        os << " \"distance\": [\n";
        for (HVec::const_iterator i = dist.begin(); i != dist.end(); ++i) {
            os << "    { "
               << "\"intratile_distance\": " << i->name
               << ", "
               << "\"count\": " << i->count
               << " }";
            if (i + 1 != dist.end()) {
                os << ",\n";
            }
        }
        os << "\n ],\n";

        os << " \"num_times_duplicated\": [\n";
        HVec ndup = number_of_dups.as_sorted_vector();
        for (HVec::const_iterator i = ndup.begin(); i != ndup.end(); ++i) {
            os << "    { "
               << "\"num_duplicates\": " << i->name
               << ", "
               << "\"count\": " << i->count
               << " }";
            if (i + 1 != ndup.end()) {
                os << ",\n";
            }
        }
        os << "\n ],\n";

        os << " \"insert_size\": [\n";
        HVec isizes = nondup_insert_sizes.as_sorted_vector();
        for (HVec::const_iterator i = isizes.begin(); i != isizes.end(); ++i) {
            os << "    { "
               << "\"insert_size\": " << i->name
               << ", "
               << "\"unique_count\": " << i->count
               << ", "
               << "\"duplicate_count\": " << dup_insert_sizes[i->name]
               << " }";
            if (i + 1 != isizes.end()) {
                os << ",\n";
            }
        }
        os << "\n ]\n}\n";

        std::cerr << total_dups << " duplicates found out of " << total_fragments << ".\n";
    }
};
<|endoftext|>


<commit_before>/*
 * exception.cpp
 *
 *  Created on: Jun 5, 2017
 *      Author: jiang
 */

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <metaverse/bitcoin/error.hpp>
#include <metaverse/explorer/extensions/exception.hpp>

namespace libbitcoin {
namespace explorer {

explorer_exception::explorer_exception(uint32_t code, const std::string& message) :
        code_{code}, message_{message}
{
}

std::ostream& operator<<(std::ostream& out, const explorer_exception& ex)
{
    boost::format fmt{"{\"code\":%d, \"message\":\"%s\", \"result\":null}"};
    out << (fmt % ex.code() % ex.message());
    return out;
}

void relay_exception(std::stringstream& ss)
{
    std::stringstream sin;
    sin.str(ss.str());
    ss.str(""); // clear

    std::string code;
    std::string msg;
    // parse json
    using namespace boost::property_tree;
    try
    {
        ptree pt;
        read_json(sin, pt);

        code = pt.get<std::string>("code");
        msg = pt.get<std::string>("message");
    }
    catch (...)
    {
        return;
    }
    uint32_t ex_code;
    ss << code;
    ss >> ex_code;
    ss.str(""); // clear
    throw explorer_exception{ex_code, msg};
}

} //namespace explorer
} //namespace libbitcoin
<commit_msg>Update exception.cpp<commit_after>/*
 * exception.cpp
 *
 *  Created on: Jun 5, 2017
 *      Author: jiang
 */

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <metaverse/bitcoin/error.hpp>
#include <metaverse/explorer/extensions/exception.hpp>

namespace libbitcoin {
namespace explorer {

explorer_exception::explorer_exception(uint32_t code, const std::string& message) :
        code_{code}, message_{message}
{
}

std::ostream& operator<<(std::ostream& out, const explorer_exception& ex)
{
    boost::format fmt{"{\"code\":%d, \"message\":\"%s\", \"result\":null}"};
    out << (fmt % ex.code() % ex.message());
    return out;
}

void relay_exception(std::stringstream& ss)
{
    // parse json
    using namespace boost::property_tree;
    try
    {
        ptree pt;
        read_json(ss, pt);
        uint32_t code = pt.get<std::string>("code");
        std::string msg = pt.get<std::string>("message");
        if (code)
            return;
        throw explorer_exception{ex_code, msg};
    }
    catch (const std::exception& e)
    {
    }
}

} //namespace explorer
} //namespace libbitcoin
<|endoftext|>


<commit_before>/*
* (C) 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/stateful_rng.h>
#include <botan/internal/os_utils.h>
#include <botan/loadstor.h>

namespace Botan {

void Stateful_RNG::clear()
   {
   m_reseed_counter = 0;
   m_last_pid = 0;
   }

void Stateful_RNG::force_reseed()
   {
   m_reseed_counter = 0;
   }

bool Stateful_RNG::is_seeded() const
   {
   return m_reseed_counter > 0;
   }

void Stateful_RNG::initialize_with(const uint8_t input[], size_t len)
   {
   add_entropy(input, len);

   if(8*len >= security_level())
      {
      m_reseed_counter = 1;
      }
   }

void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len)
   {
   uint8_t additional_input[24] = { 0 };
   store_le(OS::get_system_timestamp_ns(), additional_input);
   store_le(OS::get_high_resolution_clock(), additional_input + 8);
   store_le(m_last_pid, additional_input + 16);
   store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);

   randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
   }

size_t Stateful_RNG::reseed(Entropy_Sources& srcs,
                            size_t poll_bits,
                            std::chrono::milliseconds poll_timeout)
   {
   size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout);

   if(bits_collected >= security_level())
      {
      m_reseed_counter = 1;
      }

   return bits_collected;
   }

void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits)
   {
   RandomNumberGenerator::reseed_from_rng(rng, poll_bits);

   if(poll_bits >= security_level())
      {
      m_reseed_counter = 1;
      }
   }

void Stateful_RNG::reseed_check()
   {
   const uint32_t cur_pid = OS::get_process_id();

   const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);

   if(is_seeded() == false ||
      fork_detected ||
      (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval))
      {
      m_reseed_counter = 0;
      m_last_pid = cur_pid;

      if(m_underlying_rng)
         {
         reseed_from_rng(*m_underlying_rng, security_level());
         }

      if(m_entropy_sources)
         {
         reseed(*m_entropy_sources, security_level());
         }

      if(!is_seeded())
         {
         if(fork_detected)
            throw Exception("Detected use of fork but cannot reseed DRBG");
         else
            throw PRNG_Unseeded(name());
         }
      }
   else
      {
      BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
      m_reseed_counter += 1;
      }
   }

}
<commit_msg>Use new reset_reseed_counter function within Stateful_RNG as well<commit_after>/*
* (C) 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/stateful_rng.h>
#include <botan/internal/os_utils.h>
#include <botan/loadstor.h>

namespace Botan {

void Stateful_RNG::clear()
   {
   m_reseed_counter = 0;
   m_last_pid = 0;
   }

void Stateful_RNG::force_reseed()
   {
   m_reseed_counter = 0;
   }

bool Stateful_RNG::is_seeded() const
   {
   return m_reseed_counter > 0;
   }

void Stateful_RNG::initialize_with(const uint8_t input[], size_t len)
   {
   add_entropy(input, len);

   if(8*len >= security_level())
      {
      reset_reseed_counter();
      }
   }

void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len)
   {
   uint8_t additional_input[24] = { 0 };
   store_le(OS::get_system_timestamp_ns(), additional_input);
   store_le(OS::get_high_resolution_clock(), additional_input + 8);
   store_le(m_last_pid, additional_input + 16);
   store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);

   randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
   }

size_t Stateful_RNG::reseed(Entropy_Sources& srcs,
                            size_t poll_bits,
                            std::chrono::milliseconds poll_timeout)
   {
   size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout);

   if(bits_collected >= security_level())
      {
      reset_reseed_counter();
      }

   return bits_collected;
   }

void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits)
   {
   RandomNumberGenerator::reseed_from_rng(rng, poll_bits);

   if(poll_bits >= security_level())
      {
      reset_reseed_counter();
      }
   }

void Stateful_RNG::reseed_check()
   {
   const uint32_t cur_pid = OS::get_process_id();

   const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);

   if(is_seeded() == false ||
      fork_detected ||
      (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval))
      {
      m_reseed_counter = 0;
      m_last_pid = cur_pid;

      if(m_underlying_rng)
         {
         reseed_from_rng(*m_underlying_rng, security_level());
         }

      if(m_entropy_sources)
         {
         reseed(*m_entropy_sources, security_level());
         }

      if(!is_seeded())
         {
         if(fork_detected)
            throw Exception("Detected use of fork but cannot reseed DRBG");
         else
            throw PRNG_Unseeded(name());
         }
      }
   else
      {
      BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
      m_reseed_counter += 1;
      }
   }

}
<|endoftext|>


<commit_before>#include "precompiled.h"
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// TextureStorage.cpp: Implements the abstract rx::TextureStorageInterface class and its concrete derived
// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the
// GPU-side texture.

#include "libGLESv2/renderer/TextureStorage.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h"

#include "common/debug.h"

namespace rx
{
unsigned int TextureStorageInterface::mCurrentTextureSerial = 1;

TextureStorageInterface::TextureStorageInterface()
    : mTextureSerial(issueTextureSerial()),
      mInstance(NULL)
{
}

TextureStorageInterface::~TextureStorageInterface()
{
    delete mInstance;
}

bool TextureStorageInterface::isRenderTarget() const
{
    return mInstance->isRenderTarget();
}

bool TextureStorageInterface::isManaged() const
{
    return mInstance->isManaged();
}

unsigned int TextureStorageInterface::getTextureSerial() const
{
    return mTextureSerial;
}

unsigned int TextureStorageInterface::issueTextureSerial()
{
    return mCurrentTextureSerial++;
}

int TextureStorageInterface::getLodOffset() const
{
    return mInstance->getLodOffset();
}

int TextureStorageInterface::levelCount()
{
    return mInstance->levelCount();
}

TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain)
    : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
{
    mInstance = renderer->createTextureStorage2D(swapchain);
}

TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
    : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
{
    mInstance = renderer->createTextureStorage2D(levels, internalformat, usage, forceRenderable, width, height);
}

TextureStorageInterface2D::~TextureStorageInterface2D()
{
}

RenderTarget *TextureStorageInterface2D::getRenderTarget() const
{
    return mInstance->getRenderTarget(0);
}

void TextureStorageInterface2D::generateMipmap(int level)
{
    mInstance->generateMipmap(level);
}

unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLenum target) const
{
    return mRenderTargetSerial;
}

TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
    : mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
{
    mInstance = renderer->createTextureStorageCube(levels, internalformat, usage, forceRenderable, size);
}

TextureStorageInterfaceCube::~TextureStorageInterfaceCube()
{
}

RenderTarget *TextureStorageInterfaceCube::getRenderTarget(GLenum faceTarget) const
{
    return mInstance->getRenderTarget(faceTarget);
}

void TextureStorageInterfaceCube::generateMipmap(int face, int level)
{
    mInstance->generateMipmap(face, level);
}

unsigned int TextureStorageInterfaceCube::getRenderTargetSerial(GLenum target) const
{
    return mFirstRenderTargetSerial + gl::TextureCubeMap::faceIndex(target);
}

TextureStorageInterface3D::TextureStorageInterface3D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage,
                                                     GLsizei width, GLsizei height, GLsizei depth)
{
    mInstance = renderer->createTextureStorage3D(levels, internalformat, usage, width, height, depth);
}

TextureStorageInterface3D::~TextureStorageInterface3D()
{
}

void TextureStorageInterface3D::generateMipmap(int level)
{
    mInstance->generateMipmap(level);
}

unsigned int TextureStorageInterface3D::getRenderTargetSerial(GLenum target) const
{
    // TODO: 3D render targets not supported yet.
    return 0;
}

TextureStorageInterface2DArray::TextureStorageInterface2DArray(Renderer *renderer, int levels, GLenum internalformat, GLenum usage,
                                                               GLsizei width, GLsizei height, GLsizei depth)
{
    mInstance = renderer->createTextureStorage2DArray(levels, internalformat, usage, width, height, depth);
}

TextureStorageInterface2DArray::~TextureStorageInterface2DArray()
{
}

void TextureStorageInterface2DArray::generateMipmap(int level)
{
    mInstance->generateMipmap(level);
}

unsigned int TextureStorageInterface2DArray::getRenderTargetSerial(GLenum target) const
{
    return 0;
}

}
<commit_msg>Fix calling the right overloaded method for getting a cube map face's render target.<commit_after>#include "precompiled.h"
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// TextureStorage.cpp: Implements the abstract rx::TextureStorageInterface class and its concrete derived
// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the
// GPU-side texture.

#include "libGLESv2/renderer/TextureStorage.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h"

#include "common/debug.h"

namespace rx
{
unsigned int TextureStorageInterface::mCurrentTextureSerial = 1;

TextureStorageInterface::TextureStorageInterface()
    : mTextureSerial(issueTextureSerial()),
      mInstance(NULL)
{
}

TextureStorageInterface::~TextureStorageInterface()
{
    delete mInstance;
}

bool TextureStorageInterface::isRenderTarget() const
{
    return mInstance->isRenderTarget();
}

bool TextureStorageInterface::isManaged() const
{
    return mInstance->isManaged();
}

unsigned int TextureStorageInterface::getTextureSerial() const
{
    return mTextureSerial;
}

unsigned int TextureStorageInterface::issueTextureSerial()
{
    return mCurrentTextureSerial++;
}

int TextureStorageInterface::getLodOffset() const
{
    return mInstance->getLodOffset();
}

int TextureStorageInterface::levelCount()
{
    return mInstance->levelCount();
}

TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain)
    : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
{
    mInstance = renderer->createTextureStorage2D(swapchain);
}

TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
    : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
{
    mInstance = renderer->createTextureStorage2D(levels, internalformat, usage, forceRenderable, width, height);
}

TextureStorageInterface2D::~TextureStorageInterface2D()
{
}

RenderTarget *TextureStorageInterface2D::getRenderTarget() const
{
    return mInstance->getRenderTarget(0);
}

void TextureStorageInterface2D::generateMipmap(int level)
{
    mInstance->generateMipmap(level);
}

unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLenum target) const
{
    return mRenderTargetSerial;
}

TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
    : mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
{
    mInstance = renderer->createTextureStorageCube(levels, internalformat, usage, forceRenderable, size);
}

TextureStorageInterfaceCube::~TextureStorageInterfaceCube()
{
}

RenderTarget *TextureStorageInterfaceCube::getRenderTarget(GLenum faceTarget) const
{
    return mInstance->getRenderTarget(faceTarget, 0);
}

void TextureStorageInterfaceCube::generateMipmap(int face, int level)
{
    mInstance->generateMipmap(face, level);
}

unsigned int TextureStorageInterfaceCube::getRenderTargetSerial(GLenum target) const
{
    return mFirstRenderTargetSerial + gl::TextureCubeMap::faceIndex(target);
}

TextureStorageInterface3D::TextureStorageInterface3D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage,
                                                     GLsizei width, GLsizei height, GLsizei depth)
{
    mInstance = renderer->createTextureStorage3D(levels, internalformat, usage, width, height, depth);
}

TextureStorageInterface3D::~TextureStorageInterface3D()
{
}

void TextureStorageInterface3D::generateMipmap(int level)
{
    mInstance->generateMipmap(level);
}

unsigned int TextureStorageInterface3D::getRenderTargetSerial(GLenum target) const
{
    // TODO: 3D render targets not supported yet.
    return 0;
}

TextureStorageInterface2DArray::TextureStorageInterface2DArray(Renderer *renderer, int levels, GLenum internalformat, GLenum usage,
                                                               GLsizei width, GLsizei height, GLsizei depth)
{
    mInstance = renderer->createTextureStorage2DArray(levels, internalformat, usage, width, height, depth);
}

TextureStorageInterface2DArray::~TextureStorageInterface2DArray()
{
}

void TextureStorageInterface2DArray::generateMipmap(int level)
{
    mInstance->generateMipmap(level);
}

unsigned int TextureStorageInterface2DArray::getRenderTargetSerial(GLenum target) const
{
    return 0;
}

}
<|endoftext|>