<commit_before>#include "anime/FrameAnime.h"

using fei::FrameAnime;

FrameAnime::FrameAnime()
: curFrameIndex(0),
  fps(60.0f)
{
}

void FrameAnime::load(const fei::ImagePool& imagePool)
{
	framePool = imagePool;
	curFrameIndex = 0;
}

void FrameAnime::loadTextureAndSIP(const fei::Texture& texture, const std::string& sipName)
{
	framePool.loadTextureAndSIP(texture, sipName);
	curFrameIndex = 0;
}

void FrameAnime::load(const std::string& name)
{
	loadImageFileAndSIP(name + ".png", name + ".sip");
}

void FrameAnime::load(const std::string& name1, const std::string& name2)
{
	loadImageFileAndSIP(name1, name2);
}

void FrameAnime::loadImageFileAndSIP(const std::string& textureName, const std::string& sipName)
{
	fei::Texture tmpTex;
	tmpTex.load(textureName);
	loadTextureAndSIP(tmpTex, sipName);
}

void FrameAnime::loadImageFileAndIPI(const std::string& textureName, const std::string& ipiName)
{
	fei::Texture tmpTex;
	tmpTex.load(textureName);
	loadTextureAndIPI(tmpTex, ipiName);
}

void FrameAnime::loadTextureAndIPI(const fei::Texture& texture, const std::string& ipiName)
{
	framePool.loadTextureAndIPI(texture, ipiName);
	curFrameIndex = 0;
}

void FrameAnime::feiUpdate(fei::RenderObj* rObj)
{
	updateFrameIndex();
	updateFrameContent(rObj);
	update(rObj);
}

void FrameAnime::updateFrameIndex()
{
	if (isPlay()) {
		curFrameIndex += getFps() * getDeltaTime();
		if (curFrameIndex >= getFrameNum()) {
			if (isLoop()) {
				curFrameIndex = 0;
			} else {
				stop();
			}
		}
	}
}

void FrameAnime::updateFrameContent(fei::RenderObj* rObj)
{
	rObj->setSubstitute(nullptr);
	if (!isStop()) {
		fei::Image *image = framePool.getImage((int)curFrameIndex);
		rObj->setSubstitute(image);
	}
}

float FrameAnime::getFps()
{
	return fps;
}

void FrameAnime::setFps(float f)
{
	fps = f;
}

int FrameAnime::getFrameNum()
{
	return framePool.getImageNum();
}

int FrameAnime::getCurFrameIndex()
{
	return (int)curFrameIndex;
}

void FrameAnime::setCurFrameIndex(int cfi)
{
	curFrameIndex = cfi;
}

fei::ImagePool* FrameAnime::getFramePool()
{
	return &framePool;
}
<commit_msg>fix a anime bug<commit_after>#include "anime/FrameAnime.h"

using fei::FrameAnime;

FrameAnime::FrameAnime()
: curFrameIndex(0),
  fps(60.0f)
{
}

void FrameAnime::load(const fei::ImagePool& imagePool)
{
	framePool = imagePool;
	curFrameIndex = 0;
}

void FrameAnime::loadTextureAndSIP(const fei::Texture& texture, const std::string& sipName)
{
	framePool.loadTextureAndSIP(texture, sipName);
	curFrameIndex = 0;
}

void FrameAnime::load(const std::string& name)
{
	loadImageFileAndSIP(name + ".png", name + ".sip");
}

void FrameAnime::load(const std::string& name1, const std::string& name2)
{
	loadImageFileAndSIP(name1, name2);
}

void FrameAnime::loadImageFileAndSIP(const std::string& textureName, const std::string& sipName)
{
	fei::Texture tmpTex;
	tmpTex.load(textureName);
	loadTextureAndSIP(tmpTex, sipName);
}

void FrameAnime::loadImageFileAndIPI(const std::string& textureName, const std::string& ipiName)
{
	fei::Texture tmpTex;
	tmpTex.load(textureName);
	loadTextureAndIPI(tmpTex, ipiName);
}

void FrameAnime::loadTextureAndIPI(const fei::Texture& texture, const std::string& ipiName)
{
	framePool.loadTextureAndIPI(texture, ipiName);
	curFrameIndex = 0;
}

void FrameAnime::feiUpdate(fei::RenderObj* rObj)
{
	updateFrameIndex();
	updateFrameContent(rObj);
	update(rObj);
}

void FrameAnime::updateFrameIndex()
{
	if (isPlay()) {
		curFrameIndex += getFps() * getDeltaTime();
		if (curFrameIndex >= getFrameNum()) {
			curFrameIndex = 0;
			if (!isLoop()) {
				stop();
			}
		}
	}
}

void FrameAnime::updateFrameContent(fei::RenderObj* rObj)
{
	rObj->setSubstitute(nullptr);
	if (!isStop()) {
		fei::Image *image = framePool.getImage((int)curFrameIndex);
		rObj->setSubstitute(image);
	}
}

float FrameAnime::getFps()
{
	return fps;
}

void FrameAnime::setFps(float f)
{
	fps = f;
}

int FrameAnime::getFrameNum()
{
	return framePool.getImageNum();
}

int FrameAnime::getCurFrameIndex()
{
	return (int)curFrameIndex;
}

void FrameAnime::setCurFrameIndex(int cfi)
{
	curFrameIndex = cfi;
}

fei::ImagePool* FrameAnime::getFramePool()
{
	return &framePool;
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The Descent map loader
//
// NAME         : Hog
// PURPOSE      : Providing a decoder and wrapper for the Descent .HOG format.
// COPYRIGHT    : (c) 2011 Sean Donnellan. All Rights Reserved.
// AUTHORS      : Sean Donnellan (darkdonno@gmail.com)
// DESCRIPTION  : A decoder for the HOG file format that is used by Parallax
//                Software in the computer game, Descent.
//
//                The file format is as follows:
//
//                - Magic number which is 3 bytes and corresponding to the
//                  string "DHF"

//                - A series of files which are preceded by a short header,
//                  which describes the name of the file and the numer of bytes.
//
//                 | "DHF" - 3 bytes
//                 |---------------- Start of the first file
//                 | filename - 13 bytes
//                 | size - 4 bytes
//                 | data - the size of this part is by the size before it.
//                 |---------------- The next header/file comes straight after.
//                 | filename - 13 bytes
//                 | size - 4 bytes
//                 | data - the size of this part is by the size before it.
//
//===----------------------------------------------------------------------===//

/////
// Developer notes
// Different file formats: http://www.descent2.com/ddn/kb/files/
//
/////

#include <iterator>
#include <utility>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// The 3-byte MAGIC number at the start of the file format used to identifiy the
// file as being a Descent HOG file.
static char magic[3] = {'D', 'H', 'F'};

struct HogFileHeader
{
    char name[13]; // Padded to 13 bytes with \0.
    int size; // The filesize as N bytes.
};

// Warning: The above structure is padded on x86 so you can not just read in the
// whole thing.

// class File
// {
//   public File(FILE* file, int size);

// private:
//   // TODO: Consider storing a std::string of the filename.
//   int size;
//   unsigned char* myData;
// };

class HogReaderIterator;

class HogReader
{
public:
    typedef HogReaderIterator iterator;

    HogReader(const char* filename);
    ~HogReader();

    bool IsValid() const;
    // Returns true if the file was succesfully opened and the magic header is
    // correct.

    bool NextFile();

    const char* CurrentFileName() const;
    unsigned int CurrentFileSize() const;

    iterator begin();
    iterator end();

  unsigned char* operator *();

private:
    FILE* myFile;
    char myHeader[sizeof(magic)];
    struct HogFileHeader myChildFile;
};

class HogReaderIterator
{
public:
  typedef std::pair<const char*, unsigned int> value_type;

  HogReaderIterator()
    : myReader(NULL),
      myProgress(false)
    {
      myData.first = NULL;
      myData.second = 0;
    }

  HogReaderIterator( HogReader& Reader )
    :  myReader(&Reader),
       myProgress(Reader.IsValid())
    {
      myData.first = Reader.CurrentFileName();
      myData.second = Reader.CurrentFileSize();
    }
  // Itr(const Itr& o);                   // Copy constructor
  // Itr& operator=(const Itr& o);        // Assignment operator
  HogReaderIterator& operator++();                   // Next element
  value_type& operator*();                   // Dereference
  bool operator==(const HogReaderIterator& o) const; // Comparison
  bool operator!=(const HogReaderIterator& o) const; // { return !(this == o);

private:
  std::pair<const char*, unsigned int> myData;
  bool myProgress;
  HogReader* myReader;
};

HogReaderIterator& HogReaderIterator::operator++()
{
    // You can't increment the null so error.
    myProgress = myReader->NextFile();
    myData.first = myReader->CurrentFileName();
    myData.second = myReader->CurrentFileSize();
    return *this;
}

HogReaderIterator::value_type& HogReaderIterator::operator*()
{
  return myData;
}

bool HogReaderIterator::operator==(const HogReaderIterator& o) const
{
    if (myReader == o.myReader) return true;
    if (myReader && o.myReader)
    {
	return myData == o.myData;
    }
    return myProgress == o.myProgress;
}

bool HogReaderIterator::operator!=(const HogReaderIterator& o) const
{
    return !(*this == o);
}

HogReader::iterator HogReader::begin()
{
  // Sync back up to the start just after the magic number.
  if (IsValid())
  {
    fseek ( myFile , sizeof(magic) , SEEK_SET );
    if( fread( &myChildFile.name, 13, 1, myFile ) != 1 ) HogReaderIterator();
    if( fread( &myChildFile.size, 4, 1, myFile ) != 1 )  HogReaderIterator();
  }

  return HogReaderIterator(*this);
}

HogReader::iterator HogReader::end()
{
  return HogReaderIterator();
}

HogReader::HogReader(const char* filename)
: myFile(NULL)
{
    myFile = fopen( filename, "rb" );
    myChildFile.name[0] = '\0';
    myChildFile.size = 0;
    if( !myFile ) return;

    const size_t count = 1;
    if( fread(myHeader, sizeof(myHeader), count, myFile) != count )
    {
	myHeader[0] = '\0'; // Failed to load.
	return;
    }

    // Read in the header for the first file.
    if (IsValid())
    {
	if( fread( &myChildFile.name, 13, 1, myFile ) != 1 ) return;
	if( fread( &myChildFile.size, 4, 1, myFile ) != 1 ) return;
    }
}

HogReader::~HogReader()
{
    if (myFile) fclose(myFile);
}

bool HogReader::IsValid() const
{
    if( !myFile ) return false;
    return strncmp( myHeader, magic, 3 ) == 0;
}

bool HogReader::NextFile()
{
    // Skip the current file.
    if( feof(myFile) ) return false;
    if( fseek( myFile, myChildFile.size, SEEK_CUR ) != 0 ) return false;

    // Read in the header for the next file.
    if( fread( &myChildFile.name, 13, 1, myFile ) != 1 ) return false;
    if( fread( &myChildFile.size, 4, 1, myFile ) != 1 ) return false;

    return true;
}

const char* HogReader::CurrentFileName() const
{
    return myChildFile.name;
}

unsigned int HogReader::CurrentFileSize() const
{
    return myChildFile.size;
}

unsigned char* HogReader::operator *()
{

  unsigned char* data = new unsigned char[CurrentFileSize()];

  return data;
}

#include "rdl.cpp"

#include <string>
#include <algorithm>

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    printf("usage: %s filename\n", argv[0]);
    return 1;
  }

  HogReader reader(argv[1]);
  if (!reader.IsValid())
  {
    fprintf(stderr, "error to open the hog file");
    return 1;
  }

  // File list.

  const bool listingAllFiles = false;

  if (listingAllFiles)
  {
    std::for_each(
      reader.begin(), reader.end(),
      [](HogReader::iterator::value_type n)
      {
	printf("%s %d\n", n.first, n.second);
      });
  }
  else
  {
    // Iterate over the file list and list all the files which do not
    // end in the 'rdl' file extension.
    std::string extentionRdl(".sng");

    std::for_each(
      reader.begin(), reader.end(),
      [&extentionRdl](HogReader::iterator::value_type n)
      {
	std::string filename(n.first);
	if (!std::equal(extentionRdl.rbegin(),
			extentionRdl.rend(),
			filename.rbegin())) return;
	printf("%s %d\n", n.first, n.second);

	//RdlReader
      });

    std::for_each(
      reader.begin(), reader.end(),
      [&extentionRdl](HogReader::iterator::value_type n)
      {
	std::string filename(n.first);
	if (!std::equal(extentionRdl.rbegin(),
			extentionRdl.rend(),
			filename.rbegin())) return;
	printf("%s %d\n", n.first, n.second);

//	unsigned char* data = *(n.second);
//	printf("%c%c%c\n", data[0], data[1], data[2]);

	//RdlReader
      });
  }
  return 0;
}
<commit_msg>Now supports deferencing the reader to get the data for the current file. The file can be deferenced multiple times while the iterator is still valid.<commit_after>//===----------------------------------------------------------------------===//
//
//                     The Descent map loader
//
// NAME         : Hog
// PURPOSE      : Providing a decoder and wrapper for the Descent .HOG format.
// COPYRIGHT    : (c) 2011 Sean Donnellan. All Rights Reserved.
// AUTHORS      : Sean Donnellan (darkdonno@gmail.com)
// DESCRIPTION  : A decoder for the HOG file format that is used by Parallax
//                Software in the computer game, Descent.
//
//                The file format is as follows:
//
//                - Magic number which is 3 bytes and corresponding to the
//                  string "DHF"

