<commit_before>package sdl

/*
#include <SDL2/SDL_surface.h>
*/
import "C"
import "unsafe"

const (
	SWSURFACE	= 0
	PREALLOC	= 0x00000001
	RLEACCEL	= 0x00000002
	DONTFREE	= 0x00000004
)

type Surface struct {
	Flags uint32
	Format PixelFormat
	W int
	H int
	Pitch int
	Pixels unsafe.Pointer
	UserData unsafe.Pointer
	Locked int
	LockData unsafe.Pointer
	ClipRect Rect
	_map *[0]byte
	RefCount int
}

type blit C.SDL_blit

func (surface *Surface) MustLock() bool {
	return (surface.Flags & RLEACCEL) != 0
}

func CreateRGBSurface(flags uint32, width, height, depth int32,
		Rmask, Gmask, Bmask, Amask uint32) *Surface {
	_flags := (C.Uint32) (flags)
	_width := (C.int) (width)
	_height := (C.int) (height)
	_depth := (C.int) (depth)
	_Rmask := (C.Uint32) (Rmask)
	_Gmask := (C.Uint32) (Gmask)
	_Bmask := (C.Uint32) (Bmask)
	_Amask := (C.Uint32) (Amask)
	return (*Surface) (unsafe.Pointer(C.SDL_CreateRGBSurface(_flags, _width, _height,
				_depth, _Rmask, _Gmask, _Bmask, _Amask)))
}

func CreateRGBSurfaceFrom(pixels unsafe.Pointer, width, height, depth, pitch int32,
		Rmask, Gmask, Bmask, Amask uint32) *Surface {
	_width := (C.int) (width)
	_height := (C.int) (height)
	_depth := (C.int) (depth)
	_pitch := (C.int) (pitch)
	_Rmask := (C.Uint32) (Rmask)
	_Gmask := (C.Uint32) (Gmask)
	_Bmask := (C.Uint32) (Bmask)
	_Amask := (C.Uint32) (Amask)
	return (*Surface) (unsafe.Pointer(C.SDL_CreateRGBSurfaceFrom(pixels, _width, _height,
				_depth, _pitch, _Rmask, _Gmask, _Bmask, _Amask)))
}

func (surface *Surface) Free() {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	C.SDL_FreeSurface(_surface)
}

func (surface *Surface) SetPalette(palette *Palette) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_palette := (*C.SDL_Palette) (unsafe.Pointer(palette))
	return (int) (C.SDL_SetSurfacePalette(_surface, _palette))
}

func (surface *Surface) Lock() {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	C.SDL_LockSurface(_surface)
}

func (surface *Surface) Unlock() {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	C.SDL_UnlockSurface(_surface)
}

func LoadBMP_RW(src *RWops, freesrc int) *Surface {
	_src := (*C.SDL_RWops) (unsafe.Pointer(src))
	_freesrc := (C.int) (freesrc)
	return (*Surface) (unsafe.Pointer(C.SDL_LoadBMP_RW(_src, _freesrc)))
}

func LoadBMP(file string) *Surface {
	return (*Surface) (LoadBMP_RW(RWFromFile(file, "rb"), 1))
}

func (surface *Surface) SaveBMP_RW(dst *RWops, freedst int) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_dst := (*C.SDL_RWops) (unsafe.Pointer(dst))
	_freedst := (C.int) (freedst)
	return (int) (C.SDL_SaveBMP_RW(_surface, _dst, _freedst))
}

func (surface *Surface) SaveBMP(file string) int {
	return (int) (surface.SaveBMP_RW(RWFromFile(file, "wb"), 1))
}

func (surface *Surface) SetRLE(flag int) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_flag := (C.int) (flag)
	return (int) (C.SDL_SetSurfaceRLE(_surface, _flag))
}

func (surface *Surface) SetColorKey(flag int, key uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_flag := (C.int) (flag)
	_key := (C.Uint32) (key)
	return (int) (C.SDL_SetColorKey(_surface, _flag, _key))
}

func (surface *Surface) GetColorKey(key *uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_key := (*C.Uint32) (unsafe.Pointer(key))
	return (int) (C.SDL_GetColorKey(_surface, _key))
}

func (surface *Surface) SetColorMod(r, g, b uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_r := (C.Uint8) (r)
	_g := (C.Uint8) (g)
	_b := (C.Uint8) (b)
	return (int) (C.SDL_SetSurfaceColorMod(_surface, _r, _g, _b))
}

func (surface *Surface) GetColorMod(r, g, b *uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_r := (*C.Uint8) (unsafe.Pointer(r))
	_g := (*C.Uint8) (unsafe.Pointer(g))
	_b := (*C.Uint8) (unsafe.Pointer(b))
	return (int) (C.SDL_GetSurfaceColorMod(_surface, _r, _g, _b))
}

func (surface *Surface) SetAlphaMod(alpha uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_alpha := (C.Uint8) (alpha)
	return (int) (C.SDL_SetSurfaceAlphaMod(_surface, _alpha))
}

func (surface *Surface) GetAlphaMod(alpha *uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_alpha := (*C.Uint8) (unsafe.Pointer(alpha))
	return (int) (C.SDL_GetSurfaceAlphaMod(_surface, _alpha))
}

func (surface *Surface) SetBlendMode(blendMode BlendMode) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_blendMode := (C.SDL_BlendMode) (blendMode)
	return (int) (C.SDL_SetSurfaceBlendMode(_surface, _blendMode))
}

func (surface *Surface) GetBlendMode(blendMode *BlendMode) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_blendMode := (*C.SDL_BlendMode) (unsafe.Pointer(blendMode))
	return (int) (C.SDL_GetSurfaceBlendMode(_surface, _blendMode))
}

func (surface *Surface) SetClipRect(rect *Rect) bool {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rect := (*C.SDL_Rect) (unsafe.Pointer(rect))
	return C.SDL_SetClipRect(_surface, _rect) > 0
}

func (surface *Surface) GetClipRect(rect *Rect) {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rect := (*C.SDL_Rect) (unsafe.Pointer(rect))
	C.SDL_GetClipRect(_surface, _rect)
}

func (surface *Surface) Convert(fmt *PixelFormat, flags uint32) *Surface {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_fmt := (*C.SDL_PixelFormat) (unsafe.Pointer(fmt))
	_flags := (C.Uint32) (flags)
	return (*Surface) (unsafe.Pointer(C.SDL_ConvertSurface(_surface, _fmt, _flags)))
}

func (surface *Surface) ConvertFormat(pixel_format uint32, flags uint32) *Surface {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_pixel_format := (C.Uint32) (pixel_format)
	_flags := (C.Uint32) (flags)
	return (*Surface) (unsafe.Pointer(C.SDL_ConvertSurfaceFormat(_surface, _pixel_format, _flags)))
}

func ConvertPixels(width, height int, src_format uint32, src unsafe.Pointer, src_pitch int,
		dst_format uint32, dst unsafe.Pointer, dst_pitch int) int {
	_width := (C.int) (width)
	_height := (C.int) (height)
	_src_format := (C.Uint32) (src_format)
	_src_pitch := (C.int) (src_pitch)
	_dst_format := (C.Uint32) (dst_format)
	_dst_pitch := (C.int) (dst_pitch)
	return (int) (C.SDL_ConvertPixels(_width, _height, _src_format, src, _src_pitch, _dst_format, dst, _dst_pitch))
}

func (surface *Surface) FillRect(rect *Rect, color uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rect := (*C.SDL_Rect) (unsafe.Pointer(rect))
	_color := (C.Uint32) (color)
	return (int) (C.SDL_FillRect(_surface, _rect, _color))
}

func (surface *Surface) FillRects(rects *Rect, count int, color uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rects := (*C.SDL_Rect) (unsafe.Pointer(rects))
	_count := (C.int) (count)
	_color := (C.Uint32) (color)
	return (int) (C.SDL_FillRects(_surface, _rects, _count, _color))
}

func (src *Surface) Blit(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_BlitSurface(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) BlitScaled(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_BlitScaled(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) UpperBlit(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_UpperBlit(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) LowerBlit(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_LowerBlit(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) SoftStretch(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_SoftStretch(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) UpperBlitScaled(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_UpperBlitScaled(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) LowerBlitScaled(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_LowerBlitScaled(_src, _srcrect, _dst, _dstrect))
}
<commit_msg>Fixed: wrong member type in sdl.Surface<commit_after>package sdl

/*
#include <SDL2/SDL_surface.h>
*/
import "C"
import "unsafe"

const (
	SWSURFACE	= 0
	PREALLOC	= 0x00000001
	RLEACCEL	= 0x00000002
	DONTFREE	= 0x00000004
)

type Surface struct {
	Flags uint32
	Format unsafe.Pointer
	W int
	H int
	Pitch int
	Pixels unsafe.Pointer
	UserData unsafe.Pointer
	Locked int
	LockData unsafe.Pointer
	ClipRect Rect
	_map *[0]byte
	RefCount int
}

type blit C.SDL_blit

func (surface *Surface) MustLock() bool {
	return (surface.Flags & RLEACCEL) != 0
}

func CreateRGBSurface(flags uint32, width, height, depth int32,
		Rmask, Gmask, Bmask, Amask uint32) *Surface {
	_flags := (C.Uint32) (flags)
	_width := (C.int) (width)
	_height := (C.int) (height)
	_depth := (C.int) (depth)
	_Rmask := (C.Uint32) (Rmask)
	_Gmask := (C.Uint32) (Gmask)
	_Bmask := (C.Uint32) (Bmask)
	_Amask := (C.Uint32) (Amask)
	return (*Surface) (unsafe.Pointer(C.SDL_CreateRGBSurface(_flags, _width, _height,
				_depth, _Rmask, _Gmask, _Bmask, _Amask)))
}

func CreateRGBSurfaceFrom(pixels unsafe.Pointer, width, height, depth, pitch int32,
		Rmask, Gmask, Bmask, Amask uint32) *Surface {
	_width := (C.int) (width)
	_height := (C.int) (height)
	_depth := (C.int) (depth)
	_pitch := (C.int) (pitch)
	_Rmask := (C.Uint32) (Rmask)
	_Gmask := (C.Uint32) (Gmask)
	_Bmask := (C.Uint32) (Bmask)
	_Amask := (C.Uint32) (Amask)
	return (*Surface) (unsafe.Pointer(C.SDL_CreateRGBSurfaceFrom(pixels, _width, _height,
				_depth, _pitch, _Rmask, _Gmask, _Bmask, _Amask)))
}

func (surface *Surface) Free() {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	C.SDL_FreeSurface(_surface)
}

func (surface *Surface) SetPalette(palette *Palette) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_palette := (*C.SDL_Palette) (unsafe.Pointer(palette))
	return (int) (C.SDL_SetSurfacePalette(_surface, _palette))
}

func (surface *Surface) Lock() {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	C.SDL_LockSurface(_surface)
}

func (surface *Surface) Unlock() {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	C.SDL_UnlockSurface(_surface)
}

func LoadBMP_RW(src *RWops, freesrc int) *Surface {
	_src := (*C.SDL_RWops) (unsafe.Pointer(src))
	_freesrc := (C.int) (freesrc)
	return (*Surface) (unsafe.Pointer(C.SDL_LoadBMP_RW(_src, _freesrc)))
}

func LoadBMP(file string) *Surface {
	return (*Surface) (LoadBMP_RW(RWFromFile(file, "rb"), 1))
}

func (surface *Surface) SaveBMP_RW(dst *RWops, freedst int) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_dst := (*C.SDL_RWops) (unsafe.Pointer(dst))
	_freedst := (C.int) (freedst)
	return (int) (C.SDL_SaveBMP_RW(_surface, _dst, _freedst))
}

func (surface *Surface) SaveBMP(file string) int {
	return (int) (surface.SaveBMP_RW(RWFromFile(file, "wb"), 1))
}

func (surface *Surface) SetRLE(flag int) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_flag := (C.int) (flag)
	return (int) (C.SDL_SetSurfaceRLE(_surface, _flag))
}

func (surface *Surface) SetColorKey(flag int, key uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_flag := (C.int) (flag)
	_key := (C.Uint32) (key)
	return (int) (C.SDL_SetColorKey(_surface, _flag, _key))
}

func (surface *Surface) GetColorKey(key *uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_key := (*C.Uint32) (unsafe.Pointer(key))
	return (int) (C.SDL_GetColorKey(_surface, _key))
}

func (surface *Surface) SetColorMod(r, g, b uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_r := (C.Uint8) (r)
	_g := (C.Uint8) (g)
	_b := (C.Uint8) (b)
	return (int) (C.SDL_SetSurfaceColorMod(_surface, _r, _g, _b))
}

func (surface *Surface) GetColorMod(r, g, b *uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_r := (*C.Uint8) (unsafe.Pointer(r))
	_g := (*C.Uint8) (unsafe.Pointer(g))
	_b := (*C.Uint8) (unsafe.Pointer(b))
	return (int) (C.SDL_GetSurfaceColorMod(_surface, _r, _g, _b))
}

func (surface *Surface) SetAlphaMod(alpha uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_alpha := (C.Uint8) (alpha)
	return (int) (C.SDL_SetSurfaceAlphaMod(_surface, _alpha))
}

func (surface *Surface) GetAlphaMod(alpha *uint8) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_alpha := (*C.Uint8) (unsafe.Pointer(alpha))
	return (int) (C.SDL_GetSurfaceAlphaMod(_surface, _alpha))
}

func (surface *Surface) SetBlendMode(blendMode BlendMode) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_blendMode := (C.SDL_BlendMode) (blendMode)
	return (int) (C.SDL_SetSurfaceBlendMode(_surface, _blendMode))
}

