<commit_before>package gocb

import (
	"gopkg.in/couchbase/gocbcore.v7"
)

const (
	goCbVersionStr = "v1.3.2"
)

const (
	// Legacy flag format for JSON data.
	lfJson = 0

	// Common flags mask
	cfMask = 0xFF000000
	// Common flags mask for data format
	cfFmtMask = 0x0F000000
	// Common flags mask for compression mode.
	cfCmprMask = 0xE0000000

	// Common flag format for sdk-private data.
	cfFmtPrivate = 1 << 24
	// Common flag format for JSON data.
	cfFmtJson = 2 << 24
	// Common flag format for binary data.
	cfFmtBinary = 3 << 24
	// Common flag format for string data.
	cfFmtString = 4 << 24

	// Common flags compression for disabled compression.
	cfCmprNone = 0 << 29
)

// IndexType provides information on the type of indexer used for an index.
type IndexType string

const (
	// IndexTypeN1ql indicates that GSI was used to build the index.
	IndexTypeN1ql = IndexType("gsi")

	// IndexTypeView indicates that views were used to build the index.
	IndexTypeView = IndexType("views")
)

// SubdocFlag provides special handling flags for sub-document operations
type SubdocFlag gocbcore.SubdocFlag

const (
	// SubdocFlagNone indicates no special behaviours
	SubdocFlagNone = SubdocFlag(gocbcore.SubdocFlagNone)

	// SubdocFlagCreatePath indicates you wish to recursively create the tree of paths
	// if it does not already exist within the document.
	SubdocFlagCreatePath = SubdocFlag(gocbcore.SubdocFlagMkDirP)

	// SubdocFlagXattr indicates your path refers to an extended attribute rather than the document.
	SubdocFlagXattr = SubdocFlag(gocbcore.SubdocFlagXattrPath)

	// SubdocFlagUseMacros indicates that you wish macro substitution to occur on the value
	SubdocFlagUseMacros = SubdocFlag(gocbcore.SubdocFlagExpandMacros)
)

// SubdocDocFlag specifies document-level flags for a sub-document operation.
type SubdocDocFlag gocbcore.SubdocDocFlag

const (
	// SubdocDocFlagNone indicates no special behaviours
	SubdocDocFlagNone = SubdocDocFlag(gocbcore.SubdocDocFlagNone)

	// SubdocDocFlagMkDoc indicates that the document should be created if it does not already exist.
	SubdocDocFlagMkDoc = SubdocDocFlag(gocbcore.SubdocDocFlagMkDoc)

	// SubdocDocFlagReplaceDoc indices that this operation should be a replace rather than upsert.
	SubdocDocFlagReplaceDoc = SubdocDocFlag(gocbcore.SubdocDocFlagReplaceDoc)

	// SubdocDocFlagAccessDeleted indicates that you wish to receive soft-deleted documents.
	SubdocDocFlagAccessDeleted = SubdocDocFlag(gocbcore.SubdocDocFlagAccessDeleted)
)

// ServiceType specifies a particular Couchbase service type.
type ServiceType gocbcore.ServiceType

const (
	// MemdService represents a memcached service.
	MemdService = ServiceType(gocbcore.MemdService)

	// MgmtService represents a management service (typically ns_server).
	MgmtService = ServiceType(gocbcore.MgmtService)

	// CapiService represents a CouchAPI service (typically for views).
	CapiService = ServiceType(gocbcore.CapiService)

	// N1qlService represents a N1QL service (typically for query).
	N1qlService = ServiceType(gocbcore.N1qlService)

	// FtsService represents a full-text-search service.
	FtsService = ServiceType(gocbcore.FtsService)

	// CbasService represents an analytics service.
	CbasService = ServiceType(gocbcore.CbasService)
)
<commit_msg>Bump version number to v1.3.3<commit_after>package gocb

import (
	"gopkg.in/couchbase/gocbcore.v7"
)

const (
	goCbVersionStr = "v1.3.3"
)

const (
	// Legacy flag format for JSON data.
	lfJson = 0

	// Common flags mask
	cfMask = 0xFF000000
	// Common flags mask for data format
	cfFmtMask = 0x0F000000
	// Common flags mask for compression mode.
	cfCmprMask = 0xE0000000

	// Common flag format for sdk-private data.
	cfFmtPrivate = 1 << 24
	// Common flag format for JSON data.
	cfFmtJson = 2 << 24
	// Common flag format for binary data.
	cfFmtBinary = 3 << 24
	// Common flag format for string data.
	cfFmtString = 4 << 24

	// Common flags compression for disabled compression.
	cfCmprNone = 0 << 29
)

// IndexType provides information on the type of indexer used for an index.
type IndexType string

const (
	// IndexTypeN1ql indicates that GSI was used to build the index.
	IndexTypeN1ql = IndexType("gsi")

	// IndexTypeView indicates that views were used to build the index.
	IndexTypeView = IndexType("views")
)

// SubdocFlag provides special handling flags for sub-document operations
type SubdocFlag gocbcore.SubdocFlag

const (
	// SubdocFlagNone indicates no special behaviours
	SubdocFlagNone = SubdocFlag(gocbcore.SubdocFlagNone)

	// SubdocFlagCreatePath indicates you wish to recursively create the tree of paths
	// if it does not already exist within the document.
	SubdocFlagCreatePath = SubdocFlag(gocbcore.SubdocFlagMkDirP)

	// SubdocFlagXattr indicates your path refers to an extended attribute rather than the document.
	SubdocFlagXattr = SubdocFlag(gocbcore.SubdocFlagXattrPath)

	// SubdocFlagUseMacros indicates that you wish macro substitution to occur on the value
	SubdocFlagUseMacros = SubdocFlag(gocbcore.SubdocFlagExpandMacros)
)

// SubdocDocFlag specifies document-level flags for a sub-document operation.
type SubdocDocFlag gocbcore.SubdocDocFlag

const (
	// SubdocDocFlagNone indicates no special behaviours
	SubdocDocFlagNone = SubdocDocFlag(gocbcore.SubdocDocFlagNone)

	// SubdocDocFlagMkDoc indicates that the document should be created if it does not already exist.
	SubdocDocFlagMkDoc = SubdocDocFlag(gocbcore.SubdocDocFlagMkDoc)

	// SubdocDocFlagReplaceDoc indices that this operation should be a replace rather than upsert.
	SubdocDocFlagReplaceDoc = SubdocDocFlag(gocbcore.SubdocDocFlagReplaceDoc)

	// SubdocDocFlagAccessDeleted indicates that you wish to receive soft-deleted documents.
	SubdocDocFlagAccessDeleted = SubdocDocFlag(gocbcore.SubdocDocFlagAccessDeleted)
)

// ServiceType specifies a particular Couchbase service type.
type ServiceType gocbcore.ServiceType

const (
	// MemdService represents a memcached service.
	MemdService = ServiceType(gocbcore.MemdService)

	// MgmtService represents a management service (typically ns_server).
	MgmtService = ServiceType(gocbcore.MgmtService)

	// CapiService represents a CouchAPI service (typically for views).
	CapiService = ServiceType(gocbcore.CapiService)

	// N1qlService represents a N1QL service (typically for query).
	N1qlService = ServiceType(gocbcore.N1qlService)

	// FtsService represents a full-text-search service.
	FtsService = ServiceType(gocbcore.FtsService)

	// CbasService represents an analytics service.
	CbasService = ServiceType(gocbcore.CbasService)
)
<|endoftext|>


<commit_before>// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build integration,go1.7

package testing

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
	"testing"
	"text/template"
	"time"

	"cloud.google.com/go/profiler/proftest"
	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	compute "google.golang.org/api/compute/v1"
)

var (
	repo   = flag.String("repo", "https://github.com/googleapis/cloud-profiler-nodejs.git", "git repo to test")
	branch = flag.String("branch", "", "git branch to test")
	commit = flag.String("commit", "", "git commit to test")
	pr     = flag.Int("pr", 0, "git pull request to test")

	runID             = strings.Replace(time.Now().Format("2006-01-02-15-04-05.000000-0700"), ".", "-", -1)
	benchFinishString = "busybench finished profiling"
	errorString       = "failed to set up or run the benchmark"
)

const cloudScope = "https://www.googleapis.com/auth/cloud-platform"

const startupTemplate = `
#! /bin/bash

(

# Signal any unexpected error.
trap 'echo "{{.ErrorString}}"' ERR

# Shut down the VM in 5 minutes after this script exits
# to stop accounting the VM for billing and cores quota.
trap "sleep 300 && poweroff" EXIT

retry() {
  for i in {1..3}; do
    "${@}" && return 0
  done
  return 1
}

npm_install() {
	timeout 60 npm install "${@}"
}

# Fail on any error
set -eo pipefail

# Display commands being run
set -x
# Install git
retry apt-get update >/dev/null
retry apt-get -y -q install git >/dev/null

# Install desired version of Node.js
retry curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash >/dev/null
export NVM_DIR="$HOME/.nvm" >/dev/null
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" >/dev/null

# nvm install writes to stderr and stdout on successful install, so both are
# redirected to serial port 3.
retry nvm install {{.NodeVersion}} &>/dev/ttyS2
npm -v
node -v
NODEDIR=$(dirname $(dirname $(which node)))

# Install agent
retry git clone {{.Repo}}
cd cloud-profiler-nodejs
retry git fetch origin {{if .PR}}pull/{{.PR}}/head{{else}}{{.Branch}}{{end}}:pull_branch
git checkout pull_branch
git reset --hard {{.Commit}}

retry npm_install --nodedir="$NODEDIR" &>/dev/ttyS2

npm run compile
npm pack --nodedir="$NODEDIR" >/dev/null
VERSION=$(node -e "console.log(require('./package.json').version);")
PROFILER="$HOME/cloud-profiler-nodejs/google-cloud-profiler-$VERSION.tgz"

TESTDIR="$HOME/test"
mkdir -p "$TESTDIR"
cp -r "system-test/busybench" "$TESTDIR"
cd "$TESTDIR/busybench"

retry npm_install node-pre-gyp &>/dev/ttyS2
retry npm_install --nodedir="$NODEDIR" "$PROFILER" typescript gts &>/dev/ttyS2

npm run compile

# Run benchmark with agent
GCLOUD_PROFILER_LOGLEVEL=5 GAE_SERVICE={{.Service}} node --trace-warnings build/src/busybench.js 600

# Indicate to test that script has finished running
echo "{{.FinishString}}"

# Write output to serial port 2 with timestamp.
) 2>&1 | while read line; do echo "$(date): ${line}"; done >/dev/ttyS1
`

type profileSummary struct {
	profileType  string
	functionName string
	sourceFile   string
}

type nodeGCETestCase struct {
	proftest.InstanceConfig
	name         string
	nodeVersion  string
	wantProfiles []profileSummary
}

func (tc *nodeGCETestCase) initializeStartUpScript(template *template.Template) error {
	var buf bytes.Buffer
	err := template.Execute(&buf,
		struct {
			Service      string
			NodeVersion  string
			Repo         string
			PR           int
			Branch       string
			Commit       string
			FinishString string
			ErrorString  string
		}{
			Service:      tc.name,
			NodeVersion:  tc.nodeVersion,
			Repo:         *repo,
			PR:           *pr,
			Branch:       *branch,
			Commit:       *commit,
			FinishString: benchFinishString,
			ErrorString:  errorString,
		})
	if err != nil {
		return fmt.Errorf("failed to render startup script for %s: %v", tc.name, err)
	}
	tc.StartupScript = buf.String()
	return nil
}

