<commit_before>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <iostream>
#include <fstream>

#include <minizinc/model.hh>
#include <minizinc/parser.hh>
#include <minizinc/prettyprinter.hh>
#include <minizinc/typecheck.hh>
#include <minizinc/exception.hh>

#include <minizinc/flatten.hh>
#include <minizinc/optimize.hh>
#include <minizinc/builtins.hh>

using namespace MiniZinc;
using namespace std;

int main(int argc, char** argv) {
  int i=1;
  string filename;
  vector<string> datafiles;
  vector<string> includePaths;
  bool flag_ignoreStdlib = false;
  bool flag_typecheck = true;
  bool flag_eval = true;
  bool flag_output = true;
  bool flag_verbose = false;
  bool flag_newfzn = false;
  bool flag_optimize = true;
  if (argc < 2)
    goto error;

  GC::init();

  for (;;) {
    if (string(argv[i])==string("-h") || string(argv[i])==string("--help"))
        goto error;
    if (string(argv[i])==string("-I")) {
      i++;
      if (i==argc) {
        goto error;
      }
      includePaths.push_back(argv[i]+string("/"));
    } else if (string(argv[i])==string("--ignore-stdlib")) {
      flag_ignoreStdlib = true;
    } else if (string(argv[i])==string("--no-output")) {
      flag_output = false;
    } else if (string(argv[i])==string("--no-typecheck")) {
      flag_typecheck = false; flag_eval=false;
    } else if (string(argv[i])==string("--no-eval")) {
      flag_eval = false;
    } else if (string(argv[i])==string("--verbose")) {
      flag_verbose = true;
    } else if (string(argv[i])==string("--newfzn")) {
      flag_newfzn = true;
    } else if (string(argv[i])==string("--no-optimize")) {
      flag_optimize = false;
    } else {
      break;
    }
    i++;
  }

  if (i==argc) {
    goto error;
  }
  filename = argv[i++];

  while (i<argc)
    datafiles.push_back(argv[i++]);

  {
    if (flag_verbose)
      std::cerr << "Parsing '" << filename << "' ..." << std::endl;
    if (Model* m = parse(filename, datafiles, includePaths, flag_ignoreStdlib,
                         std::cerr)) {
      try {
        if (flag_typecheck) {
          if (flag_verbose)
            std::cerr << "Typechecking..." << std::endl;
          MiniZinc::typecheck(m);
          MiniZinc::registerBuiltins(m);

          if (flag_verbose)
            std::cerr << "Flattening..." << std::endl;
          Model* flat = flatten(m);

          if (flag_optimize) {
            if (flag_verbose)
              std::cerr << "Optimizing..." << std::endl;
            optimize(flat);
          }

          if (flag_output) {
            if (!flag_newfzn) {
              if (flag_verbose)
                std::cerr << "Converting to old FlatZinc..." << std::endl;
              oldflatzinc(flat);
            }

            if (flag_verbose)
              std::cerr << "Printing FlatZinc..." << std::endl;
            Printer p;
            p.print(flat,std::cout);
          }
        }
      } catch (LocationException& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        std::cerr << e.loc() << std::endl;
        exit(EXIT_FAILURE);
      } catch (Exception& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        exit(EXIT_FAILURE);
      }
      delete m;
    }
  }

  if (flag_verbose)
    std::cerr << "Done." << std::endl;
  return 0;

error:
  std::cerr << "Usage: "<< argv[0]
            << " [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...]" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "\t--help  -h\tPrint this help message" << std::endl
            << "\t--ignore-stdlib\tIgnore the standard libraries stdlib.mzn and builtins.mzn" << std::endl
            << "\t--newfzn\tOutput in the new FlatZinc format" << std::endl
            << "\t--verbose\tPrint progress statements" << std::endl
            << "\t--no-typecheck\tDo not typecheck (implies --no-eval)" << std::endl
            << "\t--no-eval\tDo not evaluate" << std::endl
            << "\t--no-optimize\tDo not optimize the FlatZinc (may speed up large instances)" << std::endl
            << "\t--no-output\tDo not print the output" << std::endl;

  exit(EXIT_FAILURE);
}
<commit_msg>Print with --no-typecheck too<commit_after>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <iostream>
#include <fstream>

#include <minizinc/model.hh>
#include <minizinc/parser.hh>
#include <minizinc/prettyprinter.hh>
#include <minizinc/typecheck.hh>
#include <minizinc/exception.hh>

#include <minizinc/flatten.hh>
#include <minizinc/optimize.hh>
#include <minizinc/builtins.hh>

using namespace MiniZinc;
using namespace std;