func (surface *Surface) GetBlendMode(blendMode *BlendMode) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_blendMode := (*C.SDL_BlendMode) (unsafe.Pointer(blendMode))
	return (int) (C.SDL_GetSurfaceBlendMode(_surface, _blendMode))
}

func (surface *Surface) SetClipRect(rect *Rect) bool {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rect := (*C.SDL_Rect) (unsafe.Pointer(rect))
	return C.SDL_SetClipRect(_surface, _rect) > 0
}

func (surface *Surface) GetClipRect(rect *Rect) {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rect := (*C.SDL_Rect) (unsafe.Pointer(rect))
	C.SDL_GetClipRect(_surface, _rect)
}

func (surface *Surface) Convert(fmt *PixelFormat, flags uint32) *Surface {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_fmt := (*C.SDL_PixelFormat) (unsafe.Pointer(fmt))
	_flags := (C.Uint32) (flags)
	return (*Surface) (unsafe.Pointer(C.SDL_ConvertSurface(_surface, _fmt, _flags)))
}

func (surface *Surface) ConvertFormat(pixel_format uint32, flags uint32) *Surface {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_pixel_format := (C.Uint32) (pixel_format)
	_flags := (C.Uint32) (flags)
	return (*Surface) (unsafe.Pointer(C.SDL_ConvertSurfaceFormat(_surface, _pixel_format, _flags)))
}

func ConvertPixels(width, height int, src_format uint32, src unsafe.Pointer, src_pitch int,
		dst_format uint32, dst unsafe.Pointer, dst_pitch int) int {
	_width := (C.int) (width)
	_height := (C.int) (height)
	_src_format := (C.Uint32) (src_format)
	_src_pitch := (C.int) (src_pitch)
	_dst_format := (C.Uint32) (dst_format)
	_dst_pitch := (C.int) (dst_pitch)
	return (int) (C.SDL_ConvertPixels(_width, _height, _src_format, src, _src_pitch, _dst_format, dst, _dst_pitch))
}

func (surface *Surface) FillRect(rect *Rect, color uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rect := (*C.SDL_Rect) (unsafe.Pointer(rect))
	_color := (C.Uint32) (color)
	return (int) (C.SDL_FillRect(_surface, _rect, _color))
}

func (surface *Surface) FillRects(rects *Rect, count int, color uint32) int {
	_surface := (*C.SDL_Surface) (unsafe.Pointer(surface))
	_rects := (*C.SDL_Rect) (unsafe.Pointer(rects))
	_count := (C.int) (count)
	_color := (C.Uint32) (color)
	return (int) (C.SDL_FillRects(_surface, _rects, _count, _color))
}

func (src *Surface) Blit(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_BlitSurface(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) BlitScaled(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_BlitScaled(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) UpperBlit(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_UpperBlit(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) LowerBlit(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_LowerBlit(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) SoftStretch(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_SoftStretch(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) UpperBlitScaled(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_UpperBlitScaled(_src, _srcrect, _dst, _dstrect))
}

func (src *Surface) LowerBlitScaled(srcrect *Rect, dst *Surface, dstrect *Rect) int {
	_src := (*C.SDL_Surface) (unsafe.Pointer(src))
	_srcrect := (*C.SDL_Rect) (unsafe.Pointer(srcrect))
	_dst := (*C.SDL_Surface) (unsafe.Pointer(dst))
	_dstrect := (*C.SDL_Rect) (unsafe.Pointer(dstrect))
	return (int) (C.SDL_LowerBlitScaled(_src, _srcrect, _dst, _dstrect))
}
<|endoftext|>


<commit_before>package containeranalysis

import (
	"context"
	"errors"
	"strings"

	containeranalysisapi "cloud.google.com/go/containeranalysis/apiv1"
	grafeasv1 "cloud.google.com/go/grafeas/apiv1"

	"github.com/docker/distribution/reference"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	grafeas "google.golang.org/genproto/googleapis/grafeas/v1"

	voucher "github.com/grafeas/voucher/v2"
	"github.com/grafeas/voucher/v2/attestation"
	"github.com/grafeas/voucher/v2/docker/uri"
	"github.com/grafeas/voucher/v2/repository"
	"github.com/grafeas/voucher/v2/signer"
)

var errCannotAttest = errors.New("cannot create attestations, keyring is empty")

// Client implements voucher.MetadataClient, connecting to containeranalysis Grafeas.
type Client struct {
	containeranalysis  *grafeasv1.Client        // The client reference.
	keyring            signer.AttestationSigner // The keyring used for signing metadata.
	binauthProject     string                   // The project that Binauth Notes and Occurrences are written to.
	buildDetailProject string                   // [optional] the fallback project where Build Notes are written to.
}

// CanAttest returns true if the client can create and sign attestations.
func (g *Client) CanAttest() bool {
	return nil != g.keyring
}

// NewPayloadBody returns a payload body appropriate for this MetadataClient.
func (g *Client) NewPayloadBody(ref reference.Canonical) (string, error) {
	payload, err := attestation.NewPayload(ref).ToString()
	if err != nil {
		return "", err
	}

	return payload, err
}

// AddAttestationToImage adds a new attestation with the passed Attestation
// to the image described by ImageData.
func (g *Client) AddAttestationToImage(ctx context.Context, ref reference.Canonical, attestation voucher.Attestation) (voucher.SignedAttestation, error) {
	if !g.CanAttest() {
		return voucher.SignedAttestation{}, errCannotAttest
	}

	signedAttestation, err := voucher.SignAttestation(g.keyring, attestation)
	if nil != err {
		return voucher.SignedAttestation{}, err
	}

	_, err = g.containeranalysis.CreateOccurrence(
		ctx,
		newOccurrenceAttestation(
			ref,
			signedAttestation,
			g.binauthProject,
		),
	)

	if isAttestionExistsErr(err) {
		err = nil

		signedAttestation.Signature = ""
	}

	return signedAttestation, err
}

// GetAttestations returns all of the attestations associated with an image.
func (g *Client) GetAttestations(ctx context.Context, ref reference.Canonical) ([]voucher.SignedAttestation, error) {
	filterStr := kindFilterStr(ref, grafeas.NoteKind_ATTESTATION)

	var attestations []voucher.SignedAttestation

	project := projectPath(g.binauthProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		occ, err := occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				return attestations, nil
			}
			return nil, err
		}

		note, err := g.containeranalysis.GetOccurrenceNote(
			ctx,
			&grafeas.GetOccurrenceNoteRequest{
				Name: occ.GetName(),
			},
		)
		if nil != err {
			return nil, err
		}

		name := getCheckNameFromNoteName(g.binauthProject, note.GetName())

		attestations = append(
			attestations,
			OccurrenceToAttestation(name, occ),
		)
	}
}

// GetVulnerabilities returns the detected vulnerabilities for the Image described by voucher.ImageData.
func (g *Client) GetVulnerabilities(ctx context.Context, ref reference.Canonical) (vulnerabilities []voucher.Vulnerability, err error) {
	filterStr := kindFilterStr(ref, grafeas.NoteKind_VULNERABILITY)

	err = pollForDiscoveries(ctx, g, ref)
	if nil != err {
		return []voucher.Vulnerability{}, err
	}

	project, err := uri.ReferenceToProjectName(ref)
	if nil != err {
		return []voucher.Vulnerability{}, err
	}

	req := &grafeas.ListOccurrencesRequest{Parent: projectPath(project), Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		var occ *grafeas.Occurrence

		occ, err = occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				err = nil
			}

			break
		}

		vuln := OccurrenceToVulnerability(occ)
		vulnerabilities = append(vulnerabilities, vuln)
	}

	return
}

// Close closes the containeranalysis Grafeas client.
func (g *Client) Close() {
	if nil != g.keyring {
		_ = g.keyring.Close()
	}
	g.containeranalysis.Close()
}

// GetBuildDetail gets the BuildDetail for the passed image.
func (g *Client) GetBuildDetail(ctx context.Context, ref reference.Canonical) (repository.BuildDetail, error) {
	var err error

	filterStr := kindFilterStr(ref, grafeas.NoteKind_BUILD)

	project, err := uri.ReferenceToProjectName(ref)
	if nil != err {
		return repository.BuildDetail{}, err
	}

	parent := projectPath(project)

	// Scan thru image project for build details and fallback to buildDetailProject if buildDetailProject is set.
	// and the build details are not found in the image project.
	// Cases:
	// 1. No build notes found for image + fallback (image does not have build metadata)
	// 2. No build notes found for image project, but build notes found for fallback project (image has a central local for storing build metadata)
	// 3. Build notes found for image project (image has build metadata)
	// 4. Image has multiple build notes (image has build metadata)
	projectToScan := []string{parent}
	if g.buildDetailProject != "" {
		projectToScan = append(projectToScan, projectPath(g.buildDetailProject))
	}

	buildDetail := repository.BuildDetail{}
	for _, p := range projectToScan {
		req := &grafeas.ListOccurrencesRequest{Parent: p, Filter: filterStr}
		occIterator := g.containeranalysis.ListOccurrences(ctx, req)

		occ, err := occIterator.Next()

		// If no build notes found, continue to fallback project.
		if !strings.HasSuffix(p, g.buildDetailProject) && err != nil {
			continue
		}

		if err != nil {
			if err == iterator.Done {
				return repository.BuildDetail{}, &voucher.NoMetadataError{
					Type: voucher.BuildDetailsType,
					Err:  errNoOccurrences,
				}
			}
			return repository.BuildDetail{}, err
		}

		// Muliple build notes found - invalid
		if _, err := occIterator.Next(); err != iterator.Done {
			return repository.BuildDetail{}, errors.New("Found multiple Grafeas occurrences for " + ref.String())
		}

		buildDetail = OccurrenceToBuildDetail(occ)
	}
	return buildDetail, nil
}

// NewClient creates a new containeranalysis Grafeas Client.
func NewClient(ctx context.Context, binauthProject string, buildDetailproject string, keyring signer.AttestationSigner) (*Client, error) {
	// These options emulate cloud.google.com/go/containeranalysis/apiv1.NewClient
	grafeasClient, err := grafeasv1.NewClient(ctx, option.WithEndpoint("containeranalysis.googleapis.com:443"), option.WithScopes(containeranalysisapi.DefaultAuthScopes()...))
	if err != nil {
		return nil, err
	}
	client := &Client{
		containeranalysis:  grafeasClient,
		keyring:            keyring,
		binauthProject:     binauthProject,
		buildDetailProject: buildDetailproject,
	}

	return client, nil
}
<commit_msg>spelling...<commit_after>package containeranalysis

import (
	"context"
	"errors"
	"strings"

	containeranalysisapi "cloud.google.com/go/containeranalysis/apiv1"
	grafeasv1 "cloud.google.com/go/grafeas/apiv1"

	"github.com/docker/distribution/reference"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	grafeas "google.golang.org/genproto/googleapis/grafeas/v1"

	voucher "github.com/grafeas/voucher/v2"
	"github.com/grafeas/voucher/v2/attestation"
	"github.com/grafeas/voucher/v2/docker/uri"
	"github.com/grafeas/voucher/v2/repository"
	"github.com/grafeas/voucher/v2/signer"
)

var errCannotAttest = errors.New("cannot create attestations, keyring is empty")

// Client implements voucher.MetadataClient, connecting to containeranalysis Grafeas.
type Client struct {
	containeranalysis  *grafeasv1.Client        // The client reference.
	keyring            signer.AttestationSigner // The keyring used for signing metadata.
	binauthProject     string                   // The project that Binauth Notes and Occurrences are written to.
	buildDetailProject string                   // [optional] the fallback project where Build Notes are written to.
}

