<commit_before>//
//  main.cpp
//  Unit Tests
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "../cPWP/generateSimulatedData.h"
#include "../cPWP/bamsToBin.h"
//#include "../cPWP/calcPWP.h"
#include "../cPWP/calcPWPchunks.h"
#include "../cPWP/calcCOVARchunks.h"
#include "catch.hpp"
#include <string>
#include <iostream>
#include <fstream>

/*
TEST_CASE( "Simulated reads are generated", "[generateReads]" ) {
    // Make sure that the read simulation finishes
    REQUIRE( generateReadsAndMap(1, 0.01, "0.0", "300", "50", "1000000", "100", "1234", "scaffold_0.fasta") == 0);
}
 */

TEST_CASE( "Generate reference genome for simulation tests", "[generateReference]") {
    REQUIRE( createReferenceGenome(1000000, 0.42668722, "simulatedReferenceGenome.fasta") == 0 );
    //createReferenceGenome (int totalBases, double gcContent, std::string genomeOutFile)
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenome]") {
    REQUIRE( createMutatedGenome("simulatedReferenceGenome.fasta", "simulatedReferenceGenomeMutated.fasta", 0.01) == 0);
    //createMutatedGenome (std::string reference, std::string mutatedReferenceFile, float percDivergent)
}

TEST_CASE( "Generate sequence reads 5", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 5, 100, 300, "normalRef5") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// We need to create a set of reads that are half as dense as the first set, because when we concatenate the heterozygous chromosome reads to them we don't
// want the coverage to be twice as high.
TEST_CASE( "Generate sequence reads 10", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 10, 100, 300, "normalRef10") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// Map the reads for the homozygous individual
TEST_CASE( " Mapping first set of reads", "[mapReads]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "normalRef5_R1.fastq", "normalRef5_R2.fastq", "normal.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Generate the reads from the mutated reference chromosome
TEST_CASE( "Generate sequence reads 2", "[perfectReads2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutated.fasta", 10, 100, 300, "mutatedRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// Concatenate the het-reference reads to the homozygous reads reference for R1
TEST_CASE( "Create heterozygous R1", "[createHetR1]") {
    REQUIRE( createHeterozygousGenome("normalRef10_R1.fastq", "mutatedRef_R1.fastq", "hetRef_R1.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R2
TEST_CASE( "Create heterozygous R2", "[createHetR1]") {
    REQUIRE( createHeterozygousGenome("normalRef10_R2.fastq", "mutatedRef_R2.fastq", "hetRef_R2.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Map the reads for the heterozygous individual
TEST_CASE( " Mapping het reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "hetRef_R1.fastq", "hetRef_R2.fastq", "het.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Use angsd to generate the read counts for the two individuals
TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "5", "angsdOutLog.txt") == 0);
    //runANGSDforReadCounts (std::string bamlist, std::string angsdPrefix, std::string nThreads, std::string angsdOutputLog)
}

// Convert read counts to binary
TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("angsdOut", "angsdOut.readCounts.binary", 2, 250) == 0);
    //convertANGSDcountsToBinary(std::string angsdPrefix, std::string binaryOutputFileName, int numIndividuals, int readDepthMax)
}

// Run the PWP calculation
TEST_CASE( "Calculate PWP from the binary representations of the ANGSD readcounts", "[calcPWP]") {
    REQUIRE( calcPWPfromBinaryFile("angsdOut.readCounts.binary", 999990, 2, "testingOut.pwp", 1000, 5) == 0);
    //int calcPWPfromBinaryFile (std::string binaryFile, unsigned long long int numLoci, const int numIndividuals, std::string outFile, int lociChunkSize, int numThreads=30);
}

/*
 Covariance unit tests are below. They require different reference genomes to be used. In the example above, the homozygous reference genome
 has no variance in the major allele frequencies (they're always 1). The genomes created by this example have

 */

TEST_CASE( "Generate reference genome for the covariance tests", "[generateReferenceCovar]") {
    REQUIRE( createReferenceGenome(10000000, 0.42668722, "simulatedReferenceGenome10mil.fasta") == 0 );
    //createReferenceGenome (int totalBases, double gcContent, std::string genomeOutFile)
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenomeCovar]") {
    REQUIRE( createMutatedGenomesForCovar("simulatedReferenceGenome10mil.fasta", "simulatedReferenceGenomeMutatedRef1.fasta", "simulatedReferenceGenomeMutatedRef2.fasta", 0.01) == 0);
    //createMutatedGenomesForCovar (std::string reference, std::string mutatedReferenceFile1, std::string mutatedReferenceFile2, float percDivergent)
}

TEST_CASE( "Generate nonmutated chromosome covariance sequence reads for ind1 and ind2", "[perfectReadsCovarNoMut]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome10mil.fasta", 10, 100, 300, "covarRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( "Generate mutated chromosome covariance sequence reads for ind1", "[perfectReadsCovarInd1]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutatedRef1.fasta", 10, 100, 300, "covarMutRef1") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( "Generate mutated chromosome covariance sequence reads for ind2", "[perfectReadsCovarInd2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutatedRef2.fasta", 10, 100, 300, "covarMutRef2") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// Combine the mutated and non-mutated chromosome reads for each individual
// Concatenate the het-reference reads to the homozygous reads reference for R1
TEST_CASE( "Create heterozygous R1covar1", "[createHetR1covar1]") {
    REQUIRE( createHeterozygousGenome("covarRef_R1.fastq", "covarMutRef1_R1.fastq", "covarRef1_R1.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R2
TEST_CASE( "Create heterozygous R2covar1", "[createHetR2covar1]") {
    REQUIRE( createHeterozygousGenome("covarRef_R2.fastq", "covarMutRef1_R2.fastq", "covarRef1_R2.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R1
TEST_CASE( "Create heterozygous R1covar2", "[createHetR1covar2]") {
    REQUIRE( createHeterozygousGenome("covarRef_R1.fastq", "covarMutRef2_R1.fastq", "covarRef2_R1.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R2
TEST_CASE( "Create heterozygous R2covar2", "[createHetR2covar2]") {
    REQUIRE( createHeterozygousGenome("covarRef_R2.fastq", "covarMutRef2_R2.fastq", "covarRef2_R2.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Map the reads for individual 1
TEST_CASE( " Mapping reads for covariance ind1", "[mapReadsCovar1]") {
    REQUIRE( mapReads("simulatedReferenceGenome10mil.fasta", "covarRef1_R1.fastq", "covarRef1_R2.fastq", "covarInd1.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Map the reads for individual 2
TEST_CASE( " Mapping reads for covariance ind2", "[mapReadsCovar2]") {
    REQUIRE( mapReads("simulatedReferenceGenome10mil.fasta", "covarRef2_R1.fastq", "covarRef2_R2.fastq", "covarInd2.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Use angsd to generate the read counts for the two individuals
TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("covarBamlist.txt", "covarAngsdOut", "5", "covarAngsdOutLog.txt") == 0);
    //runANGSDforReadCounts (std::string bamlist, std::string angsdPrefix, std::string nThreads, std::string angsdOutputLog)
}

// Convert read counts to binary
TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("covarAngsdOut", "covarAngsdOut.readCounts.binary", 2, 250) == 0);
    //convertANGSDcountsToBinary(std::string angsdPrefix, std::string binaryOutputFileName, int numIndividuals, int readDepthMax)
}

TEST_CASE( "Calculate covariances from the same representations of the ANGSD readcounts", "[calcCovar]") {
    REQUIRE(  calcCOVARfromBinaryFile("covarAngsdOut.readCounts.binary", 9999990, 2, "testingOut.covar", 1000, 5)== 0);
    //calcCOVARfromBinaryFile (std::string binaryFile, long long int numLoci, const int numIndividuals, std::string outFile, int lociChunkSize, const int numThreads)
}

<commit_msg>Minor change<commit_after>//
//  main.cpp
//  Unit Tests
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "../cPWP/generateSimulatedData.h"
#include "../cPWP/bamsToBin.h"
//#include "../cPWP/calcPWP.h"
#include "../cPWP/calcPWPchunks.h"
#include "../cPWP/calcCOVARchunks.h"
#include "catch.hpp"
#include <string>
#include <iostream>
#include <fstream>

/*
TEST_CASE( "Simulated reads are generated", "[generateReads]" ) {
    // Make sure that the read simulation finishes
    REQUIRE( generateReadsAndMap(1, 0.01, "0.0", "300", "50", "1000000", "100", "1234", "scaffold_0.fasta") == 0);
}
 */

TEST_CASE( "Generate reference genome for simulation tests", "[generateReference]") {
    REQUIRE( createReferenceGenome(1000000, 0.42668722, "simulatedReferenceGenome.fasta") == 0 );
    //createReferenceGenome (int totalBases, double gcContent, std::string genomeOutFile)
}

TEST_CASE ( "Mutate a reference genome", "[mutateRefGenome]") {
    REQUIRE( createMutatedGenome("simulatedReferenceGenome.fasta", "simulatedReferenceGenomeMutated.fasta", 0.01) == 0);
    //createMutatedGenome (std::string reference, std::string mutatedReferenceFile, float percDivergent)
}

TEST_CASE( "Generate sequence reads 5", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 5, 100, 300, "normalRef5") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// We need to create a set of reads that are half as dense as the first set, because when we concatenate the heterozygous chromosome reads to them we don't
// want the coverage to be twice as high.
TEST_CASE( "Generate sequence reads 10", "[perfectReads]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome.fasta", 10, 100, 300, "normalRef10") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// Map the reads for the homozygous individual
TEST_CASE( " Mapping first set of reads", "[mapReads]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "normalRef5_R1.fastq", "normalRef5_R2.fastq", "normal.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Generate the reads from the mutated reference chromosome
TEST_CASE( "Generate sequence reads 2", "[perfectReads2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutated.fasta", 10, 100, 300, "mutatedRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// Concatenate the het-reference reads to the homozygous reads reference for R1
TEST_CASE( "Create heterozygous R1", "[createHetR1]") {
    REQUIRE( createHeterozygousGenome("normalRef10_R1.fastq", "mutatedRef_R1.fastq", "hetRef_R1.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R2
TEST_CASE( "Create heterozygous R2", "[createHetR1]") {
    REQUIRE( createHeterozygousGenome("normalRef10_R2.fastq", "mutatedRef_R2.fastq", "hetRef_R2.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Map the reads for the heterozygous individual
TEST_CASE( " Mapping het reads", "[mapReads2]") {
    REQUIRE( mapReads("simulatedReferenceGenome.fasta", "hetRef_R1.fastq", "hetRef_R2.fastq", "het.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Use angsd to generate the read counts for the two individuals
TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("bamlist.txt", "angsdOut", "5", "angsdOutLog.txt") == 0);
    //runANGSDforReadCounts (std::string bamlist, std::string angsdPrefix, std::string nThreads, std::string angsdOutputLog)
}

// Convert read counts to binary
TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("angsdOut", "angsdOut.readCounts.binary", 2, 250) == 0);
    //convertANGSDcountsToBinary(std::string angsdPrefix, std::string binaryOutputFileName, int numIndividuals, int readDepthMax)
}

// Run the PWP calculation
TEST_CASE( "Calculate PWP from the binary representations of the ANGSD readcounts", "[calcPWP]") {
    REQUIRE( calcPWPfromBinaryFile("angsdOut.readCounts.binary", 999990, 2, "testingOut.pwp", 1000, 5) == 0);
    //int calcPWPfromBinaryFile (std::string binaryFile, unsigned long long int numLoci, const int numIndividuals, std::string outFile, int lociChunkSize, int numThreads=30);
}

/*
 Covariance unit tests are below. They require different reference genomes to be used. In the example above, the homozygous reference genome
 has no variance in the major allele frequencies (they're always 1). The genomes created by this example have

 */

TEST_CASE( "Generate reference genome for the covariance tests", "[generateReferenceCovar]") {
    REQUIRE( createReferenceGenome(10000000, 0.42668722, "simulatedReferenceGenome10mil.fasta") == 0 );
    //createReferenceGenome (int totalBases, double gcContent, std::string genomeOutFile)
}

TEST_CASE ( "Mutate a reference genome for the covariance test", "[mutateRefGenomeCovar]") {
    REQUIRE( createMutatedGenomesForCovar("simulatedReferenceGenome10mil.fasta", "simulatedReferenceGenomeMutatedRef1.fasta", "simulatedReferenceGenomeMutatedRef2.fasta", 0.01) == 0);
    //createMutatedGenomesForCovar (std::string reference, std::string mutatedReferenceFile1, std::string mutatedReferenceFile2, float percDivergent)
}

TEST_CASE( "Generate nonmutated chromosome covariance sequence reads for ind1 and ind2", "[perfectReadsCovarNoMut]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenome10mil.fasta", 10, 100, 300, "covarRef") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( "Generate mutated chromosome covariance sequence reads for ind1", "[perfectReadsCovarInd1]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutatedRef1.fasta", 10, 100, 300, "covarMutRef1") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

TEST_CASE( "Generate mutated chromosome covariance sequence reads for ind2", "[perfectReadsCovarInd2]") {
    REQUIRE( generatePerfectReads ("simulatedReferenceGenomeMutatedRef2.fasta", 10, 100, 300, "covarMutRef2") == 0);
    //generatePerfectReads (std::string reference, unsigned int stagger, unsigned int readLengths, unsigned int fragmentLengths, std::string readPrefix);
}

// Combine the mutated and non-mutated chromosome reads for each individual
// Concatenate the het-reference reads to the homozygous reads reference for R1
TEST_CASE( "Create heterozygous R1covar1", "[createHetR1covar1]") {
    REQUIRE( createHeterozygousGenome("covarRef_R1.fastq", "covarMutRef1_R1.fastq", "covarRef1_R1.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R2
TEST_CASE( "Create heterozygous R2covar1", "[createHetR2covar1]") {
    REQUIRE( createHeterozygousGenome("covarRef_R2.fastq", "covarMutRef1_R2.fastq", "covarRef1_R2.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R1
TEST_CASE( "Create heterozygous R1covar2", "[createHetR1covar2]") {
    REQUIRE( createHeterozygousGenome("covarRef_R1.fastq", "covarMutRef2_R1.fastq", "covarRef2_R1.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Concatenate the het-reference reads to the homozygous reads reference for R2
TEST_CASE( "Create heterozygous R2covar2", "[createHetR2covar2]") {
    REQUIRE( createHeterozygousGenome("covarRef_R2.fastq", "covarMutRef2_R2.fastq", "covarRef2_R2.fastq") == 0);
    //createHeterozygousGenome(std::string firstFile, std::string secondFile, std::string outputGenome)
}

// Map the reads for individual 1
TEST_CASE( " Mapping reads for covariance ind1", "[mapReadsCovar1]") {
    REQUIRE( mapReads("simulatedReferenceGenome10mil.fasta", "covarRef1_R1.fastq", "covarRef1_R2.fastq", "covarInd1.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Map the reads for individual 2
TEST_CASE( " Mapping reads for covariance ind2", "[mapReadsCovar2]") {
    REQUIRE( mapReads("simulatedReferenceGenome10mil.fasta", "covarRef2_R1.fastq", "covarRef2_R2.fastq", "covarInd2.bam", "5") == 0);
    //mapReads (std::string reference, std::string R1file, std::string R2file, std::string outBam, std::string threads)
}

// Use angsd to generate the read counts for the two individuals
TEST_CASE( "Run ANGSD on simulated reads", "[runANGSD]" ) {
    REQUIRE( runANGSDforReadCounts("covarBamlist.txt", "covarAngsdOut", "5", "covarAngsdOutLog.txt") == 0);
    //runANGSDforReadCounts (std::string bamlist, std::string angsdPrefix, std::string nThreads, std::string angsdOutputLog)
}

// Convert read counts to binary
TEST_CASE( "Convert ANGSD read counts to unsigned chars for major and minor counts", "[convertCountsToBinary]") {
    REQUIRE( convertANGSDcountsToBinary("covarAngsdOut", "covarAngsdOut.readCounts.binary", 2, 250) == 0);
    //convertANGSDcountsToBinary(std::string angsdPrefix, std::string binaryOutputFileName, int numIndividuals, int readDepthMax)
}

TEST_CASE( "Calculate covariances from the same representations of the ANGSD readcounts", "[calcCovar]") {
    REQUIRE(  calcCOVARfromBinaryFile("covarAngsdOut.readCounts.binary", 9999990, 2, "testingOut.covar", 1000, 5)== 0);
    //calcCOVARfromBinaryFile (std::string binaryFile, long long int numLoci, const int numIndividuals, std::string outFile, int lociChunkSize, const int numThreads)
}

<|endoftext|>


<commit_before>#include "Graphics/TextureSet.h"

#include "TextureSets.h"
#include "vulkan/EngineInternal.h"

#include "DataCompression/LosslessCompression.h"
#include "core/Log.h"

#include "tsl/robin_map.h"

#include <bitset>
#include <unordered_map>

using namespace std;
using namespace CR;
using namespace CR::Graphics;

namespace {
	constexpr uint16_t c_maxTextureSets{8};
	constexpr uint16_t c_idSetShift{10};
	constexpr uint16_t c_maxTexturesPerSet{1024};
	static_assert((1 << c_idSetShift) == c_maxTexturesPerSet);
	static_assert(c_maxTextureSets * c_maxTexturesPerSet < numeric_limits<uint16_t>::max(),
	              "textures use a 16 bit id, some bits hold the texture set, some hold the index inside the set");

	// Must match whats in TextureProcessor, assuming dont need this every frame.
#pragma pack(4)
	struct Header {
		uint16_t Width{0};
		uint16_t Height{0};
	};
#pragma pack()

	struct TextureSetImpl {
		vector<string> m_names;
		vector<Header> m_headers;
		vector<vk::Image> m_images;
		vector<vk::ImageView> m_views;
		vk::DeviceMemory m_ImageMemory;
	};

	bitset<c_maxTextureSets> g_used;
	TextureSetImpl g_textureSets[c_maxTextureSets];
	tsl::robin_map<string, uint16_t> g_lookup;

	uint16_t CalcID(uint16_t a_set, uint16_t a_slot) {
		Core::Log::Assert(a_set < c_maxTextureSets, "invalid set");
		Core::Log::Assert(a_slot < c_maxTexturesPerSet, "invalid slot");
		return (a_set << c_idSetShift) | a_slot;
	}
	uint16_t GetSet(uint16_t a_id) { return a_id >> c_idSetShift; }
}    // namespace

TextureSet ::~TextureSet() {
	if(m_id != c_unused) {
		uint16_t set = GetSet(m_id);
		// for(auto& view : g_textureSets[set].m_views) { GetDevice().destroyImageView(view); }
		for(auto& img : g_textureSets[set].m_images) { GetDevice().destroyImage(img); }
		g_used[m_id] = false;
	}
}

TextureSet::TextureSet(TextureSet&& a_other) {
	*this = move(a_other);
}

TextureSet& TextureSet::operator=(TextureSet&& a_other) {
	m_id = a_other.m_id;

	a_other.m_id = c_unused;
	return *this;
}

TextureSet Graphics::CreateTextureSet(const Core::Span<TextureCreateInfo> a_textures) {
	if(a_textures.size() > c_maxTexturesPerSet) {
		Core::Log::Fail("Texture Sets have a maximum size of {}. {} were requested", c_maxTexturesPerSet,
		                a_textures.size());
	}
	uint16_t set = c_maxTextureSets;
	for(uint16_t i = 0; i < c_maxTextureSets; ++i) {
		if(!g_used[i]) {
			set = i;
			break;
		}
	}
	if(set == c_maxTextureSets) { Core::Log::Fail("Ran out of available texture sets"); }

	g_used[set] = true;

	g_textureSets[set].m_names.reserve(a_textures.size());
	g_textureSets[set].m_headers.reserve(a_textures.size());
	for(uint32_t slot = 0; slot < a_textures.size(); ++slot) {
		vector<byte> textureData = DataCompression::Decompress(a_textures[slot].TextureData.data(),
		                                                       (uint32_t)(a_textures[slot].TextureData.size()));
		if(textureData.size() < sizeof(Header)) { Core::Log::Fail("corrupt crtex file {}", a_textures[slot].Name); }
		Header& header = g_textureSets[set].m_headers.emplace_back();
		memcpy(&header, textureData.data(), sizeof(Header));

		g_textureSets[set].m_names.push_back(a_textures[slot].Name);
		g_lookup.emplace(a_textures[slot].Name, CalcID(set, slot));

		vk::ImageCreateInfo createInfo;
		createInfo.extent.width  = header.Width;
		createInfo.extent.height = header.Height;
		createInfo.extent.depth  = 1;
		createInfo.arrayLayers   = 1;
		createInfo.mipLevels     = 1;
		createInfo.tiling        = vk::ImageTiling::eOptimal;
		createInfo.sharingMode   = vk::SharingMode::eExclusive;
		createInfo.usage         = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst;
		createInfo.initialLayout = vk::ImageLayout::eUndefined;
		createInfo.imageType     = vk::ImageType::e2D;
		createInfo.flags         = vk::ImageCreateFlags{0};
		createInfo.format        = vk::Format::eBc7SrgbBlock;

		g_textureSets[set].m_images.push_back(GetDevice().createImage(createInfo));

		/*vk::ImageViewCreateInfo viewInfo;
		viewInfo.image                           = g_textureSets[set].m_images.back();
		viewInfo.viewType                        = vk::ImageViewType::e2D;
		viewInfo.format                          = createInfo.format;
		viewInfo.subresourceRange.aspectMask     = vk::ImageAspectFlagBits::eColor;
		viewInfo.subresourceRange.baseMipLevel   = 0;
		viewInfo.subresourceRange.levelCount     = 1;
		viewInfo.subresourceRange.baseArrayLayer = 0;
		viewInfo.subresourceRange.layerCount     = 1;

		g_textureSets[set].m_views.push_back(GetDevice().createImageView(viewInfo));*/
	}

	TextureSet result{set};
	return result;
}

void TexturePool::Init() {
	g_used.reset();
}

void TexturePool::Shutdown() {}
<commit_msg>allocate memory for the textures. I need to move some of this to the background thread. and as it is, this is going to use a ton of memory. Going to have to synchronize access to the device to fix though, which is a large refactoring.<commit_after>#include "Graphics/TextureSet.h"

#include "TextureSets.h"
#include "vulkan/EngineInternal.h"

#include "DataCompression/LosslessCompression.h"
#include "core/Log.h"

#include "tsl/robin_map.h"

#include <bitset>
#include <unordered_map>

using namespace std;
using namespace CR;
using namespace CR::Graphics;

namespace {
	constexpr uint16_t c_maxTextureSets{8};
	constexpr uint16_t c_idSetShift{10};
	constexpr uint16_t c_maxTexturesPerSet{1024};
	static_assert((1 << c_idSetShift) == c_maxTexturesPerSet);
	static_assert(c_maxTextureSets * c_maxTexturesPerSet < numeric_limits<uint16_t>::max(),
	              "textures use a 16 bit id, some bits hold the texture set, some hold the index inside the set");

	// Must match whats in TextureProcessor, assuming dont need this every frame.
#pragma pack(4)
	struct Header {
		uint16_t Width{0};
		uint16_t Height{0};
	};
#pragma pack()

	struct TextureSetImpl {
		vector<string> m_names;
		vector<Header> m_headers;
		vector<vk::Image> m_images;
		vector<vk::ImageView> m_views;
		vk::DeviceMemory m_imageMemory;

		vector<vk::Buffer> m_stagingBuffer;
		vk::DeviceMemory m_stagingMemory;
	};

	bitset<c_maxTextureSets> g_used;
	TextureSetImpl g_textureSets[c_maxTextureSets];
	tsl::robin_map<string, uint16_t> g_lookup;

	uint16_t CalcID(uint16_t a_set, uint16_t a_slot) {
		Core::Log::Assert(a_set < c_maxTextureSets, "invalid set");
		Core::Log::Assert(a_slot < c_maxTexturesPerSet, "invalid slot");
		return (a_set << c_idSetShift) | a_slot;
	}
	uint16_t GetSet(uint16_t a_id) { return a_id >> c_idSetShift; }
	uint16_t GetSlot(uint16_t a_id) { return a_id & (c_maxTexturesPerSet - 1); }
}    // namespace

TextureSet ::~TextureSet() {
	if(m_id != c_unused) {
		uint16_t set = GetSet(m_id);
		for(auto& view : g_textureSets[set].m_views) { GetDevice().destroyImageView(view); }
		for(auto& img : g_textureSets[set].m_images) { GetDevice().destroyImage(img); }
		for(auto& buf : g_textureSets[set].m_stagingBuffer) {
			if(buf) { GetDevice().destroyBuffer(buf); }
		}
		GetDevice().freeMemory(g_textureSets[set].m_imageMemory);
		if(g_textureSets[set].m_stagingMemory) { GetDevice().freeMemory(g_textureSets[set].m_stagingMemory); }
		g_used[m_id] = false;
	}
}

TextureSet::TextureSet(TextureSet&& a_other) {
	*this = move(a_other);
}

TextureSet& TextureSet::operator=(TextureSet&& a_other) {
	m_id = a_other.m_id;

	a_other.m_id = c_unused;
	return *this;
}

TextureSet Graphics::CreateTextureSet(const Core::Span<TextureCreateInfo> a_textures) {
	if(a_textures.size() > c_maxTexturesPerSet) {
		Core::Log::Fail("Texture Sets have a maximum size of {}. {} were requested", c_maxTexturesPerSet,
		                a_textures.size());
	}
	uint16_t set = c_maxTextureSets;
	for(uint16_t i = 0; i < c_maxTextureSets; ++i) {
		if(!g_used[i]) {
			set = i;
			break;
		}
	}
	if(set == c_maxTextureSets) { Core::Log::Fail("Ran out of available texture sets"); }

	g_used[set] = true;

	vector<uint32_t> memOffsets;
	memOffsets.reserve(a_textures.size());
	uint32_t memOffset{0};

	vector<uint32_t> stagOffsets;
	stagOffsets.reserve(a_textures.size());
	uint32_t stagOffset{0};

	g_textureSets[set].m_names.reserve(a_textures.size());
	g_textureSets[set].m_headers.reserve(a_textures.size());
	for(uint32_t slot = 0; slot < a_textures.size(); ++slot) {
		vector<byte> textureData = DataCompression::Decompress(a_textures[slot].TextureData.data(),
		                                                       (uint32_t)(a_textures[slot].TextureData.size()));
		if(textureData.size() < sizeof(Header)) { Core::Log::Fail("corrupt crtex file {}", a_textures[slot].Name); }
		Header& header = g_textureSets[set].m_headers.emplace_back();
		memcpy(&header, textureData.data(), sizeof(Header));

		g_textureSets[set].m_names.push_back(a_textures[slot].Name);
		g_lookup.emplace(a_textures[slot].Name, CalcID(set, slot));

		vk::ImageCreateInfo createInfo;
		createInfo.extent.width  = header.Width;
		createInfo.extent.height = header.Height;
		createInfo.extent.depth  = 1;
		createInfo.arrayLayers   = 1;
		createInfo.mipLevels     = 1;
		createInfo.tiling        = vk::ImageTiling::eOptimal;
		createInfo.sharingMode   = vk::SharingMode::eExclusive;
		createInfo.usage         = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst;
		createInfo.initialLayout = vk::ImageLayout::eUndefined;
		createInfo.imageType     = vk::ImageType::e2D;
		createInfo.flags         = vk::ImageCreateFlags{0};
		createInfo.format        = vk::Format::eBc7SrgbBlock;

		g_textureSets[set].m_images.push_back(GetDevice().createImage(createInfo));

		auto imageRequirements = GetDevice().getImageMemoryRequirements(g_textureSets[set].m_images.back());
		memOffset = (uint32_t)((memOffset + (imageRequirements.alignment - 1)) & ~(imageRequirements.alignment - 1));
		memOffsets.push_back(memOffset);
		memOffset += (uint32_t)imageRequirements.size;

		vk::BufferCreateInfo stagInfo;
		stagInfo.flags       = vk::BufferCreateFlags{};
		stagInfo.sharingMode = vk::SharingMode::eExclusive;
		stagInfo.size        = a_textures[slot].TextureData.size() - sizeof(Header);
		stagInfo.usage       = vk::BufferUsageFlagBits::eTransferSrc;

		g_textureSets[set].m_stagingBuffer.push_back(GetDevice().createBuffer(stagInfo));
		auto bufferRequirements = GetDevice().getBufferMemoryRequirements(g_textureSets[set].m_stagingBuffer.back());
		stagOffset =
		    (uint32_t)((stagOffset + (bufferRequirements.alignment - 1)) & ~(bufferRequirements.alignment - 1));
		stagOffsets.push_back(stagOffset);
		stagOffset += (uint32_t)bufferRequirements.size;
	}

	vk::MemoryAllocateInfo allocInfo;
	allocInfo.memoryTypeIndex        = GetDeviceMemoryIndex();
	allocInfo.allocationSize         = memOffset;
	g_textureSets[set].m_imageMemory = GetDevice().allocateMemory(allocInfo);

	allocInfo.memoryTypeIndex          = GetHostMemoryIndex();
	allocInfo.allocationSize           = stagOffset;
	g_textureSets[set].m_stagingMemory = GetDevice().allocateMemory(allocInfo);

	for(uint32_t slot = 0; slot < a_textures.size(); ++slot) {
		GetDevice().bindImageMemory(g_textureSets[set].m_images[slot], g_textureSets[set].m_imageMemory,
		                            memOffsets[slot]);
		vk::ImageViewCreateInfo viewInfo;
		viewInfo.image                           = g_textureSets[set].m_images[slot];
		viewInfo.viewType                        = vk::ImageViewType::e2D;
		viewInfo.format                          = vk::Format::eBc7SrgbBlock;
		viewInfo.subresourceRange.aspectMask     = vk::ImageAspectFlagBits::eColor;
		viewInfo.subresourceRange.baseMipLevel   = 0;
		viewInfo.subresourceRange.levelCount     = 1;
		viewInfo.subresourceRange.baseArrayLayer = 0;
		viewInfo.subresourceRange.layerCount     = 1;

		g_textureSets[set].m_views.push_back(GetDevice().createImageView(viewInfo));

		GetDevice().bindBufferMemory(g_textureSets[set].m_stagingBuffer[slot], g_textureSets[set].m_stagingMemory,
		                             stagOffsets[slot]);
	}

	TextureSet result{set};
	return result;
}

void TexturePool::Init() {
	g_used.reset();
}

void TexturePool::Shutdown() {}
<|endoftext|>


<commit_before><commit_msg>Update VideoDevice.cpp<commit_after>#include "VideoDevice.hpp"
#include <opencv2/opencv.hpp>
using namespace cv;

VideoDevice::VideoDevice(){
    //does absolutely nothing
}

void VideoDevice::startCapture(int id){
    camera = VideoCapture(id);
}

Mat VideoDevice:: getImage(){
    takeImage();
    return image;
}

void VideoDevice::takeImage(){
    camera >> image;
}
<|endoftext|>


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

// git.cpp - source file for functions related to git tree parsing and pulling
std::string gitLogCommand = "git log "
    "--pretty=format:user:%aN%n%ct "
    "--reverse --raw --encoding=UTF-8 "
    "--no-renames";

int getCustomGitLog(std::string directory,std::string outfile)
{
	printf("\nmaking an outfile %s \n",outfile.c_str());
	int commandReturnValue = 0;
	std::string gitLogWithOutput = gitLogCommand + " > " + outfile;
	commandReturnValue = system(gitLogCommand.c_str());
	return commandReturnValue;
}

<commit_msg>updated function call<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>

// git.cpp - source file for functions related to git tree parsing and pulling
std::string gitLogCommand = "git log --pretty=format:user:%aN%n%ct --reverse --raw --encoding=UTF-8 --no-renames";

int getCustomGitLog(std::string directory,std::string outfile)
{
	printf("\nmaking an outfile %s \n",outfile.c_str());
	int commandReturnValue = 0;
	std::string gitLogWithOutput = gitLogCommand + " > " + outfile;
        printf("\n%s\n",gitLogWithOutput.c_str());
	commandReturnValue = system(gitLogWithOutput.c_str());
	return commandReturnValue;
}

<|endoftext|>


<commit_before>/**
 ** \file parser/metavar-map.hxx
 ** \brief Implementation of parse::MetavarMap.
 */

#ifndef PARSER_METAVAR_MAP_HXX
# define PARSER_METAVAR_MAP_HXX

# include <sstream>
# include <parser/metavar-map.hh>

namespace parser
{

  template <typename Data>
  MetavarMap<Data>::MetavarMap (const std::string& name)
    : name_ (name), map_ ()
  {
  }

  template <typename Data>
  MetavarMap<Data>::~MetavarMap ()
  {
    // All the values must have been used.
    passert (map_, empty_ ());
  }

  template <typename Data>
  std::ostream&
  MetavarMap<Data>::dump (std::ostream& o) const
  {
    return o
      << name_ << " map:"
      << libport::incendl << map_ << libport::decendl;
  }

  template <typename Data>
  std::string
  MetavarMap<Data>::append_ (unsigned& count, Data data)
  {
    map_[count] = data;
    std::string s = "_" + name_ + " (" +
      boost::lexical_cast<std::string> (count++) + ")";
    return s;
  }

  template <typename Data>
  Data
  MetavarMap<Data>::take_ (unsigned key) throw (std::range_error)
  {
    return map_.take (key);
  }

  template <typename Data>
  void
  MetavarMap<Data>::insert_(MetavarMap<Data>& other)
  {
    return map_.insert(other.map_);
  }

  template <typename Data>
  bool
  MetavarMap<Data>::must_be_unique_ (Data) const
  {
    return true;
  }

  template <typename Data>
  bool
  MetavarMap<Data>::empty_ () const
  {
    return map_.empty();
  }

  /*--------------------------.
  | Free standing functions.  |
  `--------------------------*/

  template <typename Data>
  std::ostream&
  operator<< (std::ostream& o, const MetavarMap<Data>& t)
  {
    return t.dump (o);
  }

}

#endif // !PARSER_METAVAR_MAP_HXX
<commit_msg>Assert that enough parameters are given to parametric asts.<commit_after>/**
 ** \file parser/metavar-map.hxx
 ** \brief Implementation of parse::MetavarMap.
 */

#ifndef PARSER_METAVAR_MAP_HXX
# define PARSER_METAVAR_MAP_HXX

# include <sstream>
# include <parser/metavar-map.hh>

namespace parser
{

  template <typename Data>
  MetavarMap<Data>::MetavarMap (const std::string& name)
    : name_ (name), map_ ()
  {
  }

  template <typename Data>
  MetavarMap<Data>::~MetavarMap ()
  {
    // All the values must have been used.
    passert (map_, empty_ ());
  }

  template <typename Data>
  std::ostream&
  MetavarMap<Data>::dump (std::ostream& o) const
  {
    return o
      << name_ << " map:"
      << libport::incendl << map_ << libport::decendl;
  }

  template <typename Data>
  std::string
  MetavarMap<Data>::append_ (unsigned& count, Data data)
  {
    map_[count] = data;
    std::string s = "_" + name_ + " (" +
      boost::lexical_cast<std::string> (count++) + ")";
    return s;
  }

  template <typename Data>
  Data
  MetavarMap<Data>::take_ (unsigned key) throw (std::range_error)
  {
    assert(libport::mhas(map_, key));
    return map_.take (key);
  }

  template <typename Data>
  void
  MetavarMap<Data>::insert_(MetavarMap<Data>& other)
  {
    return map_.insert(other.map_);
  }

  template <typename Data>
  bool
  MetavarMap<Data>::must_be_unique_ (Data) const
  {
    return true;
  }

  template <typename Data>
  bool
  MetavarMap<Data>::empty_ () const
  {
    return map_.empty();
  }

  /*--------------------------.
  | Free standing functions.  |
  `--------------------------*/

  template <typename Data>
  std::ostream&
  operator<< (std::ostream& o, const MetavarMap<Data>& t)
  {
    return t.dump (o);
  }

}

#endif // !PARSER_METAVAR_MAP_HXX
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C $   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_npu_scominit.C
/// @brief Apply SCOM overrides for the NPU unit via an init file
///
// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: HB

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_npu_scominit.H>
#include <p9_npu_scom.H>
#include <p9_nv_ref_clk_enable.H>

///
/// p9_npu_scominit HWP entry point (Defined in .H file)
///
fapi2::ReturnCode p9_npu_scominit(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
                                  & i_target)
{
    fapi2::ReturnCode l_rc;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
    auto l_nv_targets = i_target.getChildren<fapi2::TARGET_TYPE_NV>();

    FAPI_DBG("Entering ...");

    if (l_nv_targets.size())
    {
        FAPI_DBG("Invoking p9.npu.scom.initfile...");
        FAPI_EXEC_HWP(l_rc, p9_npu_scom, i_target, FAPI_SYSTEM);

        if (l_rc)
        {
            FAPI_ERR("Error from p9.npu.scom.initfile");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }

        FAPI_DBG("Invoking p9_nv_ref_clk_enable...");
        FAPI_EXEC_HWP(l_rc, p9_nv_ref_clk_enable, i_target);

        if (l_rc)
        {
            FAPI_ERR("Error from p9_nv_ref_clk_enable");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }
    }
    else
    {
        FAPI_DBG("Skipping NPU initialization");
    }

fapi_try_exit:
    FAPI_DBG("Exiting ...");
    return fapi2::current_err;
}
<commit_msg>NPU scan/scom init updates<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C $   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_npu_scominit.C
/// @brief Apply SCOM overrides for the NPU unit via an init file
///
// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: HB

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_npu_scominit.H>
#include <p9_npu_scom.H>
#include <p9_nv_ref_clk_enable.H>
#include <p9_misc_scom_addresses.H>
#include <p9_misc_scom_addresses_fld.H>

///
/// p9_npu_scominit HWP entry point (Defined in .H file)
///
fapi2::ReturnCode p9_npu_scominit(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
                                  & i_target)
{
    fapi2::ReturnCode l_rc;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
    auto l_nv_targets = i_target.getChildren<fapi2::TARGET_TYPE_NV>();
    fapi2::buffer<uint64_t> l_atrmiss = 0;

    FAPI_DBG("Entering ...");

    if (l_nv_targets.size())
    {
        FAPI_DBG("Invoking p9.npu.scom.initfile...");
        FAPI_EXEC_HWP(l_rc, p9_npu_scom, i_target, FAPI_SYSTEM);

        if (l_rc)
        {
            FAPI_ERR("Error from p9.npu.scom.initfile");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }

        l_atrmiss.setBit<PU_NPU_SM2_XTS_ATRMISS_FLAG_MAP>()
        .setBit<PU_NPU_SM2_XTS_ATRMISS_ENA>();
        FAPI_TRY(fapi2::putScomUnderMask(i_target, PU_NPU_SM2_XTS_ATRMISS, l_atrmiss, l_atrmiss),
                 "Error from putScomUnderMask (PU_NPU_SM2_XTS_ATRMISS)");

        FAPI_DBG("Invoking p9_nv_ref_clk_enable...");
        FAPI_EXEC_HWP(l_rc, p9_nv_ref_clk_enable, i_target);

        if (l_rc)
        {
            FAPI_ERR("Error from p9_nv_ref_clk_enable");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }
    }
    else
    {
        FAPI_DBG("Skipping NPU initialization");
    }

fapi_try_exit:
    FAPI_DBG("Exiting ...");
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.C $   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//-----------------------------------------------------------------------------------
///
/// @file p9_spr_name_map.C
/// @brief Utility to map SPR name to SPR number
///
//-----------------------------------------------------------------------------------
// *HWP HWP Owner        : Liu Yang Fan <shliuyf@cn.ibm.com>
// *HWP HWP Backup Owner : Gou Peng Fei <shgoupf@cn.ibm.com>
// *HWP FW Owner         : Thi Tran <thi@us.ibm.com>
// *HWP Team             : Perv
// *HWP Level            : 2
// *HWP Consumed by      : None (Cronus test only)
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <p9_spr_name_map.H>

//-----------------------------------------------------------------------------------
// Function definitions
//-----------------------------------------------------------------------------------
std::map<std::string, SPRMapEntry> spr_map;

fapi2::ReturnCode p9_spr_name_map_init()
{
    FAPI_INF("Start SPR name map init");

    FAPI_ASSERT(spr_map.empty(),
                fapi2::P9_SPR_NAME_MAP_INIT_ERR(),
                "SPR name map is not empty when initialization");

    {
        LIST_SPR_REG(DO_SPR_MAP)
    }

fapi_try_exit:
    FAPI_INF("Exiting SPR name map init");
    return fapi2::current_err;
}

//-----------------------------------------------------------------------------------
bool p9_spr_name_map_check_flag(unsigned char i_reg_flag, bool i_write)
{
    unsigned char op_flag = ((unsigned char)i_write) + 0x1;

    return (bool)(i_reg_flag & op_flag);
}

//-----------------------------------------------------------------------------------
fapi2::ReturnCode p9_spr_name_map(const std::string i_name, const bool i_write, uint32_t& o_number)
{
    FAPI_INF("Start SPR name map");
    bool l_check_flag = false;

    if(spr_map.find(i_name) != spr_map.end())
    {
        l_check_flag = p9_spr_name_map_check_flag(spr_map[i_name].flag, i_write);

        FAPI_ASSERT(l_check_flag,
                    fapi2::P9_SPR_INVALID_RW_MODE_ACCESS_ERR()
                    .set_REGNAME(i_name)
                    .set_RWFLAG(spr_map[i_name].flag),
                    "SPR RW mode check failed");

        o_number = spr_map[i_name].number;
    }
    else
    {
        FAPI_ASSERT(false,
                    fapi2::P9_SPR_INVALID_NAME_ACCESS_ERR()
                    .set_REGNAME(i_name),
                    "SPR name is invalid");
    }

fapi_try_exit:
    FAPI_INF("Exiting SPR name map");
    return fapi2::current_err;
}
<commit_msg>Update RAM procedures.<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.C $   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//-----------------------------------------------------------------------------------
///
/// @file p9_spr_name_map.C
/// @brief Utility to map SPR name to SPR number
///
//-----------------------------------------------------------------------------------
// *HWP HWP Owner        : Liu Yang Fan <shliuyf@cn.ibm.com>
// *HWP HWP Backup Owner : Gou Peng Fei <shgoupf@cn.ibm.com>
// *HWP FW Owner         : Thi Tran <thi@us.ibm.com>
// *HWP Team             : Perv
// *HWP Level            : 2
// *HWP Consumed by      : None (Cronus test only)
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <p9_spr_name_map.H>

std::map<std::string, SPRMapEntry> SPR_MAP;
bool spr_map_initialized = false;

//-----------------------------------------------------------------------------------
// Function definitions
//-----------------------------------------------------------------------------------
bool p9_spr_name_map_init()
{
    if (spr_map_initialized)
    {
        return true;
    }

    if (!SPR_MAP.empty())
    {
        return false;
    }

    LIST_SPR_REG(DO_SPR_MAP)
    spr_map_initialized = true;

    return true;
}

//-----------------------------------------------------------------------------------
bool p9_spr_name_map_check_flag(unsigned char i_reg_flag, bool i_write)
{
    unsigned char op_flag = ((unsigned char)i_write) + 0x1;

    return (bool)(i_reg_flag & op_flag);
}

//-----------------------------------------------------------------------------------
bool p9_spr_name_map(const std::string i_name, const bool i_write, uint32_t& o_number)
{
    bool l_check_flag = false;

    if(SPR_MAP.find(i_name) != SPR_MAP.end())
    {
        l_check_flag = p9_spr_name_map_check_flag(SPR_MAP[i_name].flag, i_write);

        if(l_check_flag)
        {
            o_number = SPR_MAP[i_name].number;
        }
    }

    return l_check_flag;
}

//-----------------------------------------------------------------------------------
bool p9_get_share_type(const std::string i_name, Enum_ShareType& o_share_type)
{
    bool l_rc = false;

    if(SPR_MAP.find(i_name) != SPR_MAP.end())
    {
        o_share_type = SPR_MAP[i_name].share_type;
        l_rc = true;
    }

    return l_rc;
}

//-----------------------------------------------------------------------------------
bool p9_get_bit_length(const std::string i_name, uint8_t& o_bit_length)
{
    bool l_rc = false;

    if(SPR_MAP.find(i_name) != SPR_MAP.end())
    {
        o_bit_length = SPR_MAP[i_name].bit_length;
        l_rc = true;
    }

    return l_rc;
}

//-----------------------------------------------------------------------------------
bool p9_get_spr_entry(const std::string i_name, SPRMapEntry& o_spr_entry)
{
    bool l_rc = false;

    if(SPR_MAP.find(i_name) != SPR_MAP.end())
    {
        o_spr_entry = SPR_MAP[i_name];
        l_rc = true;
    }

    return l_rc;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.C $   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_quad_power_off.C
/// @brief Power off the EQ -- including the functional cores associatated
///        with it.
///
//  *HWP HWP Owner: Amit Kumar <akumar3@us.ibm.com>
//  *HWP HWP Backup Owner: Greg Still <stillgs@us.ibm.com>
//  *HWP FW Owner:  Sangeetha T S <sangeet2@in.ibm.com>
//  *HWP Team: PM
//  *HWP Level: 1
//  *HWP Consumed by: FSP:HS
///
/// @verbatim
/// High-level procedure flow:
///     - for each good EC associated with the targeted EQ, power it off
///     - power off the EQ
/// @endverbatim
///
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------

#include <p9_quad_power_off.H>

// ----------------------------------------------------------------------
// Procedure Function
// ----------------------------------------------------------------------

fapi2::ReturnCode
p9_quad_power_off(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_eq_target)
{
    FAPI_INF("> p9_quad_power_off...");

//fapi_try_exit:
    FAPI_INF("< p9_quad_power_off...");
    return fapi2::current_err;
}
<commit_msg>L2 HWP p9_quad_power_off<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_quad_power_off.C $   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_quad_power_off.C
/// @brief Power off the EQ including the functional cores associatated with it.
///
//----------------------------------------------------------------------------
// *HWP HWP Owner       : Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner        : Sumit Kumar <sumit_kumar@in.ibm.com>
// *HWP Team            : PM
// *HWP Level           : 2
// *HWP Consumed by     : OCC:CME:FSP
//----------------------------------------------------------------------------
//
// @verbatim
// High-level procedure flow:
//     - For each good EC associated with the targeted EQ, power it off.
//     - Power off the EQ.
// @endverbatim
//
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_quad_power_off.H>

// ----------------------------------------------------------------------
// Function definitions
// ----------------------------------------------------------------------

// Procedure p9_quad_power_off entry point, comments in header
fapi2::ReturnCode p9_quad_power_off(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target)
{
    fapi2::ReturnCode rc   = fapi2::FAPI2_RC_SUCCESS;
    uint8_t l_unit_pos     = 0;

    FAPI_INF("p9_quad_power_off: Entering...");

    // Get chiplet position
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_unit_pos));
    FAPI_INF("Quad power off chiplet no.%d", l_unit_pos);

    // Call the procedure
    p9_pm_pfet_control_eq(i_target,
                          PM_PFET_TYPE_C::BOTH,
                          PM_PFET_TYPE_C::OFF);

    FAPI_INF("p9_quad_power_off: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014-2017 Oleg Linkin <maledictusdemagog@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "getpocketapi.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QSettings>
#include <QStandardPaths>

#include "settings/accountsettings.h"

namespace LinksBag
{
GetPocketApi::GetPocketApi(QObject *parent)
: QObject(parent)
, m_ConsumerKey("36050-db8157de51cbb0c5f72edc33")
, m_NAM(new QNetworkAccessManager(this))
{
}

namespace
{
    QNetworkRequest CreateRequest(const QString& path)
    {
        QNetworkRequest request(QUrl(QString("https://getpocket.com/v3") +
                path));
        request.setHeader(QNetworkRequest::ContentTypeHeader,
                "application/json; charset=UTF-8");
        request.setRawHeader("X-Accept", "application/json");

        return request;
    }
}

void GetPocketApi::ObtainRequestToken()
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["redirect_uri"] = "linksbag://authorizationFinished";

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/oauth/request"),
            doc.toJson());

    connect(reply,
            &QNetworkReply::finished,
            this,
            &GetPocketApi::handleObtainRequestToken);
}

void GetPocketApi::RequestAccessToken()
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["code"] = m_RequestToken;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/oauth/authorize"),
            doc.toJson());

    connect(reply,
            &QNetworkReply::finished,
            this,
            &GetPocketApi::handleRequestAccessToken);
}

void GetPocketApi::LoadBookmarks(int lastUpdate)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    params["state"] = "all";
    params["sort"] = "oldest";
    params["detailType"] = "complete";
    params["since"] = lastUpdate;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/get"),
            doc.toJson());

    connect(reply,
            &QNetworkReply::finished,
            this,
            &GetPocketApi::handleLoadBookmarks);
}

void GetPocketApi::RemoveBookmark(const QString& id)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = "delete";
    action["item_id"] = id;
    actions.append(action);
    params["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [=]()
            {
                handleRemoveBookmark(id);
            });
}

void GetPocketApi::MarkBookmarkAsFavorite(const QString& id, bool favorite)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = favorite ? "favorite" : "unfavorite";
    action["item_id"] = id;
    actions.append(action);
    params["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [this, id, favorite]()
            {
                handleMarkBookmarkAsFavorite(id, favorite);
            });
}

void GetPocketApi::MarkBookmarkAsRead(const QString& id, bool read)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = read ? "archive" : "readd";
    action["item_id"] = id;
    actions.append(action);
    params ["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [this, id, read]()
            {
                handleMarkBookmarkAsRead(id, read);
            });
}

void GetPocketApi::UpdateTags(const QString& id, const QString& tags)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = "tags_replace";
    action["item_id"] = id;
    action["tags"] = tags;
    actions.append(action);
    params ["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [this, id, tags]()
            {
                handleTagsUpdated(id, tags);
    });
}

void GetPocketApi::ResetAccount()
{
    m_RequestToken.clear();
}

QJsonDocument GetPocketApi::PreparsingReply(QObject *sender, bool& ok)
{
    QJsonDocument doc;
    auto reply = qobject_cast<QNetworkReply*> (sender);
    if (!reply)
    {
        qDebug() << "Invalid reply";
        emit requestFinished(false, tr("General error"));
        ok = false;
        return doc;
    }
    reply->deleteLater();

    if (reply->error() != QNetworkReply::NoError &&
            reply->error() != QNetworkReply::UnknownContentError &&
            reply->error() != QNetworkReply::UnknownNetworkError &&
            reply->error() != m_InvalidRequestError &&
            reply->error() != m_AuthError &&
            reply->error() != m_PermissionsRateError &&
            reply->error() != m_MaintenanceError)
    {
        qDebug() << Q_FUNC_INFO << "There is network error: "
                << reply->error() << reply->errorString();
        emit requestFinished(false, tr("Network error %1: %2")
                .arg(reply->error())
                .arg(reply->errorString()));
        ok = false;
        return doc;
    }
    else if (reply->error() != QNetworkReply::NoError)
    {
        const int errorCode = reply->rawHeader("X-Error-Code").toInt();
        const QString errorString = reply->rawHeader("X-Error");
        qDebug() << Q_FUNC_INFO << "There is getpocket error: "
                << errorCode << errorString;
        emit error(errorString, errorCode, ETGetPocket);
        ok = false;
        return doc;
    }

    ok = false;
    QJsonParseError error;
    doc = QJsonDocument::fromJson(reply->readAll(), &error);
    if (error.error != QJsonParseError::NoError)
    {
        qDebug() << "Unable to generate json from reply";
        emit requestFinished(false, tr("Reply data is corrupted"));
        return doc;
    }

    ok = true;
    return doc;
}

void GetPocketApi::handleObtainRequestToken()
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    m_RequestToken = doc.object()["code"].toString();
    emit requestTokenChanged(m_RequestToken);
    emit requestFinished(true);
}

void GetPocketApi::handleRequestAccessToken()
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& accessToken = doc.object()["access_token"].toString();
    const auto& userName = doc.object()["username"].toString();
    emit logged(!accessToken.isEmpty() && !userName.isEmpty(),
            accessToken, userName);
    emit requestFinished(true);
}

void GetPocketApi::handleLoadBookmarks()
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    QJsonObject rootObject = doc.object();
    const quint64 since = rootObject["since"].toDouble();

    const auto& listObject = rootObject["list"].toObject();
    Bookmarks_t bookmarks;
    for(const auto& key : listObject.keys())
    {
        QJsonObject bookmarkObject = listObject[key].toObject();

        Bookmark bm;
        bm.SetID(bookmarkObject["item_id"].toString());
        bm.SetUrl(bookmarkObject["resolved_url"].toString());
        QString title = bookmarkObject["resolved_title"].toString();
        if(title.isEmpty())
        {
            title = bookmarkObject["given_title"].toString();
        }
        if(title.isEmpty())
        {
            title = bm.GetUrl().toString();
        }
        bm.SetTitle(title);
        bm.SetDescription(bookmarkObject["excerpt"].toString());
        bm.SetIsFavorite(bookmarkObject["favorite"].toString() != "0" ||
                bookmarkObject["time_favorited"].toString() != "0");
        bm.SetIsRead(bookmarkObject["read"].toString() == "1" ||
                bookmarkObject["time_read"].toString() != "0");
        bm.SetAddTime(QDateTime::fromTime_t(bookmarkObject["time_added"]
                .toString().toLongLong()));
        bm.SetUpdateTime(QDateTime::fromTime_t(bookmarkObject["time_updated"]
                .toString().toLongLong()));
        const auto& tagsObject = bookmarkObject["tags"].toObject();
        bm.SetTags(tagsObject.keys());
        bm.SetImageUrl(bookmarkObject["image"].toObject()["src"].toString());
        bm.SetStatus(static_cast<Bookmark::Status>(bookmarkObject["status"]
                .toString().toInt()));

        bookmarks << bm;
    }

    emit gotBookmarks(bookmarks, since);
    emit requestFinished(true);
}

void GetPocketApi::handleRemoveBookmark(const QString& id)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit bookmarkRemoved(id);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to remove bookamark"));
    }
}

void GetPocketApi::handleMarkBookmarkAsFavorite(const QString& id, bool favorite)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit bookmarkMarkedAsFavorite(id, favorite);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to mark bookamark as %1")
                .arg(favorite ? tr("favorite") : tr("unfavorite")));
    }
}

void GetPocketApi::handleMarkBookmarkAsRead(const QString& id, bool read)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit bookmarkMarkedAsRead(id, read);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to mark bookamark as %1")
                .arg(read ? tr("read") : tr("unread")));
    }
}

void GetPocketApi::handleTagsUpdated(const QString& id, const QString& tags)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit tagsUpdated(id, tags);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to update tags"));
    }
}
} // namespace LinksBag
<commit_msg>Style fix<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014-2017 Oleg Linkin <maledictusdemagog@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "getpocketapi.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QSettings>
#include <QStandardPaths>

#include "settings/accountsettings.h"

namespace LinksBag
{
GetPocketApi::GetPocketApi(QObject *parent)
: QObject(parent)
, m_ConsumerKey("36050-db8157de51cbb0c5f72edc33")
, m_NAM(new QNetworkAccessManager(this))
{
}

namespace
{
    QNetworkRequest CreateRequest(const QString& path)
    {
        QNetworkRequest request(QUrl(QString("https://getpocket.com/v3") +
                path));
        request.setHeader(QNetworkRequest::ContentTypeHeader,
                "application/json; charset=UTF-8");
        request.setRawHeader("X-Accept", "application/json");

        return request;
    }
}

void GetPocketApi::ObtainRequestToken()
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["redirect_uri"] = "linksbag://authorizationFinished";

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/oauth/request"),
            doc.toJson());

    connect(reply,
            &QNetworkReply::finished,
            this,
            &GetPocketApi::handleObtainRequestToken);
}

void GetPocketApi::RequestAccessToken()
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["code"] = m_RequestToken;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/oauth/authorize"),
            doc.toJson());

    connect(reply,
            &QNetworkReply::finished,
            this,
            &GetPocketApi::handleRequestAccessToken);
}

void GetPocketApi::LoadBookmarks(int lastUpdate)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    params["state"] = "all";
    params["sort"] = "oldest";
    params["detailType"] = "complete";
    params["since"] = lastUpdate;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/get"),
            doc.toJson());

    connect(reply,
            &QNetworkReply::finished,
            this,
            &GetPocketApi::handleLoadBookmarks);
}

void GetPocketApi::RemoveBookmark(const QString& id)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = "delete";
    action["item_id"] = id;
    actions.append(action);
    params["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [=]()
            {
                handleRemoveBookmark(id);
            });
}

void GetPocketApi::MarkBookmarkAsFavorite(const QString& id, bool favorite)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = favorite ? "favorite" : "unfavorite";
    action["item_id"] = id;
    actions.append(action);
    params["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [this, id, favorite]()
            {
                handleMarkBookmarkAsFavorite(id, favorite);
            });
}

void GetPocketApi::MarkBookmarkAsRead(const QString& id, bool read)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = read ? "archive" : "readd";
    action["item_id"] = id;
    actions.append(action);
    params ["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [this, id, read]()
            {
                handleMarkBookmarkAsRead(id, read);
            });
}

void GetPocketApi::UpdateTags(const QString& id, const QString& tags)
{
    QVariantMap params;
    params["consumer_key"] = m_ConsumerKey;
    params["access_token"] = AccountSettings::Instance(this)->value("access_token");
    QVariantList actions;
    QVariantMap action;
    action["action"] = "tags_replace";
    action["item_id"] = id;
    action["tags"] = tags;
    actions.append(action);
    params ["actions"] = actions;

    QJsonDocument doc(QJsonObject::fromVariantMap(params));

    QNetworkReply *reply = m_NAM->post(CreateRequest("/send"),
            doc.toJson());
    connect(reply,
            &QNetworkReply::finished,
            this,
            [this, id, tags]()
            {
                handleTagsUpdated(id, tags);
            });
}

void GetPocketApi::ResetAccount()
{
    m_RequestToken.clear();
}

QJsonDocument GetPocketApi::PreparsingReply(QObject *sender, bool& ok)
{
    QJsonDocument doc;
    auto reply = qobject_cast<QNetworkReply*> (sender);
    if (!reply)
    {
        qDebug() << "Invalid reply";
        emit requestFinished(false, tr("General error"));
        ok = false;
        return doc;
    }
    reply->deleteLater();

    if (reply->error() != QNetworkReply::NoError &&
            reply->error() != QNetworkReply::UnknownContentError &&
            reply->error() != QNetworkReply::UnknownNetworkError &&
            reply->error() != m_InvalidRequestError &&
            reply->error() != m_AuthError &&
            reply->error() != m_PermissionsRateError &&
            reply->error() != m_MaintenanceError)
    {
        qDebug() << Q_FUNC_INFO << "There is network error: "
                << reply->error() << reply->errorString();
        emit requestFinished(false, tr("Network error %1: %2")
                .arg(reply->error())
                .arg(reply->errorString()));
        ok = false;
        return doc;
    }
    else if (reply->error() != QNetworkReply::NoError)
    {
        const int errorCode = reply->rawHeader("X-Error-Code").toInt();
        const QString errorString = reply->rawHeader("X-Error");
        qDebug() << Q_FUNC_INFO << "There is getpocket error: "
                << errorCode << errorString;
        emit error(errorString, errorCode, ETGetPocket);
        ok = false;
        return doc;
    }

    ok = false;
    QJsonParseError error;
    doc = QJsonDocument::fromJson(reply->readAll(), &error);
    if (error.error != QJsonParseError::NoError)
    {
        qDebug() << "Unable to generate json from reply";
        emit requestFinished(false, tr("Reply data is corrupted"));
        return doc;
    }

    ok = true;
    return doc;
}

void GetPocketApi::handleObtainRequestToken()
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    m_RequestToken = doc.object()["code"].toString();
    emit requestTokenChanged(m_RequestToken);
    emit requestFinished(true);
}

void GetPocketApi::handleRequestAccessToken()
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& accessToken = doc.object()["access_token"].toString();
    const auto& userName = doc.object()["username"].toString();
    emit logged(!accessToken.isEmpty() && !userName.isEmpty(),
            accessToken, userName);
    emit requestFinished(true);
}

void GetPocketApi::handleLoadBookmarks()
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    QJsonObject rootObject = doc.object();
    const quint64 since = rootObject["since"].toDouble();

    const auto& listObject = rootObject["list"].toObject();
    Bookmarks_t bookmarks;
    for(const auto& key : listObject.keys())
    {
        QJsonObject bookmarkObject = listObject[key].toObject();

        Bookmark bm;
        bm.SetID(bookmarkObject["item_id"].toString());
        bm.SetUrl(bookmarkObject["resolved_url"].toString());
        QString title = bookmarkObject["resolved_title"].toString();
        if(title.isEmpty())
        {
            title = bookmarkObject["given_title"].toString();
        }
        if(title.isEmpty())
        {
            title = bm.GetUrl().toString();
        }
        bm.SetTitle(title);
        bm.SetDescription(bookmarkObject["excerpt"].toString());
        bm.SetIsFavorite(bookmarkObject["favorite"].toString() != "0" ||
                bookmarkObject["time_favorited"].toString() != "0");
        bm.SetIsRead(bookmarkObject["read"].toString() == "1" ||
                bookmarkObject["time_read"].toString() != "0");
        bm.SetAddTime(QDateTime::fromTime_t(bookmarkObject["time_added"]
                .toString().toLongLong()));
        bm.SetUpdateTime(QDateTime::fromTime_t(bookmarkObject["time_updated"]
                .toString().toLongLong()));
        const auto& tagsObject = bookmarkObject["tags"].toObject();
        bm.SetTags(tagsObject.keys());
        bm.SetImageUrl(bookmarkObject["image"].toObject()["src"].toString());
        bm.SetStatus(static_cast<Bookmark::Status>(bookmarkObject["status"]
                .toString().toInt()));

        bookmarks << bm;
    }

    emit gotBookmarks(bookmarks, since);
    emit requestFinished(true);
}

void GetPocketApi::handleRemoveBookmark(const QString& id)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit bookmarkRemoved(id);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to remove bookamark"));
    }
}

void GetPocketApi::handleMarkBookmarkAsFavorite(const QString& id, bool favorite)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit bookmarkMarkedAsFavorite(id, favorite);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to mark bookamark as %1")
                .arg(favorite ? tr("favorite") : tr("unfavorite")));
    }
}

void GetPocketApi::handleMarkBookmarkAsRead(const QString& id, bool read)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit bookmarkMarkedAsRead(id, read);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to mark bookamark as %1")
                .arg(read ? tr("read") : tr("unread")));
    }
}

void GetPocketApi::handleTagsUpdated(const QString& id, const QString& tags)
{
    bool ok = false;
    QJsonDocument doc = PreparsingReply(sender(), ok);
    if (!ok)
    {
        qDebug() << Q_FUNC_INFO << "Failed preparsing reply phase";
        return;
    }

    const auto& rootObject = doc.object();
    if(rootObject ["status"].toInt() == 1)
    {
        emit tagsUpdated(id, tags);
        emit requestFinished(true);
    }
    else
    {
        emit requestFinished(false, tr("Unable to update tags"));
    }
}
} // namespace LinksBag
<|endoftext|>