int main(int argc, char** argv) {
  int i=1;
  string filename;
  vector<string> datafiles;
  vector<string> includePaths;
  bool flag_ignoreStdlib = false;
  bool flag_typecheck = true;
  bool flag_eval = true;
  bool flag_output = true;
  bool flag_verbose = false;
  bool flag_newfzn = false;
  bool flag_optimize = true;
  if (argc < 2)
    goto error;

  GC::init();

  for (;;) {
    if (string(argv[i])==string("-h") || string(argv[i])==string("--help"))
        goto error;
    if (string(argv[i])==string("-I")) {
      i++;
      if (i==argc) {
        goto error;
      }
      includePaths.push_back(argv[i]+string("/"));
    } else if (string(argv[i])==string("--ignore-stdlib")) {
      flag_ignoreStdlib = true;
    } else if (string(argv[i])==string("--no-output")) {
      flag_output = false;
    } else if (string(argv[i])==string("--no-typecheck")) {
      flag_typecheck = false; flag_eval=false;
    } else if (string(argv[i])==string("--no-eval")) {
      flag_eval = false;
    } else if (string(argv[i])==string("--verbose")) {
      flag_verbose = true;
    } else if (string(argv[i])==string("--newfzn")) {
      flag_newfzn = true;
    } else if (string(argv[i])==string("--no-optimize")) {
      flag_optimize = false;
    } else {
      break;
    }
    i++;
  }

  if (i==argc) {
    goto error;
  }
  filename = argv[i++];

  while (i<argc)
    datafiles.push_back(argv[i++]);

  {
    if (flag_verbose)
      std::cerr << "Parsing '" << filename << "' ..." << std::endl;
    if (Model* m = parse(filename, datafiles, includePaths, flag_ignoreStdlib,
                         std::cerr)) {
      try {
        if (flag_typecheck) {
          if (flag_verbose)
            std::cerr << "Typechecking..." << std::endl;
          MiniZinc::typecheck(m);
          MiniZinc::registerBuiltins(m);

          if (flag_verbose)
            std::cerr << "Flattening..." << std::endl;
          Model* flat = flatten(m);

          if (flag_optimize) {
            if (flag_verbose)
              std::cerr << "Optimizing..." << std::endl;
            optimize(flat);
          }

          if (flag_output) {
            if (!flag_newfzn) {
              if (flag_verbose)
                std::cerr << "Converting to old FlatZinc..." << std::endl;
              oldflatzinc(flat);
            }

            if (flag_verbose)
              std::cerr << "Printing FlatZinc..." << std::endl;
            Printer p;
            p.print(flat,std::cout);
          }
          delete flat;
        } else if (flag_output) { // !flag_typecheck
          Printer p;
          p.print(m,std::cout);
        }
      } catch (LocationException& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        std::cerr << e.loc() << std::endl;
        exit(EXIT_FAILURE);
      } catch (Exception& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        exit(EXIT_FAILURE);
      }
      delete m;
    }
  }

  if (flag_verbose)
    std::cerr << "Done." << std::endl;
  return 0;

error:
  std::cerr << "Usage: "<< argv[0]
            << " [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...]" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "\t--help  -h\tPrint this help message" << std::endl
            << "\t--ignore-stdlib\tIgnore the standard libraries stdlib.mzn and builtins.mzn" << std::endl
            << "\t--newfzn\tOutput in the new FlatZinc format" << std::endl
            << "\t--verbose\tPrint progress statements" << std::endl
            << "\t--no-typecheck\tDo not typecheck (implies --no-eval)" << std::endl
            << "\t--no-eval\tDo not evaluate" << std::endl
            << "\t--no-optimize\tDo not optimize the FlatZinc (may speed up large instances)" << std::endl
            << "\t--no-output\tDo not print the output" << std::endl;

  exit(EXIT_FAILURE);
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <string>
#include <fstream>
#include <iostream>

// Endianess macro
#define little_endian true

// Macros for string processing
#define cut(s,i,sz) ((s).substr((i),(sz)))
#define to_c(s) ((s).c_str())
#define getHex(s,n) (sscanf(s,"%x",&(n)))

// Macros for bits manipulation
#define get4Bits(w,B) (((w)&((0xF)<<(B*4)))>>(B*4))
#define getByte(w,B) (((w)&((0xFF)<<(B*8)))>>(B*8))
#define getBit(w,b) (((w)&((0x1)<<b))>>b)
#define shiftBits(w,b) ((w)<<b)

// Macros to evaluate commands
#define AVR_EXE printf

using namespace std;

// temporal buffer to manage commands
char tmp[102];

// Just for debugging process
#if 1
char logs[123456];
#define DEBUG(...) sprintf(logs,__VA_ARGS__)
#else
#define DEBUG printf
#endif

// Type to store array of functions
typedef void (*Handler)(int &opCode);

// Return true when the checksum of hex line is OK
int checksum_ok(string &str, int &size, int &checkSum) {
	unsigned int check=0;
	int twoByte, i=1;
	for(; i< size; i += 2) {
		getHex(to_c(cut(str,i,2)),twoByte);
		check += twoByte;
		check &= 0xFF;
		DEBUG("i(%d) %x %d %x\n",i,twoByte,twoByte,check);
	}
	// Two complement of a function
	check = (~check) + 1;
	check &= 0xFF;
	// Verify against cheksum expected
	return (check != checkSum) ? -EINVAL : 0;
}

// Separates commands from each hex line
int parse_cmd(string &str, string &cmds) {
	int byteCount, address, recordType;
	int checkSum, idx = 1;

	// Clear whatever cmds contains
	cmds = "";
	if(!str.size() || ':' != str[0] ){
		return -EINVAL;
	}

	/**
	* Byte Count: two hex digits, indicating
	* the number of bytes (hex digit pairs)
	* in the data field
	**/
	getHex(to_c(cut(str,idx,2)),byteCount);
	idx += 2;
	DEBUG("byteCount: %02d %02x\n",byteCount,byteCount);

	/**
	* Address: four hex digits, representing
	* the 16-bit beginning memory address offset
	* of the data.
	**/
	getHex(to_c(cut(str,idx,4)),address);
	idx += 4;
	DEBUG("address: %04d %04x\n",address,address);
	DEBUG("start address: %04d %04x\n",address/2,address/2);

	/** Record type: (see record types below),
	* two hex digits, 00 to 05, defining the
	* meaning of the data field.
	* 00	Data
	* 01	End Of File
	* 02	Extended Segment Address
	* 03	Start Segment Address
	* 04	Extended Linear Address
	* 05	Start Linear Address
	**/
	getHex(to_c(cut(str,idx,2)),recordType);
	idx += 2;
	DEBUG("recordType: %02d %02x\n",recordType,recordType);

	/** Data: a sequence of n bytes of data, represented
	* by 2n hex digits.
	**/
	cmds = cut(str,idx,2*byteCount);
	idx += 2*byteCount;
	DEBUG("data: %s\n",to_c(cmds));

	/** Checksum, two hex digits, a computed value that
	* can be used to verify the record has no errors.
	**/
	getHex(to_c(cut(str,idx,2)),checkSum);
	DEBUG("checkSum: %02d %02x\n",checkSum,checkSum);
	return checksum_ok(str, idx, checkSum);
}

void op0xzz(int &opCode) {
	int B = get4Bits(opCode,2);
	int d=0, r=0;
	string cmd, param;
	DEBUG("OpCode 0x%x B0x%x\n",opCode,B);
	if(0 == B){
		cmd = (0 == opCode) ? "nop" : "[R]";
		param = "";
	}else if(0x4 <= B){
		cmd = (0xC<=B)?"add":((0x8<=B)?"sbc":"cpc");
		r = shiftBits(getBit(opCode,9),4) + get4Bits(opCode,0);
		d = shiftBits(getBit(opCode,8),4) + get4Bits(opCode,1);
		sprintf(tmp,"R%d, R%d",d,r);
		param = tmp;
	}else {
		switch(B){
			case 1:
			case 2: {
				r = get4Bits(opCode,0);
				d = get4Bits(opCode,1);
				cmd = (2==B)?"movw":"muls";
				break;
			}
			case 3: {
				//Turn off last bit for each word
				r = get4Bits(opCode,0)^0x8;
				d = get4Bits(opCode,1)^0x8;
				// Generate new code to see which type of mul is
				int mCode = shiftBits(getBit(opCode,7),1);
				   mCode += shiftBits(getBit(opCode,3),0);
				switch(mCode){
					case 0:{cmd = "mulsu";break;}
					case 1:{cmd = "fmul";break;}
					case 2:{cmd = "fmuls";break;}
					case 3:{cmd = "fmulsu";break;}
				}
				break;
			}
		}
		sprintf(tmp,"R%d, R%d",d,r);
		param = tmp;
	}
	AVR_EXE("%s\n",to_c(cmd+" "+param));
}

void op1_2xzz(int &opCode) {
	int B = get4Bits(opCode,2) >> 2;
	int A = get4Bits(opCode,3);
	string cmds[2][4] = {{"cpse","cp","sub","adc"},{"and","eor","or","mov"}};
	string cmd, param;
	int r = shiftBits(getBit(opCode,9),4) + get4Bits(opCode,0);
	int d = shiftBits(getBit(opCode,8),4) + get4Bits(opCode,1);
	sprintf(tmp,"R%d, R%d",d,r);
	param = tmp;
	cmd = cmds[A-1][B];
	DEBUG("OpCode 0x%x B0x%x\n",opCode,B);
	AVR_EXE("%s\n",to_c(cmd+" "+param));
}

void op3_7xzz(int &opCode){
	int k = shiftBits(get4Bits(opCode,2),8) + get4Bits(opCode,0);
	int A = get4Bits(opCode,3);
	int d = get4Bits(opCode,1);
	string cmd, param, cmds[] = {"cpi","sbci","subi","ori","andi"};
	cmd = cmds[A - 0x3];
	sprintf(tmp,"R%d, %d",d,k);
	AVR_EXE("%s\n",to_c(cmd+" "+param));
}
void op8xzz(int &opCode){printf("%s\n",__FUNCTION__);}
void op9xzz(int &opCode){printf("%s\n",__FUNCTION__);}
void opAxzz(int &opCode){printf("%s\n",__FUNCTION__);}

void opBxzz(int &opCode){
	int op = getBit(opCode,11);
	int d = shiftBits(getBit(opCode, 8),4) + get4Bits(opCode,1);
	int A = shiftBits(getBit(opCode, 9),4);
	    A = shiftBits(getBit(opCode,10),5) + get4Bits(opCode,0);
	if(op) {
		sprintf(tmp,"out %d, R%d",A,d);
	}else {
		sprintf(tmp,"in R%d, %d",d,A);
	}
	string cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}

void opC_Dxzz(int &opCode){
	int A = get4Bits(opCode,3);
	// Just ignore the most significative nibble
	int k = opCode & 0x0FFF;
	sprintf(tmp,"%s %d",(0xC==A)?"rjmp":"rcall",k);
	string cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}
void opExzz(int &opCode){
	// Just ignore the most significative nibble
	int k = shiftBits(get4Bits(opCode,2),4) + get4Bits(opCode,0);
	int d = get4Bits(opCode,1);
	sprintf(tmp,"%s R%d, %d","ldi",d,k);
	string cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}
void opFxzz(int &opCode){printf("%s\n",__FUNCTION__);}

// Axzz Array to select based on the first bytes
Handler oAxzz[] = {
    op0xzz,   op1_2xzz, op1_2xzz, op3_7xzz,
    op3_7xzz, op3_7xzz, op3_7xzz, op3_7xzz,
    op8xzz,     op9xzz,   opAxzz,   opBxzz,
    opC_Dxzz, opC_Dxzz,   opExzz,   opFxzz
};

// Choose the right command to execute based on some reduction
void execute_cmd( int &opCode ) {
	int A = get4Bits(opCode,3);
	// Delegate the responsability to next functions
	DEBUG("A (%02d) (%x)",A,A);
	oAxzz[A](opCode);
}

void split_cmds(string &cmds) {
	// We had blocks of 4 bytes, lets process them
	int opCode, swapCode;
	for(int i=0; i<cmds.size(); i += 4) {
		getHex(to_c(cut(cmds,i,4)),opCode);
		DEBUG("opCode: %04d %04x\n",opCode,opCode);
		/** Now that we know each opcode lets 'execute' them
		* Each opcode is an int of 16 bits
		**/
		if(little_endian) {
			/* We have to swap the byte order to Endianess */
			swapCode  = shiftBits(getByte(opCode,0),8);
			swapCode |= shiftBits(getByte(opCode,1),0);
			opCode = swapCode;
		}
		execute_cmd(opCode);
	}
}

int main() {
	string hexLine;
	string parsedCmd;
	ifstream hexFile;

	//For test purposes
	hexFile.open("main.hex");
	int err = 0;

	// Read each line from .hex file while possible
	while (getline(hexFile, hexLine)) {
		// Now parse the string to a more friendly format
		err = parse_cmd(hexLine, parsedCmd);
		if(err) {
			printf("Error ocurred %d\n",err);
			break;
		}
		// If no errors proceed to execute the command
		split_cmds(parsedCmd);
	}
	return 0;
}<commit_msg>Implement more opcode instructions<commit_after>#include <cstdio>
#include <string>
#include <fstream>
#include <iostream>

// Endianess macro
#define little_endian true

// Macros for string processing
#define cut(s,i,sz) ((s).substr((i),(sz)))
#define to_c(s) ((s).c_str())
#define getHex(s,n) (sscanf(s,"%x",&(n)))

// Macros for bits manipulation
#define get4Bits(w,B) (((w)&((0xF)<<(B*4)))>>(B*4))
#define getByte(w,B) (((w)&((0xFF)<<(B*8)))>>(B*8))
#define getBit(w,b) (((w)&((0x1)<<b))>>b)
#define shiftBits(w,b) ((w)<<b)

// Macros to evaluate commands
#define AVR_EXE printf

using namespace std;

// temporal buffer to manage commands
char tmp[102];

// Just for debugging process
#if 1
char logs[123456];
#define DEBUG(...) sprintf(logs,__VA_ARGS__)
#else
#define DEBUG printf
#endif

// Type to store array of functions
typedef void (*Handler)(int &opCode);

// Return true when the checksum of hex line is OK
int checksum_ok(string &str, int &size, int &checkSum) {
	unsigned int check=0;
	int twoByte, i=1;
	for(; i< size; i += 2) {
		getHex(to_c(cut(str,i,2)),twoByte);
		check += twoByte;
		check &= 0xFF;
		DEBUG("i(%d) %x %d %x\n",i,twoByte,twoByte,check);
	}
	// Two complement of a function
	check = (~check) + 1;
	check &= 0xFF;
	// Verify against cheksum expected
	return (check != checkSum) ? -EINVAL : 0;
}

// Separates commands from each hex line
int parse_cmd(string &str, string &cmds) {
	int byteCount, address, recordType;
	int checkSum, idx = 1;

	// Clear whatever cmds contains
	cmds = "";
	if(!str.size() || ':' != str[0] ){
		return -EINVAL;
	}

	/**
	* Byte Count: two hex digits, indicating
	* the number of bytes (hex digit pairs)
	* in the data field
	**/
	getHex(to_c(cut(str,idx,2)),byteCount);
	idx += 2;
	DEBUG("byteCount: %02d %02x\n",byteCount,byteCount);

	/**
	* Address: four hex digits, representing
	* the 16-bit beginning memory address offset
	* of the data.
	**/
	getHex(to_c(cut(str,idx,4)),address);
	idx += 4;
	DEBUG("address: %04d %04x\n",address,address);
	DEBUG("start address: %04d %04x\n",address/2,address/2);

	/** Record type: (see record types below),
	* two hex digits, 00 to 05, defining the
	* meaning of the data field.
	* 00	Data
	* 01	End Of File
	* 02	Extended Segment Address
	* 03	Start Segment Address
	* 04	Extended Linear Address
	* 05	Start Linear Address
	**/
	getHex(to_c(cut(str,idx,2)),recordType);
	idx += 2;
	DEBUG("recordType: %02d %02x\n",recordType,recordType);

	/** Data: a sequence of n bytes of data, represented
	* by 2n hex digits.
	**/
	cmds = cut(str,idx,2*byteCount);
	idx += 2*byteCount;
	DEBUG("data: %s\n",to_c(cmds));

	/** Checksum, two hex digits, a computed value that
	* can be used to verify the record has no errors.
	**/
	getHex(to_c(cut(str,idx,2)),checkSum);
	DEBUG("checkSum: %02d %02x\n",checkSum,checkSum);
	return checksum_ok(str, idx, checkSum);
}

void op0xzz(int &opCode) {
	int B = get4Bits(opCode,2);
	int d=0, r=0;
	string cmd, param;
	DEBUG("OpCode 0x%x B0x%x\n",opCode,B);
	if(0 == B){
		cmd = (0 == opCode) ? "nop" : "[R]";
		param = "";
	}else if(0x4 <= B){
		cmd = (0xC<=B)?"add":((0x8<=B)?"sbc":"cpc");
		r = shiftBits(getBit(opCode,9),4) + get4Bits(opCode,0);
		d = shiftBits(getBit(opCode,8),4) + get4Bits(opCode,1);
		sprintf(tmp,"R%d, R%d",d,r);
		param = tmp;
	}else {
		switch(B){
			case 1:
			case 2: {
				r = get4Bits(opCode,0);
				d = get4Bits(opCode,1);
				cmd = (2==B)?"movw":"muls";
				break;
			}
			case 3: {
				//Turn off last bit for each word
				r = get4Bits(opCode,0)^0x8;
				d = get4Bits(opCode,1)^0x8;
				// Generate new code to see which type of mul is
				int mCode = shiftBits(getBit(opCode,7),1);
				   mCode += shiftBits(getBit(opCode,3),0);
				switch(mCode){
					case 0:{cmd = "mulsu";break;}
					case 1:{cmd = "fmul";break;}
					case 2:{cmd = "fmuls";break;}
					case 3:{cmd = "fmulsu";break;}
				}
				break;
			}
		}
		sprintf(tmp,"R%d, R%d",d,r);
		param = tmp;
	}
	AVR_EXE("%s\n",to_c(cmd+" "+param));
}

void op1_2xzz(int &opCode) {
	int B = get4Bits(opCode,2) >> 2;
	int A = get4Bits(opCode,3);
	string cmds[2][4] = {{"cpse","cp","sub","adc"},{"and","eor","or","mov"}};
	string cmd, param;
	int r = shiftBits(getBit(opCode,9),4) + get4Bits(opCode,0);
	int d = shiftBits(getBit(opCode,8),4) + get4Bits(opCode,1);
	sprintf(tmp,"R%d, R%d",d,r);
	param = tmp;
	cmd = cmds[A-1][B];
	DEBUG("OpCode 0x%x B0x%x\n",opCode,B);
	AVR_EXE("%s\n",to_c(cmd+" "+param));
}

void op3_7xzz(int &opCode){
	int k = shiftBits(get4Bits(opCode,2),8) + get4Bits(opCode,0);
	int A = get4Bits(opCode,3);
	int d = get4Bits(opCode,1);
	string cmd, param, cmds[] = {"cpi","sbci","subi","ori","andi"};
	cmd = cmds[A - 0x3];
	sprintf(tmp,"R%d, %d",d,k);
	AVR_EXE("%s\n",to_c(cmd+" "+param));
}
void op8xzz(int &opCode){printf("%s\n",__FUNCTION__);}
void op9xzz(int &opCode){printf("%s\n",__FUNCTION__);}
void opAxzz(int &opCode){printf("%s\n",__FUNCTION__);}

void opBxzz(int &opCode){
	int op = getBit(opCode,11);
	int d = shiftBits(getBit(opCode, 8),4) + get4Bits(opCode,1);
	int A = shiftBits(getBit(opCode, 9),4);
	    A = shiftBits(getBit(opCode,10),5) + get4Bits(opCode,0);
	if(op) {
		sprintf(tmp,"out %d, R%d",A,d);
	}else {
		sprintf(tmp,"in R%d, %d",d,A);
	}
	string cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}

void opC_Dxzz(int &opCode){
	int A = get4Bits(opCode,3);
	// Just ignore the most significative nibble
	int k = opCode & 0x0FFF;
	sprintf(tmp,"%s %d",(0xC==A)?"rjmp":"rcall",k);
	string cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}
void opExzz(int &opCode){
	// Just ignore the most significative nibble
	int k = shiftBits(get4Bits(opCode,2),4) + get4Bits(opCode,0);
	int d = get4Bits(opCode,1);;
	sprintf(tmp,"%s R%d, %d","ldi",d,k);
	string cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}
void opFxzz(int &opCode){
	int s = opCode & 0x7;
	int B = get4Bits(opCode,2) >> 2;
	int d = shiftBits(getBit(opCode, 8),4) + get4Bits(opCode,1);
	int k  = shiftBits(getByte(opCode,1),1);
		k += getBit(opCode,3);
		k += shiftBits((opCode & 0x300),5);
	string cmd;

	switch(B) {
		case 0:{
			sprintf(tmp,"brbs %d, %d",s,k);
			break;
		}
		case 1:{
			sprintf(tmp,"brbc %d, %d",s,k);
			break;
		}
		case 2:{
			sprintf(tmp,"%s R%d, %d",(getBit(opCode,9)?"bst":"bld"),d,s);
			break;
		}
		case 3:{
			sprintf(tmp,"%s R%d, %d",(getBit(opCode,9)?"sbrs":"sbrc"),d,s);
			break;
		}
	}
	cmd = tmp;
	AVR_EXE("%s\n",to_c(cmd));
}

// Axzz Array to select based on the first bytes
Handler oAxzz[] = {
    op0xzz,   op1_2xzz, op1_2xzz, op3_7xzz,
    op3_7xzz, op3_7xzz, op3_7xzz, op3_7xzz,
    op8xzz,     op9xzz,   opAxzz,   opBxzz,
    opC_Dxzz, opC_Dxzz,   opExzz,   opFxzz
};

// Choose the right command to execute based on some reduction
void execute_cmd( int &opCode ) {
	int A = get4Bits(opCode,3);
	// Delegate the responsability to next functions
	DEBUG("A (%02d) (%x)",A,A);
	oAxzz[A](opCode);
}

void split_cmds(string &cmds) {
	// We had blocks of 4 bytes, lets process them
	int opCode, swapCode;
	for(int i=0; i<cmds.size(); i += 4) {
		getHex(to_c(cut(cmds,i,4)),opCode);
		DEBUG("opCode: %04d %04x\n",opCode,opCode);
		/** Now that we know each opcode lets 'execute' them
		* Each opcode is an int of 16 bits
		**/
		if(little_endian) {
			/* We have to swap the byte order to Endianess */
			swapCode  = shiftBits(getByte(opCode,0),8);
			swapCode |= shiftBits(getByte(opCode,1),0);
			opCode = swapCode;
		}
		execute_cmd(opCode);
	}
}

int main() {
	string hexLine;
	string parsedCmd;
	ifstream hexFile;

	//For test purposes
	hexFile.open("main.hex");
	int err = 0;

	// Read each line from .hex file while possible
	while (getline(hexFile, hexLine)) {
		// Now parse the string to a more friendly format
		err = parse_cmd(hexLine, parsedCmd);
		if(err) {
			printf("Error ocurred %d\n",err);
			break;
		}
		// If no errors proceed to execute the command
		split_cmds(parsedCmd);
	}
	return 0;
}<|endoftext|>


<commit_before>#ifndef CONTEXT_HPP_
#define CONTEXT_HPP_

#include <string>
#include <atomic>
#include <memory>
#include <thread>
#include <cstdio>
#include <mutex>
#include <chrono>

#include "SharedMap.hpp"

template<typename T>
class AtomicWrapper {

	mutable std::mutex lock;

	T value;

public:

	template<typename U>
	AtomicWrapper(U&& u) : lock() {
		std::lock_guard<decltype(lock)> g(lock);
		value = T(u);
	}

	template<typename U>
	AtomicWrapper& operator=(U&& newValue) {
		std::lock_guard<decltype(lock)> g(lock);
		value = std::forward<U>(newValue);
		return *this;
	}

	operator T() const {
		std::lock_guard<decltype(lock)> g(lock);
		T ret = value;
		return ret;
	}

};

std::string runCommand(std::string command) {
	std::FILE* pipe = popen(command.c_str(), "r");

	if(!pipe) return "";

	char buffer[128];

	std::string result;

	while(!std::feof(pipe)) {
		std::fgets(buffer, sizeof(buffer), pipe);
		result += buffer;
	}
	pclose(pipe);
	return result;
}

class Context: std::enable_shared_from_this<Context> {
	std::atomic_bool isRunning;
	std::string cwd;
	std::size_t paneId;

	SharedMap<std::size_t, SharedString>& sm;

	AtomicWrapper<std::string> currentResult = "";

public:

	Context(SharedMap<std::size_t, SharedString>& sm): sm(sm) {
		isRunning.store(false);
	}

	const std::string& getCwd() const { return cwd; }

	void run() {
		isRunning = true;
		std::thread t(
				[&](){
					auto self = this->shared_from_this();
					for(;;) {
						if(isRunning.load())
							self->currentResult = runCommand("cd "+cwd+"&& ls -la");
							self->sm.insert(paneId, static_cast<std::string>(self->currentResult).c_str());
							std::this_thread::sleep_for(std::chrono::seconds(5));
					}
				}
		);
	}

	void stop() {
		isRunning = false;
	}

	std::string getResult() const {
		return currentResult;
	}

	~Context() {
	}

};

#endif /* CONTEXT_HPP_ */
<commit_msg>Remove AtomicWrapper and currentResult from Context<commit_after>#ifndef CONTEXT_HPP_
#define CONTEXT_HPP_

#include <string>
#include <atomic>
#include <memory>
#include <thread>
#include <cstdio>
#include <mutex>
#include <chrono>

#include "SharedMap.hpp"

std::string runCommand(std::string command) {
	std::FILE* pipe = popen(command.c_str(), "r");

	if(!pipe) return "";

	char buffer[128];

	std::string result;

	while(!std::feof(pipe)) {
		std::fgets(buffer, sizeof(buffer), pipe);
		result += buffer;
	}
	pclose(pipe);
	return result;
}

class Context: std::enable_shared_from_this<Context> {
	std::atomic_bool isRunning;
	std::string cwd;
	std::size_t paneId;

	SharedMap<std::size_t, SharedString>& sm;

public:

	Context(SharedMap<std::size_t, SharedString>& sm): sm(sm) {
		isRunning.store(false);
	}

	const std::string& getCwd() const { return cwd; }

	void run() {
		isRunning = true;
		std::thread t(
				[&](){
					auto self = this->shared_from_this();
					for(;;) {
						if(isRunning.load()) {
							std::string result = runCommand("cd "+cwd+"&& ls -la");
							self->sm.insert(paneId, result.c_str());
							std::this_thread::sleep_for(std::chrono::seconds(5));
						}
					}
				}
		);
	}

	void stop() {
		isRunning = false;
	}

	std::string getResult() const {
		return sm[paneId].c_str();
	}

	~Context() {
	}

};

#endif /* CONTEXT_HPP_ */
<|endoftext|>


<commit_before>#include <stack.h>
#include "yatf/include/yatf.h"

using namespace yacppl;

TEST(stack, canCreateEmptyStack) {
    stack<int> stack;
    unsigned long size = stack.size();
    REQUIRE(size == 0);
}

TEST(stack, canPushTempElement) {
    stack<int> stack;
    stack.push(439);
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 439);
}

