<commit_before>
#include "font_manager.h"
#include "font.h"

#include <iostream>
#include <stdexcept>
#include <sstream>
#include <tuple>
#include <map>
#include <vector>
#include <base/scope_guard.h>

#include <fontconfig/fontconfig.h>
#include <ft2build.h>
#include FT_FREETYPE_H

namespace script { namespace fontconfig
{

struct font_manager::pimpl
{
	FcConfig *config = nullptr;
	FT_Library ftlib;
};

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

font_manager::font_manager( void )
	: _impl( new pimpl )
{
	if ( FcInit() != FcTrue )
		throw std::runtime_error( "error intializing fontconfig" );

	/*
	set_manager_name( "fontconfig" );
	std::stringstream version;
	int v = FcGetVersion();
	version << v/10000 << '.' << (v/100)%100 << '.' << v%100;
	set_manager_version( version.str() );
	*/

	_impl->config = FcConfigGetCurrent();
	FcConfigSetRescanInterval( _impl->config, 0 );

	if ( FT_Init_FreeType( &(_impl->ftlib) ) != 0 )
		throw std::runtime_error( "freetype initialization failed" );
}

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

font_manager::~font_manager( void )
{
	FT_Done_FreeType( _impl->ftlib );

	delete _impl;
	FcFini();
}

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

std::set<std::string> font_manager::get_families( void )
{
	std::set<std::string> ret;

	FcPattern *pat = FcPatternCreate();
	FcObjectSet *os = FcObjectSetBuild( FC_FAMILY, nullptr );
	FcFontSet *fs = FcFontList( _impl->config, pat, os );
	if ( fs )
	{
		FcChar8 *name = nullptr;
		for ( int i = 0; i < fs->nfont; ++i )
		{
			FcPattern *font = fs->fonts[i];
			if ( FcPatternGetString( font, FC_FAMILY, 0, &name ) == FcResultMatch )
				ret.emplace( reinterpret_cast<const char*>( name ) );
		}
		FcFontSetDestroy( fs );
	}
	FcObjectSetDestroy( os );
	FcPatternDestroy( pat );

	return ret;
}

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

std::set<std::string> font_manager::get_styles( const std::string &family )
{
	std::set<std::string> ret;

	FcPattern *pat = FcPatternBuild( nullptr, FC_FAMILY, FcTypeString, family.c_str(), nullptr );
	FcObjectSet *os = FcObjectSetBuild( FC_STYLE, nullptr );
	FcFontSet *fs = FcFontList( _impl->config, pat, os );
	if ( fs )
	{
		FcChar8 *name = nullptr;
		for ( int i = 0; i < fs->nfont; ++i )
		{
			FcPattern *font = fs->fonts[i];
			if ( FcPatternGetString( font, FC_STYLE, 0, &name ) == FcResultMatch )
				ret.emplace( reinterpret_cast<const char*>( name ) );
		}
		FcFontSetDestroy( fs );
	}
	FcObjectSetDestroy( os );
	FcPatternDestroy( pat );

	return ret;
}

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

std::shared_ptr<script::font>
font_manager::get_font( const std::string &family, const std::string &style,
						double pixsize )
{
	FcPattern *pat = FcPatternBuild( nullptr,
		FC_FAMILY, FcTypeString, family.c_str(),
		FC_STYLE, FcTypeString, style.c_str(),
		FC_PIXEL_SIZE, FcTypeDouble, pixsize,
		nullptr );

	if ( ! pat )
		throw std::runtime_error( "Unable to build font pattern" );

	FcResult result;
	FcPattern *matched = FcFontMatch( _impl->config, pat, &result );
	FcPatternDestroy( pat );
	on_scope_exit { if ( matched ) FcPatternDestroy( matched ); };

	std::shared_ptr<script::font> ret;
	if ( matched && result == FcResultMatch )
	{
		FcChar8 *filename = nullptr;
		int fontid = 0;
		if ( FcPatternGetString( matched, FC_FILE, 0, &filename ) == FcResultMatch &&
			 FcPatternGetInteger( matched, FC_INDEX, 0, &fontid ) == FcResultMatch )
		{
			FT_Face ftface;
			auto error = FT_New_Face( _impl->ftlib, reinterpret_cast<const char*>( filename ), fontid, &ftface );
			if ( error )
				throw std::runtime_error( font::errorstr( error ) );

			try
			{
				ret = std::make_shared<script::fontconfig::font>( ftface, family, style, pixsize );
			}
			catch ( ... )
			{
				FT_Done_Face( ftface );
			}
		}
		else
			throw std::runtime_error( "Unable to extract font information" );
	}
	else
		throw std::runtime_error( "No matching font found" );

	return ret;
}

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

} }

<commit_msg>use new language abstraction to restrict fonts based on desired language<commit_after>
#include "font_manager.h"
#include "font.h"

#include <iostream>
#include <stdexcept>
#include <sstream>
#include <tuple>
#include <map>
#include <vector>
#include <base/scope_guard.h>
#include <base/language.h>

#include <fontconfig/fontconfig.h>
#include <ft2build.h>
#include FT_FREETYPE_H

namespace script { namespace fontconfig
{

struct font_manager::pimpl
{
	FcConfig *config = nullptr;
	FT_Library ftlib;
};

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

font_manager::font_manager( void )
	: _impl( new pimpl )
{
	if ( FcInit() != FcTrue )
		throw std::runtime_error( "error intializing fontconfig" );

	/*
	set_manager_name( "fontconfig" );
	std::stringstream version;
	int v = FcGetVersion();
	version << v/10000 << '.' << (v/100)%100 << '.' << v%100;
	set_manager_version( version.str() );
	*/

	_impl->config = FcConfigGetCurrent();
	FcConfigSetRescanInterval( _impl->config, 0 );

	if ( FT_Init_FreeType( &(_impl->ftlib) ) != 0 )
		throw std::runtime_error( "freetype initialization failed" );
}

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

font_manager::~font_manager( void )
{
	FT_Done_FreeType( _impl->ftlib );

	delete _impl;
	FcFini();
}

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

std::set<std::string> font_manager::get_families( void )
{
	std::set<std::string> ret;

	FcPattern *pat = FcPatternCreate();
	FcObjectSet *os = FcObjectSetBuild( FC_FAMILY, nullptr );
	FcFontSet *fs = FcFontList( _impl->config, pat, os );
	if ( fs )
	{
		FcChar8 *name = nullptr;
		for ( int i = 0; i < fs->nfont; ++i )
		{
			FcPattern *font = fs->fonts[i];
			if ( FcPatternGetString( font, FC_FAMILY, 0, &name ) == FcResultMatch )
				ret.emplace( reinterpret_cast<const char*>( name ) );
		}
		FcFontSetDestroy( fs );
	}
	FcObjectSetDestroy( os );
	FcPatternDestroy( pat );

	return ret;
}

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

std::set<std::string> font_manager::get_styles( const std::string &family )
{
	std::set<std::string> ret;

	FcPattern *pat = FcPatternBuild( nullptr, FC_FAMILY, FcTypeString, family.c_str(), nullptr );
	FcObjectSet *os = FcObjectSetBuild( FC_STYLE, nullptr );
	FcFontSet *fs = FcFontList( _impl->config, pat, os );
	if ( fs )
	{
		FcChar8 *name = nullptr;
		for ( int i = 0; i < fs->nfont; ++i )
		{
			FcPattern *font = fs->fonts[i];
			if ( FcPatternGetString( font, FC_STYLE, 0, &name ) == FcResultMatch )
				ret.emplace( reinterpret_cast<const char*>( name ) );
		}
		FcFontSetDestroy( fs );
	}
	FcObjectSetDestroy( os );
	FcPatternDestroy( pat );

	return ret;
}

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

std::shared_ptr<script::font>
font_manager::get_font( const std::string &family, const std::string &style,
						double pixsize )
{
	std::string lang = base::locale::language();
	FcPattern *pat = FcPatternBuild( nullptr,
		FC_FAMILY, FcTypeString, family.c_str(),
		FC_STYLE, FcTypeString, style.c_str(),
									 FC_LANG, FcTypeString, lang.c_str(),
		FC_PIXEL_SIZE, FcTypeDouble, pixsize,
		nullptr );

	if ( ! pat )
		throw std::runtime_error( "Unable to build font pattern" );

	FcResult result;
	FcPattern *matched = FcFontMatch( _impl->config, pat, &result );
	FcPatternDestroy( pat );
	on_scope_exit { if ( matched ) FcPatternDestroy( matched ); };

	std::shared_ptr<script::font> ret;
	if ( matched && result == FcResultMatch )
	{
		FcChar8 *filename = nullptr;
		int fontid = 0;
		if ( FcPatternGetString( matched, FC_FILE, 0, &filename ) == FcResultMatch &&
			 FcPatternGetInteger( matched, FC_INDEX, 0, &fontid ) == FcResultMatch )
		{
			FT_Face ftface;
			auto error = FT_New_Face( _impl->ftlib, reinterpret_cast<const char*>( filename ), fontid, &ftface );
			if ( error )
				throw std::runtime_error( font::errorstr( error ) );

			try
			{
				ret = std::make_shared<script::fontconfig::font>( ftface, family, style, pixsize );
			}
			catch ( ... )
			{
				FT_Done_Face( ftface );
			}
		}
		else
			throw std::runtime_error( "Unable to extract font information" );
	}
	else
		throw std::runtime_error( "No matching font found" );

	return ret;
}

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

} }

<|endoftext|>


<commit_before>#include <sys/mman.h>

// Driver header file