func TestAgentIntegration(t *testing.T) {
	projectID := os.Getenv("GCLOUD_TESTS_NODEJS_PROJECT_ID")
	if projectID == "" {
		t.Fatalf("Getenv(GCLOUD_TESTS_NODEJS_PROJECT_ID) got empty string")
	}

	zone := os.Getenv("GCLOUD_TESTS_NODEJS_ZONE")
	if zone == "" {
		t.Fatalf("Getenv(GCLOUD_TESTS_NODEJS_ZONE) got empty string")
	}

	if *commit == "" {
		t.Fatal("commit flag is not set")
	}

	ctx := context.Background()

	client, err := google.DefaultClient(ctx, cloudScope)
	if err != nil {
		t.Fatalf("failed to get default client: %v", err)
	}

	computeService, err := compute.New(client)
	if err != nil {
		t.Fatalf("failed to initialize compute Service: %v", err)
	}

	template, err := template.New("startupScript").Parse(startupTemplate)
	if err != nil {
		t.Fatalf("failed to parse startup script template: %v", err)
	}

	gceTr := proftest.GCETestRunner{
		TestRunner: proftest.TestRunner{
			Client: client,
		},
		ComputeService: computeService,
	}

	wantProfiles := []profileSummary{
		{"WALL", "busyLoop", "busybench.ts"},
		{"HEAP", "benchmark", "busybench.ts"},
	}

	testcases := []nodeGCETestCase{
		{
			InstanceConfig: proftest.InstanceConfig{
				ProjectID:   projectID,
				Zone:        zone,
				Name:        fmt.Sprintf("profiler-test-node8-%s", runID),
				MachineType: "n1-standard-1",
			},
			name:         fmt.Sprintf("profiler-test-node8-%s-gce", runID),
			wantProfiles: wantProfiles,
			nodeVersion:  "8",
		},
		{
			InstanceConfig: proftest.InstanceConfig{
				ProjectID:   projectID,
				Zone:        zone,
				Name:        fmt.Sprintf("profiler-test-node10-%s", runID),
				MachineType: "n1-standard-1",
			},
			name:         fmt.Sprintf("profiler-test-node10-%s-gce", runID),
			wantProfiles: wantProfiles,
			nodeVersion:  "10",
		},
		{
			InstanceConfig: proftest.InstanceConfig{
				ProjectID:   projectID,
				Zone:        zone,
				Name:        fmt.Sprintf("profiler-test-node11-%s", runID),
				MachineType: "n1-standard-1",
			},
			name:         fmt.Sprintf("profiler-test-node11-%s-gce", runID),
			wantProfiles: wantProfiles,
			nodeVersion:  "11",
		},
	}

	// Allow test cases to run in parallel.
	runtime.GOMAXPROCS(len(testcases))

	for _, tc := range testcases {
		tc := tc // capture range variable
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			if err := tc.initializeStartUpScript(template); err != nil {
				t.Fatalf("failed to initialize startup script: %v", err)
			}

			gceTr.StartInstance(ctx, &tc.InstanceConfig)
			defer func() {
				if gceTr.DeleteInstance(ctx, &tc.InstanceConfig); err != nil {
					t.Fatal(err)
				}
			}()

			timeoutCtx, cancel := context.WithTimeout(ctx, time.Minute*25)
			defer cancel()
			if err := gceTr.PollForSerialOutput(timeoutCtx, &tc.InstanceConfig, benchFinishString, errorString); err != nil {
				t.Fatal(err)
			}

			timeNow := time.Now()
			endTime := timeNow.Format(time.RFC3339)
			startTime := timeNow.Add(-1 * time.Hour).Format(time.RFC3339)
			for _, wantProfile := range tc.wantProfiles {
				pr, err := gceTr.TestRunner.QueryProfiles(tc.ProjectID, tc.name, startTime, endTime, wantProfile.profileType)
				if err != nil {
					t.Errorf("QueryProfiles(%s, %s, %s, %s, %s) got error: %v", tc.ProjectID, tc.name, startTime, endTime, wantProfile.profileType, err)
					continue
				}
				if wantProfile.sourceFile != "" {
					if err := pr.HasFunctionInFile(wantProfile.functionName, wantProfile.sourceFile); err != nil {
						t.Errorf("Function %s not found in source file %s in profiles of type %s: %v", wantProfile.functionName, wantProfile.sourceFile, wantProfile.profileType, err)
					}
					continue
				}
				if err := pr.HasFunction(wantProfile.functionName); err != nil {
					t.Errorf("Function %s not found in profiles of type %s: %v", wantProfile.functionName, wantProfile.profileType, err)
				}
			}
		})
	}
}
<commit_msg>build: share some code for E2E tests (#505)<commit_after>// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build integration,go1.7

package testing

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
	"testing"
	"text/template"
	"time"

	"cloud.google.com/go/profiler/proftest"
	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	compute "google.golang.org/api/compute/v1"
)

var (
	repo   = flag.String("repo", "https://github.com/googleapis/cloud-profiler-nodejs.git", "git repo to test")
	branch = flag.String("branch", "", "git branch to test")
	commit = flag.String("commit", "", "git commit to test")
	pr     = flag.Int("pr", 0, "git pull request to test")

	runID             = strings.Replace(time.Now().Format("2006-01-02-15-04-05.000000-0700"), ".", "-", -1)
	benchFinishString = "busybench finished profiling"
	errorString       = "failed to set up or run the benchmark"
)

const cloudScope = "https://www.googleapis.com/auth/cloud-platform"

const startupTemplate = `
{{- template "prologue" . }}

npm_install() {
	timeout 60 npm install "${@}"
}

# Install git
retry apt-get update >/dev/null
retry apt-get -y -q install git >/dev/null

# Install desired version of Node.js
retry curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash >/dev/null
export NVM_DIR="$HOME/.nvm" >/dev/null
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" >/dev/null

# nvm install writes to stderr and stdout on successful install, so both are
# redirected to serial port 3.
retry nvm install {{.NodeVersion}} &>/dev/ttyS2
npm -v
node -v
NODEDIR=$(dirname $(dirname $(which node)))

# Install agent
retry git clone {{.Repo}}
cd cloud-profiler-nodejs
retry git fetch origin {{if .PR}}pull/{{.PR}}/head{{else}}{{.Branch}}{{end}}:pull_branch
git checkout pull_branch
git reset --hard {{.Commit}}

retry npm_install --nodedir="$NODEDIR" &>/dev/ttyS2

npm run compile
npm pack --nodedir="$NODEDIR" >/dev/null
VERSION=$(node -e "console.log(require('./package.json').version);")
PROFILER="$HOME/cloud-profiler-nodejs/google-cloud-profiler-$VERSION.tgz"

TESTDIR="$HOME/test"
mkdir -p "$TESTDIR"
cp -r "system-test/busybench" "$TESTDIR"
cd "$TESTDIR/busybench"

retry npm_install node-pre-gyp &>/dev/ttyS2
retry npm_install --nodedir="$NODEDIR" "$PROFILER" typescript gts &>/dev/ttyS2

npm run compile

# Run benchmark with agent
GCLOUD_PROFILER_LOGLEVEL=5 GAE_SERVICE={{.Service}} node --trace-warnings build/src/busybench.js 600

# Indicate to test that script has finished running
echo "{{.FinishString}}"

{{ template "epilogue" . -}}
`

type profileSummary struct {
	profileType  string
	functionName string
	sourceFile   string
}

type nodeGCETestCase struct {
	proftest.InstanceConfig
	name         string
	nodeVersion  string
	wantProfiles []profileSummary
}

func (tc *nodeGCETestCase) initializeStartUpScript(template *template.Template) error {
	var buf bytes.Buffer
	err := template.Execute(&buf,
		struct {
			Service      string
			NodeVersion  string
			Repo         string
			PR           int
			Branch       string
			Commit       string
			FinishString string
			ErrorString  string
		}{
			Service:      tc.name,
			NodeVersion:  tc.nodeVersion,
			Repo:         *repo,
			PR:           *pr,
			Branch:       *branch,
			Commit:       *commit,
			FinishString: benchFinishString,
			ErrorString:  errorString,
		})
	if err != nil {
		return fmt.Errorf("failed to render startup script for %s: %v", tc.name, err)
	}
	tc.StartupScript = buf.String()
	return nil
}

func TestAgentIntegration(t *testing.T) {
	projectID := os.Getenv("GCLOUD_TESTS_NODEJS_PROJECT_ID")
	if projectID == "" {
		t.Fatalf("Getenv(GCLOUD_TESTS_NODEJS_PROJECT_ID) got empty string")
	}

	zone := os.Getenv("GCLOUD_TESTS_NODEJS_ZONE")
	if zone == "" {
		t.Fatalf("Getenv(GCLOUD_TESTS_NODEJS_ZONE) got empty string")
	}

	if *commit == "" {
		t.Fatal("commit flag is not set")
	}

	ctx := context.Background()

	client, err := google.DefaultClient(ctx, cloudScope)
	if err != nil {
		t.Fatalf("failed to get default client: %v", err)
	}

	computeService, err := compute.New(client)
	if err != nil {
		t.Fatalf("failed to initialize compute Service: %v", err)
	}

	template, err := proftest.BaseStartupTmpl.Parse(startupTemplate)
	if err != nil {
		t.Fatalf("failed to parse startup script template: %v", err)
	}

	gceTr := proftest.GCETestRunner{
		TestRunner: proftest.TestRunner{
			Client: client,
		},
		ComputeService: computeService,
	}

	wantProfiles := []profileSummary{
		{"WALL", "busyLoop", "busybench.ts"},
		{"HEAP", "benchmark", "busybench.ts"},
	}

	testcases := []nodeGCETestCase{
		{
			InstanceConfig: proftest.InstanceConfig{
				ProjectID:   projectID,
				Zone:        zone,
				Name:        fmt.Sprintf("profiler-test-node8-%s", runID),
				MachineType: "n1-standard-1",
			},
			name:         fmt.Sprintf("profiler-test-node8-%s-gce", runID),
			wantProfiles: wantProfiles,
			nodeVersion:  "8",
		},
		{
			InstanceConfig: proftest.InstanceConfig{
				ProjectID:   projectID,
				Zone:        zone,
				Name:        fmt.Sprintf("profiler-test-node10-%s", runID),
				MachineType: "n1-standard-1",
			},
			name:         fmt.Sprintf("profiler-test-node10-%s-gce", runID),
			wantProfiles: wantProfiles,
			nodeVersion:  "10",
		},
		{
			InstanceConfig: proftest.InstanceConfig{
				ProjectID:   projectID,
				Zone:        zone,
				Name:        fmt.Sprintf("profiler-test-node11-%s", runID),
				MachineType: "n1-standard-1",
			},
			name:         fmt.Sprintf("profiler-test-node11-%s-gce", runID),
			wantProfiles: wantProfiles,
			nodeVersion:  "11",
		},
	}

	// Allow test cases to run in parallel.
	runtime.GOMAXPROCS(len(testcases))

	for _, tc := range testcases {
		tc := tc // capture range variable
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			if err := tc.initializeStartUpScript(template); err != nil {
				t.Fatalf("failed to initialize startup script: %v", err)
			}

			gceTr.StartInstance(ctx, &tc.InstanceConfig)
			defer func() {
				if gceTr.DeleteInstance(ctx, &tc.InstanceConfig); err != nil {
					t.Fatal(err)
				}
			}()

			timeoutCtx, cancel := context.WithTimeout(ctx, time.Minute*25)
			defer cancel()
			if err := gceTr.PollForSerialOutput(timeoutCtx, &tc.InstanceConfig, benchFinishString, errorString); err != nil {
				t.Fatal(err)
			}

			timeNow := time.Now()
			endTime := timeNow.Format(time.RFC3339)
			startTime := timeNow.Add(-1 * time.Hour).Format(time.RFC3339)
			for _, wantProfile := range tc.wantProfiles {
				pr, err := gceTr.TestRunner.QueryProfiles(tc.ProjectID, tc.name, startTime, endTime, wantProfile.profileType)
				if err != nil {
					t.Errorf("QueryProfiles(%s, %s, %s, %s, %s) got error: %v", tc.ProjectID, tc.name, startTime, endTime, wantProfile.profileType, err)
					continue
				}
				if wantProfile.sourceFile != "" {
					if err := pr.HasFunctionInFile(wantProfile.functionName, wantProfile.sourceFile); err != nil {
						t.Errorf("Function %s not found in source file %s in profiles of type %s: %v", wantProfile.functionName, wantProfile.sourceFile, wantProfile.profileType, err)
					}
					continue
				}
				if err := pr.HasFunction(wantProfile.functionName); err != nil {
					t.Errorf("Function %s not found in profiles of type %s: %v", wantProfile.functionName, wantProfile.profileType, err)
				}
			}
		})
	}
}
<|endoftext|>


<commit_before>package poker

import (
	. "github.com/dohodges/fifty2"
	"reflect"
	"testing"
)

func BenchmarkGetHandStrength5(b *testing.B) {
	deck := NewDeck()
	for i := 0; i < b.N; i++ {
		Shuffle(deck)
		hand := deck[:5]
		GetHandStrength(hand)
	}
}

func BenchmarkGetHandStrength7(b *testing.B) {
	deck := NewDeck()
	for i := 0; i < b.N; i++ {
		Shuffle(deck)
		hand := deck[:7]
		GetHandStrength(hand)
	}
}

func BenchmarkGetHandStrength13(b *testing.B) {
	deck := NewDeck()
	for i := 0; i < b.N; i++ {
		Shuffle(deck)
		hand := deck[:13]
		GetHandStrength(hand)
	}
}