//                - A series of files which are preceded by a short header,
//                  which describes the name of the file and the numer of bytes.
//
//                 | "DHF" - 3 bytes
//                 |---------------- Start of the first file
//                 | filename - 13 bytes
//                 | size - 4 bytes
//                 | data - the size of this part is by the size before it.
//                 |---------------- The next header/file comes straight after.
//                 | filename - 13 bytes
//                 | size - 4 bytes
//                 | data - the size of this part is by the size before it.
//
//===----------------------------------------------------------------------===//

/////
// Developer notes
// Different file formats: http://www.descent2.com/ddn/kb/files/
//
/////

#include <iterator>
#include <utility>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _MSC_VER
  typedef signed __int8     int8_t;
  typedef signed __int16    int16_t;
  typedef signed __int32    int32_t;
  typedef unsigned __int8   uint8_t;
  typedef unsigned __int16  uint16_t;
  typedef unsigned __int32  uint32_t;
#else
  #include <stdint.h>
#endif

static_assert( sizeof(uint8_t) == 1 , "The size of uint8_t is incorrect it must be 1-byte" );
static_assert( sizeof(uint32_t) == 4, "The size of uint32_t is incorrect it must be 4-bytes" );
static_assert( sizeof(uint8_t) == sizeof(char), "The size of a char must be 1-byte" );

// The 3-byte MAGIC number at the start of the file format used to identifiy the
// file as being a Descent HOG file.
static uint8_t magic[3] = {'D', 'H', 'F'};

struct HogFileHeader
{
  char name[13]; // Padded to 13 bytes with \0.
  uint32_t size; // The filesize as N bytes.
};

// Warning: The above structure is padded on x86 so you can not just read in the
// whole thing.

class HogReaderIterator;

class HogReader
{
public:
    typedef HogReaderIterator iterator;

    HogReader(const char* filename);
    ~HogReader();

    bool IsValid() const;
    // Returns true if the file was succesfully opened and the magic header is
    // correct.

    bool NextFile();

    const char* CurrentFileName() const;
    unsigned int CurrentFileSize() const;

    iterator begin();
    iterator end();

  unsigned char* operator *();
  // This increments to the next file.
  // DONE: Make it so it returns the same value if called multiple times.

private:
  FILE* myFile;
  uint8_t myHeader[sizeof(magic)];
  struct HogFileHeader myChildFile;
  uint8_t* myFileDataPtr; // Only valid when we are deferenced until the next read.
};

class HogReaderIterator
{
public:
  typedef std::pair<const char*, HogReader*> value_type;

  HogReaderIterator()
    : myReader(NULL),
      myProgress(false)
    {
      myData.first = NULL;
      myData.second = myReader;
    }

  HogReaderIterator( HogReader& Reader )
    :  myReader(&Reader),
       myProgress(Reader.IsValid())
    {
      myData.first = Reader.CurrentFileName();
      myData.second = myReader;
    }
  // Itr(const Itr& o);                   // Copy constructor
  // Itr& operator=(const Itr& o);        // Assignment operator
  HogReaderIterator& operator++();                   // Next element
  value_type& operator*();                   // Dereference
  bool operator==(const HogReaderIterator& o) const; // Comparison
  bool operator!=(const HogReaderIterator& o) const; // { return !(this == o);

private:
  value_type myData;
  bool myProgress;
  HogReader* myReader;
};

HogReaderIterator& HogReaderIterator::operator++()
{
    // You can't increment the null so error.
    myProgress = myReader->NextFile();
    myData.first = myReader->CurrentFileName();

    // myData.second == myReader.
    //myData.second = myReader->CurrentFileSize();
    return *this;
}

HogReaderIterator::value_type& HogReaderIterator::operator*()
{
  return myData;
}

bool HogReaderIterator::operator==(const HogReaderIterator& o) const
{
    if (myReader == o.myReader) return true;
    if (myReader && o.myReader)
    {
	return myData == o.myData;
    }
    return myProgress == o.myProgress;
}

bool HogReaderIterator::operator!=(const HogReaderIterator& o) const
{
    return !(*this == o);
}

HogReader::iterator HogReader::begin()
{
  // Sync back up to the start just after the magic number.
  if (IsValid())
  {
    fseek ( myFile , sizeof(magic) , SEEK_SET );
    if( fread( &myChildFile.name, 13, 1, myFile ) != 1 ) HogReaderIterator();
    if( fread( &myChildFile.size, 4, 1, myFile ) != 1 )  HogReaderIterator();
  }

  return HogReaderIterator(*this);
}

HogReader::iterator HogReader::end()
{
  return HogReaderIterator();
}

HogReader::HogReader(const char* filename)
  : myFile(NULL),
    myFileDataPtr(NULL)
{
    myFile = fopen( filename, "rb" );
    myChildFile.name[0] = '\0';
    myChildFile.size = 0;
    if( !myFile ) return;

    const size_t count = 1;
    if( fread(myHeader, sizeof(myHeader), count, myFile) != count )
    {
	myHeader[0] = '\0'; // Failed to load.
	return;
    }

    // Read in the header for the first file.
    if (IsValid())
    {
	if( fread( &myChildFile.name, 13, 1, myFile ) != 1 ) return;
	if( fread( &myChildFile.size, 4, 1, myFile ) != 1 ) return;
    }
}

HogReader::~HogReader()
{
    if (myFile) fclose(myFile);
}

bool HogReader::IsValid() const
{
    if( !myFile ) return false;
    return memcmp( myHeader, magic, 3 ) == 0;
}

bool HogReader::NextFile()
{
    // Skip the current file.
    if( feof(myFile) ) return false;

    if (myFileDataPtr)
    {
      // The data for the current file has already been read in and the header for
      // the next file has already been read.
      myFileDataPtr = NULL;
      return true;
    }

    // Skip of the data for the current file.
    if( fseek( myFile, myChildFile.size, SEEK_CUR ) != 0 ) return false;

    // Read in the header for the next file.
    if( fread( &myChildFile.name, 13, 1, myFile ) != 1 ) return false;
    if( fread( &myChildFile.size, 4, 1, myFile ) != 1 ) return false;

    return true;
}

const char* HogReader::CurrentFileName() const
{
    return myChildFile.name;
}

unsigned int HogReader::CurrentFileSize() const
{
    return myChildFile.size;
}

unsigned char* HogReader::operator *()
{
  if( myFileDataPtr )
  {
    // The current file has already be de-ferenced so just return it.
    return myFileDataPtr;
  }

  // Skip the current file.
  if( feof(myFile) ) return NULL;

  const unsigned int size = CurrentFileSize();

  uint8_t* data = new unsigned char[size];

  if( fread( data, size, 1, myFile ) != 1 ) return NULL;

  // The data is read so we need to inform the NextFile function not to increment.
  myFileDataPtr = data;

  // Read in the header for the next file.
  fread( &myChildFile.name, 13, 1, myFile );
  fread( &myChildFile.size, 4, 1, myFile );

  return data;
}