#include <prussdrv.h>
#include <pruss_intc_mapping.h>

#include "prupwm.h"
#include "mraa.hpp"

#define OUTPUT_READABLE_QUATERNION
#define OUTPUT_READABLE_YAWPITCHROLL

const double UPDATE_RATE = 50; // desired publication rate of IMU data

#define DDR_BASEADDR     0x80000000
#define OFFSET_DDR       0x00001000
#define OFFSET_SHAREDRAM 2048       //equivalent with 0x00002000

#define PRUSS0_SHARED_DATARAM    4

#define PRU_BIN_NAME  "/lib/firmware/pru0.bin"

#define MS_TO_CYCLE(ms)    ((ms)*200000)

PruPwm::PruPwm()
{

}

PruPwm::~PruPwm()
{

}

void PruPwm::Setup()
{
    int ret;
    tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

    printf("\nINFO: Starting PRU.\r\n");
    /* Initialize the PRU */
    prussdrv_init ();

    /* Open PRU Interrupt */
    ret = prussdrv_open(PRU_EVTOUT_0);
    if (ret)
    {
        printf("prussdrv_open open failed\n");
        return ;
    }

     /* Get the interrupt initialized */
    prussdrv_pruintc_init(&pruss_intc_initdata);

   /* open the device */
    mem_fd = open("/dev/mem", O_RDWR);
    if (mem_fd < 0) {
        printf("Failed to open /dev/mem (%s)\n", strerror(errno));
        return ;
    }

    /* map the DDR memory */
    ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, DDR_BASEADDR);
    if (ddrMem == NULL) {
        printf("Failed to map the device (%s)\n", strerror(errno));
        close(mem_fd);
        return ;
    }

    pwm_param = (struct prupwm_param *)(ddrMem + OFFSET_DDR);
    memset(pwm_param, 0, sizeof(struct prupwm_param));
    pwm_param->flag = 0xcf;
    pwm_param->period = MS_TO_CYCLE(0.5);

    /* Get the interrupt initialized */
    prussdrv_pruintc_init(&pruss_intc_initdata);

    /* Execute example on PRU */
    ret = prussdrv_exec_program (0, PRU_BIN_NAME);
    printf("\tINFO: Executing PRU. ret=%d\r\n", ret);

struct prupwm_param *param = Report();
    printf("flag=0x%x, period=0x%x, cycle0=0x%x, cycle1=0x%x, cycle3=0x%x, cycle4=0x%x\n", param->flag, param->period, param->cycle[0], param->cycle[1], param->cycle[2], param->cycle[3]);

    return ;
}

struct prupwm_param *PruPwm::Report()
{
	struct prupwm_param *param;
    prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, &sharedMem);
    param = (struct prupwm_param *) sharedMem;

	return param;
}

void PruPwm::Close()
{
    munmap(ddrMem, 0x0FFFFFFF);
    close(mem_fd);
}
<commit_msg>debug pru pwm node<commit_after>#include <sys/mman.h>

// Driver header file

#include <prussdrv.h>
#include <pruss_intc_mapping.h>

#include "prupwm.h"
#include "mraa.hpp"

#define OUTPUT_READABLE_QUATERNION
#define OUTPUT_READABLE_YAWPITCHROLL

const double UPDATE_RATE = 50; // desired publication rate of IMU data

#define DDR_BASEADDR     0x80000000
#define OFFSET_DDR       0x00001000
#define OFFSET_SHAREDRAM 2048       //equivalent with 0x00002000

#define PRUSS0_SHARED_DATARAM    4

#define PRU_BIN_NAME  "/lib/firmware/pru0.bin"

#define MS_TO_CYCLE(ms)    ((ms)*200000)

PruPwm::PruPwm()
{

}

PruPwm::~PruPwm()
{

}

void PruPwm::Setup()
{
    int ret;
    tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

    printf("\nINFO: Starting PRU.\r\n");
    /* Initialize the PRU */
    prussdrv_init ();

    /* Open PRU Interrupt */
    ret = prussdrv_open(PRU_EVTOUT_0);
    if (ret)
    {
        printf("prussdrv_open open failed\n");
        return ;
    }

     /* Get the interrupt initialized */
    prussdrv_pruintc_init(&pruss_intc_initdata);

   /* open the device */
    mem_fd = open("/dev/mem", O_RDWR);
    if (mem_fd < 0) {
        printf("Failed to open /dev/mem (%s)\n", strerror(errno));
        return ;
    }

    /* map the DDR memory */
    ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, DDR_BASEADDR);
    if (ddrMem == NULL) {
        printf("Failed to map the device (%s)\n", strerror(errno));
        close(mem_fd);
        return ;
    }

    pwm_param = (struct prupwm_param *)(ddrMem + OFFSET_DDR);
    memset(pwm_param, 0, sizeof(struct prupwm_param));
    pwm_param->flag = 0xcf;
    pwm_param->period = MS_TO_CYCLE(0.5);

    /* Get the interrupt initialized */
    prussdrv_pruintc_init(&pruss_intc_initdata);

    /* Execute example on PRU */
    ret = prussdrv_exec_program (0, PRU_BIN_NAME);
    printf("\tINFO: Executing PRU. ret=%d\r\n", ret);

struct prupwm_param *param = Report();
    printf("flag=0x%x, period=0x%x, cycle0=0x%x, cycle1=0x%x, cycle3=0x%x, cycle4=0x%x\n", param->flag, param->period, param->cycle[0], param->cycle[1], param->cycle[2], param->cycle[3]);

    return ;
}

struct prupwm_param *PruPwm::Report()
{
	struct prupwm_param *param;
    prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, &sharedMem);
    param = (struct prupwm_param *) ((unsigned int*)sharedMem + OFFSET_SHAREDRAM);

	return param;
}

void PruPwm::Close()
{
    munmap(ddrMem, 0x0FFFFFFF);
    close(mem_fd);
}
<|endoftext|>


<commit_before>/* Copyright (C) 2005-2011 Fabio Riccardi */
/* Copyright (C) 2014-     Masahir Kitagawa */

#include <jni.h>
#include <climits>
#include <cstdlib>

#ifndef AUTO_DEP
#include "javah/com_lightcrafts_utils_DCRaw.h"
#endif

#include "LC_JNIUtils.h"
#include "../include/mathlz.h"

#define DCRaw_METHOD(method) \
        name4(Java_,com_lightcrafts_utils_DCRaw,_,method)

#define srcDatum(x, y) \
        srcData[(y) * srcLineStride + (x) + srcOffset]

#define dstDatum(x, y, offset) \
        dstData[3 * ((y) * dstLineStride + (x)) + (offset)]

#define datum(x, y, offset) \
        data[3 * ((y) * lineStride + (x)) + (offset)]