func TestStraightFlush(t *testing.T) {
	h := []Card{
		Card{Ace, Spades},
		Card{King, Spades},
		Card{Queen, Spades},
		Card{Jack, Spades},
		Card{Ten, Spades},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{StraightFlush, []CardStrength{AceHigh}})
	assertStrength(t, GetLowHandStrength(h), HandStrength{HighCard, []CardStrength{
		CardStrength(King),
		CardStrength(Queen),
		CardStrength(Jack),
		CardStrength(Ten),
		AceLow,
	}})

	h = []Card{
		Card{Ace, Clubs},
		Card{Two, Clubs},
		Card{Three, Clubs},
		Card{Four, Clubs},
		Card{Five, Clubs},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{StraightFlush, []CardStrength{CardStrength(Five)}})
	assertStrength(t, GetLowHandStrength(h), HandStrength{HighCard, []CardStrength{
		CardStrength(Five),
		CardStrength(Four),
		CardStrength(Three),
		CardStrength(Two),
		AceLow,
	}})
}

func TestQuads(t *testing.T) {
	h := []Card{
		Card{Seven, Clubs},
		Card{King, Hearts},
		Card{King, Clubs},
		Card{King, Diamonds},
		Card{King, Spades},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{Quads, []CardStrength{
		CardStrength(King),
		CardStrength(Seven),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{Quads, []CardStrength{
		CardStrength(King),
		CardStrength(Seven),
	}})
}

func TestFullHouse(t *testing.T) {
	h := []Card{
		Card{Five, Clubs},
		Card{Five, Diamonds},
		Card{Eight, Spades},
		Card{Five, Spades},
		Card{Eight, Clubs},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{FullHouse, []CardStrength{
		CardStrength(Five),
		CardStrength(Eight),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{FullHouse, []CardStrength{
		CardStrength(Five),
		CardStrength(Eight),
	}})
}

func TestFlush(t *testing.T) {
	h := []Card{
		Card{Two, Hearts},
		Card{Three, Hearts},
		Card{Ten, Hearts},
		Card{Four, Hearts},
		Card{Jack, Hearts},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{Flush, []CardStrength{
		CardStrength(Jack),
		CardStrength(Ten),
		CardStrength(Four),
		CardStrength(Three),
		CardStrength(Two),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{HighCard, []CardStrength{
		CardStrength(Jack),
		CardStrength(Ten),
		CardStrength(Four),
		CardStrength(Three),
		CardStrength(Two),
	}})
}

func TestStraight(t *testing.T) {
	h := []Card{
		Card{Eight, Hearts},
		Card{Nine, Spades},
		Card{Jack, Hearts},
		Card{Ten, Spades},
		Card{Seven, Diamonds},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{Straight, []CardStrength{CardStrength(Jack)}})
	assertStrength(t, GetLowHandStrength(h), HandStrength{HighCard, []CardStrength{
		CardStrength(Jack),
		CardStrength(Ten),
		CardStrength(Nine),
		CardStrength(Eight),
		CardStrength(Seven),
	}})
}

func TestTrips(t *testing.T) {
	h := []Card{
		Card{Nine, Hearts},
		Card{Eight, Spades},
		Card{Nine, Spades},
		Card{Four, Clubs},
		Card{Nine, Clubs},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{Trips, []CardStrength{
		CardStrength(Nine),
		CardStrength(Eight),
		CardStrength(Four),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{Trips, []CardStrength{
		CardStrength(Nine),
		CardStrength(Eight),
		CardStrength(Four),
	}})
}

func TestTwoPair(t *testing.T) {
	h := []Card{
		Card{Seven, Hearts},
		Card{Two, Spades},
		Card{Two, Clubs},
		Card{King, Diamonds},
		Card{Seven, Clubs},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{TwoPair, []CardStrength{
		CardStrength(Seven),
		CardStrength(Two),
		CardStrength(King),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{TwoPair, []CardStrength{
		CardStrength(Seven),
		CardStrength(Two),
		CardStrength(King),
	}})
}

func TestPair(t *testing.T) {
	h := []Card{
		Card{Ace, Hearts},
		Card{King, Hearts},
		Card{Seven, Diamonds},
		Card{Ace, Clubs},
		Card{Two, Hearts},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{Pair, []CardStrength{
		AceHigh,
		CardStrength(King),
		CardStrength(Seven),
		CardStrength(Two),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{Pair, []CardStrength{
		AceLow,
		CardStrength(King),
		CardStrength(Seven),
		CardStrength(Two),
	}})
}

func TestHighCard(t *testing.T) {
	h := []Card{
		Card{Seven, Spades},
		Card{Queen, Diamonds},
		Card{Two, Hearts},
		Card{Ace, Spades},
		Card{Three, Clubs},
	}

	assertStrength(t, GetHandStrength(h), HandStrength{HighCard, []CardStrength{
		AceHigh,
		CardStrength(Queen),
		CardStrength(Seven),
		CardStrength(Three),
		CardStrength(Two),
	}})

	assertStrength(t, GetLowHandStrength(h), HandStrength{HighCard, []CardStrength{
		CardStrength(Queen),
		CardStrength(Seven),
		CardStrength(Three),
		CardStrength(Two),
		AceLow,
	}})
}

func assertStrength(t *testing.T, actual, expect HandStrength) {
	if !reflect.DeepEqual(expect, actual) {
		t.Errorf("expected - %v\nactual - %v", expect, actual)
	}
}
<commit_msg>update tests<commit_after>package poker

import (
	. "github.com/dohodges/fifty2"
	"testing"
)

func BenchmarkGetHandStrength5(b *testing.B) {
	deck := NewDeck()
	for i := 0; i < b.N; i++ {
		Shuffle(deck)
		hand := deck[:5]
		GetHandStrength(hand)
	}
}

func BenchmarkGetHandStrength7(b *testing.B) {
	deck := NewDeck()
	for i := 0; i < b.N; i++ {
		Shuffle(deck)
		hand := deck[:7]
		GetHandStrength(hand)
	}
}

func BenchmarkGetHandStrength13(b *testing.B) {
	deck := NewDeck()
	for i := 0; i < b.N; i++ {
		Shuffle(deck)
		hand := deck[:13]
		GetHandStrength(hand)
	}
}

func TestStraightFlush(t *testing.T) {
	h := []Card{
		Card{Ace, Spades},
		Card{King, Spades},
		Card{Queen, Spades},
		Card{Jack, Spades},
		Card{Ten, Spades},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(StraightFlush, AceHigh, 0, 0))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(HighCard, 0, 0, 0x1E01))

	h = []Card{
		Card{Ace, Clubs},
		Card{Two, Clubs},
		Card{Three, Clubs},
		Card{Four, Clubs},
		Card{Five, Clubs},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(StraightFlush, CardStrength(Five), 0, 0))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(HighCard, 0, 0, 0x001F))
}

func TestQuads(t *testing.T) {
	h := []Card{
		Card{Seven, Clubs},
		Card{King, Hearts},
		Card{King, Clubs},
		Card{King, Diamonds},
		Card{King, Spades},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(Quads, CardStrength(King), 0, 0x0040))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(Quads, CardStrength(King), 0, 0x0040))
}

func TestFullHouse(t *testing.T) {
	h := []Card{
		Card{Five, Clubs},
		Card{Five, Diamonds},
		Card{Eight, Spades},
		Card{Five, Spades},
		Card{Eight, Clubs},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(FullHouse, CardStrength(Five), CardStrength(Eight), 0))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(FullHouse, CardStrength(Five), CardStrength(Eight), 0))
}

func TestFlush(t *testing.T) {
	h := []Card{
		Card{Two, Hearts},
		Card{Three, Hearts},
		Card{Ten, Hearts},
		Card{Four, Hearts},
		Card{Jack, Hearts},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(Flush, 0, 0, 0x060E))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(HighCard, 0, 0, 0x060E))
}

func TestStraight(t *testing.T) {
	h := []Card{
		Card{Eight, Hearts},
		Card{Nine, Spades},
		Card{Jack, Hearts},
		Card{Ten, Spades},
		Card{Seven, Diamonds},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(Straight, CardStrength(Jack), 0, 0))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(HighCard, 0, 0, 0x07C0))
}

func TestTrips(t *testing.T) {
	h := []Card{
		Card{Nine, Hearts},
		Card{Eight, Spades},
		Card{Nine, Spades},
		Card{Four, Clubs},
		Card{Nine, Clubs},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(Trips, CardStrength(Nine), 0, 0x088))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(Trips, CardStrength(Nine), 0, 0x088))
}

func TestTwoPair(t *testing.T) {
	h := []Card{
		Card{Seven, Hearts},
		Card{Two, Spades},
		Card{Two, Clubs},
		Card{King, Diamonds},
		Card{Seven, Clubs},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(TwoPair, CardStrength(Seven), CardStrength(Two), 0x1000))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(TwoPair, CardStrength(Seven), CardStrength(Two), 0x1000))
}

func TestPair(t *testing.T) {
	h := []Card{
		Card{Ace, Hearts},
		Card{King, Hearts},
		Card{Seven, Diamonds},
		Card{Ace, Clubs},
		Card{Two, Hearts},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(Pair, AceHigh, 0, 0x1042))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(Pair, AceLow, 0, 0x1042))
}

func TestHighCard(t *testing.T) {
	h := []Card{
		Card{Seven, Spades},
		Card{Queen, Diamonds},
		Card{Two, Hearts},
		Card{Ace, Spades},
		Card{Three, Clubs},
	}

	assertStrength(t, GetHandStrength(h), MakeHandStrength(HighCard, 0, 0, 0x2846))
	assertStrength(t, GetLowHandStrength(h), MakeHandStrength(HighCard, 0, 0, 0x0847))
}

func assertStrength(t *testing.T, actual, expect HandStrength) {
	if expect != actual {
		t.Errorf("expected - %#X\nactual - %#X", expect, actual)
	}
}
<|endoftext|>


<commit_before>package base

import (
	"math/big"
	"strings"
)

const (
	CHARSET_D = 1
	CHARSET_U = 2
	CHARSET_L = 4
	CHARSET_S = 8

	CHARS_D = "0123456789"
	CHARS_U = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	CHARS_L = "abcdefghijklmnopqrstuvwxyz"
	CHARS_S = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
)

var CHARSETS, CHARSETS_LEN [4]int

type CharsetInfo struct {
	Chars map[int]string
	Len   map[int]int
}

var MaskInfo []CharsetInfo

func (charset CharsetInfo) count(charsetMask int) uint {
	var cnt uint

	if (charsetMask & CHARSET_D) == CHARSET_D {
		if charset.Len[CHARSET_D] > 0 {
			cnt += uint(charset.Len[CHARSET_D])
		}
	}

	if (charsetMask & CHARSET_U) == CHARSET_U {
		if charset.Len[CHARSET_U] > 0 {
			cnt += uint(charset.Len[CHARSET_U])
		}
	}

	if (charsetMask & CHARSET_L) == CHARSET_L {
		if charset.Len[CHARSET_L] > 0 {
			cnt += uint(charset.Len[CHARSET_L])
		}
	}

	if (charsetMask & CHARSET_S) == CHARSET_S {
		if charset.Len[CHARSET_S] > 0 {
			cnt += uint(charset.Len[CHARSET_S])
		}
	}

	return cnt
}

func InitBase() {
	CHARSETS[0] = CHARSET_D
	CHARSETS[1] = CHARSET_U
	CHARSETS[2] = CHARSET_L
	CHARSETS[3] = CHARSET_S

	CHARSETS_LEN[0] = len(CHARS_D)
	CHARSETS_LEN[1] = len(CHARS_U)
	CHARSETS_LEN[2] = len(CHARS_L)
	CHARSETS_LEN[3] = len(CHARS_S)
}

func GetCharsetName(id int) string {
	switch id {
	case CHARSET_D:
		return "?d"
	case CHARSET_U:
		return "?u"
	case CHARSET_L:
		return "?l"
	case CHARSET_S:
		return "?s"
	default:
		return ""
	}
}

func combination(maskLen int, posMask *map[int]int, charsetMask int) *big.Int {
	cnt := big.NewInt(1)

	zeroInt := big.NewInt(0)
	for l := 0; l < maskLen; l++ {
		mask := charsetMask
		if posMask != nil {
			if _, ok := (*posMask)[l]; ok {
				mask &= (*posMask)[l]
			}
		}

		cnt.Mul(cnt, big.NewInt(int64(MaskInfo[l].count(mask))))
		if cnt.Cmp(zeroInt) == 0 {
			break
		}
	}

	return cnt
}

func PolicyCombination(maskLen int, posMask *map[int]int) *big.Int {
	result := big.NewInt(0)

	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U+CHARSET_L+CHARSET_S))

	result.Sub(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U+CHARSET_L))
	result.Sub(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U+CHARSET_S))
	result.Sub(result, combination(maskLen, posMask, CHARSET_D+CHARSET_L+CHARSET_S))
	result.Sub(result, combination(maskLen, posMask, CHARSET_U+CHARSET_L+CHARSET_S))

	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U))
	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_L))
	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_S))
	result.Add(result, combination(maskLen, posMask, CHARSET_U+CHARSET_L))
	result.Add(result, combination(maskLen, posMask, CHARSET_U+CHARSET_S))
	result.Add(result, combination(maskLen, posMask, CHARSET_L+CHARSET_S))

	result.Sub(result, combination(maskLen, posMask, CHARSET_D))
	result.Sub(result, combination(maskLen, posMask, CHARSET_U))
	result.Sub(result, combination(maskLen, posMask, CHARSET_L))
	result.Sub(result, combination(maskLen, posMask, CHARSET_S))

	return result
}