TEST(stack, canPushElement) {
    stack<int> stack;
    auto element = 5423;
    stack.push(element);
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 5423);
}

TEST(stack, canPushMoreElements) {
    stack<int> stack;
    stack.push(33);
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 33);
    stack.push(21);
    REQUIRE(stack.size() == 2);
    REQUIRE_EQ(stack.front(), 21);
    stack.push(594);
    REQUIRE(stack.size() == 3);
    REQUIRE_EQ(stack.front(), 594);
    stack.push(37);
    REQUIRE(stack.size() == 4);
    REQUIRE_EQ(stack.front(), 37);
}

TEST(stack, canPushAndPopElement) {
    stack<int> stack;
    stack.push(439);
    stack.pop();
    REQUIRE(stack.size() == 0);
}

TEST(stack, canPushAndPopMoreElements) {
    stack<int> stack;
    stack.push(439);
    stack.push(599);
    stack.push(238);
    stack.push(70);
    stack.push(43);
    REQUIRE(stack.size() == 5);
    REQUIRE_EQ(stack.front(), 43);
    stack.pop();
    REQUIRE(stack.size() == 4);
    REQUIRE_EQ(stack.front(), 70);
    stack.pop();
    REQUIRE(stack.size() == 3);
    REQUIRE_EQ(stack.front(), 238);
    stack.pop();
    REQUIRE(stack.size() == 2);
    REQUIRE_EQ(stack.front(), 599);
    stack.pop();
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 439);
    stack.pop();
    REQUIRE(stack.size() == 0);
}

TEST(stack, canPushAndPopByShiftOperators) {
    stack<int> stack;
    int temp = -4;
    stack << temp;
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), -4);
    stack << 93 << 24;
    REQUIRE(stack.size() == 3);
    REQUIRE_EQ(stack.front(), 24);
    stack << 325 << 0 << 3267;
    REQUIRE(stack.size() == 6);
    REQUIRE_EQ(stack.front(), 3267);
    int result[6];
    stack >> result[0];
    REQUIRE(stack.size() == 5);
    REQUIRE_EQ(stack.front(), 0);
    stack >> result[1] >> result[2] >> result[3] >> result[4] >> result[5];
    REQUIRE(stack.size() == 0);
    REQUIRE_EQ(result[0], 3267);
    REQUIRE_EQ(result[1], 0);
    REQUIRE_EQ(result[2], 325);
    REQUIRE_EQ(result[3], 24);
    REQUIRE_EQ(result[4], 93);
    REQUIRE_EQ(result[5], -4);
}
<commit_msg>Remove old camel-case names from stack tests<commit_after>#include <stack.h>
#include "yatf/include/yatf.h"

using namespace yacppl;

TEST(stack, can_create_empty_stack) {
    stack<int> stack;
    unsigned long size = stack.size();
    REQUIRE(size == 0);
}

TEST(stack, can_push_temp_element) {
    stack<int> stack;
    stack.push(439);
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 439);
}

TEST(stack, can_push_element) {
    stack<int> stack;
    auto element = 5423;
    stack.push(element);
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 5423);
}

TEST(stack, can_push_more_elements) {
    stack<int> stack;
    stack.push(33);
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 33);
    stack.push(21);
    REQUIRE(stack.size() == 2);
    REQUIRE_EQ(stack.front(), 21);
    stack.push(594);
    REQUIRE(stack.size() == 3);
    REQUIRE_EQ(stack.front(), 594);
    stack.push(37);
    REQUIRE(stack.size() == 4);
    REQUIRE_EQ(stack.front(), 37);
}

TEST(stack, can_push_and_pop_element) {
    stack<int> stack;
    stack.push(439);
    stack.pop();
    REQUIRE(stack.size() == 0);
}

TEST(stack, can_push_and_pop_more_elements) {
    stack<int> stack;
    stack.push(439);
    stack.push(599);
    stack.push(238);
    stack.push(70);
    stack.push(43);
    REQUIRE(stack.size() == 5);
    REQUIRE_EQ(stack.front(), 43);
    stack.pop();
    REQUIRE(stack.size() == 4);
    REQUIRE_EQ(stack.front(), 70);
    stack.pop();
    REQUIRE(stack.size() == 3);
    REQUIRE_EQ(stack.front(), 238);
    stack.pop();
    REQUIRE(stack.size() == 2);
    REQUIRE_EQ(stack.front(), 599);
    stack.pop();
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), 439);
    stack.pop();
    REQUIRE(stack.size() == 0);
}

TEST(stack, can_push_and_pop_by_shift_operators) {
    stack<int> stack;
    int temp = -4;
    stack << temp;
    REQUIRE(stack.size() == 1);
    REQUIRE_EQ(stack.front(), -4);
    stack << 93 << 24;
    REQUIRE(stack.size() == 3);
    REQUIRE_EQ(stack.front(), 24);
    stack << 325 << 0 << 3267;
    REQUIRE(stack.size() == 6);
    REQUIRE_EQ(stack.front(), 3267);
    int result[6];
    stack >> result[0];
    REQUIRE(stack.size() == 5);
    REQUIRE_EQ(stack.front(), 0);
    stack >> result[1] >> result[2] >> result[3] >> result[4] >> result[5];
    REQUIRE(stack.size() == 0);
    REQUIRE_EQ(result[0], 3267);
    REQUIRE_EQ(result[1], 0);
    REQUIRE_EQ(result[2], 325);
    REQUIRE_EQ(result[3], 24);
    REQUIRE_EQ(result[4], 93);
    REQUIRE_EQ(result[5], -4);
}