// CanAttest returns true if the client can create and sign attestations.
func (g *Client) CanAttest() bool {
	return nil != g.keyring
}

// NewPayloadBody returns a payload body appropriate for this MetadataClient.
func (g *Client) NewPayloadBody(ref reference.Canonical) (string, error) {
	payload, err := attestation.NewPayload(ref).ToString()
	if err != nil {
		return "", err
	}

	return payload, err
}

// AddAttestationToImage adds a new attestation with the passed Attestation
// to the image described by ImageData.
func (g *Client) AddAttestationToImage(ctx context.Context, ref reference.Canonical, attestation voucher.Attestation) (voucher.SignedAttestation, error) {
	if !g.CanAttest() {
		return voucher.SignedAttestation{}, errCannotAttest
	}

	signedAttestation, err := voucher.SignAttestation(g.keyring, attestation)
	if nil != err {
		return voucher.SignedAttestation{}, err
	}

	_, err = g.containeranalysis.CreateOccurrence(
		ctx,
		newOccurrenceAttestation(
			ref,
			signedAttestation,
			g.binauthProject,
		),
	)

	if isAttestionExistsErr(err) {
		err = nil

		signedAttestation.Signature = ""
	}

	return signedAttestation, err
}

// GetAttestations returns all of the attestations associated with an image.
func (g *Client) GetAttestations(ctx context.Context, ref reference.Canonical) ([]voucher.SignedAttestation, error) {
	filterStr := kindFilterStr(ref, grafeas.NoteKind_ATTESTATION)

	var attestations []voucher.SignedAttestation

	project := projectPath(g.binauthProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		occ, err := occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				return attestations, nil
			}
			return nil, err
		}

		note, err := g.containeranalysis.GetOccurrenceNote(
			ctx,
			&grafeas.GetOccurrenceNoteRequest{
				Name: occ.GetName(),
			},
		)
		if nil != err {
			return nil, err
		}

		name := getCheckNameFromNoteName(g.binauthProject, note.GetName())

		attestations = append(
			attestations,
			OccurrenceToAttestation(name, occ),
		)
	}
}

// GetVulnerabilities returns the detected vulnerabilities for the Image described by voucher.ImageData.
func (g *Client) GetVulnerabilities(ctx context.Context, ref reference.Canonical) (vulnerabilities []voucher.Vulnerability, err error) {
	filterStr := kindFilterStr(ref, grafeas.NoteKind_VULNERABILITY)

	err = pollForDiscoveries(ctx, g, ref)
	if nil != err {
		return []voucher.Vulnerability{}, err
	}

	project, err := uri.ReferenceToProjectName(ref)
	if nil != err {
		return []voucher.Vulnerability{}, err
	}

	req := &grafeas.ListOccurrencesRequest{Parent: projectPath(project), Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		var occ *grafeas.Occurrence

		occ, err = occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				err = nil
			}

			break
		}

		vuln := OccurrenceToVulnerability(occ)
		vulnerabilities = append(vulnerabilities, vuln)
	}

	return
}

// Close closes the containeranalysis Grafeas client.
func (g *Client) Close() {
	if nil != g.keyring {
		_ = g.keyring.Close()
	}
	g.containeranalysis.Close()
}

// GetBuildDetail gets the BuildDetail for the passed image.
func (g *Client) GetBuildDetail(ctx context.Context, ref reference.Canonical) (repository.BuildDetail, error) {
	var err error

	filterStr := kindFilterStr(ref, grafeas.NoteKind_BUILD)

	project, err := uri.ReferenceToProjectName(ref)
	if nil != err {
		return repository.BuildDetail{}, err
	}

	parent := projectPath(project)

	// Scan thru image project for build details and fallback to buildDetailProject if buildDetailProject is set.
	// and the build details are not found in the image project.
	// Cases:
	// 1. No build notes found for image + fallback (image does not have build metadata)
	// 2. No build notes found for image project, but build notes found for fallback project (image has a central local for storing build metadata)
	// 3. Build notes found for image project (image has build metadata)
	// 4. Image has multiple build notes (image has build metadata)
	projectToScan := []string{parent}
	if g.buildDetailProject != "" {
		projectToScan = append(projectToScan, projectPath(g.buildDetailProject))
	}

	buildDetail := repository.BuildDetail{}
	for _, p := range projectToScan {
		req := &grafeas.ListOccurrencesRequest{Parent: p, Filter: filterStr}
		occIterator := g.containeranalysis.ListOccurrences(ctx, req)

		occ, err := occIterator.Next()

		// If no build notes found, continue to fallback project.
		if !strings.HasSuffix(p, g.buildDetailProject) && err != nil {
			continue
		}

		if err != nil {
			if err == iterator.Done {
				return repository.BuildDetail{}, &voucher.NoMetadataError{
					Type: voucher.BuildDetailsType,
					Err:  errNoOccurrences,
				}
			}
			return repository.BuildDetail{}, err
		}

		// Multiple build notes found - invalid
		if _, err := occIterator.Next(); err != iterator.Done {
			return repository.BuildDetail{}, errors.New("Found multiple Grafeas occurrences for " + ref.String())
		}

		buildDetail = OccurrenceToBuildDetail(occ)
	}
	return buildDetail, nil
}

// NewClient creates a new containeranalysis Grafeas Client.
func NewClient(ctx context.Context, binauthProject string, buildDetailproject string, keyring signer.AttestationSigner) (*Client, error) {
	// These options emulate cloud.google.com/go/containeranalysis/apiv1.NewClient
	grafeasClient, err := grafeasv1.NewClient(ctx, option.WithEndpoint("containeranalysis.googleapis.com:443"), option.WithScopes(containeranalysisapi.DefaultAuthScopes()...))
	if err != nil {
		return nil, err
	}
	client := &Client{
		containeranalysis:  grafeasClient,
		keyring:            keyring,
		binauthProject:     binauthProject,
		buildDetailProject: buildDetailproject,
	}

	return client, nil
}
<|endoftext|>


<commit_before>package jsonpatch

import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"testing"
)

func reformatJSON(j string) string {
	buf := new(bytes.Buffer)

	json.Indent(buf, []byte(j), "", "  ")

	return buf.String()
}

func compareJSON(a, b string) bool {
	// return Equal([]byte(a), []byte(b))

	var obj_a, obj_b map[string]interface{}
	json.Unmarshal([]byte(a), &obj_a)
	json.Unmarshal([]byte(b), &obj_b)

	// fmt.Printf("Comparing %#v\nagainst %#v\n", obj_a, obj_b)
	return reflect.DeepEqual(obj_a, obj_b)
}

func applyPatch(doc, patch string) (string, error) {
	obj, err := DecodePatch([]byte(patch))

	if err != nil {
		panic(err)
	}

	out, err := obj.Apply([]byte(doc))

	if err != nil {
		return "", err
	}

	return string(out), nil
}

type Case struct {
	doc, patch, result string
}

var Cases = []Case{
	{
		`{ "foo": "bar"}`,
		`[
         { "op": "add", "path": "/baz", "value": "qux" }
     ]`,
		`{
       "baz": "qux",
       "foo": "bar"
     }`,
	},
	{
		`{ "foo": [ "bar", "baz" ] }`,
		`[
     { "op": "add", "path": "/foo/1", "value": "qux" }
    ]`,
		`{ "foo": [ "bar", "qux", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "remove", "path": "/baz" } ]`,
		`{ "foo": "bar" }`,
	},
	{
		`{ "foo": [ "bar", "qux", "baz" ] }`,
		`[ { "op": "remove", "path": "/foo/1" } ]`,
		`{ "foo": [ "bar", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "replace", "path": "/baz", "value": "boo" } ]`,
		`{ "baz": "boo", "foo": "bar" }`,
	},
	{
		`{
     "foo": {
       "bar": "baz",
       "waldo": "fred"
     },
     "qux": {
       "corge": "grault"
     }
   }`,
		`[ { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" } ]`,
		`{
     "foo": {
       "bar": "baz"
     },
     "qux": {
       "corge": "grault",
       "thud": "fred"
     }
   }`,
	},
	{
		`{ "foo": [ "all", "grass", "cows", "eat" ] }`,
		`[ { "op": "move", "from": "/foo/1", "path": "/foo/3" } ]`,
		`{ "foo": [ "all", "cows", "eat", "grass" ] }`,
	},
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/child", "value": { "grandchild": { } } } ]`,
		`{ "foo": "bar", "child": { "grandchild": { } } }`,
	},
	{
		`{ "foo": ["bar"] }`,
		`[ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] } ]`,
		`{ "foo": ["bar", ["abc", "def"]] }`,
	},
	{
		`{ "foo": "bar", "qux": { "baz": 1, "bar": null } }`,
		`[ { "op": "remove", "path": "/qux/bar" } ]`,
		`{ "foo": "bar", "qux": { "baz": 1 } }`,
	},
}

type BadCase struct {
	doc, patch string
}

var MutationTestCases = []BadCase{
	{
		`{ "foo": "bar", "qux": { "baz": 1, "bar": null } }`,
		`[ { "op": "remove", "path": "/qux/bar" } ]`,
	},
	{
		`{ "foo": "bar", "qux": { "baz": 1, "bar": null } }`,
		`[ { "op": "replace", "path": "/qux/baz", "value": null } ]`,
	},
}

var BadCases = []BadCase{
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/baz/bat", "value": "qux" } ]`,
	},
}

func TestAllCases(t *testing.T) {
	for _, c := range Cases {
		out, err := applyPatch(c.doc, c.patch)

		if err != nil {
			t.Errorf("Unable to apply patch: %s", err)
		}

		if !compareJSON(out, c.result) {
			t.Errorf("Patch did not apply. Expected:\n%s\n\nActual:\n%s",
				reformatJSON(c.result), reformatJSON(out))
		}
	}

	for _, c := range MutationTestCases {
		out, err := applyPatch(c.doc, c.patch)

		if err != nil {
			t.Errorf("Unable to apply patch: %s", err)
		}

		if compareJSON(out, c.doc) {
			t.Errorf("Patch did not apply. Original:\n%s\n\nPatched:\n%s",
				reformatJSON(c.doc), reformatJSON(out))
		}
	}

	for _, c := range BadCases {
		_, err := applyPatch(c.doc, c.patch)

		if err == nil {
			t.Errorf("Patch should have failed to apply but it did not")
		}
	}
}

type TestCase struct {
	doc, patch string
	result     bool
	failedPath string
}

var TestCases = []TestCase{
	{
		`{
			"baz": "qux",
			"foo": [ "a", 2, "c" ]
		}`,
		`[
			{ "op": "test", "path": "/baz", "value": "qux" },
			{ "op": "test", "path": "/foo/1", "value": 2 }
		]`,
		true,
		"",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/baz", "value": "bar" } ]`,
		false,
		"/baz",
	},
	{
		`{
			"baz": "qux",
			"foo": ["a", 2, "c"]
		}`,
		`[
			{ "op": "test", "path": "/baz", "value": "qux" },
			{ "op": "test", "path": "/foo/1", "value": "c" }
		]`,
		false,
		"/foo/1",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/foo", "value": 42 } ]`,
		false,
		"/foo",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/foo", "value": null } ]`,
		true,
		"",
	},
}

func TestAllTest(t *testing.T) {
	for _, c := range TestCases {
		_, err := applyPatch(c.doc, c.patch)

		if c.result && err != nil {
			t.Errorf("Testing failed when it should have passed: %s", err)
		} else if !c.result && err == nil {
			t.Errorf("Testing passed when it should have faild: %s", err)
		} else if !c.result {
			expected := fmt.Sprintf("Testing value %s failed", c.failedPath)
			if err.Error() != expected {
				t.Errorf("Testing failed as expected but invalid message: expected [%s], got [%s]", expected, err)
			}
		}
	}
}
<commit_msg>Add test case for adding a null value using patch<commit_after>package jsonpatch

import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"testing"
)

func reformatJSON(j string) string {
	buf := new(bytes.Buffer)

	json.Indent(buf, []byte(j), "", "  ")

	return buf.String()
}

func compareJSON(a, b string) bool {
	// return Equal([]byte(a), []byte(b))

	var obj_a, obj_b map[string]interface{}
	json.Unmarshal([]byte(a), &obj_a)
	json.Unmarshal([]byte(b), &obj_b)

	// fmt.Printf("Comparing %#v\nagainst %#v\n", obj_a, obj_b)
	return reflect.DeepEqual(obj_a, obj_b)
}