#include "rdl.cpp"

#include <string>
#include <algorithm>

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    printf("usage: %s filename\n", argv[0]);
    return 1;
  }

  HogReader reader(argv[1]);
  if (!reader.IsValid())
  {
    fprintf(stderr, "error to open the hog file");
    return 1;
  }

  // File list.

  const bool listingAllFiles = false;

  if (listingAllFiles)
  {
    std::for_each(
      reader.begin(), reader.end(),
      [](HogReader::iterator::value_type n)
      {
	printf("%s %d\n", n.first, n.second);
      });
  }
  else
  {
    // Iterate over the file list and list all the files which do not
    // end in the 'rdl' file extension.
    std::string extentionRdl(".rdl");

    std::for_each(
      reader.begin(), reader.end(),
      [&extentionRdl](HogReader::iterator::value_type n)
      {
	std::string filename(n.first);
	if (!std::equal(extentionRdl.rbegin(),
			extentionRdl.rend(),
			filename.rbegin())) return;

       	printf("%s %d\n", n.first, n.second->CurrentFileSize());
	unsigned char* data = **(n.second);
	printf("%c%c%c\n", data[0], data[1], data[2]);

	delete[] data;
      });

    // std::for_each(
    //   reader.begin(), reader.end(),
    //   [&extentionRdl](HogReader::iterator::value_type n)
    //   {
    // 	std::string filename(n.first);
    // 	if (!std::equal(extentionRdl.rbegin(),
    // 			extentionRdl.rend(),
    // 			filename.rbegin())) return;
    // 	printf("%s %d\n", n.first, n.second->CurrentFileSize());
    //   });
  }
  return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

//============implete a int Stack.==========
class intStack{
    private:
        int num[100];
        int length;
    public:
        void push(int i);
        int pop();
        intStack();
};

intStack::intStack(void){
    length=0;
}

void intStack::push(int i){
    if(length==100){
        cout << "intStack is full.\n";
    }else{
        num[length]=i;
        length++;
    }
}
int intStack::pop (){
    if(length==0){
        cout << "intStack is empty.\n";
        return -1;
    }
    return num[--length];
}
//============implete a int Stack.==========

//============MyString=========
class MyString{
    private:
        int length;
        char C[100];
    public:
        MyString();
        void debug();
        char* varC();
        void dump();
        void set(char *CC);
        void push(char CC);
        int getLength();
        char* getString();
        int find(MyString subject);

};
MyString::MyString(void){
    length=0;
}
void MyString::debug(){
    printf("length:%d\n" ,length);
    dump();
}
char* MyString::varC(){
    return C;
}
void MyString::dump(){
    for(int i=0; i<length; i++){
        printf("%c",C[i]);
    }
    printf("\n");
}

void MyString::push(char CC){
    C[length]=CC;
    length++;
}
int MyString::getLength(){
    return length;
}
char* MyString::getString(){
    char *tmp;
    tmp=C;
    tmp[length]='\n';
    return tmp;
}
int MyString::find(MyString subject) { // return found index , -1 means not found.
    int subi=0; //substring index
    bool found=false;
    char *subjectC=subject.varC();
    for(int stri=0; stri< this->getLength(); stri++){
        //scan every entry of C;
        if(found==true && subi==subject.getLength()){
            return stri-subject.getLength();
        }else{
            if(C[stri]==subjectC[subi]){
                found=true;
                subi++;
            }else{
                found=false;
                subi=0;
            }
        }
    }

    return -1;
}
//==========MyString========
int main() {
    MyString str;
    cout << "Hello! Please input string S first>>";
    char tmp;
    while(scanf("%c" , &tmp)){
        if(tmp=='\n'){
            break;
        }else{
            str.push(tmp);
        }
    }

    cout << "Please input string str which will find in S>>";
    MyString tofind;
    while(scanf("%c" , &tmp)){
        if(tmp=='\n'){
            break;
        }else{
            tofind.push(tmp);
        }
    }
    printf("%d" , str.find(tofind));
    return 0;
}
<commit_msg>MyString support find with start<commit_after>#include <iostream>
using namespace std;

//============implete a int Stack.==========
class intStack{
    private:
        int num[100];
        int length;
    public:
        void push(int i);
        int pop();
        intStack();
};

intStack::intStack(void){
    length=0;
}

void intStack::push(int i){
    if(length==100){
        cout << "intStack is full.\n";
    }else{
        num[length]=i;
        length++;
    }
}
int intStack::pop (){
    if(length==0){
        cout << "intStack is empty.\n";
        return -1;
    }
    return num[--length];
}

//============implete a int Stack.==========

//============MyString=========
class MyString{
    private:
        int length;
        char C[100];
    public:
        MyString();
        void debug();
        char* varC();
        void dump();
        void set(char *CC);
        void push(char CC);
        int getLength();
        char* getString();
        int find(MyString subject , int Start);

};
MyString::MyString(void){
    length=0;
}
void MyString::debug(){
    printf("length:%d\n" ,length);
    dump();
}
char* MyString::varC(){
    return C;
}
void MyString::dump(){
    for(int i=0; i<length; i++){
        printf("%c",C[i]);
    }
    printf("\n");
}

void MyString::push(char CC){
    C[length]=CC;
    length++;
}
int MyString::getLength(){
    return length;
}
char* MyString::getString(){
    char *tmp;
    tmp=C;
    tmp[length]='\n';
    return tmp;
}
int MyString::find(MyString subject ,int start) { // return found index , -1 means not found.
    int subi=0; //substring index
    bool found=false;
    char *subjectC=subject.varC();

    for(int stri=start; stri< this->getLength(); stri++){
        //scan every entry of C;
        if(found==true && subi==subject.getLength()){
            return stri-subject.getLength();
            // intStack.push(stri-subject.getLength());
        }else{
            if(C[stri]==subjectC[subi]){
                found=true;
                subi++;
            }else{
                found=false;
                subi=0;
            }
        }
    }
    return -1;
}
//==========MyString========
int main() {

    MyString str;
    cout << "Hello! Please input string S first>>";
    char tmp;
    while(scanf("%c" , &tmp)){
        if(tmp=='\n'){
            break;
        }else{
            str.push(tmp);
        }
    }

    cout << "Please input string str which will find in S>>";
    MyString tofind;
    while(scanf("%c" , &tmp)){
        if(tmp=='\n'){
            break;
        }else{
            tofind.push(tmp);
        }
    }

    printf("%d" , str.find(tofind,5));
    return 0;
}

<|endoftext|>


<commit_before>/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 *
 *  Gearmand client and server library.
 *
 *  Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
 *  Copyright (C) 2008 Brian Aker, Eric Day
 *  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.
 *
 *      * The names of its contributors may not 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.
 *
 */

/**
 * @file
 * @brief libmemcached Queue Storage Definitions
 */

#include "gear_config.h"

#include <libgearman-server/common.h>

#include <libgearman-server/plugins/queue/base.h>
#include <libgearman-server/plugins/queue/libmemcached/queue.h>
#include <libmemcached/memcached.h>

#include "libgearman-server/log.h"

#include <cerrno>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"

using namespace gearmand;

/**
 * @addtogroup gearmand::plugins::queue::Libmemcachedatic Static libmemcached Queue Storage Functions
 * @ingroup gearman_queue_libmemcached
 * @{
 */

/**
 * Default values.
 */
#define GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX "gear_"

namespace gearmand { namespace plugins { namespace queue { class Libmemcached;  }}}

namespace gearmand {
namespace queue {

class LibmemcachedQueue : public gearmand::queue::Context
{
public:
  LibmemcachedQueue(plugins::queue::Libmemcached*, memcached_server_st* servers) :
    memc_(NULL)
  {
    memc_= memcached_create(NULL);

    memcached_server_push(memc_, servers);
  }

  bool init()
  {
    return bool(bool(memc_) and memcached_server_count(memc_));
  }

  ~LibmemcachedQueue()
  {
    memcached_free(memc_);
    memc_= NULL;
  }

  gearmand_error_t add(gearman_server_st *server,
                       const char *unique, size_t unique_size,
                       const char *function_name, size_t function_name_size,
                       const void *data, size_t data_size,
                       gearman_job_priority_t priority,
                       int64_t when);

  gearmand_error_t flush(gearman_server_st *server);

  gearmand_error_t done(gearman_server_st *server,
                        const char *unique, size_t unique_size,
                        const char *function_name, size_t function_name_size);

  gearmand_error_t replay(gearman_server_st *server);

private:
  memcached_st* memc_;
};

} // namespace queue
} // namespace gearmand

namespace gearmand {
namespace plugins {
namespace queue {

class Libmemcached : public gearmand::plugins::Queue {
public:
  Libmemcached ();
  ~Libmemcached ();

  gearmand_error_t initialize();

  std::string server_list;
private:

};

Libmemcached::Libmemcached() :
  Queue("libmemcached")
{
  command_line_options().add_options()
    ("libmemcached-servers", boost::program_options::value(&server_list), "List of Memcached servers to use.");
}

Libmemcached::~Libmemcached()
{
}

gearmand_error_t Libmemcached::initialize()
{
  gearmand_info("Initializing libmemcached module");

  memcached_server_st *servers= memcached_servers_parse(server_list.c_str());
  if (servers == NULL)
  {
    return gearmand_gerror("memcached_servers_parse", GEARMAND_QUEUE_ERROR);
  }

  gearmand::queue::LibmemcachedQueue* exec_queue= new gearmand::queue::LibmemcachedQueue(this, servers);
  if (exec_queue and exec_queue->init())
  {
    gearman_server_set_queue(Gearmand()->server, exec_queue);

    memcached_server_list_free(servers);

    return GEARMAND_SUCCESS;
  }

  return gearmand_gerror("Libmemcached::initialize()", GEARMAND_QUEUE_ERROR);
}

void initialize_libmemcached()
{
  static Libmemcached local_instance;
}

} // namespace queue
} // namespace plugins
} // namespace gearmand

/* Queue callback functions. */