func ParseChars(chars string) CharsetInfo {
	var d, u, l, s string

	chars = strings.Replace(chars, "?d", CHARS_D, -1)
	chars = strings.Replace(chars, "?u", CHARS_U, -1)
	chars = strings.Replace(chars, "?l", CHARS_L, -1)
	chars = strings.Replace(chars, "?s", CHARS_S, -1)
	chars = strings.Replace(chars, "?a", CHARS_D+CHARS_U+CHARS_L+CHARS_S, -1)
	chars = strings.Replace(chars, "??", "?", -1)

	chars = RemoveDups(chars)

	for _, c := range chars {
		switch {
		case (47 < c) && (c < 58): // 48 <= digit <= 57
			d += string(c)
		case (64 < c) && (c < 91): // 65 <= upper <= 90
			u += string(c)
		case (96 < c) && (c < 123): // 97 <= upper <= 122
			l += string(c)
		case (31 < c) && (c < 127): // 32 <= printable <= 126
			s += string(c)
		}
	}

	var charset CharsetInfo
	charset.Chars = make(map[int]string)
	charset.Len = make(map[int]int)

	if len(d) > 0 {
		charset.Chars[CHARSET_D] = d
		charset.Len[CHARSET_D] = len(d)
	}

	if len(u) > 0 {
		charset.Chars[CHARSET_U] = u
		charset.Len[CHARSET_U] = len(u)
	}

	if len(l) > 0 {
		charset.Chars[CHARSET_L] = l
		charset.Len[CHARSET_L] = len(l)
	}

	if len(s) > 0 {
		charset.Chars[CHARSET_S] = s
		charset.Len[CHARSET_S] = len(s)
	}

	return charset
}

func RemoveDups(str string) string {
	for _, c := range str {
		cnt := strings.Count(str, string(c))
		if cnt > 1 {
			str = strings.Replace(str, string(c), "", cnt-1)
		}
	}

	return str
}

func NextMaskPos(min *int, max *int, maskPos *map[int]int, maskCharset *[][]int) bool {
	(*maskPos)[*min-1]++

	for ; *min <= *max; *min++ {
		for {
			l := *min - 1
			for (*maskPos)[l] < len((*maskCharset)[l]) {
				maskCheck := 0
				for j := 0; (j < *min) && ((maskCheck & 15) != 15); j++ {
					maskCheck |= (*maskCharset)[j][(*maskPos)[j]]
				}
				if (maskCheck & 15) == 15 { // Valid mask
					return true
				}

				(*maskPos)[l]++
			}

			for l > 0 {
				(*maskPos)[l] = 0

				l--
				(*maskPos)[l]++
				if (*maskPos)[l] < len((*maskCharset)[l]) {
					l++ // ++ for last break check (l == 0)
					break
				}
			}
			if l == 0 {
				break
			}
		}
	}

	return false
}

func GetMask(maskLen int, posMask *map[int]int) string {
	mask := ""

	for l := 0; l < maskLen; l++ {
		if posMask != nil {
			if _, ok := (*posMask)[l]; ok {
				mask += MaskInfo[l].Chars[(*posMask)[l]]
				continue
			}
		}

		for ic := 0; ic < 4; ic++ {
			if MaskInfo[l].Len[CHARSETS[ic]] > 0 {
				mask += MaskInfo[l].Chars[CHARSETS[ic]]
				break
			}
		}
	}

	return mask
}
<commit_msg>Update comment!<commit_after>package base

import (
	"math/big"
	"strings"
)

const (
	CHARSET_D = 1
	CHARSET_U = 2
	CHARSET_L = 4
	CHARSET_S = 8

	CHARS_D = "0123456789"
	CHARS_U = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	CHARS_L = "abcdefghijklmnopqrstuvwxyz"
	CHARS_S = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
)

var CHARSETS, CHARSETS_LEN [4]int

type CharsetInfo struct {
	Chars map[int]string
	Len   map[int]int
}

var MaskInfo []CharsetInfo

func (charset CharsetInfo) count(charsetMask int) uint {
	var cnt uint

	if (charsetMask & CHARSET_D) == CHARSET_D {
		if charset.Len[CHARSET_D] > 0 {
			cnt += uint(charset.Len[CHARSET_D])
		}
	}

	if (charsetMask & CHARSET_U) == CHARSET_U {
		if charset.Len[CHARSET_U] > 0 {
			cnt += uint(charset.Len[CHARSET_U])
		}
	}

	if (charsetMask & CHARSET_L) == CHARSET_L {
		if charset.Len[CHARSET_L] > 0 {
			cnt += uint(charset.Len[CHARSET_L])
		}
	}

	if (charsetMask & CHARSET_S) == CHARSET_S {
		if charset.Len[CHARSET_S] > 0 {
			cnt += uint(charset.Len[CHARSET_S])
		}
	}

	return cnt
}

func InitBase() {
	CHARSETS[0] = CHARSET_D
	CHARSETS[1] = CHARSET_U
	CHARSETS[2] = CHARSET_L
	CHARSETS[3] = CHARSET_S

	CHARSETS_LEN[0] = len(CHARS_D)
	CHARSETS_LEN[1] = len(CHARS_U)
	CHARSETS_LEN[2] = len(CHARS_L)
	CHARSETS_LEN[3] = len(CHARS_S)
}

func GetCharsetName(id int) string {
	switch id {
	case CHARSET_D:
		return "?d"
	case CHARSET_U:
		return "?u"
	case CHARSET_L:
		return "?l"
	case CHARSET_S:
		return "?s"
	default:
		return ""
	}
}

func combination(maskLen int, posMask *map[int]int, charsetMask int) *big.Int {
	cnt := big.NewInt(1)

	zeroInt := big.NewInt(0)
	for l := 0; l < maskLen; l++ {
		mask := charsetMask
		if posMask != nil {
			if _, ok := (*posMask)[l]; ok {
				mask &= (*posMask)[l]
			}
		}

		cnt.Mul(cnt, big.NewInt(int64(MaskInfo[l].count(mask))))
		if cnt.Cmp(zeroInt) == 0 {
			break
		}
	}

	return cnt
}

func PolicyCombination(maskLen int, posMask *map[int]int) *big.Int {
	result := big.NewInt(0)

	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U+CHARSET_L+CHARSET_S))

	result.Sub(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U+CHARSET_L))
	result.Sub(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U+CHARSET_S))
	result.Sub(result, combination(maskLen, posMask, CHARSET_D+CHARSET_L+CHARSET_S))
	result.Sub(result, combination(maskLen, posMask, CHARSET_U+CHARSET_L+CHARSET_S))

	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_U))
	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_L))
	result.Add(result, combination(maskLen, posMask, CHARSET_D+CHARSET_S))
	result.Add(result, combination(maskLen, posMask, CHARSET_U+CHARSET_L))
	result.Add(result, combination(maskLen, posMask, CHARSET_U+CHARSET_S))
	result.Add(result, combination(maskLen, posMask, CHARSET_L+CHARSET_S))

	result.Sub(result, combination(maskLen, posMask, CHARSET_D))
	result.Sub(result, combination(maskLen, posMask, CHARSET_U))
	result.Sub(result, combination(maskLen, posMask, CHARSET_L))
	result.Sub(result, combination(maskLen, posMask, CHARSET_S))

	return result
}

func ParseChars(chars string) CharsetInfo {
	var d, u, l, s string

	chars = strings.Replace(chars, "?d", CHARS_D, -1)
	chars = strings.Replace(chars, "?u", CHARS_U, -1)
	chars = strings.Replace(chars, "?l", CHARS_L, -1)
	chars = strings.Replace(chars, "?s", CHARS_S, -1)
	chars = strings.Replace(chars, "?a", CHARS_D+CHARS_U+CHARS_L+CHARS_S, -1)
	chars = strings.Replace(chars, "??", "?", -1)

	chars = RemoveDups(chars)

	for _, c := range chars {
		switch {
		case (47 < c) && (c < 58): // 48 <= digit <= 57
			d += string(c)
		case (64 < c) && (c < 91): // 65 <= upper <= 90
			u += string(c)
		case (96 < c) && (c < 123): // 97 <= lower <= 122
			l += string(c)
		case (31 < c) && (c < 127): // 32 <= printable <= 126
			s += string(c)
		}
	}

	var charset CharsetInfo
	charset.Chars = make(map[int]string)
	charset.Len = make(map[int]int)

	if len(d) > 0 {
		charset.Chars[CHARSET_D] = d
		charset.Len[CHARSET_D] = len(d)
	}

	if len(u) > 0 {
		charset.Chars[CHARSET_U] = u
		charset.Len[CHARSET_U] = len(u)
	}

	if len(l) > 0 {
		charset.Chars[CHARSET_L] = l
		charset.Len[CHARSET_L] = len(l)
	}

	if len(s) > 0 {
		charset.Chars[CHARSET_S] = s
		charset.Len[CHARSET_S] = len(s)
	}

	return charset
}

func RemoveDups(str string) string {
	for _, c := range str {
		cnt := strings.Count(str, string(c))
		if cnt > 1 {
			str = strings.Replace(str, string(c), "", cnt-1)
		}
	}

	return str
}

func NextMaskPos(min *int, max *int, maskPos *map[int]int, maskCharset *[][]int) bool {
	(*maskPos)[*min-1]++

	for ; *min <= *max; *min++ {
		for {
			l := *min - 1
			for (*maskPos)[l] < len((*maskCharset)[l]) {
				maskCheck := 0
				for j := 0; (j < *min) && ((maskCheck & 15) != 15); j++ {
					maskCheck |= (*maskCharset)[j][(*maskPos)[j]]
				}
				if (maskCheck & 15) == 15 { // Valid mask
					return true
				}

				(*maskPos)[l]++
			}

			for l > 0 {
				(*maskPos)[l] = 0

				l--
				(*maskPos)[l]++
				if (*maskPos)[l] < len((*maskCharset)[l]) {
					l++ // ++ for last break check (l == 0)
					break
				}
			}
			if l == 0 {
				break
			}
		}
	}

	return false
}

func GetMask(maskLen int, posMask *map[int]int) string {
	mask := ""

	for l := 0; l < maskLen; l++ {
		if posMask != nil {
			if _, ok := (*posMask)[l]; ok {
				mask += MaskInfo[l].Chars[(*posMask)[l]]
				continue
			}
		}

		for ic := 0; ic < 4; ic++ {
			if MaskInfo[l].Len[CHARSETS[ic]] > 0 {
				mask += MaskInfo[l].Chars[CHARSETS[ic]]
				break
			}
		}
	}

	return mask
}
<|endoftext|>


<commit_before>package plugins

import (
	"errors"

	"github.com/spf13/cobra"
)

type BackupFunc func()
type RestoreFunc func()
type CommandOb *cobra.Command

type plugin struct {
	Name    string
	Restore RestoreFunc
	Backup  BackupFunc
	Command CommandOb
}

// Formats is the list of registered formats.
var plugins []plugin

func Register(name string, restore RestoreFunc, backup BackupFunc, command CommandOb) {
	plugins = append(plugins, plugin{name, restore, backup, command})
}

func Get(name string) (plugin, error) {
	for _, p := range plugins {
		if p.Name == name {
			return p, nil
		}
	}
	return plugin{}, errors.New("no plugin found")
}

func GetAll() []plugin {
	return plugins
}
<commit_msg>Refactored plugin manager.<commit_after>package plugins

import (
	"errors"

	"github.com/spf13/cobra"
)

func init() {
	plugins = make(map[string]Plugin)
}

type BackupFunc func()
type RestoreFunc func()
type CommandOb *cobra.Command

type Plugin struct {
	Name    string
	Restore RestoreFunc
	Backup  BackupFunc
	Command CommandOb
}

var plugins map[string]Plugin