<|endoftext|>


<commit_before>// No pragma once!!

// for clang and gcc
#pragma GCC diagnostic ignored "-Wunused-parameter"

// just for clang
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wcomma"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Wdeprecated"
#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
#pragma GCC diagnostic ignored "-Wdocumentation"
#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
#pragma GCC diagnostic ignored "-Wdouble-promotion"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#pragma GCC diagnostic ignored "-Wextra-semi"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wredundant-parens"
#pragma GCC diagnostic ignored "-Wreserved-id-macro"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wswitch-enum"
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wundefined-func-template"
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#else // g++-7
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" // boost/asio
#endif

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>porting to boost 1.67<commit_after>// No pragma once!!

// for clang and gcc
#pragma GCC diagnostic ignored "-Wunused-parameter"

// just for clang
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wcomma"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Wdeprecated"
#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
#pragma GCC diagnostic ignored "-Wdocumentation"
#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
#pragma GCC diagnostic ignored "-Wdouble-promotion"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#pragma GCC diagnostic ignored "-Wextra-semi"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wredundant-parens"
#pragma GCC diagnostic ignored "-Wreserved-id-macro"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wshadow-field"
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wswitch-enum"
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wundefined-func-template"
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#else // g++-7
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" // boost/asio
#endif

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "db/dbformat.h"
#include "util/logging.h"
#include "util/testharness.h"

namespace leveldb {

static std::string IKey(const std::string& user_key,
                        uint64_t seq,
                        ValueType vt) {
  std::string encoded;
  AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
  return encoded;
}

static std::string Shorten(const std::string& s, const std::string& l) {
  std::string result = s;
  InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);
  return result;
}

static std::string ShortSuccessor(const std::string& s) {
  std::string result = s;
  InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
  return result;
}

static void TestKey(const std::string& key,
                    uint64_t seq,
                    ValueType vt) {
  std::string encoded = IKey(key, seq, vt);

  Slice in(encoded);
  ParsedInternalKey decoded("", 0, kTypeValue);

  ASSERT_TRUE(ParseInternalKey(in, &decoded));
  ASSERT_EQ(key, decoded.user_key.ToString());
  ASSERT_EQ(seq, decoded.sequence);
  ASSERT_EQ(vt, decoded.type);

  ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
}

class FormatTest { };

TEST(FormatTest, InternalKey_EncodeDecode) {
  const char* keys[] = { "", "k", "hello", "longggggggggggggggggggggg" };
  const uint64_t seq[] = {
    1, 2, 3,
    (1ull << 8) - 1, 1ull << 8, (1ull << 8) + 1,
    (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1,
    (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1
  };
  for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
    for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
      TestKey(keys[k], seq[s], kTypeValue);
      TestKey("hello", 1, kTypeDeletion);
    }
  }
}

TEST(FormatTest, InternalKeyShortSeparator) {
  // When user keys are same
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("foo", 99, kTypeValue)));
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("foo", 101, kTypeValue)));
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("foo", 100, kTypeValue)));
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("foo", 100, kTypeDeletion)));

  // When user keys are misordered
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("bar", 99, kTypeValue)));

  // When user keys are different, but correctly ordered
  ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("hello", 200, kTypeValue)));

  // When start user key is prefix of limit user key
  ASSERT_EQ(IKey("foo", 100, kTypeValue),
            Shorten(IKey("foo", 100, kTypeValue),
                    IKey("foobar", 200, kTypeValue)));

  // When limit user key is prefix of start user key
  ASSERT_EQ(IKey("foobar", 100, kTypeValue),
            Shorten(IKey("foobar", 100, kTypeValue),
                    IKey("foo", 200, kTypeValue)));
}

TEST(FormatTest, InternalKeyShortestSuccessor) {
  ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
            ShortSuccessor(IKey("foo", 100, kTypeValue)));
  ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue),
            ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
}

}  // namespace leveldb

int main(int argc, char** argv) {
  return leveldb::test::RunAllTests();
}
<commit_msg>Delete dbformat_test.cc<commit_after><|endoftext|>


<commit_before>#define CATCH_CONFIG_RUNNER
#include <iostream>
#include "./Catch/catch.hpp"
#include "../include/Elson.hpp"

using namespace JSON;

TEST_CASE( "base/types", "Basic JSON Data types" ) {
    Value val = 5;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("5") == 0);

    val = 3.0;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("3") == 0);

    val = 1L;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("1") == 0);

    val = 7u;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("7") == 0);

    val = -7.5;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("-7.5") == 0);

    val = -.05;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("-0.05") == 0);

    val = 1E3;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("1000") == 0);

    val = -7.5;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<unsigned int>() == 7);

    val = "5";
    REQUIRE(val.is(JSON_STRING));
    REQUIRE(val.as<int>() == 5);

    val = "5L";
    REQUIRE(val.is(JSON_STRING));
    REQUIRE(val.as<long>() == 5L);

    val = "\\";
    REQUIRE(val.is(JSON_STRING));
    REQUIRE(val.as<std::string>().compare("\\") == 0);

    val = true;
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(val.as<bool>());
    REQUIRE(val.as<int>() == 1);
    REQUIRE(val.as<std::string>() == "true");

    val = false;
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(!val.as<bool>());
    REQUIRE(val.as<int>() == 0);
    REQUIRE(val.as<std::string>() == "false");

    val = { true, false };
    REQUIRE(val[0].is(JSON_BOOL));
    REQUIRE(val[1].is(JSON_BOOL));
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(val[0].as<bool>());
    REQUIRE(!val[1].as<bool>());

    val = { 1, .5, "hello world", true, false, null };
    REQUIRE(val[0].is(JSON_NUMBER));
    REQUIRE(val[1].is(JSON_NUMBER));
    REQUIRE(val[2].is(JSON_STRING));
    REQUIRE(val[3].is(JSON_BOOL));
    REQUIRE(val[4].is(JSON_BOOL));
    REQUIRE(val[5].is(JSON_NULL));

    val = { {1,0,0}, {0,1,0},{0,0,1} };
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(val.as<Array>().size() == 3);
    REQUIRE(val[0].is(JSON_ARRAY));
    REQUIRE(val[1].is(JSON_ARRAY));
    REQUIRE(val[2].is(JSON_ARRAY));
    REQUIRE(val[0].as<Array>().size() == 3);
    REQUIRE(val[1].as<Array>().size() == 3);
    REQUIRE(val[2].as<Array>().size() == 3);
    REQUIRE(val[0][0].is(JSON_NUMBER));
    REQUIRE(val[0][1].is(JSON_NUMBER));
    REQUIRE(val[0][2].is(JSON_NUMBER));
    REQUIRE(val[1][0].is(JSON_NUMBER));
    REQUIRE(val[1][1].is(JSON_NUMBER));
    REQUIRE(val[1][2].is(JSON_NUMBER));
    REQUIRE(val[2][0].is(JSON_NUMBER));
    REQUIRE(val[2][1].is(JSON_NUMBER));
    REQUIRE(val[2][2].is(JSON_NUMBER));

    std::string key = "property";
    val = Object { { "property", "value" } };
    REQUIRE(val.is(JSON_OBJECT));
    REQUIRE(val["property"].is(JSON_STRING));
    REQUIRE(val[key].is(JSON_STRING));
    REQUIRE(val[std::string("property")].is(JSON_STRING));

    REQUIRE(val["property"].as<std::string>().compare("value") == 0);

    val["property"] = 42;
    REQUIRE(val["property"].is(JSON_NUMBER));
    REQUIRE(val[key].as<unsigned int>() == 42);
}

TEST_CASE( "base/parse", "Basic parsing") {
    Parser p;
    Printer printer;
    Value val;

    REQUIRE_THROWS(p.parse(val, "[]a"));
    REQUIRE_THROWS(p.parse(val, "a[]"));

    REQUIRE_NOTHROW(p.parse(val, ""));
    REQUIRE(val.is(JSON_NULL));

    auto numbers = {"0", "1", "1E3", "1e-3", "0.5", "-.05e-07"};

    for (auto number: numbers) {
        REQUIRE_NOTHROW(p.parse(val, number));
        REQUIRE(val.is(JSON_NUMBER));
    }

    REQUIRE_THROWS(p.parse(val, "-0.5w4"));

    std::vector<std::string> strings = {
        "\"\"",
        "\"0\"",
        "\"hello world\"",
        "\"äöüȩéáã\""
    };

    for (int i = 0; i < strings.size(); i++) {
        REQUIRE_NOTHROW(p.parse(val, strings[i]));
        REQUIRE(printer.print(val).compare(strings[i]) == 0);
    }

    std::map<std::string, std::string> escapes = {
        { "\"\\\\\"", "\"\\\"" },
        { "\"\\/\"", "\"/\"" },
        { "\"\\u5022\"", "\"倢\"" }
    };

    for (auto pair: escapes) {
        REQUIRE_NOTHROW(p.parse(val, pair.first));
        REQUIRE(printer.print(val).compare(pair.second) == 0);
    }

    REQUIRE_NOTHROW(p.parse(val, "true"));
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(val.as<bool>());
    REQUIRE(printer.print(val).compare("true") == 0);

    REQUIRE_NOTHROW(p.parse(val, "false"));
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(!val.as<bool>());
    REQUIRE(printer.print(val).compare("false") == 0);

    REQUIRE_NOTHROW(p.parse(val, "null"));
    REQUIRE(val.is(JSON_NULL));
    REQUIRE(printer.print(val).compare("null") == 0);

    REQUIRE_NOTHROW(p.parse(val, "[]"));
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(printer.print(val).compare("[]") == 0);
    REQUIRE(val.as<Array>().size() == 0);

    REQUIRE_NOTHROW(p.parse(val, "[ 1, 2,   4   ]"));
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(printer.print(val).compare("[1,2,4]") == 0);
    REQUIRE(val.as<Array>().size() == 3);

    REQUIRE_THROWS(p.parse(val, "["));
    REQUIRE_THROWS(p.parse(val, "]"));
    REQUIRE_THROWS(p.parse(val, "[["));
    REQUIRE_THROWS(p.parse(val, "]]"));
    REQUIRE_THROWS(p.parse(val, "[,]"));
    REQUIRE_THROWS(p.parse(val, "[][]"));
    REQUIRE_THROWS(p.parse(val, "[1,]"));
    REQUIRE_THROWS(p.parse(val, "[,1]"));
    REQUIRE_THROWS(p.parse(val, "[1,2"));
    REQUIRE_THROWS(p.parse(val, "1,2]"));
    REQUIRE_THROWS(p.parse(val, "[[],[]"));
    REQUIRE_THROWS(p.parse(val, "[[],]]"));
    REQUIRE_THROWS(p.parse(val, "[[1,2,],[]]"));
    REQUIRE_THROWS(p.parse(val, "[[1,2,] []]"));

    REQUIRE_NOTHROW(p.parse(val, "[[]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[]]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[],[]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[]],[[]]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[1]],[[2]]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[1,null,true,false,\"\"]],[[]]]"));
    REQUIRE(val[0][0][0].is(JSON_NUMBER));
    REQUIRE(val[0][0][1].is(JSON_NULL));
    REQUIRE(val[0][0][2].is(JSON_BOOL));
    REQUIRE(val[0][0][3].is(JSON_BOOL));
    REQUIRE(val[0][0][4].is(JSON_STRING));
    REQUIRE(val[0][0].as<Array>().size() == 5);
    REQUIRE(printer.print(val).compare("[[[1,null,true,false,\"\"]],[[]]]") == 0);

    val[0][0].as<Array>().push_back(null);
    REQUIRE(val[0][0].as<Array>().size() == 5);

    val[0][0].asMutable<Array>().push_back(null);
    REQUIRE(val[0][0].as<Array>().size() == 6);

    REQUIRE_NOTHROW(p.parse(val, "{}"));
    REQUIRE_THROWS(p.parse(val, "{1}"));
    REQUIRE_THROWS(p.parse(val, "{{}}"));
    REQUIRE_NOTHROW(p.parse(val, "{\"a\": \"b\"}"));
    REQUIRE(val["a"].as<std::string>().compare("b") == 0);
    REQUIRE_THROWS(val.as<double>());

    REQUIRE_NOTHROW(p.parse(val, "[{}]"));
    REQUIRE_NOTHROW(p.parse(val, "[{},{}]"));
    REQUIRE_NOTHROW(p.parse(val, "[{},[]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[{}]]]"));
    REQUIRE_THROWS(p.parse(val, "[[[{}]]"));
    REQUIRE_THROWS(p.parse(val, "[{}]]"));
    REQUIRE_THROWS(p.parse(val, "{[]}"));
}