namespace gearmand {
namespace queue {

gearmand_error_t LibmemcachedQueue::add(gearman_server_st *server,
                                        const char *unique,
                                        size_t unique_size,
                                        const char *function_name,
                                        size_t function_name_size,
                                        const void *data, size_t data_size,
                                        gearman_job_priority_t priority,
                                        int64_t when)
{
  if (when) // No support for EPOCH jobs
  {
    return gearmand_gerror("libmemcached queue does not support epoch jobs", GEARMAND_QUEUE_ERROR);
  }

  (void)server;

  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "libmemcached add: %.*s", (uint32_t)unique_size, (char *)unique);

  char key[MEMCACHED_MAX_KEY];
  size_t key_length= (size_t)snprintf(key, MEMCACHED_MAX_KEY, "%s%.*s-%.*s",
                                      GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX,
                                      (int)function_name_size,
                                      (const char *)function_name, (int)unique_size,
                                      (const char *)unique);

  memcached_return rc= memcached_set(memc_, (const char *)key, key_length,
                                     (const char *)data, data_size, 0, (uint32_t)priority);

  if (rc != MEMCACHED_SUCCESS)
  {
    return gearmand_gerror(memcached_last_error_message(memc_), GEARMAND_QUEUE_ERROR);
  }

  return GEARMAND_SUCCESS;
}

gearmand_error_t LibmemcachedQueue::flush(gearman_server_st *)
{
  gearmand_debug("libmemcached flush");

  return GEARMAND_SUCCESS;
}

gearmand_error_t LibmemcachedQueue::done(gearman_server_st*,
                                         const char *unique, size_t unique_size,
                                         const char *function_name, size_t function_name_size)
{
  char key[MEMCACHED_MAX_KEY];

  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "libmemcached done: %.*s", (uint32_t)unique_size, (char *)unique);

  size_t key_length= (size_t)snprintf(key, MEMCACHED_MAX_KEY, "%s%.*s-%.*s",
                                      GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX,
                                      (int)function_name_size,
                                      (const char *)function_name, (int)unique_size,
                                      (const char *)unique);

  /* For the moment we will assume it happened */
  memcached_return rc= memcached_delete(memc_, (const char *)key, key_length, 0);
  if (rc != MEMCACHED_SUCCESS)
  {
    return gearmand_gerror(memcached_last_error_message(memc_), GEARMAND_QUEUE_ERROR);
  }

  return GEARMAND_SUCCESS;
}

class Replay
{
public:
  Replay(gearman_server_st* server_arg, memcached_st* _memc) :
    server_(server_arg),
    memc_(NULL)
  {
    memc_= memcached_clone(NULL, _memc);
  }

  ~Replay()
  {
    memcached_free(memc_);
    memc_= NULL;
  }

  bool init()
  {
    return bool(memc_);
  }

  memcached_st* memc()
  {
    assert(memc_);
    return memc_;
  }

  gearman_server_st* server()
  {
    return server_;
  }

private:
  gearman_server_st* server_;
  memcached_st* memc_;
};

static memcached_return callback_loader(const memcached_st*,
                                        memcached_result_st* result,
                                        void *context)
{
  Replay* replay= (Replay*)context;

  const char *key= memcached_result_key_value(result);
  if (strncmp(key, GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX, strlen(GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX)) != 0)
  {
    gearmand_debug("memcached key did not match GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX");
    return MEMCACHED_SUCCESS;
  }

  const char* function= key +strlen(GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX);

  const char* unique= index(function, '-');
  if (unique == NULL)
  {
    gearmand_debug("memcached key was malformed was not found");
    return MEMCACHED_SUCCESS;
  }

  size_t function_len= size_t(unique -function);
  unique++;
  size_t unique_size= strlen(unique);

  assert(unique);
  assert(unique_size);
  assert(function);
  assert(function_len);

  /* need to make a copy here ... gearman_server_job_free will free it later */
  char* data= (char*)malloc(memcached_result_length(result));
  if (data == NULL)
  {
    gearmand_perror(errno, "malloc");
    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
  }
  memcpy(data, memcached_result_value(result), memcached_result_length(result));

  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "libmemcached replay_add: %.*s", (uint32_t)unique_size, (char *)unique);

  /* Currently not looking at failure cases */
  LibmemcachedQueue::replay_add(replay->server(),
                                NULL,
                                unique, unique_size,
                                function, function_len,
                                data, memcached_result_length(result),
                                static_cast<gearman_job_priority_t>(memcached_result_flags(result)), int64_t(0));

  return MEMCACHED_SUCCESS;
}

/* Grab the object and load it into the loader */
static memcached_return callback_for_key(const memcached_st*,
                                         const char *key, size_t key_length,
                                         void *context)
{
  Replay* replay= (Replay*)context;
  memcached_execute_function callbacks[1];
  char *passable[1];

  callbacks[0]= (memcached_execute_fn)&callback_loader;

  passable[0]= (char *)key;
  if (memcached_success(memcached_mget(replay->memc(), passable, &key_length, 1)))
  {
    gearmand_debug(memcached_last_error_message(replay->memc()));
  }

  /* Just void errors for the moment, since other treads might have picked up the object. */
  (void)memcached_fetch_execute(replay->memc(), callbacks, replay, 1);

  return MEMCACHED_SUCCESS;
}

/*
  If we have any failures for loading values back into replay we just ignore them.
*/
gearmand_error_t LibmemcachedQueue::replay(gearman_server_st *server)
{
  memcached_dump_func callbacks[1];

  callbacks[0]= (memcached_dump_fn)&callback_for_key;

  gearmand_debug("libmemcached replay start");

  memcached_st* local_clone= memcached_clone(NULL, memc_);

  if (local_clone)
  {
    Replay replay_exec(server, memc_);

    if (replay_exec.init())
    {
      (void)memcached_dump(local_clone, callbacks, (void *)&replay_exec, 1);
    }
    else
    {
      gearmand_debug("libmemcached failed to init() Replay");
    }
    memcached_free(local_clone);
    local_clone= NULL;
  }
  gearmand_debug("libmemcached replay stop");

  return GEARMAND_SUCCESS;
}

} // queue
} // gearmand

#pragma GCC diagnostic pop
<commit_msg>Use C++11 nullptr instead of macro NULL<commit_after>/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 *
 *  Gearmand client and server library.
 *
 *  Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
 *  Copyright (C) 2008 Brian Aker, Eric Day
 *  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.
 *
 *      * The names of its contributors may not 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.
 *
 */

/**
 * @file
 * @brief libmemcached Queue Storage Definitions
 */

#include "gear_config.h"

#include <libgearman-server/common.h>

#include <libgearman-server/plugins/queue/base.h>
#include <libgearman-server/plugins/queue/libmemcached/queue.h>
#include <libmemcached/memcached.h>

#include "libgearman-server/log.h"

#include <cerrno>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"

using namespace gearmand;

/**
 * @addtogroup gearmand::plugins::queue::Libmemcachedatic Static libmemcached Queue Storage Functions
 * @ingroup gearman_queue_libmemcached
 * @{
 */

/**
 * Default values.
 */
#define GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX "gear_"

namespace gearmand { namespace plugins { namespace queue { class Libmemcached;  }}}

namespace gearmand {
namespace queue {

class LibmemcachedQueue : public gearmand::queue::Context
{
public:
  LibmemcachedQueue(plugins::queue::Libmemcached*, memcached_server_st* servers) :
    memc_(nullptr)
  {
    memc_= memcached_create(nullptr);

    memcached_server_push(memc_, servers);
  }

  bool init()
  {
    return bool(bool(memc_) and memcached_server_count(memc_));
  }

  ~LibmemcachedQueue()
  {
    memcached_free(memc_);
    memc_= nullptr;
  }

  gearmand_error_t add(gearman_server_st *server,
                       const char *unique, size_t unique_size,
                       const char *function_name, size_t function_name_size,
                       const void *data, size_t data_size,
                       gearman_job_priority_t priority,
                       int64_t when);

  gearmand_error_t flush(gearman_server_st *server);

  gearmand_error_t done(gearman_server_st *server,
                        const char *unique, size_t unique_size,
                        const char *function_name, size_t function_name_size);

  gearmand_error_t replay(gearman_server_st *server);

private:
  memcached_st* memc_;
};

} // namespace queue
} // namespace gearmand

namespace gearmand {
namespace plugins {
namespace queue {

class Libmemcached : public gearmand::plugins::Queue {
public:
  Libmemcached ();
  ~Libmemcached ();

  gearmand_error_t initialize();

  std::string server_list;
private:

};

Libmemcached::Libmemcached() :
  Queue("libmemcached")
{
  command_line_options().add_options()
    ("libmemcached-servers", boost::program_options::value(&server_list), "List of Memcached servers to use.");
}

Libmemcached::~Libmemcached()
{
}

gearmand_error_t Libmemcached::initialize()
{
  gearmand_info("Initializing libmemcached module");

  memcached_server_st *servers= memcached_servers_parse(server_list.c_str());
  if (!servers)
  {
    return gearmand_gerror("memcached_servers_parse", GEARMAND_QUEUE_ERROR);
  }

  gearmand::queue::LibmemcachedQueue* exec_queue= new gearmand::queue::LibmemcachedQueue(this, servers);
  if (exec_queue and exec_queue->init())
  {
    gearman_server_set_queue(Gearmand()->server, exec_queue);

    memcached_server_list_free(servers);

    return GEARMAND_SUCCESS;
  }

  return gearmand_gerror("Libmemcached::initialize()", GEARMAND_QUEUE_ERROR);
}

void initialize_libmemcached()
{
  static Libmemcached local_instance;
}

} // namespace queue
} // namespace plugins
} // namespace gearmand

/* Queue callback functions. */

namespace gearmand {
namespace queue {

gearmand_error_t LibmemcachedQueue::add(gearman_server_st *server,
                                        const char *unique,
                                        size_t unique_size,
                                        const char *function_name,
                                        size_t function_name_size,
                                        const void *data, size_t data_size,
                                        gearman_job_priority_t priority,
                                        int64_t when)
{
  if (when) // No support for EPOCH jobs
  {
    return gearmand_gerror("libmemcached queue does not support epoch jobs", GEARMAND_QUEUE_ERROR);
  }

  (void)server;

  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "libmemcached add: %.*s", (uint32_t)unique_size, (char *)unique);