JNIEXPORT void JNICALL DCRaw_METHOD(interpolateGreen)
( JNIEnv *env, jclass cls,
  jshortArray jsrcData, jshortArray jdstData, jint width, jint height,
  jint srcLineStride, jint dstLineStride,
  jint srcOffset, jint rOffset, jint gOffset, jint bOffset,
  jint gx, jint gy, jint ry )
{
    auto srcData = static_cast<unsigned short*>(env->GetPrimitiveArrayCritical(jsrcData, 0));
    auto dstData = static_cast<unsigned short*>(env->GetPrimitiveArrayCritical(jdstData, 0));

#pragma omp parallel shared (srcData, dstData)
{

    // copy RAW data to RGB layer and remove hot pixels

#pragma omp for schedule (dynamic)
    for (int y = 0; y < height; y++) {
        const int cOffset = (y&1) == (ry&1) ? rOffset : bOffset;
        const int x0 = (y&1) == (gy&1) ? gx+1 : gx;
        for (int x = 0; x < width; x++) {
            const bool colorPixel = (x & 1) == (x0 & 1);
            const int offset = colorPixel ? cOffset : gOffset;

            int value = srcDatum(x, y);
            if (x >= 2 && x < width-2 && y >= 2 && y < height-2) {
                int v[4];
                bool replace = true;
                if (colorPixel) {
                    if (value < 2 * (v[0] = srcDatum(x, y-2))
                            || value < 2 * (v[1] = srcDatum(x, y+2))
                            || value < 2 * (v[2] = srcDatum(x-2, y))
                            || value < 2 * (v[3] = srcDatum(x+2, y))

                            || value < 2 * 2 * srcDatum(x-1, y-1)
                            || value < 2 * 2 * srcDatum(x, y-1)
                            || value < 2 * 2 * srcDatum(x+1, y-1)

                            || value < 2 * 2 * srcDatum(x-1, y)
                            || value < 2 * 2 * srcDatum(x+1, y)

                            || value < 2 * 2 * srcDatum(x-1, y+1)
                            || value < 2 * 2 * srcDatum(x, y+1)
                            || value < 2 * 2 * srcDatum(x+1, y+1)) {
                        replace = false;
                    }
                } else {
                    if (value < 2 * (v[0] = srcDatum(x-1, y-1))
                            || value < 2 * (v[1] = srcDatum(x+1, y-1))
                            || value < 2 * (v[2] = srcDatum(x-1, y+1))
                            || value < 2 * (v[3] = srcDatum(x+1, y+1))

                            || value < 2 * 2 * srcDatum(x, y-1)
                            || value < 2 * 2 * srcDatum(x-1, y)
                            || value < 2 * 2 * srcDatum(x+1, y)
                            || value < 2 * 2 * srcDatum(x, y+1)) {
                        replace = false;
                    }
                }
                if (replace) {
                    value = (v[0] + v[1] + v[2] + v[3]) / 4;
                }
            }
            dstDatum(x, y, offset) = static_cast<unsigned short>(value);
        }
    }

    // green channel interpolation

#pragma omp for schedule (dynamic)
    for (int y = 2; y < height-2; y++) {
        const int cOffset = (y&1) == (ry&1) ? rOffset : bOffset;
        const int x0 = (y&1) == (gy&1) ? gx+1 : gx;

        int hl = dstDatum(x0-1, y, gOffset);
        int cxy = dstDatum(x0, y, cOffset);
        int chl = dstDatum(x0-2, y, cOffset);

        const int x_min = (x0 & 1) ? 3 : 2;
        for (int x = x_min; x < width-2; x += 2) {
            const int hr = dstDatum(x+1, y, gOffset);
            const int vu = dstDatum(x, y-1, gOffset);
            const int vd = dstDatum(x, y+1, gOffset);
            const int dh = abs(hl - hr);
            const int dv = abs(vu - vd);

            const int chr = dstDatum(x+2, y, cOffset);
            const int cvu = dstDatum(x, y-2, cOffset);
            const int cvd = dstDatum(x, y+2, cOffset);
            const int cdh = abs(chl + chr - 2 * cxy);
            const int cdv = abs(cvu + cvd - 2 * cxy);

            // we're doing edge directed bilinear interpolation on the green channel,
            // which is a low pass operation (averaging), so we add some signal from the
            // high frequencies of the observed color channel

            int sample;
            if (dv + cdv - (dh + cdh) > 0) {
                sample = (hl + hr) / 2;
                if (sample < 4 * cxy && cxy < 4 * sample)
                    sample += (cxy - (chl + chr)/2) / 4;
            } else if (dh + cdh - (dv + cdv) > 0) {
                sample = (vu + vd) / 2;
                if (sample < 4 * cxy && cxy < 4 * sample)
                    sample += (cxy - (cvu + cvd)/2) / 4;
            } else {
                sample = (vu + hl + vd + hr) / 4;
                if (sample < 4 * cxy && cxy < 4 * sample)
                    sample += (cxy - (chl + chr + cvu + cvd)/4) / 8;
            }
            dstDatum(x, y, gOffset) = clampUShort(sample);

            hl = hr;
            chl = cxy;
            cxy = chr;
        }
    }

    // get the constant component out of the reconstructed green pixels and add to it
    // the "high frequency" part of the corresponding observed color channel

#pragma omp for schedule (dynamic)
    for (int y = 2; y < height-2; y++) {
        const int cOffset = (y&1) == (ry&1) ? rOffset : bOffset;
        const int x0 = (y&1) == (gy&1) ? gx+1 : gx;

        int xy = dstDatum(x0, y, gOffset);
        int hl = dstDatum(x0-2, y, gOffset);
        int ul = dstDatum(x0-2, y-2, gOffset);
        int bl = dstDatum(x0-2, y+2, gOffset);

        int cxy = dstDatum(x0, y, cOffset);
        int chl = dstDatum(x0-2, y, cOffset);
        int cul = dstDatum(x0-2, y-2, cOffset);
        int cbl = dstDatum(x0-2, y+2, cOffset);

        for (int x = 2; x < width-2; x+=2) {
            const int hr = dstDatum(x+2, y, gOffset);
            const int ur = dstDatum(x+2, y-2, gOffset);
            const int br = dstDatum(x+2, y+2, gOffset);
            int vu = dstDatum(x, y-2, gOffset);
            int vd = dstDatum(x, y+2, gOffset);

            const int chr = dstDatum(x+2, y, cOffset);
            const int cur = dstDatum(x+2, y-2, cOffset);
            const int cbr = dstDatum(x+2, y+2, cOffset);
            int cvu = dstDatum(x, y-2, cOffset);
            int cvd = dstDatum(x, y+2, cOffset);

            // Only work on the pixels that have a strong enough correlation between channels

            if (xy < 4 * cxy && cxy < 4 * xy) {
                const int dh = xy - (hl + hr)/2;
                const int dv = xy - (vu + vd)/2;
                const int ne = xy - (ul + br)/2;
                const int nw = xy - (ur + bl)/2;

                const int cdh = cxy - (chl + chr)/2;
                const int cdv = cxy - (cvu + cvd)/2;
                const int cne = cxy - (cul + cbr)/2;
                const int cnw = cxy - (cur + cbl)/2;

                const int gradients[4] = {
                    abs(dh) + abs(cdh),
                    abs(dv) + abs(cdv),
                    abs(ne) + abs(cne),
                    abs(nw) + abs(cnw)
                };

                int mind = 4;
                int ming = INT_MAX;
                for (int i = 0; i < 4; i++) {
                    if (gradients[i] < ming) {
                        ming = gradients[i];
                        mind = i;
                    }
                }

                // Only work on parts of the image that have enough "detail"

                if (mind != 4 && ming > xy / 4) {
                    int sample;
                    switch (mind) {
                        case 0: // horizontal
                            sample = (xy + (hl + hr)/2 + cdh) / 2;
                            break;
                        case 1: // vertical
                            sample = (xy + (vu + vd)/2 + cdv) / 2;
                            break;
                        case 2: // north-east
                            sample = (xy + (ul + br)/2 + cne) / 2;
                            break;
                        case 3: // north-west
                            sample = (xy + (ur + bl)/2 + cnw) / 2;
                            break;
                        case 4: // flat
                            // nothing to do
                            break;
                    }
                    dstDatum(x, y, gOffset) = clampUShort(sample);
                }
            }

            hl = xy;
            xy = hr;
            ul = vu;
            vu = ur;
            bl = vd;
            vd = br;
            chl = cxy;
            cxy = chr;
            cul = cvu;
            cvu = cur;
            cbl = cvd;
            cvd = cbr;
        }
    }

} // #pragma omp parallel

    env->ReleasePrimitiveArrayCritical(jsrcData, srcData, 0);
    env->ReleasePrimitiveArrayCritical(jdstData, dstData, 0);
}

JNIEXPORT void JNICALL DCRaw_METHOD(interpolateRedBlue)
( JNIEnv *env, jclass cls,
  jshortArray jdata, jint width, jint height,
  jint lineStride,
  jint rOffset, jint gOffset, jint bOffset,
  jint rx0, jint ry0, jint bx0, jint by0 )
{
    auto data = static_cast<unsigned short*>(env->GetPrimitiveArrayCritical(jdata, 0));

    for (int i = 0; i < 2; i++) {
        int cx0, cy0, cOffset;
        if (i == 0) {
            cx0 = rx0;
            cy0 = ry0;
            cOffset = rOffset;
        } else {
            cx0 = bx0;
            cy0 = by0;
            cOffset = bOffset;
        }

#pragma omp parallel shared (data)
{
#pragma omp for schedule (dynamic) nowait
        for (int y = 1; y < height-2; y += 2) {
            for (int x = 1; x < width-2; x += 2) {
                const int cg = datum(x + cx0, y + cy0, gOffset);

                // Pixel at the other color location
                const int gne = datum(x + cx0 - 1, y + cy0 + 1, gOffset);
                const int gnw = datum(x + cx0 + 1, y + cy0 + 1, gOffset);
                const int gsw = datum(x + cx0 + 1, y + cy0 - 1, gOffset);
                const int gse = datum(x + cx0 - 1, y + cy0 - 1, gOffset);

                const int cne = gne - datum(x + cx0 - 1, y + cy0 + 1, cOffset);
                const int cnw = gnw - datum(x + cx0 + 1, y + cy0 + 1, cOffset);
                const int csw = gsw - datum(x + cx0 + 1, y + cy0 - 1, cOffset);
                const int cse = gse - datum(x + cx0 - 1, y + cy0 - 1, cOffset);

                const int sample = cg - (cne + csw + cnw + cse) / 4;
                datum(x + cx0, y + cy0, cOffset) = clampUShort(sample);
            }
            for (int x = 0; x < width-1; x += 2) {
                const int cg = datum(x + cx0, y + cy0, gOffset);

                // Pixel at green location - vertical
                const int gu = datum(x + cx0, y + cy0 - 1, gOffset);
                const int gd = datum(x + cx0, y + cy0 + 1, gOffset);

                const int cu = gu - datum(x + cx0, y + cy0 - 1, cOffset);
                const int cd = gd - datum(x + cx0, y + cy0 + 1, cOffset);

                const int sample = cg - (cu + cd) / 2;
                datum(x + cx0, y + cy0, cOffset) = clampUShort(sample);
            }
        }
#pragma omp for schedule (dynamic)
        for (int y = 0; y < height-1; y += 2) {
            for (int x = 1; x < width-2; x += 2) {
                const int cg = datum(x + cx0, y + cy0, gOffset);

                // Pixel at green location - horizontal
                const int gl = datum(x + cx0 - 1, y + cy0, gOffset);
                const int gr = datum(x + cx0 + 1, y + cy0, gOffset);

                const int cl = gl - datum(x + cx0 - 1, y + cy0, cOffset);
                const int cr = gr - datum(x + cx0 + 1, y + cy0, cOffset);

                const int sample = cg - (cl + cr) / 2;
                datum(x + cx0, y + cy0, cOffset) = clampUShort(sample);
            }
        }
} // #pragma omp parallel
    }
    env->ReleasePrimitiveArrayCritical(jdata, data, 0);
}
<commit_msg>Refactor dcrawUtils#interpolateRedBlue<commit_after>/* Copyright (C) 2005-2011 Fabio Riccardi */
/* Copyright (C) 2014-     Masahir Kitagawa */

#include <jni.h>
#include <climits>
#include <cstdlib>