TEST_CASE( "base/unicode", "Unicode escape handling") {
    Parser p;
    Printer printer;
    Value val;

    std::map<std::string, std::string> escapes = {
        { "\"\\u0041\"", "\"A\"" },
        { "\"\\u0042\"", "\"B\"" },
        { "\"\\u0043\"", "\"C\"" },
        { "\"\\u0044\"", "\"D\"" },
        { "\"\\u0045\"", "\"E\"" },
        { "\"\\u0046\"", "\"F\"" },
        { "\"\\u0047\"", "\"G\"" },
        { "\"\\u0048\"", "\"H\"" },
        { "\"\\u0049\"", "\"I\"" },
        { "\"\\u0041\\u0042\\u0043\"", "\"ABC\"" },
        { "\"\\u0041B\\u0043\"", "\"ABC\"" },
        { "\"A\\u0042\\u0043\"", "\"ABC\"" },
        { "\"\\u0041\\u0042C\"", "\"ABC\"" },
        { "[\"\\u0041\\u0042C\"]", "[\"ABC\"]" },
        { "\"\\u0041\\u004212\"", "\"AB12\"" },
    };

    for (auto pair: escapes) {
        REQUIRE_NOTHROW(p.parse(val, pair.first));
        REQUIRE(printer.print(val).compare(pair.second) == 0);
    }

    REQUIRE_THROWS(p.parse(val, "\"\\u0fg\""));
    REQUIRE_THROWS(p.parse(val, "\"\\u00\""));
    REQUIRE_THROWS(p.parse(val, "\"\\u\""));
}

TEST_CASE( "utils/base", "Unicode escape handling") {
    Value val = Object {
        { "a", 1 },
        { "b", 2 },
        { "c", 3}
    };

    PropertyList properties = traverse(val);
    REQUIRE(properties.size() == 3);

    PropertyList list = filter(traverse(val),
        [] (std::string name, Value& value) -> bool {
            return name.compare("b") == 0;
        });

    REQUIRE(list.size() == 2);
}

int main (int argc, char* const argv[]) {
     exit(Catch::Main( argc, argv ));
     return 0;
}
<commit_msg>fixed failing test<commit_after>#define CATCH_CONFIG_RUNNER
#include <iostream>
#include "./Catch/catch.hpp"
#include "../include/Elson.hpp"

using namespace JSON;

TEST_CASE( "base/types", "Basic JSON Data types" ) {
    Value val = 5;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("5") == 0);

    val = 3.0;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("3") == 0);

    val = 1L;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("1") == 0);

    val = 7u;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("7") == 0);

    val = -7.5;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("-7.5") == 0);

    val = -.05;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("-0.05") == 0);

    val = 1E3;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<std::string>().compare("1000") == 0);

    val = -7.5;
    REQUIRE(val.is(JSON_NUMBER));
    REQUIRE(val.as<unsigned int>() == 7);

    val = "5";
    REQUIRE(val.is(JSON_STRING));
    REQUIRE(val.as<int>() == 5);

    val = "5L";
    REQUIRE(val.is(JSON_STRING));
    REQUIRE(val.as<long>() == 5L);

    val = "\\";
    REQUIRE(val.is(JSON_STRING));
    REQUIRE(val.as<std::string>().compare("\\") == 0);

    val = true;
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(val.as<bool>());
    REQUIRE(val.as<int>() == 1);
    REQUIRE(val.as<std::string>() == "true");

    val = false;
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(!val.as<bool>());
    REQUIRE(val.as<int>() == 0);
    REQUIRE(val.as<std::string>() == "false");

    val = { true, false };
    REQUIRE(val[0].is(JSON_BOOL));
    REQUIRE(val[1].is(JSON_BOOL));
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(val[0].as<bool>());
    REQUIRE(!val[1].as<bool>());

    val = { 1, .5, "hello world", true, false, null };
    REQUIRE(val[0].is(JSON_NUMBER));
    REQUIRE(val[1].is(JSON_NUMBER));
    REQUIRE(val[2].is(JSON_STRING));
    REQUIRE(val[3].is(JSON_BOOL));
    REQUIRE(val[4].is(JSON_BOOL));
    REQUIRE(val[5].is(JSON_NULL));

    val = { {1,0,0}, {0,1,0},{0,0,1} };
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(val.as<Array>().size() == 3);
    REQUIRE(val[0].is(JSON_ARRAY));
    REQUIRE(val[1].is(JSON_ARRAY));
    REQUIRE(val[2].is(JSON_ARRAY));
    REQUIRE(val[0].as<Array>().size() == 3);
    REQUIRE(val[1].as<Array>().size() == 3);
    REQUIRE(val[2].as<Array>().size() == 3);
    REQUIRE(val[0][0].is(JSON_NUMBER));
    REQUIRE(val[0][1].is(JSON_NUMBER));
    REQUIRE(val[0][2].is(JSON_NUMBER));
    REQUIRE(val[1][0].is(JSON_NUMBER));
    REQUIRE(val[1][1].is(JSON_NUMBER));
    REQUIRE(val[1][2].is(JSON_NUMBER));
    REQUIRE(val[2][0].is(JSON_NUMBER));
    REQUIRE(val[2][1].is(JSON_NUMBER));
    REQUIRE(val[2][2].is(JSON_NUMBER));

    std::string key = "property";
    val = Object { { "property", "value" } };
    REQUIRE(val.is(JSON_OBJECT));
    REQUIRE(val["property"].is(JSON_STRING));
    REQUIRE(val[key].is(JSON_STRING));
    REQUIRE(val[std::string("property")].is(JSON_STRING));

    REQUIRE(val["property"].as<std::string>().compare("value") == 0);

    val["property"] = 42;
    REQUIRE(val["property"].is(JSON_NUMBER));
    REQUIRE(val[key].as<unsigned int>() == 42);
}

TEST_CASE( "base/parse", "Basic parsing") {
    Parser p;
    Printer printer;
    Value val;

    REQUIRE_THROWS(p.parse(val, "[]a"));
    REQUIRE_THROWS(p.parse(val, "a[]"));

    REQUIRE_NOTHROW(p.parse(val, ""));
    REQUIRE(val.is(JSON_NULL));

    auto numbers = {"0", "1", "1E3", "1e-3", "0.5", "-.05e-07"};

    for (auto number: numbers) {
        REQUIRE_NOTHROW(p.parse(val, number));
        REQUIRE(val.is(JSON_NUMBER));
    }

    REQUIRE_THROWS(p.parse(val, "-0.5w4"));

    std::vector<std::string> strings = {
        "\"\"",
        "\"0\"",
        "\"hello world\"",
        "\"äöüȩéáã\""
    };

    for (int i = 0; i < strings.size(); i++) {
        REQUIRE_NOTHROW(p.parse(val, strings[i]));
        REQUIRE(printer.print(val).compare(strings[i]) == 0);
    }

    std::map<std::string, std::string> escapes = {
        { "\"\\\\\"", "\"\\\"" },
        { "\"\\/\"", "\"/\"" },
        { "\"\\u5022\"", "\"倢\"" }
    };

    for (auto pair: escapes) {
        REQUIRE_NOTHROW(p.parse(val, pair.first));
        REQUIRE(printer.print(val).compare(pair.second) == 0);
    }

    REQUIRE_NOTHROW(p.parse(val, "true"));
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(val.as<bool>());
    REQUIRE(printer.print(val).compare("true") == 0);

    REQUIRE_NOTHROW(p.parse(val, "false"));
    REQUIRE(val.is(JSON_BOOL));
    REQUIRE(!val.as<bool>());
    REQUIRE(printer.print(val).compare("false") == 0);

    REQUIRE_NOTHROW(p.parse(val, "null"));
    REQUIRE(val.is(JSON_NULL));
    REQUIRE(printer.print(val).compare("null") == 0);

    REQUIRE_NOTHROW(p.parse(val, "[]"));
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(printer.print(val).compare("[]") == 0);
    REQUIRE(val.as<Array>().size() == 0);

    REQUIRE_NOTHROW(p.parse(val, "[ 1, 2,   4   ]"));
    REQUIRE(val.is(JSON_ARRAY));
    REQUIRE(printer.print(val).compare("[1,2,4]") == 0);
    REQUIRE(val.as<Array>().size() == 3);

    REQUIRE_THROWS(p.parse(val, "["));
    REQUIRE_THROWS(p.parse(val, "]"));
    REQUIRE_THROWS(p.parse(val, "[["));
    REQUIRE_THROWS(p.parse(val, "]]"));
    REQUIRE_THROWS(p.parse(val, "[,]"));
    REQUIRE_THROWS(p.parse(val, "[][]"));
    REQUIRE_THROWS(p.parse(val, "[1,]"));
    REQUIRE_THROWS(p.parse(val, "[,1]"));
    REQUIRE_THROWS(p.parse(val, "[1,2"));
    REQUIRE_THROWS(p.parse(val, "1,2]"));
    REQUIRE_THROWS(p.parse(val, "[[],[]"));
    REQUIRE_THROWS(p.parse(val, "[[],]]"));
    REQUIRE_THROWS(p.parse(val, "[[1,2,],[]]"));
    REQUIRE_THROWS(p.parse(val, "[[1,2,] []]"));

    REQUIRE_NOTHROW(p.parse(val, "[[]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[]]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[],[]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[]],[[]]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[1]],[[2]]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[1,null,true,false,\"\"]],[[]]]"));
    REQUIRE(val[0][0][0].is(JSON_NUMBER));
    REQUIRE(val[0][0][1].is(JSON_NULL));
    REQUIRE(val[0][0][2].is(JSON_BOOL));
    REQUIRE(val[0][0][3].is(JSON_BOOL));
    REQUIRE(val[0][0][4].is(JSON_STRING));
    REQUIRE(val[0][0].as<Array>().size() == 5);
    REQUIRE(printer.print(val).compare("[[[1,null,true,false,\"\"]],[[]]]") == 0);

    val[0][0].as<Array>().push_back(null);
    REQUIRE(val[0][0].as<Array>().size() == 5);

    val[0][0].asMutable<Array>().push_back(null);
    REQUIRE(val[0][0].as<Array>().size() == 6);

    REQUIRE_NOTHROW(p.parse(val, "{}"));
    REQUIRE_THROWS(p.parse(val, "{1}"));
    REQUIRE_THROWS(p.parse(val, "{{}}"));
    REQUIRE_NOTHROW(p.parse(val, "{\"a\": \"b\"}"));
    REQUIRE(val["a"].as<std::string>().compare("b") == 0);
    REQUIRE_THROWS(val.as<double>());

    REQUIRE_NOTHROW(p.parse(val, "[{}]"));
    REQUIRE_NOTHROW(p.parse(val, "[{},{}]"));
    REQUIRE_NOTHROW(p.parse(val, "[{},[]]"));
    REQUIRE_NOTHROW(p.parse(val, "[[[{}]]]"));
    REQUIRE_THROWS(p.parse(val, "[[[{}]]"));
    REQUIRE_THROWS(p.parse(val, "[{}]]"));
    REQUIRE_THROWS(p.parse(val, "{[]}"));
}

TEST_CASE( "base/unicode", "Unicode escape handling") {
    Parser p;
    Printer printer;
    Value val;

    std::map<std::string, std::string> escapes = {
        { "\"\\u0041\"", "\"A\"" },
        { "\"\\u0042\"", "\"B\"" },
        { "\"\\u0043\"", "\"C\"" },
        { "\"\\u0044\"", "\"D\"" },
        { "\"\\u0045\"", "\"E\"" },
        { "\"\\u0046\"", "\"F\"" },
        { "\"\\u0047\"", "\"G\"" },
        { "\"\\u0048\"", "\"H\"" },
        { "\"\\u0049\"", "\"I\"" },
        { "\"\\u0041\\u0042\\u0043\"", "\"ABC\"" },
        { "\"\\u0041B\\u0043\"", "\"ABC\"" },
        { "\"A\\u0042\\u0043\"", "\"ABC\"" },
        { "\"\\u0041\\u0042C\"", "\"ABC\"" },
        { "[\"\\u0041\\u0042C\"]", "[\"ABC\"]" },
        { "\"\\u0041\\u004212\"", "\"AB12\"" },
    };

    for (auto pair: escapes) {
        REQUIRE_NOTHROW(p.parse(val, pair.first));
        REQUIRE(printer.print(val).compare(pair.second) == 0);
    }

    REQUIRE_THROWS(p.parse(val, "\"\\u0fg\""));
    REQUIRE_THROWS(p.parse(val, "\"\\u00\""));
    REQUIRE_THROWS(p.parse(val, "\"\\u\""));
}