func Register(name string, restore RestoreFunc, backup BackupFunc, command CommandOb) {
	plugins[name] = Plugin{name, restore, backup, command}
}

func Get(name string) (Plugin, error) {
	p, ok := plugins[name]
	if !ok {
		return Plugin{}, errors.New("no plugin found")
	}
	return p, nil
}

func GetAll() map[string]Plugin {
	return plugins
}
<|endoftext|>


<commit_before>package handlers

import (
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/user"

	"github.com/icco/natnatnat/models"
	"github.com/pilu/traffic"
)

type RootData struct {
	Posts   interface{}
	IsAdmin bool
}

func RootHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	entries, err := models.AllPosts(c)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	data := &RootData{Posts: entries, IsAdmin: user.IsAdmin(c)}
	w.Render("index", data)
}

func AboutHandler(w traffic.ResponseWriter, r *traffic.Request) {
	http.Redirect(w, r.Request, "http://natwelch.com", 301)
}

func UnimplementedHandler(w traffic.ResponseWriter, r *traffic.Request) {
	http.Error(w, "Sorry, I haven't implemented this yet", 500)
}

func MarkdownHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)

	err := r.ParseForm()
	if err != nil {
		log.Warningf(c, "Couldn't parse form: %v", r)
		http.Error(w, "Unable to parse request.", 500)
		return
	}

	in := r.Request.FormValue("text")
	md := models.Markdown(in)

	log.Infof(c, "Markdown Recieved: %s", in)
	log.Infof(c, "Markdown Rendered: %s", md)
	w.WriteText(string(md))
}
<commit_msg>pagination to root<commit_after>package handlers

import (
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/user"

	"github.com/icco/natnatnat/models"
	"github.com/pilu/traffic"
)

type RootData struct {
	Posts   interface{}
	IsAdmin bool
}

const perPage = 50

func RootHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	pg, err := strconv.ParseInt(r.Param("page"), 10, 64)
	if err != nil {
		log.Infof(c, "Error parsing: %+v")
	}

	entries, err := models.Pagination(c, perPage, 0)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	data := &RootData{Posts: entries, IsAdmin: user.IsAdmin(c), Page: 0}
	w.Render("index", data)
}

func AboutHandler(w traffic.ResponseWriter, r *traffic.Request) {
	http.Redirect(w, r.Request, "http://natwelch.com", 301)
}

func UnimplementedHandler(w traffic.ResponseWriter, r *traffic.Request) {
	http.Error(w, "Sorry, I haven't implemented this yet", 500)
}

func MarkdownHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)

	err := r.ParseForm()
	if err != nil {
		log.Warningf(c, "Couldn't parse form: %v", r)
		http.Error(w, "Unable to parse request.", 500)
		return
	}

	in := r.Request.FormValue("text")
	md := models.Markdown(in)

	log.Infof(c, "Markdown Recieved: %s", in)
	log.Infof(c, "Markdown Rendered: %s", md)
	w.WriteText(string(md))
}
<|endoftext|>


<commit_before>package terraform

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs/configschema"
	"github.com/hashicorp/terraform/providers"
	"github.com/hashicorp/terraform/states"
	"github.com/hashicorp/terraform/tfdiags"
)

// UpgradeResourceState will, if necessary, run the provider-defined upgrade
// logic against the given state object to make it compliant with the
// current schema version. This is a no-op if the given state object is
// already at the latest version.
//
// If any errors occur during upgrade, error diagnostics are returned. In that
// case it is not safe to proceed with using the original state object.
func UpgradeResourceState(addr addrs.AbsResourceInstance, provider providers.Interface, src *states.ResourceInstanceObjectSrc, currentSchema *configschema.Block, currentVersion uint64) (*states.ResourceInstanceObjectSrc, tfdiags.Diagnostics) {
	currentTy := currentSchema.ImpliedType()

	// If the state is currently in flatmap format and the current schema
	// contains DynamicPseudoType attributes then we won't be able to convert
	// it to JSON without the provider's help even if the schema version matches,
	// since only the provider knows how to interpret the dynamic attribute
	// value in flatmap format to convert it to JSON.
	schemaHasDynamic := currentTy.HasDynamicTypes()
	stateIsFlatmap := len(src.AttrsJSON) == 0
	forceProviderUpgrade := schemaHasDynamic && stateIsFlatmap

	if src.SchemaVersion == currentVersion && !forceProviderUpgrade {
		// No upgrading required, then.
		return src, nil
	}
	if addr.Resource.Resource.Mode != addrs.ManagedResourceMode {
		// We only do state upgrading for managed resources.
		return src, nil
	}

	providerType := addr.Resource.Resource.DefaultProviderConfig().Type
	if src.SchemaVersion > currentVersion {
		log.Printf("[TRACE] UpgradeResourceState: can't downgrade state for %s from version %d to %d", addr, src.SchemaVersion, currentVersion)
		var diags tfdiags.Diagnostics
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Resource instance managed by newer provider version",
			// This is not a very good error message, but we don't retain enough
			// information in state to give good feedback on what provider
			// version might be required here. :(
			fmt.Sprintf("The current state of %s was created by a newer provider version than is currently selected. Upgrade the %s provider to work with this state.", addr, providerType),
		))
		return nil, diags
	}

	// If we get down here then we need to upgrade the state, with the
	// provider's help.
	// If this state was originally created by a version of Terraform prior to
	// v0.12, this also includes translating from legacy flatmap to new-style
	// representation, since only the provider has enough information to
	// understand a flatmap built against an older schema.
	log.Printf("[TRACE] UpgradeResourceState: upgrading state for %s from version %d to %d using provider %q", addr, src.SchemaVersion, currentVersion, providerType)

	req := providers.UpgradeResourceStateRequest{
		TypeName: addr.Resource.Resource.Type,

		// TODO: The internal schema version representations are all using
		// uint64 instead of int64, but unsigned integers aren't friendly
		// to all protobuf target languages so in practice we use int64
		// on the wire. In future we will change all of our internal
		// representations to int64 too.
		Version: int64(src.SchemaVersion),
	}

	if stateIsFlatmap {
		req.RawStateFlatmap = src.AttrsFlat
	} else {
		req.RawStateJSON = src.AttrsJSON
	}

	resp := provider.UpgradeResourceState(req)
	diags := resp.Diagnostics
	if diags.HasErrors() {
		return nil, diags
	}

	// After upgrading, the new value must conform to the current schema. When
	// going over RPC this is actually already ensured by the
	// marshaling/unmarshaling of the new value, but we'll check it here
	// anyway for robustness, e.g. for in-process providers.
	newValue := resp.UpgradedState
	if errs := newValue.Type().TestConformance(currentSchema.ImpliedType()); len(errs) > 0 {
		for _, err := range errs {
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Invalid resource state upgrade",
				fmt.Sprintf("The %s provider upgraded the state for %s from a previous version, but produced an invalid result: %s.", providerType, addr, tfdiags.FormatError(err)),
			))
		}
		return nil, diags
	}

	new, err := src.CompleteUpgrade(newValue, currentSchema.ImpliedType(), uint64(currentVersion))
	if err != nil {
		// We already checked for type conformance above, so getting into this
		// codepath should be rare and is probably a bug somewhere under CompleteUpgrade.
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Failed to encode result of resource state upgrade",
			fmt.Sprintf("Failed to encode state for %s after resource schema upgrade: %s.", addr, tfdiags.FormatError(err)),
		))
	}
	return new, diags
}
<commit_msg>core: Call providers' UpgradeResourceState every time<commit_after>package terraform

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs/configschema"
	"github.com/hashicorp/terraform/providers"
	"github.com/hashicorp/terraform/states"
	"github.com/hashicorp/terraform/tfdiags"
)

// UpgradeResourceState will, if necessary, run the provider-defined upgrade
// logic against the given state object to make it compliant with the
// current schema version. This is a no-op if the given state object is
// already at the latest version.
//
// If any errors occur during upgrade, error diagnostics are returned. In that
// case it is not safe to proceed with using the original state object.
func UpgradeResourceState(addr addrs.AbsResourceInstance, provider providers.Interface, src *states.ResourceInstanceObjectSrc, currentSchema *configschema.Block, currentVersion uint64) (*states.ResourceInstanceObjectSrc, tfdiags.Diagnostics) {
	if addr.Resource.Resource.Mode != addrs.ManagedResourceMode {
		// We only do state upgrading for managed resources.
		return src, nil
	}

	stateIsFlatmap := len(src.AttrsJSON) == 0

	providerType := addr.Resource.Resource.DefaultProviderConfig().Type
	if src.SchemaVersion > currentVersion {
		log.Printf("[TRACE] UpgradeResourceState: can't downgrade state for %s from version %d to %d", addr, src.SchemaVersion, currentVersion)
		var diags tfdiags.Diagnostics
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Resource instance managed by newer provider version",
			// This is not a very good error message, but we don't retain enough
			// information in state to give good feedback on what provider
			// version might be required here. :(
			fmt.Sprintf("The current state of %s was created by a newer provider version than is currently selected. Upgrade the %s provider to work with this state.", addr, providerType),
		))
		return nil, diags
	}

	// If we get down here then we need to upgrade the state, with the
	// provider's help.
	// If this state was originally created by a version of Terraform prior to
	// v0.12, this also includes translating from legacy flatmap to new-style
	// representation, since only the provider has enough information to
	// understand a flatmap built against an older schema.
	if src.SchemaVersion != currentVersion {
		log.Printf("[TRACE] UpgradeResourceState: upgrading state for %s from version %d to %d using provider %q", addr, src.SchemaVersion, currentVersion, providerType)
	} else {
		log.Printf("[TRACE] UpgradeResourceState: schema version of %s is still %d; calling provider %q for any other minor fixups", addr, currentVersion, providerType)
	}

	req := providers.UpgradeResourceStateRequest{
		TypeName: addr.Resource.Resource.Type,

		// TODO: The internal schema version representations are all using
		// uint64 instead of int64, but unsigned integers aren't friendly
		// to all protobuf target languages so in practice we use int64
		// on the wire. In future we will change all of our internal
		// representations to int64 too.
		Version: int64(src.SchemaVersion),
	}

	if stateIsFlatmap {
		req.RawStateFlatmap = src.AttrsFlat
	} else {
		req.RawStateJSON = src.AttrsJSON
	}

	resp := provider.UpgradeResourceState(req)
	diags := resp.Diagnostics
	if diags.HasErrors() {
		return nil, diags
	}

	// After upgrading, the new value must conform to the current schema. When
	// going over RPC this is actually already ensured by the
	// marshaling/unmarshaling of the new value, but we'll check it here
	// anyway for robustness, e.g. for in-process providers.
	newValue := resp.UpgradedState
	if errs := newValue.Type().TestConformance(currentSchema.ImpliedType()); len(errs) > 0 {
		for _, err := range errs {
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Invalid resource state upgrade",
				fmt.Sprintf("The %s provider upgraded the state for %s from a previous version, but produced an invalid result: %s.", providerType, addr, tfdiags.FormatError(err)),
			))
		}
		return nil, diags
	}

	new, err := src.CompleteUpgrade(newValue, currentSchema.ImpliedType(), uint64(currentVersion))
	if err != nil {
		// We already checked for type conformance above, so getting into this
		// codepath should be rare and is probably a bug somewhere under CompleteUpgrade.
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Failed to encode result of resource state upgrade",
			fmt.Sprintf("Failed to encode state for %s after resource schema upgrade: %s.", addr, tfdiags.FormatError(err)),
		))
	}
	return new, diags
}
<|endoftext|>


<commit_before>package processors

import (
	"fmt"

	"github.com/nanobox-io/nanobox/models"
	"github.com/nanobox-io/nanobox/processors/env"
	"github.com/nanobox-io/nanobox/util"
	"github.com/nanobox-io/nanobox/util/locker"
)

//
func Clean(envModels []*models.Env) error {
	locker.GlobalLock()
	defer locker.GlobalUnlock()

	for _, envModel := range envModels {
		// check to see if the app folder still exists
		if !util.FolderExists(envModel.Directory) {

			if err := env.Destroy(envModel); err != nil {
				return fmt.Errorf("unable to destroy environment(%s): %s", envModel.Name, err)
			}
		}
	}

	return nil
}
<commit_msg>Adding display logic to clean process<commit_after>package processors

import (
	"fmt"

	"github.com/nanobox-io/nanobox/models"
	"github.com/nanobox-io/nanobox/processors/env"
	"github.com/nanobox-io/nanobox/util"
	"github.com/nanobox-io/nanobox/util/display"
	"github.com/nanobox-io/nanobox/util/locker"
)