#ifndef AUTO_DEP
#include "javah/com_lightcrafts_utils_DCRaw.h"
#endif

#include "LC_JNIUtils.h"
#include "../include/mathlz.h"

#define DCRaw_METHOD(method) \
        name4(Java_,com_lightcrafts_utils_DCRaw,_,method)

#define srcDatum(x, y) \
        srcData[(y) * srcLineStride + (x) + srcOffset]

#define dstDatum(x, y, offset) \
        dstData[3 * ((y) * dstLineStride + (x)) + (offset)]

#define cDatum(xOffset, yOffset) \
        data[3 * ((y + cy0 + (yOffset)) * lineStride + x + cx0 + (xOffset)) + cOffset]

#define gDatum(xOffset, yOffset) \
        data[3 * ((y + cy0 + (yOffset)) * lineStride + x + cx0 + (xOffset)) + gOffset]

JNIEXPORT void JNICALL DCRaw_METHOD(interpolateGreen)
( JNIEnv *env, jclass cls,
  jshortArray jsrcData, jshortArray jdstData, jint width, jint height,
  jint srcLineStride, jint dstLineStride,
  jint srcOffset, jint rOffset, jint gOffset, jint bOffset,
  jint gx, jint gy, jint ry )
{
    auto srcData = static_cast<unsigned short*>(env->GetPrimitiveArrayCritical(jsrcData, 0));
    auto dstData = static_cast<unsigned short*>(env->GetPrimitiveArrayCritical(jdstData, 0));

#pragma omp parallel shared (srcData, dstData)
{

    // copy RAW data to RGB layer and remove hot pixels

#pragma omp for schedule (dynamic)
    for (int y = 0; y < height; y++) {
        const int cOffset = (y&1) == (ry&1) ? rOffset : bOffset;
        const int x0 = (y&1) == (gy&1) ? gx+1 : gx;
        for (int x = 0; x < width; x++) {
            const bool colorPixel = (x & 1) == (x0 & 1);
            const int offset = colorPixel ? cOffset : gOffset;

            int value = srcDatum(x, y);
            if (x >= 2 && x < width-2 && y >= 2 && y < height-2) {
                int v[4];
                bool replace = true;
                if (colorPixel) {
                    if (value < 2 * (v[0] = srcDatum(x, y-2))
                            || value < 2 * (v[1] = srcDatum(x, y+2))
                            || value < 2 * (v[2] = srcDatum(x-2, y))
                            || value < 2 * (v[3] = srcDatum(x+2, y))

                            || value < 2 * 2 * srcDatum(x-1, y-1)
                            || value < 2 * 2 * srcDatum(x, y-1)
                            || value < 2 * 2 * srcDatum(x+1, y-1)

                            || value < 2 * 2 * srcDatum(x-1, y)
                            || value < 2 * 2 * srcDatum(x+1, y)

                            || value < 2 * 2 * srcDatum(x-1, y+1)
                            || value < 2 * 2 * srcDatum(x, y+1)
                            || value < 2 * 2 * srcDatum(x+1, y+1)) {
                        replace = false;
                    }
                } else {
                    if (value < 2 * (v[0] = srcDatum(x-1, y-1))
                            || value < 2 * (v[1] = srcDatum(x+1, y-1))
                            || value < 2 * (v[2] = srcDatum(x-1, y+1))
                            || value < 2 * (v[3] = srcDatum(x+1, y+1))

                            || value < 2 * 2 * srcDatum(x, y-1)
                            || value < 2 * 2 * srcDatum(x-1, y)
                            || value < 2 * 2 * srcDatum(x+1, y)
                            || value < 2 * 2 * srcDatum(x, y+1)) {
                        replace = false;
                    }
                }
                if (replace) {
                    value = (v[0] + v[1] + v[2] + v[3]) / 4;
                }
            }
            dstDatum(x, y, offset) = static_cast<unsigned short>(value);
        }
    }

    // green channel interpolation

#pragma omp for schedule (dynamic)
    for (int y = 2; y < height-2; y++) {
        const int cOffset = (y&1) == (ry&1) ? rOffset : bOffset;
        const int x0 = (y&1) == (gy&1) ? gx+1 : gx;

        int hl = dstDatum(x0-1, y, gOffset);
        int cxy = dstDatum(x0, y, cOffset);
        int chl = dstDatum(x0-2, y, cOffset);

        const int x_min = (x0 & 1) ? 3 : 2;
        for (int x = x_min; x < width-2; x += 2) {
            const int hr = dstDatum(x+1, y, gOffset);
            const int vu = dstDatum(x, y-1, gOffset);
            const int vd = dstDatum(x, y+1, gOffset);
            const int dh = abs(hl - hr);
            const int dv = abs(vu - vd);

            const int chr = dstDatum(x+2, y, cOffset);
            const int cvu = dstDatum(x, y-2, cOffset);
            const int cvd = dstDatum(x, y+2, cOffset);
            const int cdh = abs(chl + chr - 2 * cxy);
            const int cdv = abs(cvu + cvd - 2 * cxy);

            // we're doing edge directed bilinear interpolation on the green channel,
            // which is a low pass operation (averaging), so we add some signal from the
            // high frequencies of the observed color channel

            int sample;
            if (dv + cdv - (dh + cdh) > 0) {
                sample = (hl + hr) / 2;
                if (sample < 4 * cxy && cxy < 4 * sample)
                    sample += (cxy - (chl + chr)/2) / 4;
            } else if (dh + cdh - (dv + cdv) > 0) {
                sample = (vu + vd) / 2;
                if (sample < 4 * cxy && cxy < 4 * sample)
                    sample += (cxy - (cvu + cvd)/2) / 4;
            } else {
                sample = (vu + hl + vd + hr) / 4;
                if (sample < 4 * cxy && cxy < 4 * sample)
                    sample += (cxy - (chl + chr + cvu + cvd)/4) / 8;
            }
            dstDatum(x, y, gOffset) = clampUShort(sample);

            hl = hr;
            chl = cxy;
            cxy = chr;
        }
    }

    // get the constant component out of the reconstructed green pixels and add to it
    // the "high frequency" part of the corresponding observed color channel

#pragma omp for schedule (dynamic)
    for (int y = 2; y < height-2; y++) {
        const int cOffset = (y&1) == (ry&1) ? rOffset : bOffset;
        const int x0 = (y&1) == (gy&1) ? gx+1 : gx;

        int xy = dstDatum(x0, y, gOffset);
        int hl = dstDatum(x0-2, y, gOffset);
        int ul = dstDatum(x0-2, y-2, gOffset);
        int bl = dstDatum(x0-2, y+2, gOffset);

        int cxy = dstDatum(x0, y, cOffset);
        int chl = dstDatum(x0-2, y, cOffset);
        int cul = dstDatum(x0-2, y-2, cOffset);
        int cbl = dstDatum(x0-2, y+2, cOffset);

        for (int x = 2; x < width-2; x+=2) {
            const int hr = dstDatum(x+2, y, gOffset);
            const int ur = dstDatum(x+2, y-2, gOffset);
            const int br = dstDatum(x+2, y+2, gOffset);
            int vu = dstDatum(x, y-2, gOffset);
            int vd = dstDatum(x, y+2, gOffset);

            const int chr = dstDatum(x+2, y, cOffset);
            const int cur = dstDatum(x+2, y-2, cOffset);
            const int cbr = dstDatum(x+2, y+2, cOffset);
            int cvu = dstDatum(x, y-2, cOffset);
            int cvd = dstDatum(x, y+2, cOffset);

            // Only work on the pixels that have a strong enough correlation between channels

            if (xy < 4 * cxy && cxy < 4 * xy) {
                const int dh = xy - (hl + hr)/2;
                const int dv = xy - (vu + vd)/2;
                const int ne = xy - (ul + br)/2;
                const int nw = xy - (ur + bl)/2;

                const int cdh = cxy - (chl + chr)/2;
                const int cdv = cxy - (cvu + cvd)/2;
                const int cne = cxy - (cul + cbr)/2;
                const int cnw = cxy - (cur + cbl)/2;

                const int gradients[4] = {
                    abs(dh) + abs(cdh),
                    abs(dv) + abs(cdv),
                    abs(ne) + abs(cne),
                    abs(nw) + abs(cnw)
                };

                int mind = 4;
                int ming = INT_MAX;
                for (int i = 0; i < 4; i++) {
                    if (gradients[i] < ming) {
                        ming = gradients[i];
                        mind = i;
                    }
                }

                // Only work on parts of the image that have enough "detail"

                if (mind != 4 && ming > xy / 4) {
                    int sample;
                    switch (mind) {
                        case 0: // horizontal
                            sample = (xy + (hl + hr)/2 + cdh) / 2;
                            break;
                        case 1: // vertical
                            sample = (xy + (vu + vd)/2 + cdv) / 2;
                            break;
                        case 2: // north-east
                            sample = (xy + (ul + br)/2 + cne) / 2;
                            break;
                        case 3: // north-west
                            sample = (xy + (ur + bl)/2 + cnw) / 2;
                            break;
                        case 4: // flat
                            // nothing to do
                            break;
                    }
                    dstDatum(x, y, gOffset) = clampUShort(sample);
                }
            }

            hl = xy;
            xy = hr;
            ul = vu;
            vu = ur;
            bl = vd;
            vd = br;
            chl = cxy;
            cxy = chr;
            cul = cvu;
            cvu = cur;
            cbl = cvd;
            cvd = cbr;
        }
    }

} // #pragma omp parallel

    env->ReleasePrimitiveArrayCritical(jsrcData, srcData, 0);
    env->ReleasePrimitiveArrayCritical(jdstData, dstData, 0);
}