TEST_CASE( "utils/base", "Unicode escape handling") {
    Value val = Object {
        { "a", 1 },
        { "b", 2 },
        { "c", 3}
    };

    PropertyList properties = traverse(val);
    REQUIRE(properties.size() == 3);

    PropertyList list = filter(traverse(val),
        [] (std::string name, Value& value) -> bool {
            return name.compare("b") == 0;
        });

    REQUIRE(list.size() == 1);
}

int main (int argc, char* const argv[]) {
     exit(Catch::Main( argc, argv ));
     return 0;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2013 The WebRTC 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 in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/common_types.h"

#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/video_coding_impl.h"
#include "webrtc/system_wrappers/interface/clock.h"

namespace webrtc {
namespace vcm {

VideoSender::VideoSender(const int32_t id, Clock* clock)
    : _id(id),
      clock_(clock),
      _sendCritSect(CriticalSectionWrapper::CreateCriticalSection()),
      _encoder(),
      _encodedFrameCallback(),
      _nextFrameTypes(1, kVideoFrameDelta),
      _mediaOpt(id, clock_),
      _sendStatsCallback(NULL),
      _encoderInputFile(NULL),
      _codecDataBase(id),
      frame_dropper_enabled_(true),
      _sendStatsTimer(1000, clock_) {}

VideoSender::~VideoSender() {
  delete _sendCritSect;
  if (_encoderInputFile != NULL) {
    fclose(_encoderInputFile);
  }
}

int32_t VideoSender::Process() {
  int32_t returnValue = VCM_OK;

  if (_sendStatsTimer.TimeUntilProcess() == 0) {
    _sendStatsTimer.Processed();
    if (_sendStatsCallback != NULL) {
      uint32_t bitRate;
      uint32_t frameRate;
      {
        CriticalSectionScoped cs(_sendCritSect);
        bitRate = _mediaOpt.SentBitRate();
        frameRate = _mediaOpt.SentFrameRate();
      }
      _sendStatsCallback->SendStatistics(bitRate, frameRate);
    }
  }

  return returnValue;
}

// Reset send side to initial state - all components
int32_t VideoSender::InitializeSender() {
  CriticalSectionScoped cs(_sendCritSect);
  _codecDataBase.ResetSender();
  _encoder = NULL;
  _encodedFrameCallback.SetTransportCallback(NULL);
  // setting default bitRate and frameRate to 0
  _mediaOpt.SetEncodingData(kVideoCodecUnknown, 0, 0, 0, 0, 0, 0);
  _mediaOpt.Reset();  // Resetting frame dropper
  return VCM_OK;
}

int32_t VideoSender::TimeUntilNextProcess() {
  return _sendStatsTimer.TimeUntilProcess();
}

// Register the send codec to be used.
int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec,
                                       uint32_t numberOfCores,
                                       uint32_t maxPayloadSize) {
  CriticalSectionScoped cs(_sendCritSect);
  if (sendCodec == NULL) {
    return VCM_PARAMETER_ERROR;
  }

  bool ret = _codecDataBase.SetSendCodec(
      sendCodec, numberOfCores, maxPayloadSize, &_encodedFrameCallback);

  // Update encoder regardless of result to make sure that we're not holding on
  // to a deleted instance.
  _encoder = _codecDataBase.GetEncoder();

  if (!ret) {
    WEBRTC_TRACE(webrtc::kTraceError,
                 webrtc::kTraceVideoCoding,
                 VCMId(_id),
                 "Failed to initialize encoder");
    return VCM_CODEC_ERROR;
  }

  int numLayers = (sendCodec->codecType != kVideoCodecVP8)
                      ? 1
                      : sendCodec->codecSpecific.VP8.numberOfTemporalLayers;
  // If we have screensharing and we have layers, we disable frame dropper.
  bool disable_frame_dropper =
      numLayers > 1 && sendCodec->mode == kScreensharing;
  if (disable_frame_dropper) {
    _mediaOpt.EnableFrameDropper(false);
  } else if (frame_dropper_enabled_) {
    _mediaOpt.EnableFrameDropper(true);
  }
  _nextFrameTypes.clear();
  _nextFrameTypes.resize(VCM_MAX(sendCodec->numberOfSimulcastStreams, 1),
                         kVideoFrameDelta);

  _mediaOpt.SetEncodingData(sendCodec->CodecType,
                            sendCodec->maxBitrate * 1000,
                            sendCodec->maxFramerate * 1000,
                            sendCodec->startBitrate * 1000,
                            sendCodec->width,
                            sendCodec->height,
                            numLayers);
  _mediaOpt.SetMtu(maxPayloadSize);

  return VCM_OK;
}

// Get current send codec
int32_t VideoSender::SendCodec(VideoCodec* currentSendCodec) const {
  CriticalSectionScoped cs(_sendCritSect);

  if (currentSendCodec == NULL) {
    return VCM_PARAMETER_ERROR;
  }
  return _codecDataBase.SendCodec(currentSendCodec) ? 0 : -1;
}

// Get the current send codec type
VideoCodecType VideoSender::SendCodec() const {
  CriticalSectionScoped cs(_sendCritSect);

  return _codecDataBase.SendCodec();
}

// Register an external decoder object.
// This can not be used together with external decoder callbacks.
int32_t VideoSender::RegisterExternalEncoder(VideoEncoder* externalEncoder,
                                             uint8_t payloadType,
                                             bool internalSource /*= false*/) {
  CriticalSectionScoped cs(_sendCritSect);

  if (externalEncoder == NULL) {
    bool wasSendCodec = false;
    const bool ret =
        _codecDataBase.DeregisterExternalEncoder(payloadType, &wasSendCodec);
    if (wasSendCodec) {
      // Make sure the VCM doesn't use the de-registered codec
      _encoder = NULL;
    }
    return ret ? 0 : -1;
  }
  _codecDataBase.RegisterExternalEncoder(
      externalEncoder, payloadType, internalSource);
  return 0;
}

// Get codec config parameters
int32_t VideoSender::CodecConfigParameters(uint8_t* buffer, int32_t size) {
  CriticalSectionScoped cs(_sendCritSect);
  if (_encoder != NULL) {
    return _encoder->CodecConfigParameters(buffer, size);
  }
  return VCM_UNINITIALIZED;
}

// Get encode bitrate
int VideoSender::Bitrate(unsigned int* bitrate) const {
  CriticalSectionScoped cs(_sendCritSect);
  // return the bit rate which the encoder is set to
  if (!_encoder) {
    return VCM_UNINITIALIZED;
  }
  *bitrate = _encoder->BitRate();
  return 0;
}

// Get encode frame rate
int VideoSender::FrameRate(unsigned int* framerate) const {
  CriticalSectionScoped cs(_sendCritSect);
  // input frame rate, not compensated
  if (!_encoder) {
    return VCM_UNINITIALIZED;
  }
  *framerate = _encoder->FrameRate();
  return 0;
}

// Set channel parameters
int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate,
                                          uint8_t lossRate,
                                          uint32_t rtt) {
  int32_t ret = 0;
  {
    CriticalSectionScoped sendCs(_sendCritSect);
    uint32_t targetRate =
        _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt);
    if (_encoder != NULL) {
      ret = _encoder->SetChannelParameters(lossRate, rtt);
      if (ret < 0) {
        return ret;
      }
      ret = (int32_t)_encoder->SetRates(targetRate, _mediaOpt.InputFrameRate());
      if (ret < 0) {
        return ret;
      }
    } else {
      return VCM_UNINITIALIZED;
    }  // encoder
  }    // send side
  return VCM_OK;
}

int32_t VideoSender::RegisterTransportCallback(
    VCMPacketizationCallback* transport) {
  CriticalSectionScoped cs(_sendCritSect);
  _encodedFrameCallback.SetMediaOpt(&_mediaOpt);
  _encodedFrameCallback.SetTransportCallback(transport);
  return VCM_OK;
}

// Register video output information callback which will be called to deliver
// information about the video stream produced by the encoder, for instance the
// average frame rate and bit rate.
int32_t VideoSender::RegisterSendStatisticsCallback(
    VCMSendStatisticsCallback* sendStats) {
  CriticalSectionScoped cs(_sendCritSect);
  _sendStatsCallback = sendStats;
  return VCM_OK;
}

// Register a video quality settings callback which will be called when frame
// rate/dimensions need to be updated for video quality optimization
int32_t VideoSender::RegisterVideoQMCallback(
    VCMQMSettingsCallback* videoQMSettings) {
  CriticalSectionScoped cs(_sendCritSect);
  return _mediaOpt.RegisterVideoQMCallback(videoQMSettings);
}

// Register a video protection callback which will be called to deliver the
// requested FEC rate and NACK status (on/off).
int32_t VideoSender::RegisterProtectionCallback(
    VCMProtectionCallback* protection) {
  CriticalSectionScoped cs(_sendCritSect);
  _mediaOpt.RegisterProtectionCallback(protection);
  return VCM_OK;
}

// Enable or disable a video protection method.
// Note: This API should be deprecated, as it does not offer a distinction
// between the protection method and decoding with or without errors. If such a
// behavior is desired, use the following API: SetReceiverRobustnessMode.
int32_t VideoSender::SetVideoProtection(VCMVideoProtection videoProtection,
                                        bool enable) {
  switch (videoProtection) {
    case kProtectionNack:
    case kProtectionNackSender: {
      CriticalSectionScoped cs(_sendCritSect);
      _mediaOpt.EnableProtectionMethod(enable, media_optimization::kNack);
      break;
    }

    case kProtectionNackFEC: {
      CriticalSectionScoped cs(_sendCritSect);
      _mediaOpt.EnableProtectionMethod(enable, media_optimization::kNackFec);
      break;
    }

    case kProtectionFEC: {
      CriticalSectionScoped cs(_sendCritSect);
      _mediaOpt.EnableProtectionMethod(enable, media_optimization::kFec);
      break;
    }

    case kProtectionPeriodicKeyFrames: {
      CriticalSectionScoped cs(_sendCritSect);
      return _codecDataBase.SetPeriodicKeyFrames(enable) ? 0 : -1;
      break;
    }
    case kProtectionNackReceiver:
    case kProtectionDualDecoder:
    case kProtectionKeyOnLoss:
    case kProtectionKeyOnKeyLoss:
      // Ignore decoder modes.
      return VCM_OK;
  }
  return VCM_OK;
}
// Add one raw video frame to the encoder, blocking.
int32_t VideoSender::AddVideoFrame(const I420VideoFrame& videoFrame,
                                   const VideoContentMetrics* contentMetrics,
                                   const CodecSpecificInfo* codecSpecificInfo) {
  CriticalSectionScoped cs(_sendCritSect);
  if (_encoder == NULL) {
    return VCM_UNINITIALIZED;
  }
  // TODO(holmer): Add support for dropping frames per stream. Currently we
  // only have one frame dropper for all streams.
  if (_nextFrameTypes[0] == kFrameEmpty) {
    return VCM_OK;
  }
  _mediaOpt.UpdateIncomingFrameRate();

  if (_mediaOpt.DropFrame()) {
    WEBRTC_TRACE(webrtc::kTraceStream,
                 webrtc::kTraceVideoCoding,
                 VCMId(_id),
                 "Drop frame due to bitrate");
  } else {
    _mediaOpt.UpdateContentData(contentMetrics);
    int32_t ret =
        _encoder->Encode(videoFrame, codecSpecificInfo, _nextFrameTypes);
    if (_encoderInputFile != NULL) {
      if (PrintI420VideoFrame(videoFrame, _encoderInputFile) < 0) {
        return -1;
      }
    }
    if (ret < 0) {
      WEBRTC_TRACE(webrtc::kTraceError,
                   webrtc::kTraceVideoCoding,
                   VCMId(_id),
                   "Encode error: %d",
                   ret);
      return ret;
    }
    for (size_t i = 0; i < _nextFrameTypes.size(); ++i) {
      _nextFrameTypes[i] = kVideoFrameDelta;  // Default frame type.
    }
  }
  return VCM_OK;
}