func applyPatch(doc, patch string) (string, error) {
	obj, err := DecodePatch([]byte(patch))

	if err != nil {
		panic(err)
	}

	out, err := obj.Apply([]byte(doc))

	if err != nil {
		return "", err
	}

	return string(out), nil
}

type Case struct {
	doc, patch, result string
}

var Cases = []Case{
	{
		`{ "foo": "bar"}`,
		`[
         { "op": "add", "path": "/baz", "value": "qux" }
     ]`,
		`{
       "baz": "qux",
       "foo": "bar"
     }`,
	},
	{
		`{ "foo": [ "bar", "baz" ] }`,
		`[
     { "op": "add", "path": "/foo/1", "value": "qux" }
    ]`,
		`{ "foo": [ "bar", "qux", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "remove", "path": "/baz" } ]`,
		`{ "foo": "bar" }`,
	},
	{
		`{ "foo": [ "bar", "qux", "baz" ] }`,
		`[ { "op": "remove", "path": "/foo/1" } ]`,
		`{ "foo": [ "bar", "baz" ] }`,
	},
	{
		`{ "baz": "qux", "foo": "bar" }`,
		`[ { "op": "replace", "path": "/baz", "value": "boo" } ]`,
		`{ "baz": "boo", "foo": "bar" }`,
	},
	{
		`{
     "foo": {
       "bar": "baz",
       "waldo": "fred"
     },
     "qux": {
       "corge": "grault"
     }
   }`,
		`[ { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" } ]`,
		`{
     "foo": {
       "bar": "baz"
     },
     "qux": {
       "corge": "grault",
       "thud": "fred"
     }
   }`,
	},
	{
		`{ "foo": [ "all", "grass", "cows", "eat" ] }`,
		`[ { "op": "move", "from": "/foo/1", "path": "/foo/3" } ]`,
		`{ "foo": [ "all", "cows", "eat", "grass" ] }`,
	},
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/child", "value": { "grandchild": { } } } ]`,
		`{ "foo": "bar", "child": { "grandchild": { } } }`,
	},
	{
		`{ "foo": ["bar"] }`,
		`[ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] } ]`,
		`{ "foo": ["bar", ["abc", "def"]] }`,
	},
	{
		`{ "foo": "bar", "qux": { "baz": 1, "bar": null } }`,
		`[ { "op": "remove", "path": "/qux/bar" } ]`,
		`{ "foo": "bar", "qux": { "baz": 1 } }`,
	},
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/baz", "value": null } ]`,
		`{ "baz": null, "foo": "bar" }`,
	},
}

type BadCase struct {
	doc, patch string
}

var MutationTestCases = []BadCase{
	{
		`{ "foo": "bar", "qux": { "baz": 1, "bar": null } }`,
		`[ { "op": "remove", "path": "/qux/bar" } ]`,
	},
	{
		`{ "foo": "bar", "qux": { "baz": 1, "bar": null } }`,
		`[ { "op": "replace", "path": "/qux/baz", "value": null } ]`,
	},
}

var BadCases = []BadCase{
	{
		`{ "foo": "bar" }`,
		`[ { "op": "add", "path": "/baz/bat", "value": "qux" } ]`,
	},
}

func TestAllCases(t *testing.T) {
	for _, c := range Cases {
		out, err := applyPatch(c.doc, c.patch)

		if err != nil {
			t.Errorf("Unable to apply patch: %s", err)
		}

		if !compareJSON(out, c.result) {
			t.Errorf("Patch did not apply. Expected:\n%s\n\nActual:\n%s",
				reformatJSON(c.result), reformatJSON(out))
		}
	}

	for _, c := range MutationTestCases {
		out, err := applyPatch(c.doc, c.patch)

		if err != nil {
			t.Errorf("Unable to apply patch: %s", err)
		}

		if compareJSON(out, c.doc) {
			t.Errorf("Patch did not apply. Original:\n%s\n\nPatched:\n%s",
				reformatJSON(c.doc), reformatJSON(out))
		}
	}

	for _, c := range BadCases {
		_, err := applyPatch(c.doc, c.patch)

		if err == nil {
			t.Errorf("Patch should have failed to apply but it did not")
		}
	}
}

type TestCase struct {
	doc, patch string
	result     bool
	failedPath string
}

var TestCases = []TestCase{
	{
		`{
			"baz": "qux",
			"foo": [ "a", 2, "c" ]
		}`,
		`[
			{ "op": "test", "path": "/baz", "value": "qux" },
			{ "op": "test", "path": "/foo/1", "value": 2 }
		]`,
		true,
		"",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/baz", "value": "bar" } ]`,
		false,
		"/baz",
	},
	{
		`{
			"baz": "qux",
			"foo": ["a", 2, "c"]
		}`,
		`[
			{ "op": "test", "path": "/baz", "value": "qux" },
			{ "op": "test", "path": "/foo/1", "value": "c" }
		]`,
		false,
		"/foo/1",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/foo", "value": 42 } ]`,
		false,
		"/foo",
	},
	{
		`{ "baz": "qux" }`,
		`[ { "op": "test", "path": "/foo", "value": null } ]`,
		true,
		"",
	},
}

func TestAllTest(t *testing.T) {
	for _, c := range TestCases {
		_, err := applyPatch(c.doc, c.patch)

		if c.result && err != nil {
			t.Errorf("Testing failed when it should have passed: %s", err)
		} else if !c.result && err == nil {
			t.Errorf("Testing passed when it should have faild: %s", err)
		} else if !c.result {
			expected := fmt.Sprintf("Testing value %s failed", c.failedPath)
			if err.Error() != expected {
				t.Errorf("Testing failed as expected but invalid message: expected [%s], got [%s]", expected, err)
			}
		}
	}
}
<|endoftext|>


<commit_before>package core

import (
	"bytes"
	"encoding/hex"
	"errors"
	crypto "gx/ipfs/QmPGxZ1DP2w45WcogpW1h43BvseXbfke9N91qotpoQcUeS/go-libp2p-crypto"

	"time"

	"github.com/OpenBazaar/openbazaar-go/pb"
	"github.com/OpenBazaar/spvwallet"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil"
	hd "github.com/btcsuite/btcutil/hdkeychain"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
)

func (n *OpenBazaarNode) NewOrderConfirmation(contract *pb.RicardianContract, addressRequest bool) (*pb.RicardianContract, error) {
	oc := new(pb.OrderConfirmation)
	// Calculate order ID
	orderID, err := n.CalcOrderId(contract.BuyerOrder)
	if err != nil {
		return nil, err
	}
	oc.OrderID = orderID
	if addressRequest {
		addr := n.Wallet.NewAddress(spvwallet.EXTERNAL)
		oc.PaymentAddress = addr.EncodeAddress()
	}

	ts, err := ptypes.TimestampProto(time.Now())
	if err != nil {
		return nil, err
	}
	oc.Timestamp = ts

	oc.RatingSignatures = []*pb.RatingSignature{}
	if contract.BuyerOrder.Payment.Method == pb.Order_Payment_MODERATED {
		for i, listing := range contract.VendorListings {
			buyerKey := contract.BuyerOrder.RatingKeys[i]
			moderatorKey, err := hex.DecodeString(ExtraModeratorKeyFromReddemScript(contract.BuyerOrder.Payment.RedeemScript))
			if err != nil {
				return nil, err
			}
			metadata := new(pb.RatingSignature_TransactionMetadata)
			metadata.ListingSlug = listing.Slug
			metadata.ModeratorKey = moderatorKey
			metadata.RatingKey = buyerKey

			ser, err := proto.Marshal(metadata)
			if err != nil {
				return nil, err
			}
			sig, err := n.IpfsNode.PrivateKey.Sign(ser)
			if err != nil {
				return nil, err
			}

			rs := new(pb.RatingSignature)
			rs.Metadata = metadata
			rs.Signature = sig

			oc.RatingSignatures = append(oc.RatingSignatures, rs)
		}
		oc.PaymentAddress = contract.BuyerOrder.Payment.Address
		oc.PayoutFee = n.Wallet.GetFeePerByte(spvwallet.NORMAL)
	}

	oc.RequestedAmount, err = n.CalculateOrderTotal(contract)
	if err != nil {
		return nil, err
	}
	contract.VendorOrderConfirmation = oc
	contract, err = n.SignOrderConfirmation(contract)
	if err != nil {
		return nil, err
	}
	return contract, nil
}

func (n *OpenBazaarNode) ConfirmOfflineOrder(contract *pb.RicardianContract, records []*spvwallet.TransactionRecord) error {
	contract, err := n.NewOrderConfirmation(contract, false)
	if err != nil {
		return err
	}
	if contract.BuyerOrder.Payment.Method != pb.Order_Payment_MODERATED {
		// Sweep the temp address into our wallet
		var utxos []spvwallet.Utxo
		for _, r := range records {
			if !r.Spent && r.Value > 0 {
				u := spvwallet.Utxo{}
				scriptBytes, err := hex.DecodeString(r.ScriptPubKey)
				if err != nil {
					return err
				}
				u.ScriptPubkey = scriptBytes
				hash, err := chainhash.NewHashFromStr(r.Txid)
				if err != nil {
					return err
				}
				outpoint := wire.NewOutPoint(hash, r.Index)
				u.Op = *outpoint
				u.Value = r.Value
				utxos = append(utxos, u)
			}
		}

		chaincode, err := hex.DecodeString(contract.BuyerOrder.Payment.Chaincode)
		if err != nil {
			return err
		}
		parentFP := []byte{0x00, 0x00, 0x00, 0x00}
		mPrivKey := n.Wallet.MasterPrivateKey()
		if err != nil {
			return err
		}
		mECKey, err := mPrivKey.ECPrivKey()
		if err != nil {
			return err
		}
		hdKey := hd.NewExtendedKey(
			n.Wallet.Params().HDPrivateKeyID[:],
			mECKey.Serialize(),
			chaincode,
			parentFP,
			0,
			0,
			true)

		vendorKey, err := hdKey.Child(0)
		if err != nil {
			return err
		}
		redeemScript, err := hex.DecodeString(contract.BuyerOrder.Payment.RedeemScript)
		_, err = n.Wallet.SweepAddress(utxos, nil, vendorKey, &redeemScript, spvwallet.NORMAL)
		if err != nil {
			return err
		}
	}
	err = n.SendOrderConfirmation(contract.BuyerOrder.BuyerID.PeerID, contract)
	if err != nil {
		return err
	}
	n.Datastore.Sales().Put(contract.VendorOrderConfirmation.OrderID, *contract, pb.OrderState_FUNDED, false)
	return nil
}

func (n *OpenBazaarNode) RejectOfflineOrder(contract *pb.RicardianContract, records []*spvwallet.TransactionRecord) error {
	orderId, err := n.CalcOrderId(contract.BuyerOrder)
	if err != nil {
		return err
	}
	rejectMsg := new(pb.OrderReject)
	rejectMsg.OrderID = orderId
	ts, err := ptypes.TimestampProto(time.Now())
	if err != nil {
		return err
	}
	rejectMsg.Timestamp = ts
	if contract.BuyerOrder.Payment.Method == pb.Order_Payment_MODERATED {
		var ins []spvwallet.TransactionInput
		var outValue int64
		for _, r := range records {
			if !r.Spent && r.Value > 0 {
				outpointHash, err := hex.DecodeString(r.Txid)
				if err != nil {
					return err
				}
				outValue += r.Value
				in := spvwallet.TransactionInput{OutpointIndex: r.Index, OutpointHash: outpointHash}
				ins = append(ins, in)
			}
		}

		refundAddress, err := btcutil.DecodeAddress(contract.BuyerOrder.RefundAddress, n.Wallet.Params())
		if err != nil {
			return err
		}
		var output spvwallet.TransactionOutput

		outputScript, err := txscript.PayToAddrScript(refundAddress)
		if err != nil {
			return err
		}
		output.ScriptPubKey = outputScript
		output.Value = outValue

		chaincode, err := hex.DecodeString(contract.BuyerOrder.Payment.Chaincode)
		if err != nil {
			return err
		}
		parentFP := []byte{0x00, 0x00, 0x00, 0x00}
		mPrivKey := n.Wallet.MasterPrivateKey()
		if err != nil {
			return err
		}
		mECKey, err := mPrivKey.ECPrivKey()
		if err != nil {
			return err
		}
		hdKey := hd.NewExtendedKey(
			n.Wallet.Params().HDPrivateKeyID[:],
			mECKey.Serialize(),
			chaincode,
			parentFP,
			0,
			0,
			true)

		vendorKey, err := hdKey.Child(0)
		if err != nil {
			return err
		}
		redeemScript, err := hex.DecodeString(contract.BuyerOrder.Payment.RedeemScript)

		signatures, err := n.Wallet.CreateMultisigSignature(ins, []spvwallet.TransactionOutput{output}, vendorKey, redeemScript, contract.BuyerOrder.RefundFee)
		if err != nil {
			return err
		}
		var sigs []*pb.BitcoinSignature
		for _, s := range signatures {
			pbSig := &pb.BitcoinSignature{Signature: s.Signature, InputIndex: s.InputIndex}
			sigs = append(sigs, pbSig)
		}
		rejectMsg.Sigs = sigs
	}
	err = n.SendReject(contract.BuyerOrder.BuyerID.PeerID, rejectMsg)
	if err != nil {
		return err
	}
	n.Datastore.Sales().Put(orderId, *contract, pb.OrderState_REJECTED, true)
	return nil
}