JNIEXPORT void JNICALL DCRaw_METHOD(interpolateRedBlue)
( JNIEnv *env, jclass cls,
  jshortArray jdata, jint width, jint height,
  jint lineStride,
  jint rOffset, jint gOffset, jint bOffset,
  jint rx0, jint ry0, jint bx0, jint by0 )
{
    auto data = static_cast<unsigned short*>(env->GetPrimitiveArrayCritical(jdata, 0));

    for (int i = 0; i < 2; i++) {
        int cx0, cy0, cOffset;
        if (i == 0) {
            cx0 = rx0;
            cy0 = ry0;
            cOffset = rOffset;
        } else {
            cx0 = bx0;
            cy0 = by0;
            cOffset = bOffset;
        }

#pragma omp parallel for schedule (guided) shared (data)
        for (int y = 1; y < height-2; y += 2) {
            int x = 1;
            int gne = gDatum(-1, 1);
            int gse = gDatum(-1, -1);
            int cne = gne - cDatum(-1, 1);
            int cse = gse - cDatum(-1, -1);

            for (; x < width-2; x += 2) {
                const int gnw = gDatum(1, 1);
                const int gsw = gDatum(1, -1);
                const int cnw = gnw - cDatum(1, 1);
                const int csw = gsw - cDatum(1, -1);

                // Pixel at the other color location
                const int gc = gDatum(0, 0);
                const int sample_c = gc - (cne + csw + cnw + cse) / 4;
                cDatum(0, 0) = clampUShort(sample_c);

                // Pixel at green location - vertical
                const int gw = gDatum(1, 0);
                const int sample_w = gw - (csw + cnw) / 2;
                cDatum(1, 0) = clampUShort(sample_w);

                // Pixel at green location - horizontal
                const int gs = gDatum(0, -1);
                const int sample_s = gs - (cse + csw) / 2;
                cDatum(0, -1) = clampUShort(sample_s);

                gne = gnw;
                gse = gsw;
                cne = cnw;
                cse = csw;
            }
        }
    }
    env->ReleasePrimitiveArrayCritical(jdata, data, 0);
}
<|endoftext|>