  char key[MEMCACHED_MAX_KEY];
  size_t key_length= (size_t)snprintf(key, MEMCACHED_MAX_KEY, "%s%.*s-%.*s",
                                      GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX,
                                      (int)function_name_size,
                                      (const char *)function_name, (int)unique_size,
                                      (const char *)unique);

  memcached_return rc= memcached_set(memc_, (const char *)key, key_length,
                                     (const char *)data, data_size, 0, (uint32_t)priority);

  if (rc != MEMCACHED_SUCCESS)
  {
    return gearmand_gerror(memcached_last_error_message(memc_), GEARMAND_QUEUE_ERROR);
  }

  return GEARMAND_SUCCESS;
}

gearmand_error_t LibmemcachedQueue::flush(gearman_server_st *)
{
  gearmand_debug("libmemcached flush");

  return GEARMAND_SUCCESS;
}

gearmand_error_t LibmemcachedQueue::done(gearman_server_st*,
                                         const char *unique, size_t unique_size,
                                         const char *function_name, size_t function_name_size)
{
  char key[MEMCACHED_MAX_KEY];

  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "libmemcached done: %.*s", (uint32_t)unique_size, (char *)unique);

  size_t key_length= (size_t)snprintf(key, MEMCACHED_MAX_KEY, "%s%.*s-%.*s",
                                      GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX,
                                      (int)function_name_size,
                                      (const char *)function_name, (int)unique_size,
                                      (const char *)unique);

  /* For the moment we will assume it happened */
  memcached_return rc= memcached_delete(memc_, (const char *)key, key_length, 0);
  if (rc != MEMCACHED_SUCCESS)
  {
    return gearmand_gerror(memcached_last_error_message(memc_), GEARMAND_QUEUE_ERROR);
  }

  return GEARMAND_SUCCESS;
}

class Replay
{
public:
  Replay(gearman_server_st* server_arg, memcached_st* _memc) :
    server_(server_arg),
    memc_(nullptr)
  {
    memc_= memcached_clone(nullptr, _memc);
  }

  ~Replay()
  {
    memcached_free(memc_);
    memc_= nullptr;
  }

  bool init()
  {
    return bool(memc_);
  }

  memcached_st* memc()
  {
    assert(memc_);
    return memc_;
  }

  gearman_server_st* server()
  {
    return server_;
  }

private:
  gearman_server_st* server_;
  memcached_st* memc_;
};

static memcached_return callback_loader(const memcached_st*,
                                        memcached_result_st* result,
                                        void *context)
{
  Replay* replay= (Replay*)context;

  const char *key= memcached_result_key_value(result);
  if (strncmp(key, GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX, strlen(GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX)) != 0)
  {
    gearmand_debug("memcached key did not match GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX");
    return MEMCACHED_SUCCESS;
  }

  const char* function= key +strlen(GEARMAND_QUEUE_LIBMEMCACHED_DEFAULT_PREFIX);

  const char* unique= index(function, '-');
  if (!unique)
  {
    gearmand_debug("memcached key was malformed was not found");
    return MEMCACHED_SUCCESS;
  }

  size_t function_len= size_t(unique -function);
  unique++;
  size_t unique_size= strlen(unique);

  assert(unique);
  assert(unique_size);
  assert(function);
  assert(function_len);

  /* need to make a copy here ... gearman_server_job_free will free it later */
  char* data= (char*)malloc(memcached_result_length(result));
  if (!data)
  {
    gearmand_perror(errno, "malloc");
    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
  }
  memcpy(data, memcached_result_value(result), memcached_result_length(result));

  gearmand_log_debug(GEARMAN_DEFAULT_LOG_PARAM, "libmemcached replay_add: %.*s", (uint32_t)unique_size, (char *)unique);

  /* Currently not looking at failure cases */
  LibmemcachedQueue::replay_add(replay->server(),
                                nullptr,
                                unique, unique_size,
                                function, function_len,
                                data, memcached_result_length(result),
                                static_cast<gearman_job_priority_t>(memcached_result_flags(result)), int64_t(0));

  return MEMCACHED_SUCCESS;
}

/* Grab the object and load it into the loader */
static memcached_return callback_for_key(const memcached_st*,
                                         const char *key, size_t key_length,
                                         void *context)
{
  Replay* replay= (Replay*)context;
  memcached_execute_function callbacks[1];
  char *passable[1];

  callbacks[0]= (memcached_execute_fn)&callback_loader;

  passable[0]= (char *)key;
  if (memcached_success(memcached_mget(replay->memc(), passable, &key_length, 1)))
  {
    gearmand_debug(memcached_last_error_message(replay->memc()));
  }

  /* Just void errors for the moment, since other treads might have picked up the object. */
  (void)memcached_fetch_execute(replay->memc(), callbacks, replay, 1);

  return MEMCACHED_SUCCESS;
}

/*
  If we have any failures for loading values back into replay we just ignore them.
*/
gearmand_error_t LibmemcachedQueue::replay(gearman_server_st *server)
{
  memcached_dump_func callbacks[1];

  callbacks[0]= (memcached_dump_fn)&callback_for_key;

  gearmand_debug("libmemcached replay start");

  memcached_st* local_clone= memcached_clone(nullptr, memc_);

  if (local_clone)
  {
    Replay replay_exec(server, memc_);

    if (replay_exec.init())
    {
      (void)memcached_dump(local_clone, callbacks, (void *)&replay_exec, 1);
    }
    else
    {
      gearmand_debug("libmemcached failed to init() Replay");
    }
    memcached_free(local_clone);
    local_clone= nullptr;
  }
  gearmand_debug("libmemcached replay stop");

  return GEARMAND_SUCCESS;
}

} // queue
} // gearmand

#pragma GCC diagnostic pop
<|endoftext|>


<commit_before>/**
 * @file llfloatersounddevices.cpp
 * @author Leyla Farazha
 * @brief Sound Preferences used for minimal skin
 *
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
#include "llviewerprecompiledheaders.h"

#include "llfloatersounddevices.h"

#include "llbottomtray.h"
#include "lldraghandle.h"

#include "llpanelvoicedevicesettings.h"

// Library includes
#include "indra_constants.h"

// protected
LLFloaterSoundDevices::LLFloaterSoundDevices(const LLSD& key)
:	LLTransientDockableFloater(NULL, false, key)
{
	LLTransientFloaterMgr::getInstance()->addControlView(this);

	// force docked state since this floater doesn't save it between recreations
	setDocked(true);
}

LLFloaterSoundDevices::~LLFloaterSoundDevices()
{
	LLTransientFloaterMgr::getInstance()->removeControlView(this);
}

// virtual
BOOL LLFloaterSoundDevices::postBuild()
{
	LLTransientDockableFloater::postBuild();

	LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_flyout_btn");
	setDockControl(new LLDockControl(anchor_panel, this, getDockTongue(), LLDockControl::TOP));

	setIsChrome(TRUE);
	if (mDragHandle)
		mDragHandle->setTitleVisible(TRUE);
	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)

	return TRUE;
}

//virtual
void LLFloaterSoundDevices::setDocked(bool docked, bool pop_on_undock/* = true*/)
{
	LLTransientDockableFloater::setDocked(docked, pop_on_undock);
}

// virtual
void LLFloaterSoundDevices::setFocus( BOOL b )
{
	LLTransientDockableFloater::setFocus(b);

	// Force using active floater transparency
	// We have to override setFocus() for because selecting an item of the
	// combobox causes the floater to lose focus and thus become transparent.
	updateTransparency(TT_ACTIVE);
}<commit_msg>adding newline at end of llfloatersounddevices.cpp<commit_after>/**
 * @file llfloatersounddevices.cpp
 * @author Leyla Farazha
 * @brief Sound Preferences used for minimal skin
 *
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
#include "llviewerprecompiledheaders.h"

#include "llfloatersounddevices.h"

#include "llbottomtray.h"
#include "lldraghandle.h"

#include "llpanelvoicedevicesettings.h"

// Library includes
#include "indra_constants.h"

// protected
LLFloaterSoundDevices::LLFloaterSoundDevices(const LLSD& key)
:	LLTransientDockableFloater(NULL, false, key)
{
	LLTransientFloaterMgr::getInstance()->addControlView(this);

	// force docked state since this floater doesn't save it between recreations
	setDocked(true);
}

LLFloaterSoundDevices::~LLFloaterSoundDevices()
{
	LLTransientFloaterMgr::getInstance()->removeControlView(this);
}

// virtual
BOOL LLFloaterSoundDevices::postBuild()
{
	LLTransientDockableFloater::postBuild();

	LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_flyout_btn");
	setDockControl(new LLDockControl(anchor_panel, this, getDockTongue(), LLDockControl::TOP));

	setIsChrome(TRUE);
	if (mDragHandle)
		mDragHandle->setTitleVisible(TRUE);
	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)

	return TRUE;
}

//virtual
void LLFloaterSoundDevices::setDocked(bool docked, bool pop_on_undock/* = true*/)
{
	LLTransientDockableFloater::setDocked(docked, pop_on_undock);
}

// virtual
void LLFloaterSoundDevices::setFocus( BOOL b )
{
	LLTransientDockableFloater::setFocus(b);

	// Force using active floater transparency
	// We have to override setFocus() for because selecting an item of the
	// combobox causes the floater to lose focus and thus become transparent.
	updateTransparency(TT_ACTIVE);
}
<|endoftext|>


<commit_before>/*
 * Copyright 2008 Stephen Liu
 * For license terms, see the file COPYING along with this library.
 */

#ifndef __spporting_hpp__
#define __spporting_hpp__

#ifdef WIN32

#include "spwin32port.hpp"

#else

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/time.h>

#define sp_syslog      syslog
#define sp_openlog     openlog
#define sp_closelog    closelog

#define sp_inet_aton    inet_aton
#define sp_close        close
#define sp_writev       writev
#define sp_socketpair   socketpair
#define sp_gettimeofday gettimeofday

inline int sp_initsock()
{
	return 0;
}

#endif

#endif
<commit_msg>add include header files for FreeBSD<commit_after>/*
 * Copyright 2008 Stephen Liu
 * For license terms, see the file COPYING along with this library.
 */