func (n *OpenBazaarNode) ValidateOrderConfirmation(contract *pb.RicardianContract, validateAddress bool) error {
	orderID, err := n.CalcOrderId(contract.BuyerOrder)
	if err != nil {
		return err
	}
	if contract.VendorOrderConfirmation.OrderID != orderID {
		return errors.New("Vendor's response contained invalid order ID")
	}
	if contract.VendorOrderConfirmation.RequestedAmount != contract.BuyerOrder.Payment.Amount {
		return errors.New("Vendor requested an amount different from what we calculated")
	}
	if contract.BuyerOrder.Payment.Method == pb.Order_Payment_MODERATED {
		keyExists := func(a []byte, list [][]byte) bool {
			for _, b := range list {
				if bytes.Equal(b, a) {
					return true
				}
			}
			return false
		}
		for _, sig := range contract.VendorOrderConfirmation.RatingSignatures {
			exists := false
			for _, listing := range contract.VendorListings {
				if sig.Metadata.ListingSlug == listing.Slug {
					exists = true
				}
			}
			if !exists {
				return errors.New("Rating signatures do not cover all purchased listings")
			}
			pubkey, err := crypto.UnmarshalPublicKey(contract.VendorListings[0].VendorID.Pubkeys.Identity)
			if err != nil {
				return err
			}
			moderatorKey, err := hex.DecodeString(ExtraModeratorKeyFromReddemScript(contract.BuyerOrder.Payment.RedeemScript))
			if err != nil {
				return err
			}
			if !keyExists(sig.Metadata.RatingKey, contract.BuyerOrder.RatingKeys) {
				return errors.New("Not all ratings keys are signed by ratings signatures")
			}

			if !bytes.Equal(sig.Metadata.ModeratorKey, moderatorKey) {
				return errors.New("Rating signature does not contain moderatory key")
			}
			ser, err := proto.Marshal(sig.Metadata)
			if err != nil {
				return err
			}
			valid, err := pubkey.Verify(ser, sig.Signature)
			if err != nil || !valid {
				return errors.New("Failed to verify signature on rating keys")
			}
		}
	}
	if validateAddress {
		_, err = btcutil.DecodeAddress(contract.VendorOrderConfirmation.PaymentAddress, n.Wallet.Params())
		if err != nil {
			return err
		}
	}
	err = verifySignaturesOnOrderConfirmation(contract)
	if err != nil {
		return err
	}
	return nil
}

func (n *OpenBazaarNode) SignOrderConfirmation(contract *pb.RicardianContract) (*pb.RicardianContract, error) {
	serializedOrderConf, err := proto.Marshal(contract.VendorOrderConfirmation)
	if err != nil {
		return contract, err
	}
	s := new(pb.Signature)
	s.Section = pb.Signature_ORDER_CONFIRMATION
	if err != nil {
		return contract, err
	}
	guidSig, err := n.IpfsNode.PrivateKey.Sign(serializedOrderConf)
	if err != nil {
		return contract, err
	}
	s.SignatureBytes = guidSig
	contract.Signatures = append(contract.Signatures, s)
	return contract, nil
}

func verifySignaturesOnOrderConfirmation(contract *pb.RicardianContract) error {
	if err := verifyMessageSignature(
		contract.VendorOrderConfirmation,
		contract.VendorListings[0].VendorID.Pubkeys.Identity,
		contract.Signatures,
		pb.Signature_ORDER_CONFIRMATION,
		contract.VendorListings[0].VendorID.PeerID,
	); err != nil {
		switch err.(type) {
		case noSigError:
			return errors.New("Contract does not contain a signature for the order confirmation")
		case invalidSigError:
			return errors.New("Vendor's guid signature on contact failed to verify")
		case matchKeyError:
			return errors.New("Public key in order confirmation does not match reported vendor ID")
		default:
			return err
		}
	}
	return nil
}

func ExtraModeratorKeyFromReddemScript(redeemScript string) string {
	return redeemScript[134:200]
}
<commit_msg>Fix missing error check into confirmations.go<commit_after>package core

import (
	"bytes"
	"encoding/hex"
	"errors"
	crypto "gx/ipfs/QmPGxZ1DP2w45WcogpW1h43BvseXbfke9N91qotpoQcUeS/go-libp2p-crypto"

	"time"

	"github.com/OpenBazaar/openbazaar-go/pb"
	"github.com/OpenBazaar/spvwallet"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil"
	hd "github.com/btcsuite/btcutil/hdkeychain"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
)

func (n *OpenBazaarNode) NewOrderConfirmation(contract *pb.RicardianContract, addressRequest bool) (*pb.RicardianContract, error) {
	oc := new(pb.OrderConfirmation)
	// Calculate order ID
	orderID, err := n.CalcOrderId(contract.BuyerOrder)
	if err != nil {
		return nil, err
	}
	oc.OrderID = orderID
	if addressRequest {
		addr := n.Wallet.NewAddress(spvwallet.EXTERNAL)
		oc.PaymentAddress = addr.EncodeAddress()
	}

	ts, err := ptypes.TimestampProto(time.Now())
	if err != nil {
		return nil, err
	}
	oc.Timestamp = ts

	oc.RatingSignatures = []*pb.RatingSignature{}
	if contract.BuyerOrder.Payment.Method == pb.Order_Payment_MODERATED {
		for i, listing := range contract.VendorListings {
			buyerKey := contract.BuyerOrder.RatingKeys[i]
			moderatorKey, err := hex.DecodeString(ExtraModeratorKeyFromReddemScript(contract.BuyerOrder.Payment.RedeemScript))
			if err != nil {
				return nil, err
			}
			metadata := new(pb.RatingSignature_TransactionMetadata)
			metadata.ListingSlug = listing.Slug
			metadata.ModeratorKey = moderatorKey
			metadata.RatingKey = buyerKey

			ser, err := proto.Marshal(metadata)
			if err != nil {
				return nil, err
			}
			sig, err := n.IpfsNode.PrivateKey.Sign(ser)
			if err != nil {
				return nil, err
			}

			rs := new(pb.RatingSignature)
			rs.Metadata = metadata
			rs.Signature = sig

			oc.RatingSignatures = append(oc.RatingSignatures, rs)
		}
		oc.PaymentAddress = contract.BuyerOrder.Payment.Address
		oc.PayoutFee = n.Wallet.GetFeePerByte(spvwallet.NORMAL)
	}

	oc.RequestedAmount, err = n.CalculateOrderTotal(contract)
	if err != nil {
		return nil, err
	}
	contract.VendorOrderConfirmation = oc
	contract, err = n.SignOrderConfirmation(contract)
	if err != nil {
		return nil, err
	}
	return contract, nil
}

func (n *OpenBazaarNode) ConfirmOfflineOrder(contract *pb.RicardianContract, records []*spvwallet.TransactionRecord) error {
	contract, err := n.NewOrderConfirmation(contract, false)
	if err != nil {
		return err
	}
	if contract.BuyerOrder.Payment.Method != pb.Order_Payment_MODERATED {
		// Sweep the temp address into our wallet
		var utxos []spvwallet.Utxo
		for _, r := range records {
			if !r.Spent && r.Value > 0 {
				u := spvwallet.Utxo{}
				scriptBytes, err := hex.DecodeString(r.ScriptPubKey)
				if err != nil {
					return err
				}
				u.ScriptPubkey = scriptBytes
				hash, err := chainhash.NewHashFromStr(r.Txid)
				if err != nil {
					return err
				}
				outpoint := wire.NewOutPoint(hash, r.Index)
				u.Op = *outpoint
				u.Value = r.Value
				utxos = append(utxos, u)
			}
		}

		chaincode, err := hex.DecodeString(contract.BuyerOrder.Payment.Chaincode)
		if err != nil {
			return err
		}
		parentFP := []byte{0x00, 0x00, 0x00, 0x00}
		mPrivKey := n.Wallet.MasterPrivateKey()
		if err != nil {
			return err
		}
		mECKey, err := mPrivKey.ECPrivKey()
		if err != nil {
			return err
		}
		hdKey := hd.NewExtendedKey(
			n.Wallet.Params().HDPrivateKeyID[:],
			mECKey.Serialize(),
			chaincode,
			parentFP,
			0,
			0,
			true)

		vendorKey, err := hdKey.Child(0)
		if err != nil {
			return err
		}
		redeemScript, err := hex.DecodeString(contract.BuyerOrder.Payment.RedeemScript)
		if err != nil {
			return err
		}
		_, err = n.Wallet.SweepAddress(utxos, nil, vendorKey, &redeemScript, spvwallet.NORMAL)
		if err != nil {
			return err
		}
	}
	err = n.SendOrderConfirmation(contract.BuyerOrder.BuyerID.PeerID, contract)
	if err != nil {
		return err
	}
	n.Datastore.Sales().Put(contract.VendorOrderConfirmation.OrderID, *contract, pb.OrderState_FUNDED, false)
	return nil
}

func (n *OpenBazaarNode) RejectOfflineOrder(contract *pb.RicardianContract, records []*spvwallet.TransactionRecord) error {
	orderId, err := n.CalcOrderId(contract.BuyerOrder)
	if err != nil {
		return err
	}
	rejectMsg := new(pb.OrderReject)
	rejectMsg.OrderID = orderId
	ts, err := ptypes.TimestampProto(time.Now())
	if err != nil {
		return err
	}
	rejectMsg.Timestamp = ts
	if contract.BuyerOrder.Payment.Method == pb.Order_Payment_MODERATED {
		var ins []spvwallet.TransactionInput
		var outValue int64
		for _, r := range records {
			if !r.Spent && r.Value > 0 {
				outpointHash, err := hex.DecodeString(r.Txid)
				if err != nil {
					return err
				}
				outValue += r.Value
				in := spvwallet.TransactionInput{OutpointIndex: r.Index, OutpointHash: outpointHash}
				ins = append(ins, in)
			}
		}

		refundAddress, err := btcutil.DecodeAddress(contract.BuyerOrder.RefundAddress, n.Wallet.Params())
		if err != nil {
			return err
		}
		var output spvwallet.TransactionOutput

		outputScript, err := txscript.PayToAddrScript(refundAddress)
		if err != nil {
			return err
		}
		output.ScriptPubKey = outputScript
		output.Value = outValue

		chaincode, err := hex.DecodeString(contract.BuyerOrder.Payment.Chaincode)
		if err != nil {
			return err
		}
		parentFP := []byte{0x00, 0x00, 0x00, 0x00}
		mPrivKey := n.Wallet.MasterPrivateKey()
		if err != nil {
			return err
		}
		mECKey, err := mPrivKey.ECPrivKey()
		if err != nil {
			return err
		}
		hdKey := hd.NewExtendedKey(
			n.Wallet.Params().HDPrivateKeyID[:],
			mECKey.Serialize(),
			chaincode,
			parentFP,
			0,
			0,
			true)

		vendorKey, err := hdKey.Child(0)
		if err != nil {
			return err
		}
		redeemScript, err := hex.DecodeString(contract.BuyerOrder.Payment.RedeemScript)
		if err != nil {
			return err
		}
		signatures, err := n.Wallet.CreateMultisigSignature(ins, []spvwallet.TransactionOutput{output}, vendorKey, redeemScript, contract.BuyerOrder.RefundFee)
		if err != nil {
			return err
		}
		var sigs []*pb.BitcoinSignature
		for _, s := range signatures {
			pbSig := &pb.BitcoinSignature{Signature: s.Signature, InputIndex: s.InputIndex}
			sigs = append(sigs, pbSig)
		}
		rejectMsg.Sigs = sigs
	}
	err = n.SendReject(contract.BuyerOrder.BuyerID.PeerID, rejectMsg)
	if err != nil {
		return err
	}
	n.Datastore.Sales().Put(orderId, *contract, pb.OrderState_REJECTED, true)
	return nil
}