<commit_before>#include <QtGlobal>
// Automatically generated by extract_strings.py
static const char *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "List commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks4 proxy\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for addnode and connect\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't accept connections from outside\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"\n"
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
"@STRENGTH)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s.  Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error loading wallet.dat: Wallet requires newer version of Bitcoin      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high.  This is the transaction fee you will "
"pay if you send a transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: CreateThread(StartNode) failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low  "),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to port %d on this computer.  Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This transaction is over the size limit.  You can still send it for a fee of "
"%s, which goes to the nodes that process your transaction and helps to "
"support the network.  Do you want to pay the fee?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Enter the current passphrase to the wallet."),
QT_TRANSLATE_NOOP("bitcoin-core", "Passphrase"),
QT_TRANSLATE_NOOP("bitcoin-core", "Please supply the current wallet decryption passphrase."),
QT_TRANSLATE_NOOP("bitcoin-core", "The passphrase entered for the wallet decryption was incorrect."),
QT_TRANSLATE_NOOP("bitcoin-core", "Status"),
QT_TRANSLATE_NOOP("bitcoin-core", "Date"),
QT_TRANSLATE_NOOP("bitcoin-core", "Description"),
QT_TRANSLATE_NOOP("bitcoin-core", "Debit"),
QT_TRANSLATE_NOOP("bitcoin-core", "Credit"),
QT_TRANSLATE_NOOP("bitcoin-core", "Open for %d blocks"),
QT_TRANSLATE_NOOP("bitcoin-core", "Open until %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "%d/offline?"),
QT_TRANSLATE_NOOP("bitcoin-core", "%d/unconfirmed"),
QT_TRANSLATE_NOOP("bitcoin-core", "%d confirmations"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generated"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generated (%s matures in %d more blocks)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Generated - Warning: This block was not received by any other nodes and will "
"probably not be accepted!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generated (not accepted)"),
QT_TRANSLATE_NOOP("bitcoin-core", "From: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Received with: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Payment to yourself"),
QT_TRANSLATE_NOOP("bitcoin-core", "To: "),
QT_TRANSLATE_NOOP("bitcoin-core", "    Generating"),
QT_TRANSLATE_NOOP("bitcoin-core", "(not connected)"),
QT_TRANSLATE_NOOP("bitcoin-core", "     %d connections     %d blocks     %d transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet already encrypted."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Enter the new passphrase to the wallet.\n"
"Please use a passphrase of 10 or more random characters, or eight or more "
"words."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: The supplied passphrase was too short."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE "
"ALL OF YOUR BITCOINS!\n"
"Are you sure you wish to encrypt your wallet?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Please re-enter your new wallet passphrase."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: the supplied passphrases didn't match."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet encryption failed."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Wallet Encrypted.\n"
"Remember that encrypting your wallet cannot fully protect your bitcoins from "
"being stolen by malware infecting your computer."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet is unencrypted, please encrypt it first."),
QT_TRANSLATE_NOOP("bitcoin-core", "Enter the new passphrase for the wallet."),
QT_TRANSLATE_NOOP("bitcoin-core", "Re-enter the new passphrase for the wallet."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet Passphrase Changed."),
QT_TRANSLATE_NOOP("bitcoin-core", "New Receiving Address"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"You should use a new address for each payment you receive.\n"
"\n"
"Label"),
QT_TRANSLATE_NOOP("bitcoin-core", "Status: "),
QT_TRANSLATE_NOOP("bitcoin-core", ", has not been successfully broadcast yet"),
QT_TRANSLATE_NOOP("bitcoin-core", ", broadcast through %d node"),
QT_TRANSLATE_NOOP("bitcoin-core", ", broadcast through %d nodes"),
QT_TRANSLATE_NOOP("bitcoin-core", "Date: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Source: Generated
"),
QT_TRANSLATE_NOOP("bitcoin-core", "From: "),
QT_TRANSLATE_NOOP("bitcoin-core", "unknown"),
QT_TRANSLATE_NOOP("bitcoin-core", "To: "),
QT_TRANSLATE_NOOP("bitcoin-core", " (yours, label: "),
QT_TRANSLATE_NOOP("bitcoin-core", " (yours)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Credit: "),
QT_TRANSLATE_NOOP("bitcoin-core", "(%s matures in %d more blocks)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(not accepted)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Debit: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction fee: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Net amount: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Message:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Comment:"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Generated coins must wait 120 blocks before they can be spent.  When you "
"generated this block, it was broadcast to the network to be added to the "
"block chain.  If it fails to get into the chain, it will change to \"not "
"accepted\" and not be spendable.  This may occasionally happen if another "
"node generates a block within a few seconds of yours."),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write autostart/bitcoin.desktop file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Main"),
QT_TRANSLATE_NOOP("bitcoin-core", "&Start Bitcoin on window system startup"),
QT_TRANSLATE_NOOP("bitcoin-core", "&Minimize on close"),
QT_TRANSLATE_NOOP("bitcoin-core", "version %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error in amount  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Send Coins"),
QT_TRANSLATE_NOOP("bitcoin-core", "Amount exceeds your balance  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Total exceeds your balance when the "),
QT_TRANSLATE_NOOP("bitcoin-core", " transaction fee is included  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Payment sent  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid address  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Sending %s to %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "CANCELLED"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cancelled"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transfer cancelled  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connecting..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to connect"),
QT_TRANSLATE_NOOP("bitcoin-core", "Requesting public key..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Received public key..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Recipient is not accepting transactions sent by IP address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transfer was not accepted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid response received"),
QT_TRANSLATE_NOOP("bitcoin-core", "Creating transaction..."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This transaction requires a transaction fee of at least %s because of its "
"amount, complexity, or use of recently received funds"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction creation failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction aborted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Lost connection, transaction cancelled"),
QT_TRANSLATE_NOOP("bitcoin-core", "Sending payment..."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"The transaction was rejected.  This might happen if some of the coins in "
"your wallet were already spent, such as if you used a copy of wallet.dat and "
"coins were spent in the copy but not marked as spent here."),
QT_TRANSLATE_NOOP("bitcoin-core", "Waiting for confirmation..."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"The payment was sent, but the recipient was unable to verify it.\n"
"The transaction is recorded and will credit to the recipient,\n"
"but the comment information will be blank."),
QT_TRANSLATE_NOOP("bitcoin-core", "Payment was sent, but an invalid response was received"),
QT_TRANSLATE_NOOP("bitcoin-core", "Payment completed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Name"),
QT_TRANSLATE_NOOP("bitcoin-core", "Address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Label"),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin Address"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This is one of your own addresses for receiving payments and cannot be "
"entered in the address book.  "),
QT_TRANSLATE_NOOP("bitcoin-core", "Edit Address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Edit Address Label"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add Address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin - Generating"),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin - (not connected)"),
QT_TRANSLATE_NOOP("bitcoin-core", "&Open Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "&Send Bitcoins"),
QT_TRANSLATE_NOOP("bitcoin-core", "O&ptions..."),
QT_TRANSLATE_NOOP("bitcoin-core", "E&xit"),
QT_TRANSLATE_NOOP("bitcoin-core", "Program has crashed and will terminate.  "),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: Please check that your computer's date and time are correct.  If "
"your clock is wrong Bitcoin will not work properly."),
QT_TRANSLATE_NOOP("bitcoin-core", "beta"),
};<commit_msg>Save translators some work - Remove duplicate translation strings (that somehow came from old wx UI and ended up in bitcoinstrings.cpp)<commit_after>#include <QtGlobal>
// Automatically generated by extract_strings.py
static const char *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "List commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks4 proxy\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for addnode and connect\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't accept connections from outside\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Number of seconds to keep misbehaving peers from reconnecting (default: "
"86400)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to use UPnP to map the listening port\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"\n"
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
"@STRENGTH)\n"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message\n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s.  Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error loading wallet.dat: Wallet requires newer version of Bitcoin      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat      \n"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high.  This is the transaction fee you will "
"pay if you send a transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: CreateThread(StartNode) failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low  "),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to port %d on this computer.  Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: Please check that your computer's date and time are correct.  If "
"your clock is wrong Bitcoin will not work properly."),
QT_TRANSLATE_NOOP("bitcoin-core", "beta"),
};<|endoftext|>


<commit_before>#ifndef MYPARSER_AST_HPP
#define MYPARSER_AST_HPP

#include "myparser_str.hpp"
#include "myparser_pass.hpp"

namespace myparser {

using Input = std::string::const_iterator;

using BuiltinRoot = MP_STR("root", 4);
using BuiltinSpace = MP_STR("space", 5);
using BuiltinKeyword = MP_STR("keyword", 7);
using BuiltinError = MP_STR("error", 5);

template <class TX = void> // actually not a template
class Node {
private:
    inline Node() = delete;

protected:
    inline Node(
        const Input &input
    ): pos(input), tail(input) {}

    const Input pos;
    Input tail;

public:
    virtual ~Node() {} // destructable (public)

    virtual void free() {
        delete this;
    }

    virtual bool empty() const = 0;

    virtual void runPass(PassBase<> *pass) const = 0;

    virtual const std::string &getRuleName() const = 0;

    inline const std::string getFullText() const {
        return std::string(pos, tail);
    }

    inline const Input &getPos() const {
        return pos;
    }

    inline const Input &getTail() const {
        return tail;
    }

    inline Node<> *challengeLonger(Node<> *target) {
        if (!target) {
            return this;
        }

        if (getTail() > target->getTail()) {
            target->free();
            return this;
        } else {
            this->free();
            return target;
        }
    }
};

template <class TX = void> // actually not a template
class NodeList: public Node<> {
private:
    std::vector<Node<> *> children;

    size_t basepos;
    NodeList<> *brother = nullptr;

protected:
    inline NodeList(
        const Input &input
    ): Node<>(input), children() {}

public:
    virtual ~NodeList() {
        for (size_t i = basepos; i < children.size(); ++i) {
            children[i]->free();
        }
    }

    virtual void free() {
        if (brother) {
            brother->basepos = 0;
            brother->brother = nullptr;
        }
        delete this;
    }

    virtual bool empty() const {
        for (Node<> *child: children) {
            if (!child->empty()) {
                return false;
            }
        }

        return true;
    }

    inline void bind(NodeList<> *target, const size_t pos) {
        brother = target;
        basepos = pos;
    }

    inline void putChild(Node<> *value) {
        children.push_back(value);
        tail = value->getTail();
    }

    inline const std::vector<Node<> *> &getChildren() const {
        return children;
    }
};

template <size_t I>
class NodeListIndexed: public NodeList<> {
public:
    inline NodeListIndexed(
        const Input &input
    ): NodeList<>(input) {}

    // virtual ~NodeListIndexed() {}

    inline size_t getIndex() const {
        return I;
    }
};

// TODO: remove .text and use getFullText() with cache
template <class TX = void> // actually not a template
class NodeText: public Node<> {
private:
    const std::string text;

protected:
    inline NodeText(
        const Input &input, std::string &&value
    ): Node<>(input), text(std::move(value)) {
        tail = tail + text.size();
    }

    inline NodeText(
        const Input &input, const std::string &value
    ): Node<>(input), text(value) {
        tail = tail + text.size();
    }

public:
    // virtual ~NodeText() {}

    virtual bool accepted() const {
        return true;
    }

    virtual bool empty() const {
        return accepted() && text.size() == 0;
    }

    inline const std::string &getText() const {
        return text;
    }
};

template <class TX = void> // actually not a template
class NodeTextPure: public NodeText<> {
public:
    inline NodeTextPure(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextPure() {}
};

template <class E>
class NodeTextOrError: public NodeText<> {
public:
    inline NodeTextOrError(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextOrError() {}
};

template <class E>
class NodeError: public Node<> {
public:
    inline NodeError(
        const Input &input
    ): Node<>(input) {}

    // virtual ~NodeError() {}

    virtual bool empty() const {
        return false;
    }
};

// could specialize
template <class N>
class NodeBaseList {
public:
    template <size_t I>
    using Type = NodeListIndexed<I>;
};

// could specialize
template <class N>
class NodeBaseText {
public:
    template <class TX = void> // actually not a template
    using Type = NodeTextPure<>;
};

// could specialize
template <class N>
class NodeBaseError {
public:
    template <class E>
    using Type = NodeError<E>;
};

template <class N, class T, size_t I = 0 /* bind later */>
class NodeTyped: public T {
public:
    using T::T;

    virtual void runPass(PassBase<> *pass) const {
        Pass<I>::call(pass, pass->getId(), this);
    }

    virtual const std::string &getRuleName() const {
        return N::getStr();
    }
};

template <class N, size_t I>
using NodeTypedList = NodeTyped<N, typename NodeBaseList<N>::template Type<I>>;

template <class N>
using NodeTypedText = NodeTyped<N, typename NodeBaseText<N>::template Type<>>;

template <class N, class E>
using NodeTypedError = NodeTyped<N, typename NodeBaseError<N>::template Type<E>>;

}

#endif
<commit_msg>add seek()<commit_after>#ifndef MYPARSER_AST_HPP
#define MYPARSER_AST_HPP

#include "myparser_str.hpp"
#include "myparser_pass.hpp"

namespace myparser {

using Input = std::string::const_iterator;

using BuiltinRoot = MP_STR("root", 4);
using BuiltinSpace = MP_STR("space", 5);
using BuiltinKeyword = MP_STR("keyword", 7);
using BuiltinError = MP_STR("error", 5);

template <class TX = void> // actually not a template
class Node {
private:
    inline Node() = delete;

    const Input pos;
    Input tail;

protected:
    inline Node(
        const Input &input
    ): pos(input), tail(input) {}

    inline void seek(const Input &end) {
        tail = end;
    }

public:
    virtual ~Node() {} // destructable (public)

    virtual void free() {
        delete this;
    }

    virtual bool empty() const = 0;

    virtual void runPass(PassBase<> *pass) const = 0;

    virtual const std::string &getRuleName() const = 0;

    inline const std::string getFullText() const {
        return std::string(pos, tail);
    }

    inline const Input &getPos() const {
        return pos;
    }

    inline const Input &getTail() const {
        return tail;
    }

    inline Node<> *challengeLonger(Node<> *target) {
        if (!target) {
            return this;
        }

        if (getTail() > target->getTail()) {
            target->free();
            return this;
        } else {
            this->free();
            return target;
        }
    }
};

template <class TX = void> // actually not a template
class NodeList: public Node<> {
private:
    std::vector<Node<> *> children;

    size_t basepos;
    NodeList<> *brother = nullptr;

protected:
    inline NodeList(
        const Input &input
    ): Node<>(input), children() {}

public:
    virtual ~NodeList() {
        for (size_t i = basepos; i < children.size(); ++i) {
            children[i]->free();
        }
    }

    virtual void free() {
        if (brother) {
            brother->basepos = 0;
            brother->brother = nullptr;
        }
        delete this;
    }

    virtual bool empty() const {
        for (Node<> *child: children) {
            if (!child->empty()) {
                return false;
            }
        }

        return true;
    }

    inline void bind(NodeList<> *target, const size_t pos) {
        brother = target;
        basepos = pos;
    }

    inline void putChild(Node<> *value) {
        children.push_back(value);
        seek(value->getTail());
    }

    inline const std::vector<Node<> *> &getChildren() const {
        return children;
    }
};

template <size_t I>
class NodeListIndexed: public NodeList<> {
public:
    inline NodeListIndexed(
        const Input &input
    ): NodeList<>(input) {}

    // virtual ~NodeListIndexed() {}

    inline size_t getIndex() const {
        return I;
    }
};

// TODO: remove .text and use getFullText() with cache
template <class TX = void> // actually not a template
class NodeText: public Node<> {
private:
    const std::string text;

protected:
    inline NodeText(
        const Input &input, std::string &&value
    ): Node<>(input), text(std::move(value)) {
        seek(getTail() + text.size());
    }

    inline NodeText(
        const Input &input, const std::string &value
    ): Node<>(input), text(value) {
        seek(getTail() + text.size());
    }

public:
    // virtual ~NodeText() {}

    virtual bool accepted() const {
        return true;
    }

    virtual bool empty() const {
        return accepted() && text.size() == 0;
    }

    inline const std::string &getText() const {
        return text;
    }
};

template <class TX = void> // actually not a template
class NodeTextPure: public NodeText<> {
public:
    inline NodeTextPure(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextPure() {}
};

template <class E>
class NodeTextOrError: public NodeText<> {
public:
    inline NodeTextOrError(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextOrError() {}
};

template <class E>
class NodeError: public Node<> {
public:
    inline NodeError(
        const Input &input
    ): Node<>(input) {}

    // virtual ~NodeError() {}

    virtual bool empty() const {
        return false;
    }
};

// could specialize
template <class N>
class NodeBaseList {
public:
    template <size_t I>
    using Type = NodeListIndexed<I>;
};

// could specialize
template <class N>
class NodeBaseText {
public:
    template <class TX = void> // actually not a template
    using Type = NodeTextPure<>;
};

// could specialize
template <class N>
class NodeBaseError {
public:
    template <class E>
    using Type = NodeError<E>;
};

template <class N, class T, size_t I = 0 /* bind later */>
class NodeTyped: public T {
public:
    using T::T;

    virtual void runPass(PassBase<> *pass) const {
        Pass<I>::call(pass, pass->getId(), this);
    }

    virtual const std::string &getRuleName() const {
        return N::getStr();
    }
};

template <class N, size_t I>
using NodeTypedList = NodeTyped<N, typename NodeBaseList<N>::template Type<I>>;

template <class N>
using NodeTypedText = NodeTyped<N, typename NodeBaseText<N>::template Type<>>;

template <class N, class E>
using NodeTypedError = NodeTyped<N, typename NodeBaseError<N>::template Type<E>>;

}

#endif
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// 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.

#include "google/cloud/storage/client.h"
#include "google/cloud/storage/examples/storage_examples_common.h"
#include "google/cloud/internal/getenv.h"
#include <functional>
#include <iostream>
#include <map>
#include <sstream>

namespace {

void ListDefaultObjectAcl(google::cloud::storage::Client client,
                          std::vector<std::string> const& argv) {
  //! [list default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name) {
    StatusOr<std::vector<gcs::ObjectAccessControl>> items =
        client.ListDefaultObjectAcl(bucket_name);

    if (!items) throw std::runtime_error(items.status().message());
    std::cout << "ACLs for bucket=" << bucket_name << "\n";
    for (gcs::ObjectAccessControl const& acl : *items) {
      std::cout << acl.role() << ":" << acl.entity() << "\n";
    }
  }
  //! [list default object acl]
  (std::move(client), argv.at(0));
}

void CreateDefaultObjectAcl(google::cloud::storage::Client client,
                            std::vector<std::string> const& argv) {
  //! [create default object acl] [START storage_add_bucket_default_owner]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> default_object_acl =
        client.CreateDefaultObjectAcl(bucket_name, entity, role);

    if (!default_object_acl) {
      throw std::runtime_error(default_object_acl.status().message());
    }

    std::cout << "Role " << default_object_acl->role()
              << " will be granted default to " << default_object_acl->entity()
              << " on any new object created on bucket "
              << default_object_acl->bucket() << "\n"
              << "Full attributes: " << *default_object_acl << "\n";
  }
  //! [create default object acl] [END storage_add_bucket_default_owner]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void GetDefaultObjectAcl(google::cloud::storage::Client client,
                         std::vector<std::string> const& argv) {
  //! [get default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity) {
    StatusOr<gcs::ObjectAccessControl> acl =
        client.GetDefaultObjectAcl(bucket_name, entity);

    if (!acl) throw std::runtime_error(acl.status().message());
    std::cout << "Default Object ACL entry for " << acl->entity()
              << " in bucket " << acl->bucket() << " is " << *acl << "\n";
  }
  //! [get default object acl]
  (std::move(client), argv.at(0), argv.at(1));
}

void UpdateDefaultObjectAcl(google::cloud::storage::Client client,
                            std::vector<std::string> const& argv) {
  //! [update default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> original_acl =
        client.GetDefaultObjectAcl(bucket_name, entity);

    if (!original_acl) {
      throw std::runtime_error(original_acl.status().message());
    }

    original_acl->set_role(role);

    StatusOr<gcs::ObjectAccessControl> updated_acl =
        client.UpdateDefaultObjectAcl(bucket_name, *original_acl);

    if (!updated_acl) {
      throw std::runtime_error(updated_acl.status().message());
    }

    std::cout << "Default Object ACL entry for " << updated_acl->entity()
              << " in bucket " << updated_acl->bucket() << " is now "
              << *updated_acl << "\n";
  }
  //! [update default object acl]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void PatchDefaultObjectAcl(google::cloud::storage::Client client,
                           std::vector<std::string> const& argv) {
  //! [patch default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> original_acl =
        client.GetDefaultObjectAcl(bucket_name, entity);

    if (!original_acl) {
      throw std::runtime_error(original_acl.status().message());
    }

    auto new_acl = *original_acl;
    new_acl.set_role(role);

    StatusOr<gcs::ObjectAccessControl> patched_acl =
        client.PatchDefaultObjectAcl(bucket_name, entity, *original_acl,
                                     new_acl);

    if (!patched_acl) throw std::runtime_error(patched_acl.status().message());
    std::cout << "Default Object ACL entry for " << patched_acl->entity()
              << " in bucket " << patched_acl->bucket() << " is now "
              << *patched_acl << "\n";
  }
  //! [patch default object acl]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void PatchDefaultObjectAclNoRead(google::cloud::storage::Client client,
                                 std::vector<std::string> const& argv) {
  //! [patch default object acl no-read]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> patched_acl =
        client.PatchDefaultObjectAcl(
            bucket_name, entity,
            gcs::ObjectAccessControlPatchBuilder().set_role(role));

    if (!patched_acl) throw std::runtime_error(patched_acl.status().message());
    std::cout << "Default Object ACL entry for " << patched_acl->entity()
              << " in bucket " << patched_acl->bucket() << " is now "
              << *patched_acl << "\n";
  }
  //! [patch default object acl no-read]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void DeleteDefaultObjectAcl(google::cloud::storage::Client client,
                            std::vector<std::string> const& argv) {
  //! [delete default object acl] [START storage_remove_bucket_default_owner]
  namespace gcs = google::cloud::storage;
  [](gcs::Client client, std::string bucket_name, std::string entity) {
    google::cloud::Status status =
        client.DeleteDefaultObjectAcl(bucket_name, entity);

    if (!status.ok()) throw std::runtime_error(status.message());
    std::cout << "Deleted ACL entry for " << entity << " in bucket "
              << bucket_name << "\n";
  }
  //! [delete default object acl] [END storage_remove_bucket_default_owner]
  (std::move(client), argv.at(0), argv.at(1));
}