#ifndef __spporting_hpp__
#define __spporting_hpp__

#ifdef WIN32

#include "spwin32port.hpp"

#else

#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/time.h>

#define sp_syslog      syslog
#define sp_openlog     openlog
#define sp_closelog    closelog

#define sp_inet_aton    inet_aton
#define sp_close        close
#define sp_writev       writev
#define sp_socketpair   socketpair
#define sp_gettimeofday gettimeofday

inline int sp_initsock()
{
	return 0;
}

#endif

#endif
<|endoftext|>


<commit_before>#include <fuse_lowlevel.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <algorithm>
#include <sdk/bfs.h>

baidu::bfs::FS* g_fs;
std::string g_bfs_path;
std::string g_bfs_cluster;

#define BFS "\e[0;32m[BFS]\e[0m "

static void bfs_ll_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}
/*
static void bfs_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s(size:%lu, off:%ld)\n", __func__, size, off);
}

static void bfs_ll_write(fuse_req_t req, fuse_ino_t ino, const char *buf, size_t size, off_t off, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s(size:%lu, off:%ld)\n", __func__, size, off);
}
static void bfs_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev_t dev){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_create(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_statfs(fuse_req_t req, fuse_ino_t ino){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_rename(fuse_req_t req, fuse_ino_t sparent, const char *sname, fuse_ino_t tparent, const char *tname){
	fprintf(stderr, BFS"%s(source name:%s, target name:%s)\n", __func__, sname, tname);
}

static void bfs_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t tparent, const char *tname){
	fprintf(stderr, BFS"%s(target name:%s)\n", __func__, tname);
}

static void bfs_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char *name){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_fsync(fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_access(fuse_req_t req, fuse_ino_t ino, int mask){
	fprintf(stderr, BFS"%s\n", __func__);
}
*/

int parse_bfs_args(int* argc, char* argv[]) {
    if (*argc < 2) {
        fprintf(stderr, "Usage: %s mount_point [-d]"
                        " [-c bfs_cluster_addr]"
                        " [-p bfs_path]\n",
                argv[0]);
        fprintf(stderr, "\t-d                    Fuse debug (optional)\n"
                        "\t-c bfs_cluster_addr   Ip:port\n"
                        "\t-p bfs_path           The path in BFS which you mount to the mount_point\n"
                        "Example:\n"
                        "       %s /mnt/bfs -d -c 127.0.0.1:8827 -p /\n",
                argv[0]);
        return 1;
    }

    for (int i = 1; i + 1 < *argc; i++) {
        if (strncmp(argv[i], "-c", 2) == 0) {
            g_bfs_cluster = argv[i + 1];
            printf(BFS"Use cluster: %s\n", g_bfs_cluster.c_str());
        } else if (strncmp(argv[i], "-p", 2) == 0) {
            g_bfs_path = argv[i + 1];
            printf(BFS"Use path: %s\n", g_bfs_path.c_str());
        } else {
            continue;
        }
        for (int j = i; j + 2 < *argc; j++) {
            argv[j] = argv[j + 2];
        }
        i -= 2;
        *argc -= 2;
    }
    argv[*argc] = NULL;
    return 0;
}

int main(int argc, char *argv[])
{
	//static struct fuse_lowlevel_ops bfs_ll_oper = {
	//		.lookup         = bfs_ll_lookup,
	//		.getattr        = bfs_ll_getattr,
	//		.readdir        = bfs_ll_readdir,
	//		.open           = bfs_ll_open,
	//		.opendir        = bfs_ll_opendir,
	//		.read           = bfs_ll_read,
	//		.write          = bfs_ll_write,
	//		.mknod          = bfs_ll_mknod,
	//		.mkdir          = bfs_ll_mkdir,
	//		.create         = bfs_ll_create,
	//		.statfs         = bfs_ll_statfs,
	//		.rename         = bfs_ll_rename,
	//		.link           = bfs_ll_link,
	//		.unlink         = bfs_ll_unlink,
	//		.rmdir          = bfs_ll_rmdir,
	//		.fsync          = bfs_ll_fsync,
	//		.fsyncdir       = bfs_ll_fsyncdir,
	//		.access         = bfs_ll_access,
	//
	//
	//};
	static struct fuse_lowlevel_ops bfs_ll_oper;
	bfs_ll_oper.getattr = bfs_ll_getattr;
	if(parse_bfs_args(&argc, argv)){
		return 1;
	}
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch;
	char *mountpoint;
	int err = -1;

	if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
	    (ch = fuse_mount(mountpoint, &args)) != NULL) {
		struct fuse_session *se;

		se = fuse_lowlevel_new(&args, &bfs_ll_oper,
				       sizeof(bfs_ll_oper), NULL);
		if (se != NULL) {
			if (fuse_set_signal_handlers(se) != -1) {
				fuse_session_add_chan(se, ch);
				err = fuse_session_loop(se);
				fuse_remove_signal_handlers(se);
				fuse_session_remove_chan(ch);
			}
			fuse_session_destroy(se);
		}
		fuse_unmount(mountpoint, ch);
	}
	fuse_opt_free_args(&args);

	return err ? 1 : 0;
}
<commit_msg>Update fuse_lowlevel/bfs_ll_mount.cc.<commit_after>#include <fuse_lowlevel.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <algorithm>
#include <sdk/bfs.h>

baidu::bfs::FS* g_fs;
std::string g_bfs_path;
std::string g_bfs_cluster;

#define BFS "\e[0;32m[BFS]\e[0m "

static void bfs_ll_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s(size:%lu, off:%ld)\n", __func__, size, off);
}

static void bfs_ll_write(fuse_req_t req, fuse_ino_t ino, const char *buf, size_t size, off_t off, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s(size:%lu, off:%ld)\n", __func__, size, off);
}
static void bfs_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev_t dev){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_create(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_statfs(fuse_req_t req, fuse_ino_t ino){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_rename(fuse_req_t req, fuse_ino_t sparent, const char *sname, fuse_ino_t tparent, const char *tname){
	fprintf(stderr, BFS"%s(source name:%s, target name:%s)\n", __func__, sname, tname);
}

static void bfs_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t tparent, const char *tname){
	fprintf(stderr, BFS"%s(target name:%s)\n", __func__, tname);
}

static void bfs_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char *name){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name){
	fprintf(stderr, BFS"%s(%s)\n", __func__, name);
}

static void bfs_ll_fsync(fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi){
	fprintf(stderr, BFS"%s\n", __func__);
}

static void bfs_ll_access(fuse_req_t req, fuse_ino_t ino, int mask){
	fprintf(stderr, BFS"%s\n", __func__);
}

int parse_bfs_args(int* argc, char* argv[]) {
    if (*argc < 2) {
        fprintf(stderr, "Usage: %s mount_point [-d]"
                        " [-c bfs_cluster_addr]"
                        " [-p bfs_path]\n",
                argv[0]);
        fprintf(stderr, "\t-d                    Fuse debug (optional)\n"
                        "\t-c bfs_cluster_addr   Ip:port\n"
                        "\t-p bfs_path           The path in BFS which you mount to the mount_point\n"
                        "Example:\n"
                        "       %s /mnt/bfs -d -c 127.0.0.1:8827 -p /\n",
                argv[0]);
        return 1;
    }

    for (int i = 1; i + 1 < *argc; i++) {
        if (strncmp(argv[i], "-c", 2) == 0) {
            g_bfs_cluster = argv[i + 1];
            printf(BFS"Use cluster: %s\n", g_bfs_cluster.c_str());
        } else if (strncmp(argv[i], "-p", 2) == 0) {
            g_bfs_path = argv[i + 1];
            printf(BFS"Use path: %s\n", g_bfs_path.c_str());
        } else {
            continue;
        }
        for (int j = i; j + 2 < *argc; j++) {
            argv[j] = argv[j + 2];
        }
        i -= 2;
        *argc -= 2;
    }
    argv[*argc] = NULL;
    return 0;
}

int main(int argc, char *argv[])
{
	static struct fuse_lowlevel_ops ll_oper;
	ll_oper.lookup = bfs_ll_lookup;
	ll_oper.getattr = bfs_ll_getattr;
	ll_oper.readdir = bfs_ll_readdir;
	ll_oper.open = bfs_ll_open;
	ll_oper.opendir = bfs_ll_opendir;
	ll_oper.read = bfs_ll_read;
	ll_oper.write = bfs_ll_write;
	ll_oper.mknod = bfs_ll_mknod;
	ll_oper.mkdir = bfs_ll_mkdir;
	ll_oper.create = bfs_ll_create;
	ll_oper.statfs = bfs_ll_statfs;
	ll_oper.rename = bfs_ll_rename;
	ll_oper.link = bfs_ll_link;
	ll_oper.unlink = bfs_ll_unlink;
	ll_oper.rmdir = bfs_ll_rmdir;
	ll_oper.fsync = bfs_ll_fsync;
	ll_oper.fsyncdir = bfs_ll_fsyncdir;
	ll_oper.access = bfs_ll_access;

	if(parse_bfs_args(&argc, argv)){
		return 1;
	}
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct fuse_chan *ch;
	char *mountpoint;
	int err = -1;

	if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
	    (ch = fuse_mount(mountpoint, &args)) != NULL) {
		struct fuse_session *se;

		se = fuse_lowlevel_new(&args, &ll_oper,
				       sizeof(ll_oper), NULL);
		if (se != NULL) {
			if (fuse_set_signal_handlers(se) != -1) {
				fuse_session_add_chan(se, ch);
				err = fuse_session_loop(se);
				fuse_remove_signal_handlers(se);
				fuse_session_remove_chan(ch);
			}
			fuse_session_destroy(se);
		}
		fuse_unmount(mountpoint, ch);
	}
	fuse_opt_free_args(&args);

	return err ? 1 : 0;
}
<|endoftext|>


<commit_before>#line 2 "sxc:Account/Roster.cxx"
// LICENSE/*{{{*/
/*
  sxc - Simple Xmpp Client
  Copyright (C) 2008 Dennis Felsing, Andreas Waidler

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*}}}*/

// INCLUDE/*{{{*/

#ifdef HAVE_CONFIG_H
# include <config.hxx>
#endif

#include <string>
#include <map>
#include <sstream>