//
func Clean(envModels []*models.Env) error {
	locker.GlobalLock()
	defer locker.GlobalUnlock()

	display.OpenContext("Cleaning stale environments")
	defer display.CloseContext()

	// if any of the apps are stale, we'll mark this to true
	stale := false

	for _, envModel := range envModels {
		// check to see if the app folder still exists
		if !util.FolderExists(envModel.Directory) {

			if err := env.Destroy(envModel); err != nil {
				return fmt.Errorf("unable to destroy environment(%s): %s", envModel.Name, err)
			}
		}
	}

	if !stale {
		display.StartTask("Skipping (none detected)")
		display.StopTask()
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).

//go:generate -command genxdr go run ../../syncthing/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go
//go:generate genxdr -o packets_xdr.go packets.go

package protocol

import (
	"fmt"
	syncthingprotocol "github.com/syncthing/protocol"
	"net"
)

const (
	messageTypePing int32 = iota
	messageTypePong
	messageTypeJoinRelayRequest
	messageTypeJoinSessionRequest
	messageTypeResponse
	messageTypeConnectRequest
	messageTypeSessionInvitation
)

type header struct {
	magic         uint32
	messageType   int32
	messageLength int32
}

type Ping struct{}
type Pong struct{}
type JoinRelayRequest struct{}

type JoinSessionRequest struct {
	Key []byte // max:32
}

type Response struct {
	Code    int32
	Message string
}

type ConnectRequest struct {
	ID []byte // max:32
}

type SessionInvitation struct {
	From         []byte // max:32
	Key          []byte // max:32
	Address      []byte // max:32
	Port         uint16
	ServerSocket bool
}

func (i *SessionInvitation) String() string {
	return fmt.Sprintf("%s@%s", syncthingprotocol.DeviceIDFromBytes(i.From), i.AddressString())
}

func (i *SessionInvitation) AddressString() string {
	return fmt.Sprintf("%s:%d", net.IP(i.Address), i.Port)
}
<commit_msg>Change receiver type, add GoStringer<commit_after>// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).

//go:generate -command genxdr go run ../../syncthing/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go
//go:generate genxdr -o packets_xdr.go packets.go

package protocol

import (
	"fmt"
	syncthingprotocol "github.com/syncthing/protocol"
	"net"
)

const (
	messageTypePing int32 = iota
	messageTypePong
	messageTypeJoinRelayRequest
	messageTypeJoinSessionRequest
	messageTypeResponse
	messageTypeConnectRequest
	messageTypeSessionInvitation
)

type header struct {
	magic         uint32
	messageType   int32
	messageLength int32
}

type Ping struct{}
type Pong struct{}
type JoinRelayRequest struct{}

type JoinSessionRequest struct {
	Key []byte // max:32
}

type Response struct {
	Code    int32
	Message string
}

type ConnectRequest struct {
	ID []byte // max:32
}

type SessionInvitation struct {
	From         []byte // max:32
	Key          []byte // max:32
	Address      []byte // max:32
	Port         uint16
	ServerSocket bool
}

func (i SessionInvitation) String() string {
	return fmt.Sprintf("%s@%s", syncthingprotocol.DeviceIDFromBytes(i.From), i.AddressString())
}

func (i SessionInvitation) GoString() string {
	return i.String()
}

func (i SessionInvitation) AddressString() string {
	return fmt.Sprintf("%s:%d", net.IP(i.Address), i.Port)
}
<|endoftext|>


<commit_before>package intset

import (
	"bytes"
	"fmt"
)

// An IntSet is a set of small non-negative integers.
// Its zero value represents the empty set.
type IntSet struct {
	words []uint64
}

// Has reports whether the set contains the non-negative value x.
func (s *IntSet) Has(x int) bool {
	word, bit := x/64, uint(x%64)
	return word < len(s.words) && s.words[word]&(1<<bit) != 0
}

// Add adds the non-negative value x to the set.
func (s *IntSet) Add(x int) {
	word, bit := x/64, uint(x%64)
	for word >= len(s.words) {
		s.words = append(s.words, 0)
	}
	s.words[word] |= 1 << bit
}

// UnionWith sets s to the union of s and t.
func (s *IntSet) UnionWith(t *IntSet) {
	for i, tword := range t.words {
		if i < len(s.words) {
			s.words[i] |= tword
		} else {
			s.words = append(s.words, tword)
		}
	}
}

// Len returns the number of value in the set.
func (s *IntSet) Len() int {
	var num int
	for _, word := range s.words {
		for word != 0 {
			word = word & (word - 1)
			num++
		}
	}
	return num
}

// Remove removes value from the set.
func (s *IntSet) Remove(x int) {
	// if !s.Has(x) {
	// 	return
	// }
	word, bit := x/64, uint(x%64)
	if word < len(s.words) {
		s.words[word] &= ^(1 << bit)
	}
}

// Clean removes all value from the set.
func (s *IntSet) Clean() {
	// s.words = make(IntSet, 0)
	s.words = nil
}

// Copy returns a new copy of the set.
func (s *IntSet) Copy() *IntSet {
	newSet := new(IntSet)
	newSet.words = make([]uint64, len(s.words))
	copy(newSet.words, s.words)
	return newSet
}

// AddAll adds a given values to the set.
func (s *IntSet) AddAll(values ...int) {
	for _, v := range values {
		s.Add(v)
	}
}

// Elems returns slice of values of the set.
func (s *IntSet) Elems() []int {
	elements := make([]int, 0, s.Len())
	for i, word := range s.words {
		if word == 0 {
			continue
		}
		for j := 0; j < 64; j++ {
			if word&(1<<uint(j)) != 0 {
				elements = append(elements, 64*i+j)
			}
		}
	}
	return elements
}

// String returns the set as a string of the form "{1 2 3}".
func (s *IntSet) String() string {
	var buf bytes.Buffer
	buf.WriteByte('{')
	for _, e := range s.Elems() {
		if buf.Len() > len("}") {
			buf.WriteByte(' ')
		}
		fmt.Fprintf(&buf, "%d", e)
	}
	buf.WriteByte('}')
	return buf.String()
}
<commit_msg>[6.5] Solutions is added.<commit_after>package intset

import (
	"bytes"
	"fmt"
)

// UINTSIZE represents size of uint.
const UINTSIZE = 32 << (^uint(0) >> 63)

// An IntSet is a set of small non-negative integers.
// Its zero value represents the empty set.
type IntSet struct {
	words []uint
}

// Has reports whether the set contains the non-negative value x.
func (s *IntSet) Has(x int) bool {
	word, bit := x/UINTSIZE, uint(x%UINTSIZE)
	return word < len(s.words) && s.words[word]&(1<<bit) != 0
}

// Add adds the non-negative value x to the set.
func (s *IntSet) Add(x int) {
	word, bit := x/UINTSIZE, uint(x%UINTSIZE)
	for word >= len(s.words) {
		s.words = append(s.words, 0)
	}
	s.words[word] |= 1 << bit
}

// UnionWith sets s to the union of s and t.
func (s *IntSet) UnionWith(t *IntSet) {
	for i, tword := range t.words {
		if i < len(s.words) {
			s.words[i] |= tword
		} else {
			s.words = append(s.words, tword)
		}
	}
}

// Len returns the number of value in the set.
func (s *IntSet) Len() int {
	var num int
	for _, word := range s.words {
		for word != 0 {
			word = word & (word - 1)
			num++
		}
	}
	return num
}

// Remove removes value from the set.
func (s *IntSet) Remove(x int) {
	// if !s.Has(x) {
	// 	return
	// }
	word, bit := x/UINTSIZE, uint(x%UINTSIZE)
	if word < len(s.words) {
		s.words[word] &= ^(1 << bit)
	}
}

// Clean removes all value from the set.
func (s *IntSet) Clean() {
	// s.words = make(IntSet, 0)
	s.words = nil
}

// Copy returns a new copy of the set.
func (s *IntSet) Copy() *IntSet {
	newSet := new(IntSet)
	newSet.words = make([]uint, len(s.words))
	copy(newSet.words, s.words)
	return newSet
}

// AddAll adds a given values to the set.
func (s *IntSet) AddAll(values ...int) {
	for _, v := range values {
		s.Add(v)
	}
}

// Elems returns slice of values of the set.
func (s *IntSet) Elems() []int {
	elements := make([]int, 0, s.Len())
	for i, word := range s.words {
		if word == 0 {
			continue
		}
		for j := 0; j < UINTSIZE; j++ {
			if word&(1<<uint(j)) != 0 {
				elements = append(elements, UINTSIZE*i+j)
			}
		}
	}
	return elements
}

// String returns the set as a string of the form "{1 2 3}".
func (s *IntSet) String() string {
	var buf bytes.Buffer
	buf.WriteByte('{')
	for _, e := range s.Elems() {
		if buf.Len() > len("}") {
			buf.WriteByte(' ')
		}
		fmt.Fprintf(&buf, "%d", e)
	}
	buf.WriteByte('}')
	return buf.String()
}
<|endoftext|>


<commit_before>package gorush

import (
	"context"
	"encoding/json"
	"errors"
	"sync"

	"github.com/msalihkarakasli/go-hms-push/push/config"
	"github.com/msalihkarakasli/go-hms-push/push/core"
	"github.com/msalihkarakasli/go-hms-push/push/model"
)

var (
	pushError  error
	pushClient *core.HMSClient
	once       sync.Once
)

// GetPushClient use for create HMS Push
func GetPushClient(conf *config.Config) (*core.HMSClient, error) {
	once.Do(func() {
		client, err := core.NewHttpClient(conf)
		if err != nil {
			panic(err)
		}
		pushClient = client
		pushError = err
	})

	return pushClient, pushError
}

// InitHMSClient use for initialize HMS Client.
func InitHMSClient(apiKey, appID string) (*core.HMSClient, error) {
	if apiKey == "" {
		return nil, errors.New("Missing Huawei API Key")
	}

	if appID == "" {
		return nil, errors.New("Missing Huawei APP Id")
	}

	conf := &config.Config{
		AppId:     appID,
		AppSecret: apiKey,
		AuthUrl:   "https://login.cloud.huawei.com/oauth2/v2/token",
		PushUrl:   "https://api.push.hicloud.com",
	}

	if apiKey != PushConf.Huawei.APIKey || appID != PushConf.Huawei.APPId {
		return GetPushClient(conf)
	}

	if HMSClient == nil {
		return GetPushClient(conf)
	}

	return HMSClient, nil
}

// GetHuaweiNotification use for define HMS notification.
// HTTP Connection Server Reference for HMS
// https://developer.huawei.com/consumer/en/doc/development/HMS-References/push-sendapi
func GetHuaweiNotification(req PushNotification) (*model.MessageRequest, error) {
	msgRequest := model.NewNotificationMsgRequest()

	msgRequest.Message.Android = model.GetDefaultAndroid()

	if len(req.Tokens) > 0 {
		msgRequest.Message.Token = req.Tokens
	}

	if len(req.Topic) > 0 {
		msgRequest.Message.Topic = req.Topic
	}

	if len(req.To) > 0 {
		msgRequest.Message.Topic = req.To
	}

	if len(req.Condition) > 0 {
		msgRequest.Message.Condition = req.Condition
	}

	if req.Priority == "high" {
		msgRequest.Message.Android.Urgency = "HIGH"
	}

	// if req.HuaweiCollapseKey != nil {
	msgRequest.Message.Android.CollapseKey = req.HuaweiCollapseKey
	//}

	if len(req.Category) > 0 {
		msgRequest.Message.Android.Category = req.Category
	}

	if len(req.HuaweiTTL) > 0 {
		msgRequest.Message.Android.TTL = req.HuaweiTTL
	}

	if len(req.BiTag) > 0 {
		msgRequest.Message.Android.BiTag = req.BiTag
	}

	msgRequest.Message.Android.FastAppTarget = req.FastAppTarget

	// Add data fields
	if len(req.HuaweiData) > 0 {
		msgRequest.Message.Data = req.HuaweiData
	} else {
		// Notification Message
		msgRequest.Message.Android.Notification = model.GetDefaultAndroidNotification()

		n := msgRequest.Message.Android.Notification
		isNotificationSet := false

		if req.HuaweiNotification != nil {
			isNotificationSet = true
			n = req.HuaweiNotification

			if n.ClickAction == nil {
				n.ClickAction = model.GetDefaultClickAction()
			}
		}

		if len(req.Message) > 0 {
			isNotificationSet = true
			n.Body = req.Message
		}

		if len(req.Title) > 0 {
			isNotificationSet = true
			n.Title = req.Title
		}

		if len(req.Image) > 0 {
			isNotificationSet = true
			n.Image = req.Image
		}

		if v, ok := req.Sound.(string); ok && len(v) > 0 {
			isNotificationSet = true
			n.Sound = v
		} else {
			n.DefaultSound = true
		}

		if isNotificationSet {
			msgRequest.Message.Android.Notification = n
		}
	}

	b, err := json.Marshal(msgRequest)
	if err != nil {
		LogError.Error("Failed to marshal the default message! Error is " + err.Error())
		return nil, err
	}

	LogAccess.Debugf("Default message is %s", string(b))
	return msgRequest, nil
}

// PushToHuawei provide send notification to Android server.
func PushToHuawei(req PushNotification) bool {
	LogAccess.Debug("Start push notification for Huawei")

	var (
		client     *core.HMSClient
		retryCount = 0
		maxRetry   = PushConf.Huawei.MaxRetry
	)

	if req.Retry > 0 && req.Retry < maxRetry {
		maxRetry = req.Retry
	}

	// check message
	err := CheckMessage(req)
	if err != nil {
		LogError.Error("request error: " + err.Error())
		return false
	}

Retry:
	isError := false

	notification, _ := GetHuaweiNotification(req)

	client, err = InitHMSClient(PushConf.Huawei.APIKey, PushConf.Huawei.APPId)

	if err != nil {
		// HMS server error
		LogError.Error("HMS server error: " + err.Error())
		return false
	}

	res, err := client.SendMessage(context.Background(), notification)
	if err != nil {
		// Send Message error
		LogError.Error("HMS server send message error: " + err.Error())
		return false
	}

	// Huawei Push Send API does not support exact results for each token
	if res.Code == "80000000" {
		StatStorage.AddHuaweiSuccess(int64(1))
		LogAccess.Debug("Huwaei Send Notification is completed successfully!")
	} else {
		isError = true
		StatStorage.AddHuaweiError(int64(1))
		LogAccess.Debug("Huwaei Send Notification is failed!")
	}

	if isError && retryCount < maxRetry {
		retryCount++

		// resend all tokens
		goto Retry
	}

	return isError
}
<commit_msg>show Result Code if huawei push fails (#559)<commit_after>package gorush

import (
	"context"
	"encoding/json"
	"errors"
	"sync"

	"github.com/msalihkarakasli/go-hms-push/push/config"
	"github.com/msalihkarakasli/go-hms-push/push/core"
	"github.com/msalihkarakasli/go-hms-push/push/model"
)

var (
	pushError  error
	pushClient *core.HMSClient
	once       sync.Once
)

// GetPushClient use for create HMS Push
func GetPushClient(conf *config.Config) (*core.HMSClient, error) {
	once.Do(func() {
		client, err := core.NewHttpClient(conf)
		if err != nil {
			panic(err)
		}
		pushClient = client
		pushError = err
	})

	return pushClient, pushError
}

// InitHMSClient use for initialize HMS Client.
func InitHMSClient(apiKey, appID string) (*core.HMSClient, error) {
	if apiKey == "" {
		return nil, errors.New("Missing Huawei API Key")
	}

	if appID == "" {
		return nil, errors.New("Missing Huawei APP Id")
	}

	conf := &config.Config{
		AppId:     appID,
		AppSecret: apiKey,
		AuthUrl:   "https://login.cloud.huawei.com/oauth2/v2/token",
		PushUrl:   "https://api.push.hicloud.com",
	}

	if apiKey != PushConf.Huawei.APIKey || appID != PushConf.Huawei.APPId {
		return GetPushClient(conf)
	}

	if HMSClient == nil {
		return GetPushClient(conf)
	}

	return HMSClient, nil
}

// GetHuaweiNotification use for define HMS notification.
// HTTP Connection Server Reference for HMS
// https://developer.huawei.com/consumer/en/doc/development/HMS-References/push-sendapi
func GetHuaweiNotification(req PushNotification) (*model.MessageRequest, error) {
	msgRequest := model.NewNotificationMsgRequest()

	msgRequest.Message.Android = model.GetDefaultAndroid()

	if len(req.Tokens) > 0 {
		msgRequest.Message.Token = req.Tokens
	}

	if len(req.Topic) > 0 {
		msgRequest.Message.Topic = req.Topic
	}

	if len(req.To) > 0 {
		msgRequest.Message.Topic = req.To
	}

	if len(req.Condition) > 0 {
		msgRequest.Message.Condition = req.Condition
	}

	if req.Priority == "high" {
		msgRequest.Message.Android.Urgency = "HIGH"
	}

	// if req.HuaweiCollapseKey != nil {
	msgRequest.Message.Android.CollapseKey = req.HuaweiCollapseKey
	//}

	if len(req.Category) > 0 {
		msgRequest.Message.Android.Category = req.Category
	}

	if len(req.HuaweiTTL) > 0 {
		msgRequest.Message.Android.TTL = req.HuaweiTTL
	}

	if len(req.BiTag) > 0 {
		msgRequest.Message.Android.BiTag = req.BiTag
	}

	msgRequest.Message.Android.FastAppTarget = req.FastAppTarget

	// Add data fields
	if len(req.HuaweiData) > 0 {
		msgRequest.Message.Data = req.HuaweiData
	} else {
		// Notification Message
		msgRequest.Message.Android.Notification = model.GetDefaultAndroidNotification()

		n := msgRequest.Message.Android.Notification
		isNotificationSet := false

		if req.HuaweiNotification != nil {
			isNotificationSet = true
			n = req.HuaweiNotification

			if n.ClickAction == nil {
				n.ClickAction = model.GetDefaultClickAction()
			}
		}

		if len(req.Message) > 0 {
			isNotificationSet = true
			n.Body = req.Message
		}

		if len(req.Title) > 0 {
			isNotificationSet = true
			n.Title = req.Title
		}

		if len(req.Image) > 0 {
			isNotificationSet = true
			n.Image = req.Image
		}

		if v, ok := req.Sound.(string); ok && len(v) > 0 {
			isNotificationSet = true
			n.Sound = v
		} else {
			n.DefaultSound = true
		}

		if isNotificationSet {
			msgRequest.Message.Android.Notification = n
		}
	}

	b, err := json.Marshal(msgRequest)
	if err != nil {
		LogError.Error("Failed to marshal the default message! Error is " + err.Error())
		return nil, err
	}

	LogAccess.Debugf("Default message is %s", string(b))
	return msgRequest, nil
}

// PushToHuawei provide send notification to Android server.
func PushToHuawei(req PushNotification) bool {
	LogAccess.Debug("Start push notification for Huawei")

	var (
		client     *core.HMSClient
		retryCount = 0
		maxRetry   = PushConf.Huawei.MaxRetry
	)

	if req.Retry > 0 && req.Retry < maxRetry {
		maxRetry = req.Retry
	}

	// check message
	err := CheckMessage(req)
	if err != nil {
		LogError.Error("request error: " + err.Error())
		return false
	}

Retry:
	isError := false

	notification, _ := GetHuaweiNotification(req)

	client, err = InitHMSClient(PushConf.Huawei.APIKey, PushConf.Huawei.APPId)

	if err != nil {
		// HMS server error
		LogError.Error("HMS server error: " + err.Error())
		return false
	}

	res, err := client.SendMessage(context.Background(), notification)
	if err != nil {
		// Send Message error
		LogError.Error("HMS server send message error: " + err.Error())
		return false
	}

	// Huawei Push Send API does not support exact results for each token
	if res.Code == "80000000" {
		StatStorage.AddHuaweiSuccess(int64(1))
		LogAccess.Debug("Huwaei Send Notification is completed successfully!")
	} else {
		isError = true
		StatStorage.AddHuaweiError(int64(1))
		LogAccess.Debug("Huawei Send Notification is failed! Code: " + res.Code)
	}

	if isError && retryCount < maxRetry {
		retryCount++

		// resend all tokens
		goto Retry
	}

	return isError
}
<|endoftext|>


<commit_before>package jc

import (
	"fmt"
	"reflect"
	"errors"
	"gopkg.in/mgo.v2"
	"github.com/kalcok/jc/tools"
)

type Query struct {
	Database    string
	collection  string
	filter      interface{}
	limit       int
	skip        int
	singleValue bool
	result      interface{}
	resultType  reflect.Type
}

func NewQuery(result interface{}) (newQuery Query, err error) {
	newQuery.result = result

	internalType := reflect.TypeOf(result).Elem()

	if internalType.Kind() == reflect.Slice {
		internalType = internalType.Elem()
		newQuery.singleValue = false
	} else {
		newQuery.singleValue = true
	}

	prototype := reflect.New(internalType)
	targetInterface := reflect.TypeOf((*document)(nil)).Elem()
	if !prototype.Type().Implements(targetInterface) {
		err = errors.New(
			fmt.Sprintf("Supplied 'result' type does not implement '%s'.", targetInterface.String()))
		return
	}

	newQuery.resultType = internalType
	proto_val := initPrototype(prototype, internalType)

	newQuery.collection = proto_val.FieldByName("_collectionName").String()
	newQuery.Database = proto_val.FieldByName("_collectionDB").String()

	return
}

func (q *Query) Execute(reuseSocket bool) (err error) {
	var session *mgo.Session
	masterSession, err := tools.GetSession()

	if err != nil {
		return
	}

	if reuseSocket {
		session = masterSession.Clone()
	} else {
		session = masterSession.Copy()
	}
	query := session.DB(q.Database).C(q.collection).Find(q.filter)

	if q.skip > 0 {
		query = query.Skip(q.skip)
	}

	if q.limit > 0 {
		query = query.Limit(q.limit)
	}

	if q.singleValue {
		err = query.One(q.result)
	} else {
		err = query.All(q.result)
	}

	if err != nil {
		return
	}
	q.initResult()
	return
}

func (q *Query) Filter(filter interface{}) *Query {
	q.filter = filter
	return q
}

func (q *Query) Limit(limit int) *Query {
	q.limit = limit
	return q
}

func (q *Query) Skip(skip int) *Query {
	q.skip = skip
	return q
}

func (q *Query) initResult() error {
	var err error
	resultv := reflect.ValueOf(q.result)

	if q.singleValue {
		initPrototype(resultv, q.resultType)
	} else {
		slicev := resultv.Elem()
		for i := 0; i < slicev.Len(); i++ {
			initPrototype(slicev.Index(i).Addr(), q.resultType)
		}
	}

	return err
}
<commit_msg>Add Getter for Query collection name<commit_after>package jc

import (
	"fmt"
	"reflect"
	"errors"
	"gopkg.in/mgo.v2"
	"github.com/kalcok/jc/tools"
)

type Query struct {
	Database    string
	collection  string
	filter      interface{}
	limit       int
	skip        int
	singleValue bool
	result      interface{}
	resultType  reflect.Type
}

func NewQuery(result interface{}) (newQuery Query, err error) {
	newQuery.result = result

	internalType := reflect.TypeOf(result).Elem()

	if internalType.Kind() == reflect.Slice {
		internalType = internalType.Elem()
		newQuery.singleValue = false
	} else {
		newQuery.singleValue = true
	}

	prototype := reflect.New(internalType)
	targetInterface := reflect.TypeOf((*document)(nil)).Elem()
	if !prototype.Type().Implements(targetInterface) {
		err = errors.New(
			fmt.Sprintf("Supplied 'result' type does not implement '%s'.", targetInterface.String()))
		return
	}

	newQuery.resultType = internalType
	proto_val := initPrototype(prototype, internalType)

	newQuery.collection = proto_val.FieldByName("_collectionName").String()
	newQuery.Database = proto_val.FieldByName("_collectionDB").String()

	return
}

func (q *Query) Execute(reuseSocket bool) (err error) {
	var session *mgo.Session
	masterSession, err := tools.GetSession()

	if err != nil {
		return
	}

	if reuseSocket {
		session = masterSession.Clone()
	} else {
		session = masterSession.Copy()
	}
	query := session.DB(q.Database).C(q.collection).Find(q.filter)

	if q.skip > 0 {
		query = query.Skip(q.skip)
	}

	if q.limit > 0 {
		query = query.Limit(q.limit)
	}

	if q.singleValue {
		err = query.One(q.result)
	} else {
		err = query.All(q.result)
	}

	if err != nil {
		return
	}
	q.initResult()
	return
}

func (q *Query) Collection() string {
	return q.collection
}

func (q *Query) Filter(filter interface{}) *Query {
	q.filter = filter
	return q
}

func (q *Query) Limit(limit int) *Query {
	q.limit = limit
	return q
}

func (q *Query) Skip(skip int) *Query {
	q.skip = skip
	return q
}

func (q *Query) initResult() error {
	var err error
	resultv := reflect.ValueOf(q.result)

	if q.singleValue {
		initPrototype(resultv, q.resultType)
	} else {
		slicev := resultv.Elem()
		for i := 0; i < slicev.Len(); i++ {
			initPrototype(slicev.Index(i).Addr(), q.resultType)
		}
	}

	return err
}
<|endoftext|>


<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

package main

import (
	"bytes"
	"encoding/json"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

// ============================================================================================================================
// Read - read a generic variable from ledger
//
// Shows Off GetState() - reading a key/value from the ledger
//
// Inputs - Array of strings
//  0
//  key
//  "abc"
//
// Returns - string
// ============================================================================================================================
func read(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var key, jsonResp string
	var err error
	fmt.Println("starting read")

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting key of the var to query")
	}

	// input sanitation
	err = sanitize_arguments(args)
	if err != nil {
		return shim.Error(err.Error())
	}

	key = args[0]
	valAsbytes, err := stub.GetState(key)           //get the var from ledger
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
		return shim.Error(jsonResp)
	}

	fmt.Println("- end read")
	return shim.Success(valAsbytes)                  //send it onward
}

// ============================================================================================================================
// Get everything we need (owners + marbles + companies)
//
// Inputs - none
//
// Returns:
// {
//	"owners": [{
//			"id": "o99999999",
//			"company": "United Marbles"
//			"username": "alice"
//	}],
//	"marbles": [{
//		"id": "m1490898165086",
//		"color": "white",
//		"docType" :"marble",
//		"owner": {
//			"company": "United Marbles"
//			"username": "alice"
//		},
//		"size" : 35
//	}]
// }
// ============================================================================================================================
func read_everything(stub shim.ChaincodeStubInterface) pb.Response {
	type Everything struct {
		Owners   []Owner   `json:"owners"`
		Marbles  []Marble  `json:"marbles"`
	}
	var everything Everything

	// ---- Get All Marbles ---- //
	resultsIterator, err := stub.GetStateByRange("m0", "m9999999999999999999")
	if err != nil {
		return shim.Error(err.Error())
	}
	defer resultsIterator.Close()

	for resultsIterator.HasNext() {
		queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}

		fmt.Println("on marble id - ", queryKeyAsStr)
		var marble Marble
		json.Unmarshal(queryValAsBytes, &marble)                  //un stringify it aka JSON.parse()
		everything.Marbles = append(everything.Marbles, marble)   //add this marble to the list
	}
	fmt.Println("marble array - ", everything.Marbles)

	// ---- Get All Owners ---- //
	ownersIterator, err := stub.GetStateByRange("o0", "o9999999999999999999")
	if err != nil {
		return shim.Error(err.Error())
	}
	defer ownersIterator.Close()

	for ownersIterator.HasNext() {
		queryKeyAsStr, queryValAsBytes, err := ownersIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}

		fmt.Println("on owner id - ", queryKeyAsStr)
		var owner Owner
		json.Unmarshal(queryValAsBytes, &owner)                  //un stringify it aka JSON.parse()
		everything.Owners = append(everything.Owners, owner)     //add this marble to the list
	}
	fmt.Println("owner array - ", everything.Owners)

	//change to array of bytes
	everythingAsBytes, _ := json.Marshal(everything)             //convert to array of bytes
	return shim.Success(everythingAsBytes)
}