void RunAll(std::vector<std::string> const& argv) {
  namespace examples = ::google::cloud::storage::examples;
  namespace gcs = ::google::cloud::storage;

  if (!argv.empty()) throw examples::Usage{"auto"};
  examples::CheckEnvironmentVariablesAreSet({
      "GOOGLE_CLOUD_PROJECT",
  });
  auto const project_id =
      google::cloud::internal::GetEnv("GOOGLE_CLOUD_PROJECT").value();
  auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}());
  auto const bucket_name =
      examples::MakeRandomBucketName(generator, "cloud-cpp-test-examples-");
  auto client = gcs::Client::CreateDefaultClient().value();
  std::cout << "\nCreating bucket to run the example (" << bucket_name << ")"
            << std::endl;
  auto bucket_metadata = client
                             .CreateBucketForProject(bucket_name, project_id,
                                                     gcs::BucketMetadata{})
                             .value();

  auto const reader = gcs::BucketAccessControl::ROLE_READER();
  auto const owner = gcs::BucketAccessControl::ROLE_OWNER();

  std::cout << "\nRunning ListDefaultObjectAcl() example" << std::endl;
  ListDefaultObjectAcl(client, {bucket_name});

  std::cout << "\nRunning CreateDefaultObjectAcl() example" << std::endl;
  CreateDefaultObjectAcl(client,
                         {bucket_name, "allAuthenticatedUsers", reader});

  std::cout << "\nRunning GetDefaultObjectAcl() example" << std::endl;
  GetDefaultObjectAcl(client, {bucket_name, "allAuthenticatedUsers"});

  std::cout << "\nRunning UpdateDefaultObjectAcl() example" << std::endl;
  UpdateDefaultObjectAcl(client, {bucket_name, "allAuthenticatedUsers", owner});

  std::cout << "\nRunning PatchDefaultObjectAcl() example" << std::endl;
  PatchDefaultObjectAcl(client, {bucket_name, "allAuthenticatedUsers", reader});

  std::cout << "\nRunning PatchDefaultObjectAclNoRead() example" << std::endl;
  PatchDefaultObjectAclNoRead(client,
                              {bucket_name, "allAuthenticatedUsers", owner});

  std::cout << "\nRunning DeleteDefaultObjectAcl() example" << std::endl;
  DeleteDefaultObjectAcl(client, {bucket_name, "allAuthenticatedUsers"});

  (void)client.DeleteBucket(bucket_name);
}

}  // anonymous namespace