#include <gloox/clientbase.h>
#include <gloox/jid.h>
#include <gloox/presence.h>
#include <gloox/iq.h>
#include <gloox/message.h>
#include <gloox/messagehandler.h>
#include <gloox/error.h>

#include <libsxc/generateString.hxx>
#include <libsxc/Exception/Exception.hxx>
#include <libsxc/Debug/Logger.hxx>
#include <libsxc/Error/Handler.hxx>

#include <Account/Roster.hxx>
#include <Account/RosterType.hxx>
#include <Contact/Contact.hxx>
#include <File/AbcOutput.hxx>
#include <Account/File/Info.hxx>
#include <File/createDir.hxx>
#include <Exit/Code.hxx>

/*}}}*/

namespace Account
{
  Roster::Roster(/*{{{*/
    gloox::Client &client,
    ::File::AbcOutput &out,
    File::Info &nfo,
    libsxc::Error::Handler &eh)
  : RosterListener()
  , _client(client)
  , _out(out)
  , _nfo(nfo)
  , _contacts()
  , _eh(eh)
  {
    // Asynchronous subscription request handling.
    _client.rosterManager()->registerRosterListener(this, false);
    _client.registerMessageHandler(this);
  }/*}}}*/
  Roster::~Roster()/*{{{*/
  {
    _client.rosterManager()->removeRosterListener();
    _client.removeMessageHandler(this);

    for(
    contactList::iterator entry = _contacts.begin();
    entry != _contacts.end();
    ++entry) {
      delete entry->second;
    }
  }/*}}}*/

  void Roster::sendMessage(const gloox::JID &jid, const std::string &message)/*{{{*/
  {
    _addContactLocal(jid);

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return; // FIXME: Throw exception, this is really unexpected.

    contact->second->sendMessage(message);
  }/*}}}*/

  void Roster::addContact(const gloox::JID &jid)/*{{{*/
  {
    _addContactLocal(jid);
    _addContactRemote(jid);
  }/*}}}*/
  void Roster::removeContact(const gloox::JID &jid) const/*{{{*/
  {
    _checkClient();

    LOG("Remove contact from the roster: \"" + jid.bare() + "\".");

    _client.rosterManager()->remove(jid);
    _client.rosterManager()->synchronize();
  }/*}}}*/

  void Roster::subscribe(/*{{{*/
    const gloox::JID &jid,
    const std::string &message) const
  {
    _checkClient();

    LOG(
      "Sending subscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + message + "\").");

    const gloox::StringList groups;
    _client.rosterManager()->subscribe(jid, jid.bare(), groups, message);
    _client.rosterManager()->synchronize();
  }/*}}}*/
  void Roster::unsubscribe(/*{{{*/
    const gloox::JID &jid,
    const std::string &message) const
  {
    _checkClient();

    LOG(
      "Sending unsubscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + message + "\").");

    _client.rosterManager()->unsubscribe(jid, message);
    _client.rosterManager()->synchronize();
  }/*}}}*/

  void Roster::acknowledgeSubscription(const gloox::JID &jid) const/*{{{*/
  {
    LOG(
      "Acknowledge subscription request: \"" + jid.bare() + "\".");

    _client.rosterManager()->ackSubscriptionRequest(jid, true);
  }/*}}}*/
  void Roster::declineSubscription(const gloox::JID &jid) const/*{{{*/
  {
    LOG(
      "Decline subscription request: \"" + jid.bare() + "\".");

    _client.rosterManager()->ackSubscriptionRequest(jid, false);
  }/*}}}*/

  void Roster::handleMessage(/*{{{*/
    const gloox::Message &msg,
    gloox::MessageSession *session)
  {
    _addContactLocal(msg.from()); // Local only.

    contactList::iterator contact = _getContact(msg.from().bare());
    if (_contacts.end() == contact)
      return;

    contact->second->handleMessage(msg, session);
  }/*}}}*/

  gloox::MessageSession *Roster::createMessageSession(/*{{{*/
    gloox::MessageHandler *handler,
    const gloox::JID &jid)
  {
    gloox::MessageSession *session = new gloox::MessageSession(&_client, jid);
    session->registerMessageHandler(handler);
    return session;
  }/*}}}*/
  void Roster::disposeMessageSession(gloox::MessageSession *session)/*{{{*/
  {
    // This deletes the session. Else the destructor of gloox::ClientBase would
    // handle this.
    _client.disposeMessageSession(session);
  }/*}}}*/

  const gloox::JID &Roster::getJid()/*{{{*/
  {
    return _client.jid();
  }/*}}}*/

  void Roster::handleItemAdded(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item added to the roster: \"" + jid.bare() + "\".");