func (n *OpenBazaarNode) ValidateOrderConfirmation(contract *pb.RicardianContract, validateAddress bool) error {
	orderID, err := n.CalcOrderId(contract.BuyerOrder)
	if err != nil {
		return err
	}
	if contract.VendorOrderConfirmation.OrderID != orderID {
		return errors.New("Vendor's response contained invalid order ID")
	}
	if contract.VendorOrderConfirmation.RequestedAmount != contract.BuyerOrder.Payment.Amount {
		return errors.New("Vendor requested an amount different from what we calculated")
	}
	if contract.BuyerOrder.Payment.Method == pb.Order_Payment_MODERATED {
		keyExists := func(a []byte, list [][]byte) bool {
			for _, b := range list {
				if bytes.Equal(b, a) {
					return true
				}
			}
			return false
		}
		for _, sig := range contract.VendorOrderConfirmation.RatingSignatures {
			exists := false
			for _, listing := range contract.VendorListings {
				if sig.Metadata.ListingSlug == listing.Slug {
					exists = true
				}
			}
			if !exists {
				return errors.New("Rating signatures do not cover all purchased listings")
			}
			pubkey, err := crypto.UnmarshalPublicKey(contract.VendorListings[0].VendorID.Pubkeys.Identity)
			if err != nil {
				return err
			}
			moderatorKey, err := hex.DecodeString(ExtraModeratorKeyFromReddemScript(contract.BuyerOrder.Payment.RedeemScript))
			if err != nil {
				return err
			}
			if !keyExists(sig.Metadata.RatingKey, contract.BuyerOrder.RatingKeys) {
				return errors.New("Not all ratings keys are signed by ratings signatures")
			}

			if !bytes.Equal(sig.Metadata.ModeratorKey, moderatorKey) {
				return errors.New("Rating signature does not contain moderatory key")
			}
			ser, err := proto.Marshal(sig.Metadata)
			if err != nil {
				return err
			}
			valid, err := pubkey.Verify(ser, sig.Signature)
			if err != nil || !valid {
				return errors.New("Failed to verify signature on rating keys")
			}
		}
	}
	if validateAddress {
		_, err = btcutil.DecodeAddress(contract.VendorOrderConfirmation.PaymentAddress, n.Wallet.Params())
		if err != nil {
			return err
		}
	}
	err = verifySignaturesOnOrderConfirmation(contract)
	if err != nil {
		return err
	}
	return nil
}

func (n *OpenBazaarNode) SignOrderConfirmation(contract *pb.RicardianContract) (*pb.RicardianContract, error) {
	serializedOrderConf, err := proto.Marshal(contract.VendorOrderConfirmation)
	if err != nil {
		return contract, err
	}
	s := new(pb.Signature)
	s.Section = pb.Signature_ORDER_CONFIRMATION
	if err != nil {
		return contract, err
	}
	guidSig, err := n.IpfsNode.PrivateKey.Sign(serializedOrderConf)
	if err != nil {
		return contract, err
	}
	s.SignatureBytes = guidSig
	contract.Signatures = append(contract.Signatures, s)
	return contract, nil
}

func verifySignaturesOnOrderConfirmation(contract *pb.RicardianContract) error {
	if err := verifyMessageSignature(
		contract.VendorOrderConfirmation,
		contract.VendorListings[0].VendorID.Pubkeys.Identity,
		contract.Signatures,
		pb.Signature_ORDER_CONFIRMATION,
		contract.VendorListings[0].VendorID.PeerID,
	); err != nil {
		switch err.(type) {
		case noSigError:
			return errors.New("Contract does not contain a signature for the order confirmation")
		case invalidSigError:
			return errors.New("Vendor's guid signature on contact failed to verify")
		case matchKeyError:
			return errors.New("Public key in order confirmation does not match reported vendor ID")
		default:
			return err
		}
	}
	return nil
}

func ExtraModeratorKeyFromReddemScript(redeemScript string) string {
	return redeemScript[134:200]
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"github.com/ziutek/mymysql/autorc"
	_ "github.com/ziutek/mymysql/native"
	"io"
	"log"
	"net"
	"strconv"
	"strings"
	"time"
)

// Message format (lines ended by CR or CRLF):
// FROM                                - symbol of source (<=16B)
// PHONE1[=DSTID1] PHONE2[=DSTID2] ... - list of phone numbers and dstIds
// Lines that contain optional parameters, one parameter per line: NAME or
// NAME VALUE. Implemented parameters:
// report        - report required
// delede        - delete message after sending (wait for reports, if required)
//               - empty line
// Message body
// .             - '.' as first and only character in line

// You can use optional dstIds to link recipients with your other data in db.

// Input represents source of messages
type Input struct {
	smsd                           *SMSd
	db                             *autorc.Conn
	knownSrc                       []string
	proto, addr                    string
	ln                             net.Listener
	outboxInsert, recipientsInsert autorc.Stmt
}

func NewInput(smsd *SMSd, proto, addr string, cfg *Config) *Input {
	in := new(Input)
	in.smsd = smsd
	in.db = autorc.New(
		cfg.Db.Proto, cfg.Db.Saddr, cfg.Db.Daddr,
		cfg.Db.User, cfg.Db.Pass, cfg.Db.Name,
	)
	in.db.Raw.Register(setNames)
	in.db.Raw.Register(createOutbox)
	in.db.Raw.Register(createRecipients)
	in.proto = proto
	in.addr = addr
	in.knownSrc = cfg.Source
	return in
}

const outboxInsert = `INSERT
	` + outboxTable + `
SET
	time=?,
	src=?,
	report=?,
	del=?,
	body=?
`

const recipientsInsert = `INSERT ` + recipientsTable + ` SET
	msgId=?,
	number=?,
	dstId=?
`

func (in *Input) handle(c net.Conn) {
	defer c.Close()

	if !prepareOnce(in.db, &in.outboxInsert, outboxInsert) {
		return
	}
	if !prepareOnce(in.db, &in.recipientsInsert, recipientsInsert) {
		return
	}
	r := bufio.NewReader(c)
	from, ok := readLine(r)
	if !ok {
		return
	}
	i := 0
	for i < len(in.knownSrc) && in.knownSrc[i] != from {
		i++
	}
	if i == len(in.knownSrc) {
		log.Println("Unknown source:", from)
		return
	}
	tels, ok := readLine(r)
	if !ok {
		return
	}
	// Read options until first empty line
	var del, report bool
	for {
		l, ok := readLine(r)
		if !ok {
			return
		}
		if l == "" {
			break
		}
		switch l {
		case "report":
			report = true
		case "delete":
			del = true
		}
	}
	// Read a message body
	var body []byte
	var prevIsPrefix bool
	for {
		buf, isPrefix, err := r.ReadLine()
		if err != nil {
			log.Print("Can't read message body: ", err)
			return
		}
		if !isPrefix && !prevIsPrefix && len(buf) == 1 && buf[0] == '.' {
			break
		}
		body = append(body, '\n')
		body = append(body, buf...)
		prevIsPrefix = isPrefix
	}
	// Insert message into Outbox
	_, res, err := in.outboxInsert.Exec(time.Now(), from, report, del, body[1:])
	if err != nil {
		log.Printf("Can't insert message from %s into Outbox: %s", from, err)
		// Send error response, ignore errors
		io.WriteString(c, "DB error (can't insert message)\n")
		return
	}
	msgId := uint32(res.InsertId())
	// Save recipients for this message
	for _, dst := range strings.Split(tels, " ") {
		d := strings.SplitN(dst, "=", 2)
		num := d[0]
		if !checkNumber(num) {
			log.Printf("Bad phone number: '%s' for message #%d.", num, msgId)
			// Send error response, ignore errors
			io.WriteString(c, "Bad phone number\n")
			continue
		}
		var dstId uint64
		if len(d) == 2 {
			dstId, err = strconv.ParseUint(d[1], 0, 32)
			if err != nil {
				dstId = 0
				log.Printf("Bad DstId=`%s` for number %s: %s", d[1], num, err)
				// Send error response, ignore errors
				io.WriteString(c, "Bad DstId\n")
			}
		}
		_, _, err = in.recipientsInsert.Exec(msgId, num, uint32(dstId))
		if err != nil {
			log.Printf("Can't insert phone number %s into Recipients: %s", num, err)
			// Send error response, ignore errors
			io.WriteString(c, "DB error (can't insert phone number)\n")
		}
	}
	// Send OK as response, ignore errors
	io.WriteString(c, "OK\n")

	// Inform SMSd about new message
	in.smsd.NewMsg()
}

func (in *Input) loop() {
	for {
		c, err := in.ln.Accept()
		if err != nil {
			log.Print("Can't accept connection: ", err)
			if e, ok := err.(net.Error); ok && e.Temporary() {
				continue
			}
			return
		}
		go in.handle(c)
	}
}

func (in *Input) Start() error {
	var err error
	log.Println("Listen on:", in.proto, in.addr)
	in.ln, err = net.Listen(in.proto, in.addr)
	if err != nil {
		return err
	}
	go in.loop()
	return nil
}

func (in *Input) Stop() error {
	return in.ln.Close()
}

func (in *Input) String() string {
	return in.proto + ":" + in.addr
}
<commit_msg>Send 'Unknown source' error message to the client<commit_after>package main

import (
	"bufio"
	"github.com/ziutek/mymysql/autorc"
	_ "github.com/ziutek/mymysql/native"
	"io"
	"log"
	"net"
	"strconv"
	"strings"
	"time"
)

// Message format (lines ended by CR or CRLF):
// FROM                                - symbol of source (<=16B)
// PHONE1[=DSTID1] PHONE2[=DSTID2] ... - list of phone numbers and dstIds
// Lines that contain optional parameters, one parameter per line: NAME or
// NAME VALUE. Implemented parameters:
// report        - report required
// delede        - delete message after sending (wait for reports, if required)
//               - empty line
// Message body
// .             - '.' as first and only character in line

// You can use optional dstIds to link recipients with your other data in db.

// Input represents source of messages
type Input struct {
	smsd                           *SMSd
	db                             *autorc.Conn
	knownSrc                       []string
	proto, addr                    string
	ln                             net.Listener
	outboxInsert, recipientsInsert autorc.Stmt
}

func NewInput(smsd *SMSd, proto, addr string, cfg *Config) *Input {
	in := new(Input)
	in.smsd = smsd
	in.db = autorc.New(
		cfg.Db.Proto, cfg.Db.Saddr, cfg.Db.Daddr,
		cfg.Db.User, cfg.Db.Pass, cfg.Db.Name,
	)
	in.db.Raw.Register(setNames)
	in.db.Raw.Register(createOutbox)
	in.db.Raw.Register(createRecipients)
	in.proto = proto
	in.addr = addr
	in.knownSrc = cfg.Source
	return in
}

const outboxInsert = `INSERT
	` + outboxTable + `
SET
	time=?,
	src=?,
	report=?,
	del=?,
	body=?
`

const recipientsInsert = `INSERT ` + recipientsTable + ` SET
	msgId=?,
	number=?,
	dstId=?
`