int main(int argc, char* argv[]) {
  namespace examples = ::google::cloud::storage::examples;
  auto make_entry = [](std::string const& name,
                       std::vector<std::string> arg_names,
                       examples::ClientCommand const& cmd) {
    arg_names.insert(arg_names.begin(), "<bucket-name>");
    return examples::CreateCommandEntry(name, std::move(arg_names), cmd);
  };

  google::cloud::storage::examples::Example example({
      make_entry("list-default-object-acl", {}, ListDefaultObjectAcl),
      make_entry("create-default-object-acl", {"<entity>", "<role>"},
                 CreateDefaultObjectAcl),
      make_entry("get-default-object-acl", {"<entity>"}, GetDefaultObjectAcl),
      make_entry("update-default-object-acl", {"<entity>", "<role>"},
                 UpdateDefaultObjectAcl),
      make_entry("patch-default-object-acl", {"<entity>", "<role>"},
                 PatchDefaultObjectAcl),
      make_entry("patch-default-object-acl-no-read", {"<entity>", "<role>"},
                 PatchDefaultObjectAclNoRead),
      make_entry("delete-default-object-acl", {"<entity>"},
                 DeleteDefaultObjectAcl),
      {"auto", RunAll},
  });
  return example.Run(argc, argv);
}
<commit_msg>cleanup: use the service account instead of "allAuthenticatedUsers" (#3767)<commit_after>// Copyright 2018 Google LLC
//
// 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.

#include "google/cloud/storage/client.h"
#include "google/cloud/storage/examples/storage_examples_common.h"
#include "google/cloud/internal/getenv.h"
#include <functional>
#include <iostream>
#include <map>
#include <sstream>

namespace {

void ListDefaultObjectAcl(google::cloud::storage::Client client,
                          std::vector<std::string> const& argv) {
  //! [list default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name) {
    StatusOr<std::vector<gcs::ObjectAccessControl>> items =
        client.ListDefaultObjectAcl(bucket_name);

    if (!items) throw std::runtime_error(items.status().message());
    std::cout << "ACLs for bucket=" << bucket_name << "\n";
    for (gcs::ObjectAccessControl const& acl : *items) {
      std::cout << acl.role() << ":" << acl.entity() << "\n";
    }
  }
  //! [list default object acl]
  (std::move(client), argv.at(0));
}

void CreateDefaultObjectAcl(google::cloud::storage::Client client,
                            std::vector<std::string> const& argv) {
  //! [create default object acl] [START storage_add_bucket_default_owner]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> default_object_acl =
        client.CreateDefaultObjectAcl(bucket_name, entity, role);

    if (!default_object_acl) {
      throw std::runtime_error(default_object_acl.status().message());
    }

    std::cout << "Role " << default_object_acl->role()
              << " will be granted default to " << default_object_acl->entity()
              << " on any new object created on bucket "
              << default_object_acl->bucket() << "\n"
              << "Full attributes: " << *default_object_acl << "\n";
  }
  //! [create default object acl] [END storage_add_bucket_default_owner]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void GetDefaultObjectAcl(google::cloud::storage::Client client,
                         std::vector<std::string> const& argv) {
  //! [get default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity) {
    StatusOr<gcs::ObjectAccessControl> acl =
        client.GetDefaultObjectAcl(bucket_name, entity);

    if (!acl) throw std::runtime_error(acl.status().message());
    std::cout << "Default Object ACL entry for " << acl->entity()
              << " in bucket " << acl->bucket() << " is " << *acl << "\n";
  }
  //! [get default object acl]
  (std::move(client), argv.at(0), argv.at(1));
}

void UpdateDefaultObjectAcl(google::cloud::storage::Client client,
                            std::vector<std::string> const& argv) {
  //! [update default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> original_acl =
        client.GetDefaultObjectAcl(bucket_name, entity);

    if (!original_acl) {
      throw std::runtime_error(original_acl.status().message());
    }

    original_acl->set_role(role);

    StatusOr<gcs::ObjectAccessControl> updated_acl =
        client.UpdateDefaultObjectAcl(bucket_name, *original_acl);

    if (!updated_acl) {
      throw std::runtime_error(updated_acl.status().message());
    }

    std::cout << "Default Object ACL entry for " << updated_acl->entity()
              << " in bucket " << updated_acl->bucket() << " is now "
              << *updated_acl << "\n";
  }
  //! [update default object acl]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void PatchDefaultObjectAcl(google::cloud::storage::Client client,
                           std::vector<std::string> const& argv) {
  //! [patch default object acl]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> original_acl =
        client.GetDefaultObjectAcl(bucket_name, entity);

    if (!original_acl) {
      throw std::runtime_error(original_acl.status().message());
    }

    auto new_acl = *original_acl;
    new_acl.set_role(role);

    StatusOr<gcs::ObjectAccessControl> patched_acl =
        client.PatchDefaultObjectAcl(bucket_name, entity, *original_acl,
                                     new_acl);

    if (!patched_acl) throw std::runtime_error(patched_acl.status().message());
    std::cout << "Default Object ACL entry for " << patched_acl->entity()
              << " in bucket " << patched_acl->bucket() << " is now "
              << *patched_acl << "\n";
  }
  //! [patch default object acl]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void PatchDefaultObjectAclNoRead(google::cloud::storage::Client client,
                                 std::vector<std::string> const& argv) {
  //! [patch default object acl no-read]
  namespace gcs = google::cloud::storage;
  using ::google::cloud::StatusOr;
  [](gcs::Client client, std::string bucket_name, std::string entity,
     std::string role) {
    StatusOr<gcs::ObjectAccessControl> patched_acl =
        client.PatchDefaultObjectAcl(
            bucket_name, entity,
            gcs::ObjectAccessControlPatchBuilder().set_role(role));

    if (!patched_acl) throw std::runtime_error(patched_acl.status().message());
    std::cout << "Default Object ACL entry for " << patched_acl->entity()
              << " in bucket " << patched_acl->bucket() << " is now "
              << *patched_acl << "\n";
  }
  //! [patch default object acl no-read]
  (std::move(client), argv.at(0), argv.at(1), argv.at(2));
}

void DeleteDefaultObjectAcl(google::cloud::storage::Client client,
                            std::vector<std::string> const& argv) {
  //! [delete default object acl] [START storage_remove_bucket_default_owner]
  namespace gcs = google::cloud::storage;
  [](gcs::Client client, std::string bucket_name, std::string entity) {
    google::cloud::Status status =
        client.DeleteDefaultObjectAcl(bucket_name, entity);

    if (!status.ok()) throw std::runtime_error(status.message());
    std::cout << "Deleted ACL entry for " << entity << " in bucket "
              << bucket_name << "\n";
  }
  //! [delete default object acl] [END storage_remove_bucket_default_owner]
  (std::move(client), argv.at(0), argv.at(1));
}

void RunAll(std::vector<std::string> const& argv) {
  namespace examples = ::google::cloud::storage::examples;
  namespace gcs = ::google::cloud::storage;

  if (!argv.empty()) throw examples::Usage{"auto"};
  examples::CheckEnvironmentVariablesAreSet({
      "GOOGLE_CLOUD_PROJECT",
      "GOOGLE_CLOUD_CPP_STORAGE_TEST_SERVICE_ACCOUNT",
  });
  auto const project_id =
      google::cloud::internal::GetEnv("GOOGLE_CLOUD_PROJECT").value();
  auto const service_account =
      google::cloud::internal::GetEnv(
          "GOOGLE_CLOUD_CPP_STORAGE_TEST_SERVICE_ACCOUNT")
          .value();
  auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}());
  auto const bucket_name =
      examples::MakeRandomBucketName(generator, "cloud-cpp-test-examples-");
  auto const entity = "user-" + service_account;
  auto client = gcs::Client::CreateDefaultClient().value();
  std::cout << "\nCreating bucket to run the example (" << bucket_name << ")"
            << std::endl;
  auto bucket_metadata = client
                             .CreateBucketForProject(bucket_name, project_id,
                                                     gcs::BucketMetadata{})
                             .value();

  auto const reader = gcs::BucketAccessControl::ROLE_READER();
  auto const owner = gcs::BucketAccessControl::ROLE_OWNER();

  std::cout << "\nRunning ListDefaultObjectAcl() example" << std::endl;
  ListDefaultObjectAcl(client, {bucket_name});

  std::cout << "\nRunning CreateDefaultObjectAcl() example" << std::endl;
  CreateDefaultObjectAcl(client, {bucket_name, entity, reader});

  std::cout << "\nRunning GetDefaultObjectAcl() example" << std::endl;
  GetDefaultObjectAcl(client, {bucket_name, entity});

  std::cout << "\nRunning UpdateDefaultObjectAcl() example" << std::endl;
  UpdateDefaultObjectAcl(client, {bucket_name, entity, owner});

  std::cout << "\nRunning PatchDefaultObjectAcl() example" << std::endl;
  PatchDefaultObjectAcl(client, {bucket_name, entity, reader});

  std::cout << "\nRunning PatchDefaultObjectAclNoRead() example" << std::endl;
  PatchDefaultObjectAclNoRead(client, {bucket_name, entity, owner});

  std::cout << "\nRunning DeleteDefaultObjectAcl() example" << std::endl;
  DeleteDefaultObjectAcl(client, {bucket_name, entity});

  (void)client.DeleteBucket(bucket_name);
}

}  // anonymous namespace

int main(int argc, char* argv[]) {
  namespace examples = ::google::cloud::storage::examples;
  auto make_entry = [](std::string const& name,
                       std::vector<std::string> arg_names,
                       examples::ClientCommand const& cmd) {
    arg_names.insert(arg_names.begin(), "<bucket-name>");
    return examples::CreateCommandEntry(name, std::move(arg_names), cmd);
  };

  google::cloud::storage::examples::Example example({
      make_entry("list-default-object-acl", {}, ListDefaultObjectAcl),
      make_entry("create-default-object-acl", {"<entity>", "<role>"},
                 CreateDefaultObjectAcl),
      make_entry("get-default-object-acl", {"<entity>"}, GetDefaultObjectAcl),
      make_entry("update-default-object-acl", {"<entity>", "<role>"},
                 UpdateDefaultObjectAcl),
      make_entry("patch-default-object-acl", {"<entity>", "<role>"},
                 PatchDefaultObjectAcl),
      make_entry("patch-default-object-acl-no-read", {"<entity>", "<role>"},
                 PatchDefaultObjectAclNoRead),
      make_entry("delete-default-object-acl", {"<entity>"},
                 DeleteDefaultObjectAcl),
      {"auto", RunAll},
  });
  return example.Run(argc, argv);
}
<|endoftext|>