int32_t VideoSender::IntraFrameRequest(int stream_index) {
  CriticalSectionScoped cs(_sendCritSect);
  if (stream_index < 0 ||
      static_cast<unsigned int>(stream_index) >= _nextFrameTypes.size()) {
    return -1;
  }
  _nextFrameTypes[stream_index] = kVideoFrameKey;
  if (_encoder != NULL && _encoder->InternalSource()) {
    // Try to request the frame if we have an external encoder with
    // internal source since AddVideoFrame never will be called.
    if (_encoder->RequestFrame(_nextFrameTypes) == WEBRTC_VIDEO_CODEC_OK) {
      _nextFrameTypes[stream_index] = kVideoFrameDelta;
    }
  }
  return VCM_OK;
}

int32_t VideoSender::EnableFrameDropper(bool enable) {
  CriticalSectionScoped cs(_sendCritSect);
  frame_dropper_enabled_ = enable;
  _mediaOpt.EnableFrameDropper(enable);
  return VCM_OK;
}

int32_t VideoSender::SentFrameCount(VCMFrameCount* frameCount) const {
  CriticalSectionScoped cs(_sendCritSect);
  return _mediaOpt.SentFrameCount(*frameCount);
}

int VideoSender::SetSenderNackMode(SenderNackMode mode) {
  CriticalSectionScoped cs(_sendCritSect);

  switch (mode) {
    case VideoCodingModule::kNackNone:
      _mediaOpt.EnableProtectionMethod(false, media_optimization::kNack);
      break;
    case VideoCodingModule::kNackAll:
      _mediaOpt.EnableProtectionMethod(true, media_optimization::kNack);
      break;
    case VideoCodingModule::kNackSelective:
      return VCM_NOT_IMPLEMENTED;
      break;
  }
  return VCM_OK;
}

int VideoSender::SetSenderReferenceSelection(bool enable) {
  return VCM_NOT_IMPLEMENTED;
}

int VideoSender::SetSenderFEC(bool enable) {
  CriticalSectionScoped cs(_sendCritSect);
  _mediaOpt.EnableProtectionMethod(enable, media_optimization::kFec);
  return VCM_OK;
}

int VideoSender::SetSenderKeyFramePeriod(int periodMs) {
  return VCM_NOT_IMPLEMENTED;
}

int VideoSender::StartDebugRecording(const char* file_name_utf8) {
  CriticalSectionScoped cs(_sendCritSect);
  _encoderInputFile = fopen(file_name_utf8, "wb");
  if (_encoderInputFile == NULL)
    return VCM_GENERAL_ERROR;
  return VCM_OK;
}

int VideoSender::StopDebugRecording() {
  CriticalSectionScoped cs(_sendCritSect);
  if (_encoderInputFile != NULL) {
    fclose(_encoderInputFile);
    _encoderInputFile = NULL;
  }
  return VCM_OK;
}

}  // namespace vcm
}  // namespace webrtc
<commit_msg>Fix typo in r4765.<commit_after>/*
 *  Copyright (c) 2013 The WebRTC 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 in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/common_types.h"

#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/video_coding_impl.h"
#include "webrtc/system_wrappers/interface/clock.h"

namespace webrtc {
namespace vcm {

VideoSender::VideoSender(const int32_t id, Clock* clock)
    : _id(id),
      clock_(clock),
      _sendCritSect(CriticalSectionWrapper::CreateCriticalSection()),
      _encoder(),
      _encodedFrameCallback(),
      _nextFrameTypes(1, kVideoFrameDelta),
      _mediaOpt(id, clock_),
      _sendStatsCallback(NULL),
      _encoderInputFile(NULL),
      _codecDataBase(id),
      frame_dropper_enabled_(true),
      _sendStatsTimer(1000, clock_) {}

VideoSender::~VideoSender() {
  delete _sendCritSect;
  if (_encoderInputFile != NULL) {
    fclose(_encoderInputFile);
  }
}

int32_t VideoSender::Process() {
  int32_t returnValue = VCM_OK;

  if (_sendStatsTimer.TimeUntilProcess() == 0) {
    _sendStatsTimer.Processed();
    if (_sendStatsCallback != NULL) {
      uint32_t bitRate;
      uint32_t frameRate;
      {
        CriticalSectionScoped cs(_sendCritSect);
        bitRate = _mediaOpt.SentBitRate();
        frameRate = _mediaOpt.SentFrameRate();
      }
      _sendStatsCallback->SendStatistics(bitRate, frameRate);
    }
  }

  return returnValue;
}

// Reset send side to initial state - all components
int32_t VideoSender::InitializeSender() {
  CriticalSectionScoped cs(_sendCritSect);
  _codecDataBase.ResetSender();
  _encoder = NULL;
  _encodedFrameCallback.SetTransportCallback(NULL);
  // setting default bitRate and frameRate to 0
  _mediaOpt.SetEncodingData(kVideoCodecUnknown, 0, 0, 0, 0, 0, 0);
  _mediaOpt.Reset();  // Resetting frame dropper
  return VCM_OK;
}

int32_t VideoSender::TimeUntilNextProcess() {
  return _sendStatsTimer.TimeUntilProcess();
}

// Register the send codec to be used.
int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec,
                                       uint32_t numberOfCores,
                                       uint32_t maxPayloadSize) {
  CriticalSectionScoped cs(_sendCritSect);
  if (sendCodec == NULL) {
    return VCM_PARAMETER_ERROR;
  }

  bool ret = _codecDataBase.SetSendCodec(
      sendCodec, numberOfCores, maxPayloadSize, &_encodedFrameCallback);

  // Update encoder regardless of result to make sure that we're not holding on
  // to a deleted instance.
  _encoder = _codecDataBase.GetEncoder();

  if (!ret) {
    WEBRTC_TRACE(webrtc::kTraceError,
                 webrtc::kTraceVideoCoding,
                 VCMId(_id),
                 "Failed to initialize encoder");
    return VCM_CODEC_ERROR;
  }

  int numLayers = (sendCodec->codecType != kVideoCodecVP8)
                      ? 1
                      : sendCodec->codecSpecific.VP8.numberOfTemporalLayers;
  // If we have screensharing and we have layers, we disable frame dropper.
  bool disable_frame_dropper =
      numLayers > 1 && sendCodec->mode == kScreensharing;
  if (disable_frame_dropper) {
    _mediaOpt.EnableFrameDropper(false);
  } else if (frame_dropper_enabled_) {
    _mediaOpt.EnableFrameDropper(true);
  }
  _nextFrameTypes.clear();
  _nextFrameTypes.resize(VCM_MAX(sendCodec->numberOfSimulcastStreams, 1),
                         kVideoFrameDelta);

  _mediaOpt.SetEncodingData(sendCodec->codecType,
                            sendCodec->maxBitrate * 1000,
                            sendCodec->maxFramerate * 1000,
                            sendCodec->startBitrate * 1000,
                            sendCodec->width,
                            sendCodec->height,
                            numLayers);
  _mediaOpt.SetMtu(maxPayloadSize);

  return VCM_OK;
}

// Get current send codec
int32_t VideoSender::SendCodec(VideoCodec* currentSendCodec) const {
  CriticalSectionScoped cs(_sendCritSect);

  if (currentSendCodec == NULL) {
    return VCM_PARAMETER_ERROR;
  }
  return _codecDataBase.SendCodec(currentSendCodec) ? 0 : -1;
}

// Get the current send codec type
VideoCodecType VideoSender::SendCodec() const {
  CriticalSectionScoped cs(_sendCritSect);

  return _codecDataBase.SendCodec();
}

// Register an external decoder object.
// This can not be used together with external decoder callbacks.
int32_t VideoSender::RegisterExternalEncoder(VideoEncoder* externalEncoder,
                                             uint8_t payloadType,
                                             bool internalSource /*= false*/) {
  CriticalSectionScoped cs(_sendCritSect);

  if (externalEncoder == NULL) {
    bool wasSendCodec = false;
    const bool ret =
        _codecDataBase.DeregisterExternalEncoder(payloadType, &wasSendCodec);
    if (wasSendCodec) {
      // Make sure the VCM doesn't use the de-registered codec
      _encoder = NULL;
    }
    return ret ? 0 : -1;
  }
  _codecDataBase.RegisterExternalEncoder(
      externalEncoder, payloadType, internalSource);
  return 0;
}

// Get codec config parameters
int32_t VideoSender::CodecConfigParameters(uint8_t* buffer, int32_t size) {
  CriticalSectionScoped cs(_sendCritSect);
  if (_encoder != NULL) {
    return _encoder->CodecConfigParameters(buffer, size);
  }
  return VCM_UNINITIALIZED;
}

// Get encode bitrate
int VideoSender::Bitrate(unsigned int* bitrate) const {
  CriticalSectionScoped cs(_sendCritSect);
  // return the bit rate which the encoder is set to
  if (!_encoder) {
    return VCM_UNINITIALIZED;
  }
  *bitrate = _encoder->BitRate();
  return 0;
}

// Get encode frame rate
int VideoSender::FrameRate(unsigned int* framerate) const {
  CriticalSectionScoped cs(_sendCritSect);
  // input frame rate, not compensated
  if (!_encoder) {
    return VCM_UNINITIALIZED;
  }
  *framerate = _encoder->FrameRate();
  return 0;
}

// Set channel parameters
int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate,
                                          uint8_t lossRate,
                                          uint32_t rtt) {
  int32_t ret = 0;
  {
    CriticalSectionScoped sendCs(_sendCritSect);
    uint32_t targetRate =
        _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt);
    if (_encoder != NULL) {
      ret = _encoder->SetChannelParameters(lossRate, rtt);
      if (ret < 0) {
        return ret;
      }
      ret = (int32_t)_encoder->SetRates(targetRate, _mediaOpt.InputFrameRate());
      if (ret < 0) {
        return ret;
      }
    } else {
      return VCM_UNINITIALIZED;
    }  // encoder
  }    // send side
  return VCM_OK;
}

int32_t VideoSender::RegisterTransportCallback(
    VCMPacketizationCallback* transport) {
  CriticalSectionScoped cs(_sendCritSect);
  _encodedFrameCallback.SetMediaOpt(&_mediaOpt);
  _encodedFrameCallback.SetTransportCallback(transport);
  return VCM_OK;
}

// Register video output information callback which will be called to deliver
// information about the video stream produced by the encoder, for instance the
// average frame rate and bit rate.
int32_t VideoSender::RegisterSendStatisticsCallback(
    VCMSendStatisticsCallback* sendStats) {
  CriticalSectionScoped cs(_sendCritSect);
  _sendStatsCallback = sendStats;
  return VCM_OK;
}

// Register a video quality settings callback which will be called when frame
// rate/dimensions need to be updated for video quality optimization
int32_t VideoSender::RegisterVideoQMCallback(
    VCMQMSettingsCallback* videoQMSettings) {
  CriticalSectionScoped cs(_sendCritSect);
  return _mediaOpt.RegisterVideoQMCallback(videoQMSettings);
}

// Register a video protection callback which will be called to deliver the
// requested FEC rate and NACK status (on/off).
int32_t VideoSender::RegisterProtectionCallback(
    VCMProtectionCallback* protection) {
  CriticalSectionScoped cs(_sendCritSect);
  _mediaOpt.RegisterProtectionCallback(protection);
  return VCM_OK;
}