// ============================================================================================================================
// Get history of asset
//
// Shows Off GetHistoryForKey() - reading complete history of a key/value
//
// Inputs - Array of strings
//  0
//  id
//  "m01490985296352SjAyM"
// ============================================================================================================================
func getHistory(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	type AuditHistory struct {
		TxId    string   `json:"txId"`
		Value   Marble   `json:"value"`
	}
	var history []AuditHistory;
	var marble Marble

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	marbleId := args[0]
	fmt.Printf("- start getHistoryForMarble: %s\n", marbleId)

	// Get History
	resultsIterator, err := stub.GetHistoryForKey(marbleId)
	if err != nil {
		return shim.Error(err.Error())
	}
	defer resultsIterator.Close()

	for resultsIterator.HasNext() {
		txID, historicValue, err := resultsIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}

		var tx AuditHistory
		tx.TxId = txID                             //copy transaction id over
		json.Unmarshal(historicValue, &marble)     //un stringify it aka JSON.parse()
		if historicValue == nil {                  //marble has been deleted
			var emptyMarble Marble
			tx.Value = emptyMarble                 //copy nil marble
		} else {
			json.Unmarshal(historicValue, &marble) //un stringify it aka JSON.parse()
			tx.Value = marble                      //copy marble over
		}
		history = append(history, tx)              //add this tx to the list
	}
	fmt.Printf("- getHistoryForMarble returning:\n%s", history)

	//change to array of bytes
	historyAsBytes, _ := json.Marshal(history)     //convert to array of bytes
	return shim.Success(historyAsBytes)
}