    _addContactLocal(jid);
  }/*}}}*/
  void Roster::handleItemSubscribed(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item subscribed: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleItemRemoved(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item removed from the roster: \"" + jid.bare() + "\".");

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return;
    delete contact->second;
    _contacts.erase(contact);

    // _account->print("Contact removed: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleItemUpdated(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item updated: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleItemUnsubscribed(const gloox::JID &jid)/*{{{*/
  {
    LOG(
      "Item unsubscribed: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleRoster(const gloox::Roster &roster)/*{{{*/
  {
    LOG("Initial roster received from the server.");

    for(
    gloox::Roster::const_iterator entry = roster.begin();
    entry != roster.end();
    ++entry) {
      _addContactLocal(entry->first);

      contactList::iterator contact = _getContact(entry->first);
      if (_contacts.end() == contact)
        continue;

      contact->second->updateRoster(Remote);
    }
  }/*}}}*/
  void Roster::handleRosterPresence(/*{{{*/
    const gloox::RosterItem &item,
    const std::string &resource,
    gloox::Presence::PresenceType presence,
    const std::string &msg)
  {
    std::ostringstream ss;
    ss << "Status changed: (jid: \"" << item.jid()
       << "/" << resource << "\", presence: \""
       << libsxc::genPresenceString(presence) << "\" (" << presence
       << "), message: \"" << msg << "\").";
    LOG(ss.str());

    contactList::iterator contact = _getContact(item.jid());
    if (_contacts.end() == contact)
      return;
    contact->second->updatePresence(resource, presence, msg);
  }/*}}}*/
  void Roster::handleSelfPresence(/*{{{*/
    const gloox::RosterItem &item,
    const std::string &resource,
    gloox::Presence::PresenceType presence,
    const std::string &msg)
  {
    std::ostringstream ss;
    ss << "Self-status changed: (jid: \"" << item.name()
       << "\", resource: \"" << resource << "\", presence: "
       << presence << ", message: \"" << msg << "\").";
    LOG(ss.str());

    if (resource == _client.jid().resource()) {
      _nfo.setPresence(presence);
      _nfo.setMessage(msg);
    }
  }/*}}}*/
  bool Roster::handleSubscriptionRequest(/*{{{*/
    const gloox::JID &jid,
    const std::string &msg)
  {
    LOG(
      "Received subscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + msg + "\").");

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return true;

    //_account->print(
    //  "Subscription request received: \"" + jid.bare() + "\"");

    return true;
  }/*}}}*/
  bool Roster::handleUnsubscriptionRequest(/*{{{*/
    const gloox::JID &jid,
    const std::string &msg)
  {
    LOG(
      "Received unsubscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + msg + "\").");

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return true;

    //_account->print(
    //  "Unsubscription request received: \"" + jid.bare() + "\"");

    return true;
  }/*}}}*/
  void Roster::handleNonrosterPresence(const gloox::Presence &presence)/*{{{*/
  {
    std::ostringstream ss;
    ss << "Nonroster-Status changed: (type: \"" << presence.subtype()
       << "\", message: \"" << presence.status() << "\").";
    LOG(ss.str());
  }/*}}}*/
  void Roster::handleRosterError(const gloox::IQ &iq)/*{{{*/
  {
    const gloox::Error *error = iq.error();
    if (error) {
      _eh.print(
        "Roster error received: " +
        libsxc::genStanzaErrorString(error->error()));
    }

  }/*}}}*/

  void Roster::_checkClient() const/*{{{*/
  {
    // FIXME: Better exception or none at all
    if (!gloox::StateConnected == _client.state())
      throw libsxc::Exception::Exception(
        "Connection ist not established.",
        Exit::InvalidUsage);
  }/*}}}*/
  void Roster::_addContactRemote(const gloox::JID &jid)/*{{{*/
  {
    LOG(
      "Add contact to the remote roster: \"" + jid.bare() + "\".");

    _checkClient();

    const gloox::StringList groups;
    _client.rosterManager()->add(jid, jid.bare(), groups);
    _client.rosterManager()->synchronize();

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return;

    contact->second->updateRoster(Remote);
  }/*}}}*/
  void Roster::_addContactLocal(const gloox::JID &jid)/*{{{*/
  {
    if (_contacts.end() != _getContact(jid.bare())) {
      LOG("Contact already in local roster, not adding: \"" + jid.bare() + "\"");
      return;
    }

    _out.write("Add contact: " + jid.bare());

    ::File::createDir(_client.jid().bare() + "/" + jid.bare());

    Contact::Contact *contact = new Contact::Contact(
      *this, _client.jid(), jid);
    contact->updateRoster(Local);

    _contacts.insert(std::make_pair(jid.bare(), contact));

  }/*}}}*/
  contactList::iterator Roster::_getContact(const std::string &jid)/*{{{*/
  {
    contactList::iterator contact = _contacts.find(jid);

    if (_contacts.end() == contact) {
      LOG("Item not found in local roster");
    }

    return contact;
  }/*}}}*/
}

// Use no tabs at all; two spaces indentation; max. eighty chars per line.
// vim: et ts=2 sw=2 sts=2 tw=80 fdm=marker
<commit_msg>Add workaround to show self presence<commit_after>#line 2 "sxc:Account/Roster.cxx"
// LICENSE/*{{{*/
/*
  sxc - Simple Xmpp Client
  Copyright (C) 2008 Dennis Felsing, Andreas Waidler

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*}}}*/

// INCLUDE/*{{{*/

#ifdef HAVE_CONFIG_H
# include <config.hxx>
#endif

#include <string>
#include <map>
#include <sstream>

#include <gloox/clientbase.h>
#include <gloox/jid.h>
#include <gloox/presence.h>
#include <gloox/iq.h>
#include <gloox/message.h>
#include <gloox/messagehandler.h>
#include <gloox/error.h>

#include <libsxc/generateString.hxx>
#include <libsxc/Exception/Exception.hxx>
#include <libsxc/Debug/Logger.hxx>
#include <libsxc/Error/Handler.hxx>

#include <Account/Roster.hxx>
#include <Account/RosterType.hxx>
#include <Contact/Contact.hxx>
#include <File/AbcOutput.hxx>
#include <Account/File/Info.hxx>
#include <File/createDir.hxx>
#include <Exit/Code.hxx>

/*}}}*/

namespace Account
{
  Roster::Roster(/*{{{*/
    gloox::Client &client,
    ::File::AbcOutput &out,
    File::Info &nfo,
    libsxc::Error::Handler &eh)
  : RosterListener()
  , _client(client)
  , _out(out)
  , _nfo(nfo)
  , _contacts()
  , _eh(eh)
  {
    // Asynchronous subscription request handling.
    _client.rosterManager()->registerRosterListener(this, false);
    _client.registerMessageHandler(this);
  }/*}}}*/
  Roster::~Roster()/*{{{*/
  {
    _client.rosterManager()->removeRosterListener();
    _client.removeMessageHandler(this);

    for(
    contactList::iterator entry = _contacts.begin();
    entry != _contacts.end();
    ++entry) {
      delete entry->second;
    }
  }/*}}}*/

  void Roster::sendMessage(const gloox::JID &jid, const std::string &message)/*{{{*/
  {
    _addContactLocal(jid);

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return; // FIXME: Throw exception, this is really unexpected.

    contact->second->sendMessage(message);
  }/*}}}*/

  void Roster::addContact(const gloox::JID &jid)/*{{{*/
  {
    _addContactLocal(jid);
    _addContactRemote(jid);
  }/*}}}*/
  void Roster::removeContact(const gloox::JID &jid) const/*{{{*/
  {
    _checkClient();

    LOG("Remove contact from the roster: \"" + jid.bare() + "\".");

    _client.rosterManager()->remove(jid);
    _client.rosterManager()->synchronize();
  }/*}}}*/

  void Roster::subscribe(/*{{{*/
    const gloox::JID &jid,
    const std::string &message) const
  {
    _checkClient();

    LOG(
      "Sending subscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + message + "\").");

    const gloox::StringList groups;
    _client.rosterManager()->subscribe(jid, jid.bare(), groups, message);
    _client.rosterManager()->synchronize();
  }/*}}}*/
  void Roster::unsubscribe(/*{{{*/
    const gloox::JID &jid,
    const std::string &message) const
  {
    _checkClient();

    LOG(
      "Sending unsubscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + message + "\").");

    _client.rosterManager()->unsubscribe(jid, message);
    _client.rosterManager()->synchronize();
  }/*}}}*/

  void Roster::acknowledgeSubscription(const gloox::JID &jid) const/*{{{*/
  {
    LOG(
      "Acknowledge subscription request: \"" + jid.bare() + "\".");

    _client.rosterManager()->ackSubscriptionRequest(jid, true);
  }/*}}}*/
  void Roster::declineSubscription(const gloox::JID &jid) const/*{{{*/
  {
    LOG(
      "Decline subscription request: \"" + jid.bare() + "\".");

    _client.rosterManager()->ackSubscriptionRequest(jid, false);
  }/*}}}*/

  void Roster::handleMessage(/*{{{*/
    const gloox::Message &msg,
    gloox::MessageSession *session)
  {
    _addContactLocal(msg.from()); // Local only.

    contactList::iterator contact = _getContact(msg.from().bare());
    if (_contacts.end() == contact)
      return;

    contact->second->handleMessage(msg, session);
  }/*}}}*/

  gloox::MessageSession *Roster::createMessageSession(/*{{{*/
    gloox::MessageHandler *handler,
    const gloox::JID &jid)
  {
    gloox::MessageSession *session = new gloox::MessageSession(&_client, jid);
    session->registerMessageHandler(handler);
    return session;
  }/*}}}*/
  void Roster::disposeMessageSession(gloox::MessageSession *session)/*{{{*/
  {
    // This deletes the session. Else the destructor of gloox::ClientBase would
    // handle this.
    _client.disposeMessageSession(session);
  }/*}}}*/

  const gloox::JID &Roster::getJid()/*{{{*/
  {
    return _client.jid();
  }/*}}}*/

  void Roster::handleItemAdded(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item added to the roster: \"" + jid.bare() + "\".");

    _addContactLocal(jid);
  }/*}}}*/
  void Roster::handleItemSubscribed(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item subscribed: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleItemRemoved(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item removed from the roster: \"" + jid.bare() + "\".");

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return;
    delete contact->second;
    _contacts.erase(contact);

    // _account->print("Contact removed: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleItemUpdated(const gloox::JID &jid)/*{{{*/
  {
    LOG("Item updated: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleItemUnsubscribed(const gloox::JID &jid)/*{{{*/
  {
    LOG(
      "Item unsubscribed: \"" + jid.bare() + "\".");
  }/*}}}*/
  void Roster::handleRoster(const gloox::Roster &roster)/*{{{*/
  {
    LOG("Initial roster received from the server.");

    for(
    gloox::Roster::const_iterator entry = roster.begin();
    entry != roster.end();
    ++entry) {
      _addContactLocal(entry->first);

      contactList::iterator contact = _getContact(entry->first);
      if (_contacts.end() == contact)
        continue;

      contact->second->updateRoster(Remote);
    }
  }/*}}}*/
  void Roster::handleRosterPresence(/*{{{*/
    const gloox::RosterItem &item,
    const std::string &resource,
    gloox::Presence::PresenceType presence,
    const std::string &msg)
  {
    std::ostringstream ss;
    ss << "Status changed: (jid: \"" << item.jid()
       << "/" << resource << "\", presence: \""
       << libsxc::genPresenceString(presence) << "\" (" << presence
       << "), message: \"" << msg << "\").";
    LOG(ss.str());

    if (item.jid() == _client.jid().bare()) {
      // Don't return, as it is possible to have yourself on the roster too.
      // We have to call the handleSelfPresence method from here, as gloox
      // does not call.
      handleSelfPresence(item, resource, presence, msg);
    }

    contactList::iterator contact = _getContact(item.jid());
    if (_contacts.end() == contact)
      return;
    contact->second->updatePresence(resource, presence, msg);
  }/*}}}*/
  void Roster::handleSelfPresence(/*{{{*/
    const gloox::RosterItem &item,
    const std::string &resource,
    gloox::Presence::PresenceType presence,
    const std::string &msg)
  {
    std::ostringstream ss;
    ss << "Self-status changed: (jid: \"" << item.name()
       << "\", resource: \"" << resource << "\", presence: "
       << presence << ", message: \"" << msg << "\").";
    LOG(ss.str());

    if (resource == _client.jid().resource()) {
      _nfo.setPresence(presence);
      _nfo.setMessage(msg);
    }
  }/*}}}*/
  bool Roster::handleSubscriptionRequest(/*{{{*/
    const gloox::JID &jid,
    const std::string &msg)
  {
    LOG(
      "Received subscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + msg + "\").");

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return true;

    //_account->print(
    //  "Subscription request received: \"" + jid.bare() + "\"");

    return true;
  }/*}}}*/
  bool Roster::handleUnsubscriptionRequest(/*{{{*/
    const gloox::JID &jid,
    const std::string &msg)
  {
    LOG(
      "Received unsubscription request: (jid: \"" + jid.bare() +
      "\", message: \"" + msg + "\").");

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return true;

    //_account->print(
    //  "Unsubscription request received: \"" + jid.bare() + "\"");

    return true;
  }/*}}}*/
  void Roster::handleNonrosterPresence(const gloox::Presence &presence)/*{{{*/
  {
    std::ostringstream ss;
    ss << "Nonroster-Status changed: (type: \"" << presence.subtype()
       << "\", message: \"" << presence.status() << "\").";
    LOG(ss.str());
  }/*}}}*/
  void Roster::handleRosterError(const gloox::IQ &iq)/*{{{*/
  {
    const gloox::Error *error = iq.error();
    if (error) {
      _eh.print(
        "Roster error received: " +
        libsxc::genStanzaErrorString(error->error()));
    }

  }/*}}}*/

  void Roster::_checkClient() const/*{{{*/
  {
    // FIXME: Better exception or none at all
    if (!gloox::StateConnected == _client.state())
      throw libsxc::Exception::Exception(
        "Connection ist not established.",
        Exit::InvalidUsage);
  }/*}}}*/
  void Roster::_addContactRemote(const gloox::JID &jid)/*{{{*/
  {
    LOG(
      "Add contact to the remote roster: \"" + jid.bare() + "\".");

    _checkClient();

    const gloox::StringList groups;
    _client.rosterManager()->add(jid, jid.bare(), groups);
    _client.rosterManager()->synchronize();

    contactList::iterator contact = _getContact(jid.bare());
    if (_contacts.end() == contact)
      return;

    contact->second->updateRoster(Remote);
  }/*}}}*/
  void Roster::_addContactLocal(const gloox::JID &jid)/*{{{*/
  {
    if (_contacts.end() != _getContact(jid.bare())) {
      LOG("Contact already in local roster, not adding: \"" + jid.bare() + "\"");
      return;
    }

    _out.write("Add contact: " + jid.bare());

    ::File::createDir(_client.jid().bare() + "/" + jid.bare());

    Contact::Contact *contact = new Contact::Contact(
      *this, _client.jid(), jid);
    contact->updateRoster(Local);

    _contacts.insert(std::make_pair(jid.bare(), contact));

  }/*}}}*/
  contactList::iterator Roster::_getContact(const std::string &jid)/*{{{*/
  {
    contactList::iterator contact = _contacts.find(jid);

    if (_contacts.end() == contact) {
      LOG("Item not found in local roster");
    }

    return contact;
  }/*}}}*/
}

// Use no tabs at all; two spaces indentation; max. eighty chars per line.
// vim: et ts=2 sw=2 sts=2 tw=80 fdm=marker
<|endoftext|>