// Enable or disable a video protection method.
// Note: This API should be deprecated, as it does not offer a distinction
// between the protection method and decoding with or without errors. If such a
// behavior is desired, use the following API: SetReceiverRobustnessMode.
int32_t VideoSender::SetVideoProtection(VCMVideoProtection videoProtection,
                                        bool enable) {
  switch (videoProtection) {
    case kProtectionNack:
    case kProtectionNackSender: {
      CriticalSectionScoped cs(_sendCritSect);
      _mediaOpt.EnableProtectionMethod(enable, media_optimization::kNack);
      break;
    }

    case kProtectionNackFEC: {
      CriticalSectionScoped cs(_sendCritSect);
      _mediaOpt.EnableProtectionMethod(enable, media_optimization::kNackFec);
      break;
    }

    case kProtectionFEC: {
      CriticalSectionScoped cs(_sendCritSect);
      _mediaOpt.EnableProtectionMethod(enable, media_optimization::kFec);
      break;
    }

    case kProtectionPeriodicKeyFrames: {
      CriticalSectionScoped cs(_sendCritSect);
      return _codecDataBase.SetPeriodicKeyFrames(enable) ? 0 : -1;
      break;
    }
    case kProtectionNackReceiver:
    case kProtectionDualDecoder:
    case kProtectionKeyOnLoss:
    case kProtectionKeyOnKeyLoss:
      // Ignore decoder modes.
      return VCM_OK;
  }
  return VCM_OK;
}
// Add one raw video frame to the encoder, blocking.
int32_t VideoSender::AddVideoFrame(const I420VideoFrame& videoFrame,
                                   const VideoContentMetrics* contentMetrics,
                                   const CodecSpecificInfo* codecSpecificInfo) {
  CriticalSectionScoped cs(_sendCritSect);
  if (_encoder == NULL) {
    return VCM_UNINITIALIZED;
  }
  // TODO(holmer): Add support for dropping frames per stream. Currently we
  // only have one frame dropper for all streams.
  if (_nextFrameTypes[0] == kFrameEmpty) {
    return VCM_OK;
  }
  _mediaOpt.UpdateIncomingFrameRate();

  if (_mediaOpt.DropFrame()) {
    WEBRTC_TRACE(webrtc::kTraceStream,
                 webrtc::kTraceVideoCoding,
                 VCMId(_id),
                 "Drop frame due to bitrate");
  } else {
    _mediaOpt.UpdateContentData(contentMetrics);
    int32_t ret =
        _encoder->Encode(videoFrame, codecSpecificInfo, _nextFrameTypes);
    if (_encoderInputFile != NULL) {
      if (PrintI420VideoFrame(videoFrame, _encoderInputFile) < 0) {
        return -1;
      }
    }
    if (ret < 0) {
      WEBRTC_TRACE(webrtc::kTraceError,
                   webrtc::kTraceVideoCoding,
                   VCMId(_id),
                   "Encode error: %d",
                   ret);
      return ret;
    }
    for (size_t i = 0; i < _nextFrameTypes.size(); ++i) {
      _nextFrameTypes[i] = kVideoFrameDelta;  // Default frame type.
    }
  }
  return VCM_OK;
}

int32_t VideoSender::IntraFrameRequest(int stream_index) {
  CriticalSectionScoped cs(_sendCritSect);
  if (stream_index < 0 ||
      static_cast<unsigned int>(stream_index) >= _nextFrameTypes.size()) {
    return -1;
  }
  _nextFrameTypes[stream_index] = kVideoFrameKey;
  if (_encoder != NULL && _encoder->InternalSource()) {
    // Try to request the frame if we have an external encoder with
    // internal source since AddVideoFrame never will be called.
    if (_encoder->RequestFrame(_nextFrameTypes) == WEBRTC_VIDEO_CODEC_OK) {
      _nextFrameTypes[stream_index] = kVideoFrameDelta;
    }
  }
  return VCM_OK;
}

int32_t VideoSender::EnableFrameDropper(bool enable) {
  CriticalSectionScoped cs(_sendCritSect);
  frame_dropper_enabled_ = enable;
  _mediaOpt.EnableFrameDropper(enable);
  return VCM_OK;
}

int32_t VideoSender::SentFrameCount(VCMFrameCount* frameCount) const {
  CriticalSectionScoped cs(_sendCritSect);
  return _mediaOpt.SentFrameCount(*frameCount);
}

int VideoSender::SetSenderNackMode(SenderNackMode mode) {
  CriticalSectionScoped cs(_sendCritSect);

  switch (mode) {
    case VideoCodingModule::kNackNone:
      _mediaOpt.EnableProtectionMethod(false, media_optimization::kNack);
      break;
    case VideoCodingModule::kNackAll:
      _mediaOpt.EnableProtectionMethod(true, media_optimization::kNack);
      break;
    case VideoCodingModule::kNackSelective:
      return VCM_NOT_IMPLEMENTED;
      break;
  }
  return VCM_OK;
}

int VideoSender::SetSenderReferenceSelection(bool enable) {
  return VCM_NOT_IMPLEMENTED;
}

int VideoSender::SetSenderFEC(bool enable) {
  CriticalSectionScoped cs(_sendCritSect);
  _mediaOpt.EnableProtectionMethod(enable, media_optimization::kFec);
  return VCM_OK;
}

int VideoSender::SetSenderKeyFramePeriod(int periodMs) {
  return VCM_NOT_IMPLEMENTED;
}

int VideoSender::StartDebugRecording(const char* file_name_utf8) {
  CriticalSectionScoped cs(_sendCritSect);
  _encoderInputFile = fopen(file_name_utf8, "wb");
  if (_encoderInputFile == NULL)
    return VCM_GENERAL_ERROR;
  return VCM_OK;
}

int VideoSender::StopDebugRecording() {
  CriticalSectionScoped cs(_sendCritSect);
  if (_encoderInputFile != NULL) {
    fclose(_encoderInputFile);
    _encoderInputFile = NULL;
  }
  return VCM_OK;
}

}  // namespace vcm
}  // namespace webrtc
<|endoftext|>


<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program 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; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#if HAVE_CONFIG_H
#include "config.h"
#endif

#ifndef HAVE_LIBVLC
# error This file requires libvlc
#endif

#include "NetworkFileSystemFactory.h"
#include "filesystem/network/Directory.h"
#include "utils/VLCInstance.h"
#include "MediaLibrary.h"

#include <algorithm>

namespace medialibrary
{
namespace factory
{

NetworkFileSystemFactory::NetworkFileSystemFactory( const std::string& protocol, const std::string& name )
    : m_protocol( protocol )
    , m_discoverer( VLCInstance::get(), name )
    , m_mediaList( m_discoverer.mediaList() )
{
    auto& em = m_mediaList->eventManager();
    em.onItemAdded( [this]( VLC::MediaPtr m, int ) { onDeviceAdded( std::move( m ) ); } );
    em.onItemDeleted( [this]( VLC::MediaPtr m, int ) { onDeviceRemoved( std::move( m ) ); } );
    m_discoverer.start();
}

std::shared_ptr<fs::IDirectory> NetworkFileSystemFactory::createDirectory( const std::string& path )
{
    return std::make_shared<fs::NetworkDirectory>( path, *this );
}

std::shared_ptr<fs::IDevice> NetworkFileSystemFactory::createDevice( const std::string& mrl )
{
    std::shared_ptr<fs::IDevice> res;
    std::unique_lock<compat::Mutex> lock( m_devicesLock );

    m_deviceCond.wait_for( lock, std::chrono::seconds{ 5 }, [this, &res, &mrl]() {
        auto it = std::find_if( begin( m_devices ), end( m_devices ), [&mrl]( const Device& d ) {
            return d.mrl == mrl;
        });
        if ( it == end( m_devices ) )
            return false;
        res = it->device;
        return true;
    });
    return res;
}

std::shared_ptr<fs::IDevice> NetworkFileSystemFactory::createDeviceFromMrl( const std::string& path )
{
    std::lock_guard<compat::Mutex> lock( m_devicesLock );
    auto it = std::find_if( begin( m_devices ), end( m_devices ), [&path]( const Device& d ) {
        return path.compare( 0, d.mrl.length(), d.mrl );
    });
    if ( it == end( m_devices ) )
        return nullptr;
    return it->device;
}

void NetworkFileSystemFactory::refreshDevices()
{
}

bool NetworkFileSystemFactory::isMrlSupported( const std::string& path ) const
{
    const auto idx = m_protocol.length();
    if ( path.compare( 0, idx, m_protocol ) != 0 )
        return false;
    return path[idx] == ':' && path[idx + 1] == '/' && path[idx + 2] == '/';

}

bool NetworkFileSystemFactory::isNetworkFileSystem() const
{
    return true;
}

void NetworkFileSystemFactory::onDeviceAdded( VLC::MediaPtr media )
{
    const auto& mrl = media->mrl();
    if ( mrl.compare( 0, m_protocol.length(), m_protocol ) != 0 )
        return;

    std::lock_guard<compat::Mutex> lock( m_devicesLock );
    auto it = std::find_if( begin( m_devices ), end( m_devices ), [&mrl]( const Device& d ) {
        return d.mrl== mrl;
    });
    if ( it != end( m_devices ) )
        return;
    const auto idx = m_protocol.length();
    if ( mrl[idx] != ':' || mrl[idx + 1] != '/' || mrl[idx + 2] != '/' )
        return;

    auto name = mrl.substr( idx + 3 );

    m_devices.emplace_back( name, mrl, *media );
    m_deviceCond.notify_one();
}

void NetworkFileSystemFactory::onDeviceRemoved( VLC::MediaPtr media )
{
    std::lock_guard<compat::Mutex> lock( m_devicesLock );
    const auto& mrl = media->mrl();
    m_devices.erase( std::remove_if( begin( m_devices ), end( m_devices ), [&mrl]( const Device& d ) {
        return d.mrl == mrl;
    }), end( m_devices ) );
}

}
}
<commit_msg>fs: network: Factory: Log when discovering device<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program 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; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#if HAVE_CONFIG_H
#include "config.h"
#endif

#ifndef HAVE_LIBVLC
# error This file requires libvlc
#endif

#include "NetworkFileSystemFactory.h"
#include "filesystem/network/Directory.h"
#include "utils/VLCInstance.h"
#include "MediaLibrary.h"

#include <algorithm>

#include "logging/Logger.h"

namespace medialibrary
{
namespace factory
{

NetworkFileSystemFactory::NetworkFileSystemFactory( const std::string& protocol, const std::string& name )
    : m_protocol( protocol )
    , m_discoverer( VLCInstance::get(), name )
    , m_mediaList( m_discoverer.mediaList() )
{
    auto& em = m_mediaList->eventManager();
    em.onItemAdded( [this]( VLC::MediaPtr m, int ) { onDeviceAdded( std::move( m ) ); } );
    em.onItemDeleted( [this]( VLC::MediaPtr m, int ) { onDeviceRemoved( std::move( m ) ); } );
    m_discoverer.start();
}

std::shared_ptr<fs::IDirectory> NetworkFileSystemFactory::createDirectory( const std::string& path )
{
    return std::make_shared<fs::NetworkDirectory>( path, *this );
}

std::shared_ptr<fs::IDevice> NetworkFileSystemFactory::createDevice( const std::string& mrl )
{
    std::shared_ptr<fs::IDevice> res;
    std::unique_lock<compat::Mutex> lock( m_devicesLock );

    m_deviceCond.wait_for( lock, std::chrono::seconds{ 5 }, [this, &res, &mrl]() {
        auto it = std::find_if( begin( m_devices ), end( m_devices ), [&mrl]( const Device& d ) {
            return d.mrl == mrl;
        });
        if ( it == end( m_devices ) )
            return false;
        res = it->device;
        return true;
    });
    return res;
}

std::shared_ptr<fs::IDevice> NetworkFileSystemFactory::createDeviceFromMrl( const std::string& path )
{
    std::lock_guard<compat::Mutex> lock( m_devicesLock );
    auto it = std::find_if( begin( m_devices ), end( m_devices ), [&path]( const Device& d ) {
        return path.compare( 0, d.mrl.length(), d.mrl );
    });
    if ( it == end( m_devices ) )
        return nullptr;
    return it->device;
}

void NetworkFileSystemFactory::refreshDevices()
{
}

bool NetworkFileSystemFactory::isMrlSupported( const std::string& path ) const
{
    const auto idx = m_protocol.length();
    if ( path.compare( 0, idx, m_protocol ) != 0 )
        return false;
    return path[idx] == ':' && path[idx + 1] == '/' && path[idx + 2] == '/';

}

bool NetworkFileSystemFactory::isNetworkFileSystem() const
{
    return true;
}

void NetworkFileSystemFactory::onDeviceAdded( VLC::MediaPtr media )
{
    const auto& mrl = media->mrl();
    if ( mrl.compare( 0, m_protocol.length(), m_protocol ) != 0 )
        return;

    std::lock_guard<compat::Mutex> lock( m_devicesLock );
    auto it = std::find_if( begin( m_devices ), end( m_devices ), [&mrl]( const Device& d ) {
        return d.mrl== mrl;
    });
    if ( it != end( m_devices ) )
        return;
    const auto idx = m_protocol.length();
    if ( mrl[idx] != ':' || mrl[idx + 1] != '/' || mrl[idx + 2] != '/' )
        return;

    auto name = mrl.substr( idx + 3 );

    LOG_INFO( "Adding new network device: name: ", name, " - mrl: ", mrl );
    m_devices.emplace_back( name, mrl, *media );
    m_deviceCond.notify_one();
}

void NetworkFileSystemFactory::onDeviceRemoved( VLC::MediaPtr media )
{
    std::lock_guard<compat::Mutex> lock( m_devicesLock );
    const auto& mrl = media->mrl();
    m_devices.erase( std::remove_if( begin( m_devices ), end( m_devices ), [&mrl]( const Device& d ) {
        return d.mrl == mrl;
    }), end( m_devices ) );
}

}
}
<|endoftext|>