func (in *Input) handle(c net.Conn) {
	defer c.Close()

	if !prepareOnce(in.db, &in.outboxInsert, outboxInsert) {
		return
	}
	if !prepareOnce(in.db, &in.recipientsInsert, recipientsInsert) {
		return
	}
	r := bufio.NewReader(c)
	from, ok := readLine(r)
	if !ok {
		return
	}
	i := 0
	for i < len(in.knownSrc) && in.knownSrc[i] != from {
		i++
	}
	if i == len(in.knownSrc) {
		log.Println("Unknown source:", from)
		time.Sleep(5 * time.Second)
		io.WriteString(c, "Unknown source\n")
		return
	}
	tels, ok := readLine(r)
	if !ok {
		return
	}
	// Read options until first empty line
	var del, report bool
	for {
		l, ok := readLine(r)
		if !ok {
			return
		}
		if l == "" {
			break
		}
		switch l {
		case "report":
			report = true
		case "delete":
			del = true
		}
	}
	// Read a message body
	var body []byte
	var prevIsPrefix bool
	for {
		buf, isPrefix, err := r.ReadLine()
		if err != nil {
			log.Print("Can't read message body: ", err)
			return
		}
		if !isPrefix && !prevIsPrefix && len(buf) == 1 && buf[0] == '.' {
			break
		}
		body = append(body, '\n')
		body = append(body, buf...)
		prevIsPrefix = isPrefix
	}
	// Insert message into Outbox
	_, res, err := in.outboxInsert.Exec(time.Now(), from, report, del, body[1:])
	if err != nil {
		log.Printf("Can't insert message from %s into Outbox: %s", from, err)
		// Send error response, ignore errors
		io.WriteString(c, "DB error (can't insert message)\n")
		return
	}
	msgId := uint32(res.InsertId())
	// Save recipients for this message
	for _, dst := range strings.Split(tels, " ") {
		d := strings.SplitN(dst, "=", 2)
		num := d[0]
		if !checkNumber(num) {
			log.Printf("Bad phone number: '%s' for message #%d.", num, msgId)
			// Send error response, ignore errors
			io.WriteString(c, "Bad phone number\n")
			continue
		}
		var dstId uint64
		if len(d) == 2 {
			dstId, err = strconv.ParseUint(d[1], 0, 32)
			if err != nil {
				dstId = 0
				log.Printf("Bad DstId=`%s` for number %s: %s", d[1], num, err)
				// Send error response, ignore errors
				io.WriteString(c, "Bad DstId\n")
			}
		}
		_, _, err = in.recipientsInsert.Exec(msgId, num, uint32(dstId))
		if err != nil {
			log.Printf("Can't insert phone number %s into Recipients: %s", num, err)
			// Send error response, ignore errors
			io.WriteString(c, "DB error (can't insert phone number)\n")
		}
	}
	// Send OK as response, ignore errors
	io.WriteString(c, "OK\n")

	// Inform SMSd about new message
	in.smsd.NewMsg()
}

func (in *Input) loop() {
	for {
		c, err := in.ln.Accept()
		if err != nil {
			log.Print("Can't accept connection: ", err)
			if e, ok := err.(net.Error); ok && e.Temporary() {
				continue
			}
			return
		}
		go in.handle(c)
	}
}

func (in *Input) Start() error {
	var err error
	log.Println("Listen on:", in.proto, in.addr)
	in.ln, err = net.Listen(in.proto, in.addr)
	if err != nil {
		return err
	}
	go in.loop()
	return nil
}

func (in *Input) Stop() error {
	return in.ln.Close()
}

func (in *Input) String() string {
	return in.proto + ":" + in.addr
}
<|endoftext|>


<commit_before>package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/SudoQ/ganache/item"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"time"
)

type Service struct {
	URL    string        `json:"url"`
	Port   string        `json:"port"`
	Period time.Duration `json:"-"`
	Limit  uint          `json:"limit"`
	Cache  *item.Item    `json:"-"`
	logger *log.Logger   `json:"-"`
}

func New(targetUrl, port string, limit uint) *Service {
	period, err := LimitToPeriod(limit)
	if err != nil {
		limit = 1
		period, _ = LimitToPeriod(limit)
	}
	srv := &Service{
		URL:    targetUrl,
		Port:   port,
		Period: period,
		Limit:  limit,
		Cache:  nil,
		logger: nil,
	}
	srv.initLogger()
	return srv
}

func (this *Service) initLogger() {
	u, err := url.Parse(this.URL)
	label := u.Host
	if err != nil {
		label = "?"
	}
	this.logger = log.New(os.Stdin, fmt.Sprintf("ganache[%s]: ", label), log.Lshortfile)
}

func LimitToPeriod(limit uint) (time.Duration, error) {
	if limit == 0 {
		return 0, errors.New("Division with zero")
	}

	period := (60.0 / float64(limit)) * 60
	return (time.Duration(period) * time.Second), nil
}

func NewFromJSON(jsonBlob []byte) (*Service, error) {
	var srv Service
	err := json.Unmarshal(jsonBlob, &srv)
	if err != nil {
		return nil, err
	}
	srv.Period, err = LimitToPeriod(srv.Limit)
	if err != nil {
		srv.Limit = 1
		srv.Period, _ = LimitToPeriod(srv.Limit)
	}
	srv.initLogger()
	return &srv, nil
}

func NewFromFile(filename string) (*Service, error) {
	jsonBlob, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return NewFromJSON(jsonBlob)
}

func (this *Service) LoadConfig(filename string) error {
	jsonBlob, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	err = json.Unmarshal(jsonBlob, this)
	this.initLogger()
	return err
}

func (this *Service) JSON() ([]byte, error) {
	blob, err := json.Marshal(this)
	if err != nil {
		return nil, err
	}
	return blob, nil
}

func (this *Service) SaveConfig(filename string) error {
	jsonBlob, err := this.JSON()
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, jsonBlob, 0644)
	return err
}

func (this *Service) Collect() {
	for {
		func() {
			now := time.Now()
			timeDelta := now.Sub(this.Cache.Timestamp)
			if this.Cache.Timestamp.Before(now) && timeDelta > this.Period {
				this.logger.Printf("GET %s\n", this.URL)

				resp, err := http.Get(this.URL)
				if err != nil {
					this.logger.Println(err)
					return
				}

				payload, err := ioutil.ReadAll(resp.Body)
				if err != nil {
					this.logger.Println(err)
					return
				}

				// TODO Store header info?
				newItem := item.New(now, payload)
				this.Cache = newItem
				cacheFilename := "cache.json"
				err = this.Cache.WriteFile(cacheFilename)
				if err != nil {
					this.logger.Fatal(err)
				}
				this.logger.Printf("Saved cache to %s\n", cacheFilename)

			}
		}()
		select {
		case <-time.After(this.Period):
			continue
		}
	}
}

func (this *Service) LoadCache(filename string) error {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	newItem, err := item.NewFromJSON(content)
	if err != nil {
		return err
	}
	this.Cache = newItem
	return nil
}

func (this *Service) Info() string {
	return fmt.Sprintf("Ganache API caching service v0.1")
}

func (this *Service) Run() {
	err := this.LoadCache("cache.json")
	if err != nil {
		this.logger.Fatal(err)
	}
	go this.Collect()
	r := mux.NewRouter()
	r.HandleFunc("/", this.HomeHandler)
	r.HandleFunc("/info", this.InfoHandler)
	r.HandleFunc("/cache.json", this.CacheHandler)
	port := fmt.Sprintf(":%s", this.Port)
	http.ListenAndServe(port, r)
}

func (this *Service) HomeHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	w.Write(this.Cache.Payload)
}

func (this *Service) InfoHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(200)
	w.Write([]byte(this.Info()))
}

func (this *Service) CacheHandler(w http.ResponseWriter, r *http.Request) {
	response, err := this.Cache.JSON()
	if err != nil {
		this.logger.Println(err)
		w.WriteHeader(404)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	w.Write(response)
}
<commit_msg>Removed todo<commit_after>package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/SudoQ/ganache/item"
	"github.com/gorilla/mux"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"time"
)

type Service struct {
	URL    string        `json:"url"`
	Port   string        `json:"port"`
	Period time.Duration `json:"-"`
	Limit  uint          `json:"limit"`
	Cache  *item.Item    `json:"-"`
	logger *log.Logger   `json:"-"`
}

func New(targetUrl, port string, limit uint) *Service {
	period, err := LimitToPeriod(limit)
	if err != nil {
		limit = 1
		period, _ = LimitToPeriod(limit)
	}
	srv := &Service{
		URL:    targetUrl,
		Port:   port,
		Period: period,
		Limit:  limit,
		Cache:  nil,
		logger: nil,
	}
	srv.initLogger()
	return srv
}

func (this *Service) initLogger() {
	u, err := url.Parse(this.URL)
	label := u.Host
	if err != nil {
		label = "?"
	}
	this.logger = log.New(os.Stdin, fmt.Sprintf("ganache[%s]: ", label), log.Lshortfile)
}

func LimitToPeriod(limit uint) (time.Duration, error) {
	if limit == 0 {
		return 0, errors.New("Division with zero")
	}

	period := (60.0 / float64(limit)) * 60
	return (time.Duration(period) * time.Second), nil
}

func NewFromJSON(jsonBlob []byte) (*Service, error) {
	var srv Service
	err := json.Unmarshal(jsonBlob, &srv)
	if err != nil {
		return nil, err
	}
	srv.Period, err = LimitToPeriod(srv.Limit)
	if err != nil {
		srv.Limit = 1
		srv.Period, _ = LimitToPeriod(srv.Limit)
	}
	srv.initLogger()
	return &srv, nil
}

func NewFromFile(filename string) (*Service, error) {
	jsonBlob, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return NewFromJSON(jsonBlob)
}

func (this *Service) LoadConfig(filename string) error {
	jsonBlob, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	err = json.Unmarshal(jsonBlob, this)
	this.initLogger()
	return err
}

func (this *Service) JSON() ([]byte, error) {
	blob, err := json.Marshal(this)
	if err != nil {
		return nil, err
	}
	return blob, nil
}

func (this *Service) SaveConfig(filename string) error {
	jsonBlob, err := this.JSON()
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, jsonBlob, 0644)
	return err
}

func (this *Service) Collect() {
	for {
		func() {
			now := time.Now()
			timeDelta := now.Sub(this.Cache.Timestamp)
			if this.Cache.Timestamp.Before(now) && timeDelta > this.Period {
				this.logger.Printf("GET %s\n", this.URL)

				resp, err := http.Get(this.URL)
				if err != nil {
					this.logger.Println(err)
					return
				}

				payload, err := ioutil.ReadAll(resp.Body)
				if err != nil {
					this.logger.Println(err)
					return
				}

				newItem := item.New(now, payload)
				this.Cache = newItem
				cacheFilename := "cache.json"
				err = this.Cache.WriteFile(cacheFilename)
				if err != nil {
					this.logger.Fatal(err)
				}
				this.logger.Printf("Saved cache to %s\n", cacheFilename)

			}
		}()
		select {
		case <-time.After(this.Period):
			continue
		}
	}
}

func (this *Service) LoadCache(filename string) error {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	newItem, err := item.NewFromJSON(content)
	if err != nil {
		return err
	}
	this.Cache = newItem
	return nil
}

func (this *Service) Info() string {
	return fmt.Sprintf("Ganache API caching service v0.1")
}

func (this *Service) Run() {
	err := this.LoadCache("cache.json")
	if err != nil {
		this.logger.Fatal(err)
	}
	go this.Collect()
	r := mux.NewRouter()
	r.HandleFunc("/", this.HomeHandler)
	r.HandleFunc("/info", this.InfoHandler)
	r.HandleFunc("/cache.json", this.CacheHandler)
	port := fmt.Sprintf(":%s", this.Port)
	http.ListenAndServe(port, r)
}

func (this *Service) HomeHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	w.Write(this.Cache.Payload)
}

func (this *Service) InfoHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(200)
	w.Write([]byte(this.Info()))
}