// ============================================================================================================================
// Get history of asset - performs a range query based on the start and end keys provided.
//
// Shows Off GetStateByRange() - reading a multiple key/values from the ledger
//
// Inputs - Array of strings
//       0     ,    1
//   startKey  ,  endKey
//  "marbles1" , "marbles5"
// ============================================================================================================================
func getMarblesByRange(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	startKey := args[0]
	endKey := args[1]

	resultsIterator, err := stub.GetStateByRange(startKey, endKey)
	if err != nil {
		return shim.Error(err.Error())
	}
	defer resultsIterator.Close()

	// buffer is a JSON array containing QueryResults
	var buffer bytes.Buffer
	buffer.WriteString("[")

	bArrayMemberAlreadyWritten := false
	for resultsIterator.HasNext() {
		queryResultKey, queryResultValue, err := resultsIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}
		// Add a comma before array members, suppress it for the first array member
		if bArrayMemberAlreadyWritten == true {
			buffer.WriteString(",")
		}
		buffer.WriteString("{\"Key\":")
		buffer.WriteString("\"")
		buffer.WriteString(queryResultKey)
		buffer.WriteString("\"")

		buffer.WriteString(", \"Record\":")
		// Record is a JSON object, so we write as-is
		buffer.WriteString(string(queryResultValue))
		buffer.WriteString("}")
		bArrayMemberAlreadyWritten = true
	}
	buffer.WriteString("]")

	fmt.Printf("- getMarblesByRange queryResult:\n%s\n", buffer.String())

	return shim.Success(buffer.Bytes())
}
<commit_msg>Update to use new Fabric v1 struct changes<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

package main

import (
	"bytes"
	"encoding/json"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

// ============================================================================================================================
// Read - read a generic variable from ledger
//
// Shows Off GetState() - reading a key/value from the ledger
//
// Inputs - Array of strings
//  0
//  key
//  "abc"
//
// Returns - string
// ============================================================================================================================
func read(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var key, jsonResp string
	var err error
	fmt.Println("starting read")

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting key of the var to query")
	}

	// input sanitation
	err = sanitize_arguments(args)
	if err != nil {
		return shim.Error(err.Error())
	}

	key = args[0]
	valAsbytes, err := stub.GetState(key)           //get the var from ledger
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
		return shim.Error(jsonResp)
	}

	fmt.Println("- end read")
	return shim.Success(valAsbytes)                  //send it onward
}

// ============================================================================================================================
// Get everything we need (owners + marbles + companies)
//
// Inputs - none
//
// Returns:
// {
//	"owners": [{
//			"id": "o99999999",
//			"company": "United Marbles"
//			"username": "alice"
//	}],
//	"marbles": [{
//		"id": "m1490898165086",
//		"color": "white",
//		"docType" :"marble",
//		"owner": {
//			"company": "United Marbles"
//			"username": "alice"
//		},
//		"size" : 35
//	}]
// }
// ============================================================================================================================
func read_everything(stub shim.ChaincodeStubInterface) pb.Response {
	type Everything struct {
		Owners   []Owner   `json:"owners"`
		Marbles  []Marble  `json:"marbles"`
	}
	var everything Everything

	// ---- Get All Marbles ---- //
	resultsIterator, err := stub.GetStateByRange("m0", "m9999999999999999999")
	if err != nil {
		return shim.Error(err.Error())
	}
	defer resultsIterator.Close()

	for resultsIterator.HasNext() {
                aKeyValue, err := resultsIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}
                queryKeyAsStr := aKeyValue.Key
                queryValAsBytes := aKeyValue.Value
		fmt.Println("on marble id - ", queryKeyAsStr)
		var marble Marble
		json.Unmarshal(queryValAsBytes, &marble)                  //un stringify it aka JSON.parse()
		everything.Marbles = append(everything.Marbles, marble)   //add this marble to the list
	}
	fmt.Println("marble array - ", everything.Marbles)

	// ---- Get All Owners ---- //
	ownersIterator, err := stub.GetStateByRange("o0", "o9999999999999999999")
	if err != nil {
		return shim.Error(err.Error())
	}
	defer ownersIterator.Close()

	for ownersIterator.HasNext() {
                aKeyValue, err := ownersIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}
		queryKeyAsStr := aKeyValue.Key
                queryValAsBytes := aKeyValue.Value
		fmt.Println("on owner id - ", queryKeyAsStr)
		var owner Owner
		json.Unmarshal(queryValAsBytes, &owner)                  //un stringify it aka JSON.parse()
		everything.Owners = append(everything.Owners, owner)     //add this marble to the list
	}
	fmt.Println("owner array - ", everything.Owners)

	//change to array of bytes
	everythingAsBytes, _ := json.Marshal(everything)             //convert to array of bytes
	return shim.Success(everythingAsBytes)
}

// ============================================================================================================================
// Get history of asset
//
// Shows Off GetHistoryForKey() - reading complete history of a key/value
//
// Inputs - Array of strings
//  0
//  id
//  "m01490985296352SjAyM"
// ============================================================================================================================
func getHistory(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	type AuditHistory struct {
		TxId    string   `json:"txId"`
		Value   Marble   `json:"value"`
	}
	var history []AuditHistory;
	var marble Marble

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	marbleId := args[0]
	fmt.Printf("- start getHistoryForMarble: %s\n", marbleId)

	// Get History
	resultsIterator, err := stub.GetHistoryForKey(marbleId)
	if err != nil {
		return shim.Error(err.Error())
	}
	defer resultsIterator.Close()

	for resultsIterator.HasNext() {
                historyData, err := resultsIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}

		var tx AuditHistory
		tx.TxId = historyData.TxID                             //copy transaction id over
		json.Unmarshal(historyData.Value, &marble)     //un stringify it aka JSON.parse()
		if historyData.Value == nil {                  //marble has been deleted
			var emptyMarble Marble
			tx.Value = emptyMarble                 //copy nil marble
		} else {
			json.Unmarshal(historyData.Value, &marble) //un stringify it aka JSON.parse()
			tx.Value = marble                      //copy marble over
		}
		history = append(history, tx)              //add this tx to the list
	}
	fmt.Printf("- getHistoryForMarble returning:\n%s", history)

	//change to array of bytes
	historyAsBytes, _ := json.Marshal(history)     //convert to array of bytes
	return shim.Success(historyAsBytes)
}

// ============================================================================================================================
// Get history of asset - performs a range query based on the start and end keys provided.
//
// Shows Off GetStateByRange() - reading a multiple key/values from the ledger
//
// Inputs - Array of strings
//       0     ,    1
//   startKey  ,  endKey
//  "marbles1" , "marbles5"
// ============================================================================================================================
func getMarblesByRange(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	startKey := args[0]
	endKey := args[1]

	resultsIterator, err := stub.GetStateByRange(startKey, endKey)
	if err != nil {
		return shim.Error(err.Error())
	}
	defer resultsIterator.Close()

	// buffer is a JSON array containing QueryResults
	var buffer bytes.Buffer
	buffer.WriteString("[")

	bArrayMemberAlreadyWritten := false
	for resultsIterator.HasNext() {
		aKeyValue, err := resultsIterator.Next()
		if err != nil {
			return shim.Error(err.Error())
		}
                queryResultKey := aKeyValue.Key
                queryResultValue := aKeyValue.Value

		// Add a comma before array members, suppress it for the first array member
		if bArrayMemberAlreadyWritten == true {
			buffer.WriteString(",")
		}
		buffer.WriteString("{\"Key\":")
		buffer.WriteString("\"")
		buffer.WriteString(queryResultKey)
		buffer.WriteString("\"")

		buffer.WriteString(", \"Record\":")
		// Record is a JSON object, so we write as-is
		buffer.WriteString(string(queryResultValue))
		buffer.WriteString("}")
		bArrayMemberAlreadyWritten = true
	}
	buffer.WriteString("]")

	fmt.Printf("- getMarblesByRange queryResult:\n%s\n", buffer.String())

	return shim.Success(buffer.Bytes())
}
<|endoftext|>