func (this *Service) CacheHandler(w http.ResponseWriter, r *http.Request) {
	response, err := this.Cache.JSON()
	if err != nil {
		this.logger.Println(err)
		w.WriteHeader(404)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	w.Write(response)
}
<|endoftext|>


<commit_before>package main

var settingsTpl = `import (
	"sync"

	"gir/gio-2.0"
	"gir/glib-2.0"
	"pkg.deepin.io/lib/dbus"
)

type SettingHook interface {
	WillSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{}) bool // return true to continue setting.
	DidSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{})
	WillChange(gs *gio.Settings, key string) bool // return true to continue handleing change.
	DidChange(gs *gio.Settings, key string)
}

type DefaultSettingHook struct {
}

func (DefaultSettingHook) WillSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{}) bool {
	return true
}

func (DefaultSettingHook) DidSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{}) {
}

func (DefaultSettingHook) WillChange(*gio.Settings, string) bool {
	return true
}

func (DefaultSettingHook) DidChange(*gio.Settings, string) {
}

var _defaultHook = DefaultSettingHook{}

{{ $schemas := . }}
{{ range $_, $schema := .Schemas }}{{ if $schema.Keys }}{{ $TypeName := ExportName $schema.Id }}{{ if $schema.Keys }}
const (
{{ range $_, $key := $schema.Keys }}
	// {{ $key.Summary }}
	{{$result :=  GetDefaultValue $schemas $key }}{{ if $result.Err }}panic({{ $result.Err }}){{ else }}// default: {{ $result.Value }}{{ end }}
	{{$TypeName}}{{ ExportName $key.Name }} string = "{{ $key.Name }}"
{{ end }}
){{ end }}
{{/* generate setting structure */}}
type {{ $TypeName }} struct {
	finializeOnce sync.Once
	settings *gio.Settings
	hook SettingHook

{{ range $_, $key := $schema.Keys }}{{ $PropName :=  ExportName $key.Name }}
	{{ $PropName }}Changed func({{ if $key.IsEnum }}int32{{ else }}{{ if $key.IsFlags }}uint32{{ else }}{{ MapType $key.Type }}{{ end }}{{ end }})
{{ end }}
}

func (s *{{ $TypeName}}) GetDBusInfo() dbus.DBusInfo {
	return dbus.DBusInfo{
		Dest:       "{{ DBusName }}",
		ObjectPath: "{{ DBusPath }}",
		Interface:  "{{ ConvertToDBusInterface $schema.Id }}",
	}
}

func New{{ $TypeName}}() *{{ *TypeName }} {
	return New${{ TypeName }}WithHook(nil)
}

func New{{ $TypeName }}WithHook(hook SettingHook) *{{ $TypeName }} {
	if hook == nil {
		hook = _defaultHook
	}
	s := &{{ $TypeName }} {
		hook: hook,
		settings: gio.NewSettings("{{$schema.Id}}"),
	}
	s.listenSignal()
	return s
}

func (s *{{ $TypeName }}) Finialize() {
	s.finializeOnce.Do(func() {
		s.settings.Unref()
	})
}

func (s *{{ $TypeName }}) listenSignal() {
	s.settings.Connect("changed", func(gs *gio.Settings, key string){
		if !s.hook.WillChange(gs, key) {
			return
		}
		switch key {
		{{ range $_, $key := $schema.Keys }}{{ $PropName :=  ExportName $key.Name }}
		case "{{ $key.Name }}":
			dbus.Emit(s, "{{ $PropName }}Changed", s.{{ $PropName }}())
		{{ end }}
		}
		s.hook.DidChange(gs, key)
	})
}

{{ range $_, $key := $schema.Keys }}{{ $PropName :=  ExportName $key.Name }}
{{/* not generated GetXXRange for "type", "enum", "flags" */}}
{{ if $key.Range.Min }}
{{ $rangeType := GetRangeType $key }}
// Get{{ $PropName }}Range gets the value range of {{ $PropName }}.
func (s *{{ $TypeName }}) Get{{ $PropName }}Range(key string) {{ $rangeType }} {
	return {{ $rangeType }}{Min: {{ $key.Range.Min }}, Max: {{ $key.Range.Max }}}
}
{{ end }}

// {{ $PropName }} gets {{ $PropName }}'s value.
func (s *{{ $TypeName }}) {{$PropName}}() {{ GetKeyType $key }} {
	{{ if $key.IsEnum }}value := s.settings.GetEnum("{{$key.Name}}")
	{{ else }}{{ if $key.IsFlags }}value := s.settings.GetFlags("{{$key.Name}}")
	{{ else }}value := s.settings.GetValue("{{ $key.Name }}").Get{{ MapTypeGetter $key.Type }}()
	{{ end }}{{ end }}
	return value
}

// set{{ $PropName }} used internal.
func (s *{{ $TypeName }}) set{{ $PropName }}(newValue {{ GetKeyType $key }}) bool {
	oldValue := s.{{ $PropName }}()
	if oldValue == newValue {
		return false
	}

	gs := s.settings
	if !s.hook.WillSet(gs, "{{ $key.Name }}", oldValue, newValue) {
		return false
	}
	defer s.hook.DidSet(gs, "{{ $key.Name }}", oldValue, newValue)

	{{ if $key.IsEnum }}return gs.SetEnum("{{ $key.Name }}", newValue)
	{{ else }}{{ if $key.IsFlags }}return gs.SetFlags("{{ $key.Name }}", newValue)
	{{ else }}return gs.SetValue("{{ $key.Name }}", glib.NewVariant{{ MapTypeSetter $key.Type }}(newValue)){{ end }}{{ end }}
}

// Set{{ $PropName }} sets value of {{ $PropName }} and emit {{$PropName}}Changed signal.
func (s *{{ $TypeName }}) Set{{ $PropName }}(newValue {{ GetKeyType $key }}) {
	s.set{{$PropName}}(newValue)
	dbus.Emit(s, "{{ $PropName }}Changed", newValue)
}
{{ end }}
{{ end }}

{{ end }}

`
<commit_msg>change GetXRange to GetRangeOfX.<commit_after>package main

var settingsTpl = `import (
	"sync"

	"gir/gio-2.0"
	"gir/glib-2.0"
	"pkg.deepin.io/lib/dbus"
)

type SettingHook interface {
	WillSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{}) bool // return true to continue setting.
	DidSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{})
	WillChange(gs *gio.Settings, key string) bool // return true to continue handleing change.
	DidChange(gs *gio.Settings, key string)
}

type DefaultSettingHook struct {
}

func (DefaultSettingHook) WillSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{}) bool {
	return true
}

func (DefaultSettingHook) DidSet(gs *gio.Settings, key string, oldValue interface{}, newValue interface{}) {
}

func (DefaultSettingHook) WillChange(*gio.Settings, string) bool {
	return true
}

func (DefaultSettingHook) DidChange(*gio.Settings, string) {
}

var _defaultHook = DefaultSettingHook{}

{{ $schemas := . }}
{{ range $_, $schema := .Schemas }}{{ if $schema.Keys }}{{ $TypeName := ExportName $schema.Id }}{{ if $schema.Keys }}
const (
{{ range $_, $key := $schema.Keys }}
	// {{ $key.Summary }}
	{{$result :=  GetDefaultValue $schemas $key }}{{ if $result.Err }}panic({{ $result.Err }}){{ else }}// default: {{ $result.Value }}{{ end }}
	{{$TypeName}}{{ ExportName $key.Name }} string = "{{ $key.Name }}"
{{ end }}
){{ end }}
{{/* generate setting structure */}}
type {{ $TypeName }} struct {
	finializeOnce sync.Once
	settings *gio.Settings
	hook SettingHook

{{ range $_, $key := $schema.Keys }}{{ $PropName :=  ExportName $key.Name }}
	{{ $PropName }}Changed func({{ if $key.IsEnum }}int32{{ else }}{{ if $key.IsFlags }}uint32{{ else }}{{ MapType $key.Type }}{{ end }}{{ end }})
{{ end }}
}

func (s *{{ $TypeName}}) GetDBusInfo() dbus.DBusInfo {
	return dbus.DBusInfo{
		Dest:       "{{ DBusName }}",
		ObjectPath: "{{ DBusPath }}",
		Interface:  "{{ ConvertToDBusInterface $schema.Id }}",
	}
}

func New{{ $TypeName}}() *{{ *TypeName }} {
	return New${{ TypeName }}WithHook(nil)
}

func New{{ $TypeName }}WithHook(hook SettingHook) *{{ $TypeName }} {
	if hook == nil {
		hook = _defaultHook
	}
	s := &{{ $TypeName }} {
		hook: hook,
		settings: gio.NewSettings("{{$schema.Id}}"),
	}
	s.listenSignal()
	return s
}

func (s *{{ $TypeName }}) Finialize() {
	s.finializeOnce.Do(func() {
		s.settings.Unref()
	})
}

func (s *{{ $TypeName }}) listenSignal() {
	s.settings.Connect("changed", func(gs *gio.Settings, key string){
		if !s.hook.WillChange(gs, key) {
			return
		}
		switch key {
		{{ range $_, $key := $schema.Keys }}{{ $PropName :=  ExportName $key.Name }}
		case "{{ $key.Name }}":
			dbus.Emit(s, "{{ $PropName }}Changed", s.{{ $PropName }}())
		{{ end }}
		}
		s.hook.DidChange(gs, key)
	})
}

{{ range $_, $key := $schema.Keys }}{{ $PropName :=  ExportName $key.Name }}
{{/* not generated GetRangeOfXX for "type", "enum", "flags" */}}
{{ if $key.Range.Min }}
{{ $rangeType := GetRangeType $key }}
// GetRangeOf{{ $PropName }} gets the value range of {{ $PropName }}.
func (s *{{ $TypeName }}) GetRangeOf{{ $PropName }}(key string) {{ $rangeType }} {
	return {{ $rangeType }}{Min: {{ $key.Range.Min }}, Max: {{ $key.Range.Max }}}
}
{{ end }}

// {{ $PropName }} gets {{ $PropName }}'s value.
func (s *{{ $TypeName }}) {{$PropName}}() {{ GetKeyType $key }} {
	{{ if $key.IsEnum }}value := s.settings.GetEnum("{{$key.Name}}")
	{{ else }}{{ if $key.IsFlags }}value := s.settings.GetFlags("{{$key.Name}}")
	{{ else }}value := s.settings.GetValue("{{ $key.Name }}").Get{{ MapTypeGetter $key.Type }}()
	{{ end }}{{ end }}
	return value
}

// set{{ $PropName }} used internal.
func (s *{{ $TypeName }}) set{{ $PropName }}(newValue {{ GetKeyType $key }}) bool {
	oldValue := s.{{ $PropName }}()
	if oldValue == newValue {
		return false
	}

	gs := s.settings
	if !s.hook.WillSet(gs, "{{ $key.Name }}", oldValue, newValue) {
		return false
	}
	defer s.hook.DidSet(gs, "{{ $key.Name }}", oldValue, newValue)

	{{ if $key.IsEnum }}return gs.SetEnum("{{ $key.Name }}", newValue)
	{{ else }}{{ if $key.IsFlags }}return gs.SetFlags("{{ $key.Name }}", newValue)
	{{ else }}return gs.SetValue("{{ $key.Name }}", glib.NewVariant{{ MapTypeSetter $key.Type }}(newValue)){{ end }}{{ end }}
}

// Set{{ $PropName }} sets value of {{ $PropName }} and emit {{$PropName}}Changed signal.
func (s *{{ $TypeName }}) Set{{ $PropName }}(newValue {{ GetKeyType $key }}) {
	s.set{{$PropName}}(newValue)
	dbus.Emit(s, "{{ $PropName }}Changed", newValue)
}
{{ end }}
{{ end }}

{{ end }}

`
<|endoftext|>


<commit_before>package main

import (
	"io"
	"os"
	"encoding/csv"
)

const (
	InputFile  = "source/country.txt"
	OutputFile = "output/country.csv"
)

func main() {
	// File reader
	inputFile, err := os.Open(InputFile)
	if err != nil {
		panic(err)
	}
	defer inputFile.Close()
	reader := csv.NewReader(inputFile)
	reader.Comma = '|'

	// File writer
	outputFile, err := os.Create(OutputFile)
	if err != nil {
		panic(err)
	}
	defer outputFile.Close()
	writer := csv.NewWriter(outputFile)
	defer writer.Flush()

	// Write CSV headers
	writer.Write([]string{"country_code", "country_name", "currency", "postcode_flag"})

	// Process CSV file line by line
	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			panic(err)
		}
		postcode_flag := "False"
		if record[10] == "Y" {
			postcode_flag = "True"
		}
		writer.Write([]string{record[0], record[1], record[8], postcode_flag})
	}
}
<commit_msg>go script for country generates now both csv and json<commit_after>package main

import (
	"encoding/csv"
	"encoding/json"
	"io"
	"os"
)

const (
	InputFileTXT   = "source/country.txt"
	OutputFileCSV  = "output/country.csv"
	OutputFileJSON = "output/country.json"
)

type Country struct {
	CountryCode  string `json:"cc"`
	CountryName  string `json:"cn"`
	Currency     string `json:"cu"`
	PostcodeFlag string `json:"pf"`
}

func main() {
	// File reader
	inputFile, err := os.Open(InputFileTXT)
	if err != nil {
		panic(err)
	}
	defer inputFile.Close()
	reader := csv.NewReader(inputFile)
	reader.Comma = '|'

	// Set up file writer for CSV
	outputFileCSV, err := os.Create(OutputFileCSV)
	if err != nil {
		panic(err)
	}
	defer outputFileCSV.Close()
	csvWriter := csv.NewWriter(outputFileCSV)
	defer csvWriter.Flush()

	// Set up file writer for JSON
	outputFileJSON, err := os.Create(OutputFileJSON)
	if err != nil {
		panic(err)
	}
	defer outputFileJSON.Close()

	// Write CSV headers
	csvWriter.Write([]string{"country_code", "country_name", "currency", "postcode_flag"})

	// Process file line by line
	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			panic(err)
		}
		postcode_flag := "false"
		if record[10] == "Y" {
			postcode_flag = "true"
		}
		// Write CSV record to file
		csvWriter.Write([]string{record[0], record[1], record[8], postcode_flag})
		// Write JSON document to file
		countryStruct := Country{record[0], record[1], record[8], postcode_flag}
		jsonDocument, _ := json.Marshal(countryStruct)
		outputFileJSON.WriteString(string(jsonDocument) + "\n")
	}
}

<|endoftext|>